/*
- * Copyright (C) 2012, 2013, 2014
+ * Copyright (C) 2012, 2013, 2014, 2015
* Wolfgang Bumiller
* Dale Weiler
*
/* helper function */
static ir_value* ir_builder_imm_float(ir_builder *self, float value, bool add_to_list) {
ir_value *v = ir_value_var("#IMMEDIATE", store_global, TYPE_FLOAT);
+ v->flags |= IR_FLAG_ERASABLE;
v->hasvalue = true;
v->cvq = CV_CONST;
v->constval.vfloat = value;
ir_value *operand)
{
int ot = TYPE_FLOAT;
+ ir_value *minus_1 = NULL;
+ if (opcode == VINSTR_NEG_F || opcode == VINSTR_NEG_V)
+ minus_1 = ir_builder_imm_float(self->owner->owner, -1.0f, false);
switch (opcode) {
case INSTR_NOT_F:
case INSTR_NOT_V:
case INSTR_NOT_I: */
ot = TYPE_FLOAT;
break;
-
- /*
- * Negation for virtual instructions is emulated with 0-value. Thankfully
- * the operand for 0 already exists so we just source it from here.
- */
+ /* Negation is implemented as -1 * <operand> */
case VINSTR_NEG_F:
- return ir_block_create_general_instr(self, ctx, label, INSTR_SUB_F, NULL, operand, ot);
+ return ir_block_create_general_instr(self, ctx, label, INSTR_MUL_F, minus_1, operand, TYPE_FLOAT);
case VINSTR_NEG_V:
- return ir_block_create_general_instr(self, ctx, label, INSTR_SUB_V, NULL, operand, TYPE_VECTOR);
+ return ir_block_create_general_instr(self, ctx, label, INSTR_MUL_FV, minus_1, operand, TYPE_VECTOR);
default:
ot = operand->vtype;
* If there is no definition and the thing is eraseable, we can ignore
* outputting the function to begin with.
*/
- if (global->flags & IR_FLAG_ERASEABLE && irfun->code_function_def < 0) {
+ if (global->flags & IR_FLAG_ERASABLE && irfun->code_function_def < 0) {
return true;
}
* if we're eraseable and the function isn't referenced ignore outputting
* the function.
*/
- if (global->flags & IR_FLAG_ERASEABLE && vec_size(global->reads) == 0) {
+ if (global->flags & IR_FLAG_ERASABLE && vec_size(global->reads) == 0) {
return true;
}
{
ir_value_code_setaddr(global, vec_size(self->code->globals));
if (global->hasvalue) {
+ if (global->cvq == CV_CONST && !vec_size(global->reads))
+ return true;
iptr = (int32_t*)&global->constval.ivec[0];
vec_push(self->code->globals, *iptr);
} else {
{
ir_value_code_setaddr(global, vec_size(self->code->globals));
if (global->hasvalue) {
- uint32_t load = code_genstring(self->code, global->constval.vstring);
+ uint32_t load;
+ if (global->cvq == CV_CONST && !vec_size(global->reads))
+ return true;
+ load = code_genstring(self->code, global->constval.vstring);
vec_push(self->code->globals, load);
} else {
vec_push(self->code->globals, 0);