]> git.xonotic.org Git - xonotic/gmqcc.git/commitdiff
ir_block_create_fieldaddress - and fixing operand-numbering in load_from_ent
authorWolfgang Bumiller <wolfgang.linux@bumiller.com>
Tue, 1 May 2012 14:20:44 +0000 (16:20 +0200)
committerWolfgang Bumiller <wolfgang.linux@bumiller.com>
Tue, 1 May 2012 14:20:44 +0000 (16:20 +0200)
ir.c
ir.h

diff --git a/ir.c b/ir.c
index cbfe304c1fca8ac2c7d4b39f5885a12b84ef10fd..ac174ea939044477ce9db4bda9f195923ef0fbee 100644 (file)
--- a/ir.c
+++ b/ir.c
@@ -1009,6 +1009,45 @@ on_error:
     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;
@@ -1037,7 +1076,7 @@ ir_value* ir_block_create_load_from_ent(ir_block *self, const char *label, ir_va
             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;
 
@@ -1048,8 +1087,8 @@ ir_value* ir_block_create_load_from_ent(ir_block *self, const char *label, ir_va
     }
 
     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;
     }
diff --git a/ir.h b/ir.h
index 45f419dc3d3be784d3b8bce8405f5fcb00368d7c..2e219bdb6c54c6f085d99c9ee1aa327082ea3ce7 100644 (file)
--- a/ir.h
+++ b/ir.h
@@ -157,6 +157,8 @@ bool GMQCC_WARN ir_block_create_storep(ir_block*, ir_value *target, ir_value *wh
 /* 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);