]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - ir.c
ir_value_set_field
[xonotic/gmqcc.git] / ir.c
diff --git a/ir.c b/ir.c
index 35f00b262c6e607458dfdb86ef6c173d7c6b8cf7..d007321383bb7298f90a8c4ae3262ce481745ec8 100644 (file)
--- a/ir.c
+++ b/ir.c
@@ -519,6 +519,19 @@ bool ir_instr_op(ir_instr *self, int op, ir_value *v, bool writing)
  *IR Value
  */
 
+void ir_value_code_setaddr(ir_value *self, int32_t gaddr)
+{
+    self->code.globaladdr = gaddr;
+    if (self->members[0]) self->members[0]->code.globaladdr = gaddr;
+    if (self->members[1]) self->members[1]->code.globaladdr = gaddr;
+    if (self->members[2]) self->members[2]->code.globaladdr = gaddr;
+}
+
+int32_t ir_value_code_addr(const ir_value *self)
+{
+    return self->code.globaladdr + self->code.addroffset;
+}
+
 ir_value* ir_value_var(const char *name, int storetype, int vtype)
 {
     ir_value *self;
@@ -541,6 +554,27 @@ ir_value* ir_value_var(const char *name, int storetype, int vtype)
     MEM_VECTOR_INIT(self, life);
     return self;
 }
+
+ir_value* ir_value_vector_member(ir_value *self, unsigned int member)
+{
+    ir_value *m;
+    if (member >= 3)
+        return NULL;
+
+    if (self->members[member])
+        return self->members[member];
+
+    m = ir_value_var(self->name, self->store, TYPE_FLOAT);
+    if (!m)
+        return NULL;
+    m->context = self->context;
+
+    self->members[member] = m;
+    m->code.addroffset = member;
+
+    return m;
+}
+
 MEM_VEC_FUNCTIONS(ir_value, ir_life_entry_t, life)
 MEM_VEC_FUNCTIONS_ALL(ir_value, ir_instr*, reads)
 MEM_VEC_FUNCTIONS_ALL(ir_value, ir_instr*, writes)
@@ -560,6 +594,7 @@ ir_value* ir_value_out(ir_function *owner, const char *name, int storetype, int
 
 void ir_value_delete(ir_value* self)
 {
+    size_t i;
     if (self->name)
         mem_d((void*)self->name);
     if (self->isconst)
@@ -567,6 +602,10 @@ void ir_value_delete(ir_value* self)
         if (self->vtype == TYPE_STRING)
             mem_d((void*)self->constval.vstring);
     }
+    for (i = 0; i < 3; ++i) {
+        if (self->members[i])
+            ir_value_delete(self->members[i]);
+    }
     MEM_VECTOR_CLEAR(self, reads);
     MEM_VECTOR_CLEAR(self, writes);
     MEM_VECTOR_CLEAR(self, life);
@@ -607,6 +646,15 @@ bool ir_value_set_vector(ir_value *self, vector v)
     return true;
 }
 
+bool ir_value_set_field(ir_value *self, ir_value *fld)
+{
+    if (self->vtype != TYPE_FIELD)
+        return false;
+    self->constval.vpointer = fld;
+    self->isconst = true;
+    return true;
+}
+
 bool ir_value_set_string(ir_value *self, const char *str)
 {
     if (self->vtype != TYPE_STRING)
@@ -2079,11 +2127,11 @@ static bool gen_global_field(ir_value *global)
         }
 
         /* copy the field's value */
-        global->code.globaladdr = code_globals_add(code_globals_data[fld->code.globaladdr]);
+        ir_value_code_setaddr(global, code_globals_add(code_globals_data[fld->code.globaladdr]));
     }
     else
     {
-        global->code.globaladdr = code_globals_add(0);
+        ir_value_code_setaddr(global, code_globals_add(0));
     }
     if (global->code.globaladdr < 0)
         return false;
@@ -2116,11 +2164,11 @@ static bool gen_global_pointer(ir_value *global)
             return false;
         }
 
-        global->code.globaladdr = code_globals_add(target->code.globaladdr);
+        ir_value_code_setaddr(global, code_globals_add(target->code.globaladdr));
     }
     else
     {
-        global->code.globaladdr = code_globals_add(0);
+        ir_value_code_setaddr(global, code_globals_add(0));
     }
     if (global->code.globaladdr < 0)
         return false;
@@ -2178,7 +2226,7 @@ tailcall:
              * come first: eg. optimize IFs without ELSE...
              */
 
-            stmt.o1.u1 = instr->_ops[0]->code.globaladdr;
+            stmt.o1.u1 = ir_value_code_addr(instr->_ops[0]);
             stmt.o2.u1 = 0;
             stmt.o3.s1 = 0;
 
@@ -2257,7 +2305,7 @@ tailcall:
                 stmt.o3.u1 = 0;
 
                 stmt.opcode = type_store_instr[param->vtype];
-                stmt.o1.u1 = param->code.globaladdr;
+                stmt.o1.u1 = ir_value_code_addr(param);
                 stmt.o2.u1 = OFS_PARM0 + 3 * p;
                 if (code_statements_add(stmt) < 0)
                     return false;
@@ -2265,7 +2313,7 @@ tailcall:
             stmt.opcode = INSTR_CALL0 + instr->params_count;
             if (stmt.opcode > INSTR_CALL8)
                 stmt.opcode = INSTR_CALL8;
-            stmt.o1.u1 = instr->_ops[1]->code.globaladdr;
+            stmt.o1.u1 = ir_value_code_addr(instr->_ops[1]);
             stmt.o2.u1 = 0;
             stmt.o3.u1 = 0;
             if (code_statements_add(stmt) < 0)
@@ -2277,7 +2325,7 @@ tailcall:
                 /* not to be kept in OFS_RETURN */
                 stmt.opcode = type_store_instr[retvalue->vtype];
                 stmt.o1.u1 = OFS_RETURN;
-                stmt.o2.u1 = retvalue->code.globaladdr;
+                stmt.o2.u1 = ir_value_code_addr(retvalue);
                 stmt.o3.u1 = 0;
                 if (code_statements_add(stmt) < 0)
                     return false;
@@ -2297,13 +2345,13 @@ tailcall:
 
         /* This is the general order of operands */
         if (instr->_ops[0])
-            stmt.o3.u1 = instr->_ops[0]->code.globaladdr;
+            stmt.o3.u1 = ir_value_code_addr(instr->_ops[0]);
 
         if (instr->_ops[1])
-            stmt.o1.u1 = instr->_ops[1]->code.globaladdr;
+            stmt.o1.u1 = ir_value_code_addr(instr->_ops[1]);
 
         if (instr->_ops[2])
-            stmt.o2.u1 = instr->_ops[2]->code.globaladdr;
+            stmt.o2.u1 = ir_value_code_addr(instr->_ops[2]);
 
         if (stmt.opcode == INSTR_RETURN || stmt.opcode == INSTR_DONE)
         {
@@ -2403,7 +2451,7 @@ static bool gen_global_function(ir_builder *ir, ir_value *global)
     {
         /* generate code.globaladdr for ssa values */
         ir_value *v = irfun->values[i];
-        v->code.globaladdr = local_var_end + v->code.local;
+        ir_value_code_setaddr(v, local_var_end + v->code.local);
     }
     for (i = 0; i < irfun->locals_count; ++i) {
         /* fill the locals with zeros */
@@ -2452,9 +2500,9 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global)
 
         if (global->isconst) {
             iptr = (int32_t*)&global->constval.vfloat;
-            global->code.globaladdr = code_globals_add(*iptr);
+            ir_value_code_setaddr(global, code_globals_add(*iptr));
         } else
-            global->code.globaladdr = code_globals_add(0);
+            ir_value_code_setaddr(global, code_globals_add(0));
 
         return global->code.globaladdr >= 0;
     }
@@ -2463,9 +2511,9 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global)
         if (code_defs_add(def) < 0)
             return false;
         if (global->isconst)
-            global->code.globaladdr = code_globals_add(code_cachedstring(global->constval.vstring));
+            ir_value_code_setaddr(global, code_globals_add(code_cachedstring(global->constval.vstring)));
         else
-            global->code.globaladdr = code_globals_add(0);
+            ir_value_code_setaddr(global, code_globals_add(0));
         return global->code.globaladdr >= 0;
     }
     case TYPE_VECTOR:
@@ -2476,7 +2524,7 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global)
 
         if (global->isconst) {
             iptr = (int32_t*)&global->constval.vvec;
-            global->code.globaladdr = code_globals_add(iptr[0]);
+            ir_value_code_setaddr(global, code_globals_add(iptr[0]));
             if (global->code.globaladdr < 0)
                 return false;
             for (d = 1; d < type_sizeof[global->vtype]; ++d)
@@ -2485,7 +2533,7 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global)
                     return false;
             }
         } else {
-            global->code.globaladdr = code_globals_add(0);
+            ir_value_code_setaddr(global, code_globals_add(0));
             if (global->code.globaladdr < 0)
                 return false;
             for (d = 1; d < type_sizeof[global->vtype]; ++d)
@@ -2499,12 +2547,12 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global)
     case TYPE_FUNCTION:
         if (code_defs_add(def) < 0)
             return false;
-        global->code.globaladdr = code_globals_elements;
+        ir_value_code_setaddr(global, code_globals_elements);
         code_globals_add(code_functions_elements);
         return gen_global_function(self, global);
     case TYPE_VARIANT:
         /* assume biggest type */
-            global->code.globaladdr = code_globals_add(0);
+            ir_value_code_setaddr(global, code_globals_add(0));
             for (i = 1; i < type_sizeof[TYPE_VARIANT]; ++i)
                 code_globals_add(0);
             return true;
@@ -2542,7 +2590,7 @@ static bool ir_builder_gen_field(ir_builder *self, ir_value *field)
     if (!code_globals_add(code_alloc_field(type_sizeof[field->fieldtype])))
         return false;
 
-    field->code.globaladdr = code_globals_add(fld.offset);
+    ir_value_code_setaddr(field, code_globals_add(fld.offset));
     return field->code.globaladdr >= 0;
 }