]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - ir.c
Merging master to handle vector members, fields, and members of vector fields
[xonotic/gmqcc.git] / ir.c
diff --git a/ir.c b/ir.c
index e01da4d4e102c8c6e9d93e5be5f97ed3d047b876..78c97c7058e6230e397c4ec8a9da343555a0589c 100644 (file)
--- a/ir.c
+++ b/ir.c
  * Type sizes used at multiple points in the IR codegen
  */
 
  * Type sizes used at multiple points in the IR codegen
  */
 
+const char *type_name[TYPE_COUNT] = {
+    "void",
+    "string",
+    "float",
+    "vector",
+    "entity",
+    "field",
+    "function",
+    "pointer",
+#if 0
+    "integer",
+#endif
+    "quaternion",
+    "matrix",
+    "variant"
+};
+
 size_t type_sizeof[TYPE_COUNT] = {
     1, /* TYPE_VOID     */
     1, /* TYPE_STRING   */
 size_t type_sizeof[TYPE_COUNT] = {
     1, /* TYPE_VOID     */
     1, /* TYPE_STRING   */
@@ -41,7 +58,9 @@ size_t type_sizeof[TYPE_COUNT] = {
 #if 0
     1, /* TYPE_INTEGER  */
 #endif
 #if 0
     1, /* TYPE_INTEGER  */
 #endif
-    3, /* TYPE_VARIANT  */
+    4, /* TYPE_QUATERNION */
+    16, /* TYPE_MATRIX */
+    16, /* TYPE_VARIANT  */
 };
 
 uint16_t type_store_instr[TYPE_COUNT] = {
 };
 
 uint16_t type_store_instr[TYPE_COUNT] = {
@@ -54,9 +73,12 @@ uint16_t type_store_instr[TYPE_COUNT] = {
     INSTR_STORE_FNC,
     INSTR_STORE_ENT, /* should use I */
 #if 0
     INSTR_STORE_FNC,
     INSTR_STORE_ENT, /* should use I */
 #if 0
-    INSTR_STORE_ENT, /* integer type */
+    INSTR_STORE_I, /* integer type */
 #endif
 #endif
-    INSTR_STORE_V, /* variant, should never be accessed */
+    INSTR_STORE_Q,
+    INSTR_STORE_M,
+
+    INSTR_STORE_M, /* variant, should never be accessed */
 };
 
 uint16_t type_storep_instr[TYPE_COUNT] = {
 };
 
 uint16_t type_storep_instr[TYPE_COUNT] = {
@@ -71,7 +93,10 @@ uint16_t type_storep_instr[TYPE_COUNT] = {
 #if 0
     INSTR_STOREP_ENT, /* integer type */
 #endif
 #if 0
     INSTR_STOREP_ENT, /* integer type */
 #endif
-    INSTR_STOREP_V, /* variant, should never be accessed */
+    INSTR_STOREP_Q,
+    INSTR_STOREP_M,
+
+    INSTR_STOREP_M, /* variant, should never be accessed */
 };
 
 MEM_VEC_FUNCTIONS(ir_value_vector, ir_value*, v)
 };
 
 MEM_VEC_FUNCTIONS(ir_value_vector, ir_value*, v)
@@ -187,9 +212,14 @@ ir_value* ir_builder_get_global(ir_builder *self, const char *name)
 
 ir_value* ir_builder_create_global(ir_builder *self, const char *name, int vtype)
 {
 
 ir_value* ir_builder_create_global(ir_builder *self, const char *name, int vtype)
 {
-    ir_value *ve = ir_builder_get_global(self, name);
-    if (ve) {
-        return NULL;
+    ir_value *ve;
+
+    if (name && name[0] != '#')
+    {
+        ve = ir_builder_get_global(self, name);
+        if (ve) {
+            return NULL;
+        }
     }
 
     ve = ir_value_var(name, store_global, vtype);
     }
 
     ve = ir_value_var(name, store_global, vtype);
@@ -664,6 +694,24 @@ bool ir_value_set_vector(ir_value *self, vector v)
     return true;
 }
 
     return true;
 }
 
+bool ir_value_set_quaternion(ir_value *self, quaternion v)
+{
+    if (self->vtype != TYPE_QUATERNION)
+        return false;
+    memcpy(&self->constval.vquat, v, sizeof(self->constval.vquat));
+    self->isconst = true;
+    return true;
+}
+
+bool ir_value_set_matrix(ir_value *self, matrix v)
+{
+    if (self->vtype != TYPE_MATRIX)
+        return false;
+    memcpy(&self->constval.vmat, v, sizeof(self->constval.vmat));
+    self->isconst = true;
+    return true;
+}
+
 bool ir_value_set_field(ir_value *self, ir_value *fld)
 {
     if (self->vtype != TYPE_FIELD)
 bool ir_value_set_field(ir_value *self, ir_value *fld)
 {
     if (self->vtype != TYPE_FIELD)
@@ -1384,6 +1432,8 @@ ir_value* ir_block_create_load_from_ent(ir_block *self, const char *label, ir_va
         case TYPE_POINTER: op = INSTR_LOAD_I;   break;
         case TYPE_INTEGER: op = INSTR_LOAD_I;   break;
 #endif
         case TYPE_POINTER: op = INSTR_LOAD_I;   break;
         case TYPE_INTEGER: op = INSTR_LOAD_I;   break;
 #endif
+        case TYPE_QUATERNION: op = INSTR_LOAD_Q; break;
+        case TYPE_MATRIX:     op = INSTR_LOAD_M; break;
         default:
             return NULL;
     }
         default:
             return NULL;
     }
@@ -1487,12 +1537,22 @@ ir_value* ir_block_create_mul(ir_block *self,
             case TYPE_VECTOR:
                 op = INSTR_MUL_V;
                 break;
             case TYPE_VECTOR:
                 op = INSTR_MUL_V;
                 break;
+            case TYPE_QUATERNION:
+                op = INSTR_MUL_Q;
+                break;
+            case TYPE_MATRIX:
+                op = INSTR_MUL_M;
+                break;
         }
     } else {
         if ( (l == TYPE_VECTOR && r == TYPE_FLOAT) )
             op = INSTR_MUL_VF;
         else if ( (l == TYPE_FLOAT && r == TYPE_VECTOR) )
             op = INSTR_MUL_FV;
         }
     } else {
         if ( (l == TYPE_VECTOR && r == TYPE_FLOAT) )
             op = INSTR_MUL_VF;
         else if ( (l == TYPE_FLOAT && r == TYPE_VECTOR) )
             op = INSTR_MUL_FV;
+        else if ( (l == TYPE_QUATERNION && r == TYPE_FLOAT) )
+            op = INSTR_MUL_QF;
+        else if ( (l == TYPE_MATRIX && r == TYPE_FLOAT) )
+            op = INSTR_MUL_MF;
 #if 0
         else if ( (l == TYPE_VECTOR && r == TYPE_INTEGER) )
             op = INSTR_MUL_VI;
 #if 0
         else if ( (l == TYPE_VECTOR && r == TYPE_INTEGER) )
             op = INSTR_MUL_VI;
@@ -2558,6 +2618,8 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global)
         return global->code.globaladdr >= 0;
     }
     case TYPE_VECTOR:
         return global->code.globaladdr >= 0;
     }
     case TYPE_VECTOR:
+    case TYPE_QUATERNION:
+    case TYPE_MATRIX:
     {
         size_t d;
         if (code_defs_add(def) < 0)
     {
         size_t d;
         if (code_defs_add(def) < 0)
@@ -2847,6 +2909,7 @@ void ir_value_dump(ir_value* v, int (*oprintf)(const char*, ...))
 {
        if (v->isconst) {
                switch (v->vtype) {
 {
        if (v->isconst) {
                switch (v->vtype) {
+                   default:
                        case TYPE_VOID:
                                oprintf("(void)");
                                break;
                        case TYPE_VOID:
                                oprintf("(void)");
                                break;