return NULL;
}
+ir_value* ir_block_create_fieldaddress(ir_block *self, const char *label, ir_value *ent, ir_value *field)
+{
+ ir_instr *instr;
+ ir_value *out;
+
+ /* Support for various pointer types todo if so desired */
+ if (ent->vtype != TYPE_ENTITY)
+ return NULL;
+
+ if (field->vtype != TYPE_FIELD)
+ return NULL;
+
+ out = ir_value_out(self->owner, label, store_value, TYPE_POINTER);
+ if (!out)
+ return NULL;
+
+ instr = ir_instr_new(self, INSTR_ADDRESS);
+ if (!instr) {
+ ir_value_delete(out);
+ return NULL;
+ }
+
+ if (!ir_instr_op(instr, 0, out, true) ||
+ !ir_instr_op(instr, 1, ent, false) ||
+ !ir_instr_op(instr, 2, field, false) )
+ {
+ goto on_error;
+ }
+
+ if (!ir_block_instr_add(self, instr))
+ goto on_error;
+
+ return out;
+on_error:
+ ir_instr_delete(instr);
+ ir_value_delete(out);
+ return NULL;
+}
+
ir_value* ir_block_create_load_from_ent(ir_block *self, const char *label, ir_value *ent, ir_value *field, int outype)
{
ir_instr *instr;
return NULL;
}
- out = ir_value_out(self->owner, label, store_local, outype);
+ out = ir_value_out(self->owner, label, store_value, outype);
if (!out)
return NULL;
}
if (!ir_instr_op(instr, 0, out, true) ||
- !ir_instr_op(instr, 0, ent, false) ||
- !ir_instr_op(instr, 0, field, false))
+ !ir_instr_op(instr, 1, ent, false) ||
+ !ir_instr_op(instr, 2, field, false) )
{
goto on_error;
}
/* field must be of TYPE_FIELD */
ir_value* ir_block_create_load_from_ent(ir_block*, const char *label, ir_value *ent, ir_value *field, int outype);
+ir_value* ir_block_create_fieldaddress(ir_block*, const char *label, ir_value *entity, ir_value *field);
+
ir_value* ir_block_create_add(ir_block*, const char *label, ir_value *l, ir_value *r);
ir_value* ir_block_create_sub(ir_block*, const char *label, ir_value *l, ir_value *r);
ir_value* ir_block_create_mul(ir_block*, const char *label, ir_value *l, ir_value *r);