]> git.xonotic.org Git - xonotic/gmqcc.git/commitdiff
First thing: we want quaternions and 4x4 matrices
authorWolfgang Bumiller <wolfgang.linux@bumiller.com>
Tue, 10 Jul 2012 17:26:07 +0000 (19:26 +0200)
committerWolfgang Bumiller <wolfgang.linux@bumiller.com>
Tue, 10 Jul 2012 17:26:07 +0000 (19:26 +0200)
ast.h
gmqcc.h
ir.c
ir.h

diff --git a/ast.h b/ast.h
index a08c4c0d4072d5df8bd61cacaff8fd971c59b704..37ee1714871f8eed816e098d447fdb83c2fb1368 100644 (file)
--- a/ast.h
+++ b/ast.h
@@ -107,6 +107,8 @@ struct ast_value_s
         const char   *vstring;
         int           ventity;
         ast_function *vfunc;
+        quaternion    vquat;
+        matrix        vmat;
     } constval;
 
     ir_value *ir_v;
diff --git a/gmqcc.h b/gmqcc.h
index 6a56675683904297cf8bf9538fe5f37f9b46d777..38db70069fbbdcc8dfdd3680a7b96a293ab306f2 100644 (file)
--- a/gmqcc.h
+++ b/gmqcc.h
@@ -365,6 +365,8 @@ enum {
     TYPE_FUNCTION ,
     TYPE_POINTER  ,
     /* TYPE_INTEGER  , */
+    TYPE_QUATERNION  ,
+    TYPE_MATRIX  ,
     TYPE_VARIANT  ,
 
     TYPE_COUNT
@@ -457,8 +459,11 @@ enum {
     INSTR_DONE,
     INSTR_MUL_F,
     INSTR_MUL_V,
-    INSTR_MUL_FV,
     INSTR_MUL_VF,
+    INSTR_MUL_Q,
+    INSTR_MUL_QF,
+    INSTR_MUL_M,
+    INSTR_MUL_MF,
     INSTR_DIV_F,
     INSTR_ADD_F,
     INSTR_ADD_V,
@@ -469,11 +474,15 @@ enum {
     INSTR_EQ_S,
     INSTR_EQ_E,
     INSTR_EQ_FNC,
+    INSTR_EQ_Q,
+    INSTR_EQ_M,
     INSTR_NE_F,
     INSTR_NE_V,
     INSTR_NE_S,
     INSTR_NE_E,
     INSTR_NE_FNC,
+    INSTR_NE_Q,
+    INSTR_NE_M,
     INSTR_LE,
     INSTR_GE,
     INSTR_LT,
@@ -484,6 +493,8 @@ enum {
     INSTR_LOAD_ENT,
     INSTR_LOAD_FLD,
     INSTR_LOAD_FNC,
+    INSTR_LOAD_Q,
+    INSTR_LOAD_M,
     INSTR_ADDRESS,
     INSTR_STORE_F,
     INSTR_STORE_V,
@@ -491,18 +502,24 @@ enum {
     INSTR_STORE_ENT,
     INSTR_STORE_FLD,
     INSTR_STORE_FNC,
+    INSTR_STORE_Q,
+    INSTR_STORE_M,
     INSTR_STOREP_F,
     INSTR_STOREP_V,
     INSTR_STOREP_S,
     INSTR_STOREP_ENT,
     INSTR_STOREP_FLD,
     INSTR_STOREP_FNC,
+    INSTR_STOREP_Q,
+    INSTR_STOREP_M,
     INSTR_RETURN,
     INSTR_NOT_F,
     INSTR_NOT_V,
     INSTR_NOT_S,
     INSTR_NOT_ENT,
     INSTR_NOT_FNC,
+    INSTR_INV_Q,
+    INSTR_INV_M,
     INSTR_IF,
     INSTR_IFNOT,
     INSTR_CALL0,
@@ -576,8 +593,11 @@ static const struct {
     { "DONE"      , 1, 4 },
     { "MUL_F"     , 3, 5 },
     { "MUL_V"     , 3, 5 },
-    { "MUL_FV"    , 3, 6 },
     { "MUL_VF"    , 3, 6 },
+    { "MUL_Q"     , 3, 5 },
+    { "MUL_QF"    , 3, 6 },
+    { "MUL_M"     , 3, 5 },
+    { "MUL_MF"    , 3, 6 },
     { "DIV"       , 0, 3 },
     { "ADD_F"     , 3, 5 },
     { "ADD_V"     , 3, 5 },
@@ -588,11 +608,15 @@ static const struct {
     { "EQ_S"      , 0, 4 },
     { "EQ_E"      , 0, 4 },
     { "EQ_FNC"    , 0, 6 },
+    { "EQ_Q"      , 0, 4 },
+    { "EQ_M"      , 0, 4 },
     { "NE_F"      , 0, 4 },
     { "NE_V"      , 0, 4 },
     { "NE_S"      , 0, 4 },
     { "NE_E"      , 0, 4 },
     { "NE_FNC"    , 0, 6 },
+    { "NE_Q"      , 0, 4 },
+    { "NE_M"      , 0, 4 },
     { "LE"        , 0, 2 },
     { "GE"        , 0, 2 },
     { "LT"        , 0, 2 },
@@ -603,6 +627,8 @@ static const struct {
     { "FIELD_ENT" , 0, 9 },
     { "FIELD_FLD" , 0, 9 },
     { "FIELD_FNC" , 0, 9 },
+    { "FIELD_Q"   , 0, 7 },
+    { "FIELD_M"   , 0, 7 },
     { "ADDRESS"   , 0, 7 },
     { "STORE_F"   , 0, 7 },
     { "STORE_V"   , 0, 7 },
@@ -610,18 +636,24 @@ static const struct {
     { "STORE_ENT" , 0, 9 },
     { "STORE_FLD" , 0, 9 },
     { "STORE_FNC" , 0, 9 },
+    { "STORE_Q"   , 0, 7 },
+    { "STORE_M"   , 0, 7 },
     { "STOREP_F"  , 0, 8 },
     { "STOREP_V"  , 0, 8 },
     { "STOREP_S"  , 0, 8 },
     { "STOREP_ENT", 0, 10},
     { "STOREP_FLD", 0, 10},
     { "STOREP_FNC", 0, 10},
+    { "STOREP_Q"  , 0, 8 },
+    { "STOREP_M"  , 0, 8 },
     { "RETURN"    , 0, 6 },
     { "NOT_F"     , 0, 5 },
     { "NOT_V"     , 0, 5 },
     { "NOT_S"     , 0, 5 },
     { "NOT_ENT"   , 0, 7 },
     { "NOT_FNC"   , 0, 7 },
+    { "INV_Q"     , 0, 5 },
+    { "INV_M"     , 0, 5 },
     { "IF"        , 0, 2 },
     { "IFNOT"     , 0, 5 },
     { "CALL0"     , 1, 5 },
@@ -783,6 +815,14 @@ typedef struct {
     float x, y, z;
 } vector;
 
+typedef float matrix[4][4]; /* OpenGL layout */
+typedef float quaternion[4]; /* order: x, y, z, w */
+#define MATRIX(axis, elem) ((4*(axis)) + (elem))
+#define QUAT_X 0
+#define QUAT_Y 1
+#define QUAT_Z 2
+#define QUAT_W 3
+
 /*
  * A shallow copy of a lex_file to remember where which ast node
  * came from.
diff --git a/ir.c b/ir.c
index e8b7382912775c341acc8cbf9a50981c05aec8e5..78dbc8ab3ab7c503c5cd81abdd079672fe82ae2d 100644 (file)
--- a/ir.c
+++ b/ir.c
@@ -41,7 +41,9 @@ size_t type_sizeof[TYPE_COUNT] = {
 #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] = {
@@ -54,9 +56,12 @@ uint16_t type_store_instr[TYPE_COUNT] = {
     INSTR_STORE_FNC,
     INSTR_STORE_ENT, /* should use I */
 #if 0
-    INSTR_STORE_ENT, /* integer type */
+    INSTR_STORE_I, /* integer type */
 #endif
-    INSTR_STORE_V, /* variant, should never be accessed */
+    INSTR_STORE_Q,
+    INSTR_STORE_M,
+
+    INSTR_STORE_M, /* variant, should never be accessed */
 };
 
 MEM_VEC_FUNCTIONS(ir_value_vector, ir_value*, v)
@@ -552,6 +557,24 @@ bool ir_value_set_vector(ir_value *self, vector v)
     return true;
 }
 
+bool ir_value_set_quaternion(ir_value *self, quaternion v)
+{
+    if (self->vtype != TYPE_QUATERNION)
+        return false;
+    self->constval.vquat = v;
+    self->isconst = true;
+    return true;
+}
+
+bool ir_value_set_matrix(ir_value *self, matrix v)
+{
+    if (self->vtype != TYPE_MATRIX)
+        return false;
+    self->constval.vmat = v;
+    self->isconst = true;
+    return true;
+}
+
 bool ir_value_set_string(ir_value *self, const char *str)
 {
     if (self->vtype != TYPE_STRING)
@@ -866,6 +889,12 @@ bool ir_block_create_store(ir_block *self, ir_value *target, ir_value *what)
             op = INSTR_STORE_ENT;
 #endif
             break;
+        case TYPE_QUATERNION:
+            op = INSTR_STORE_Q;
+            break;
+        case TYPE_MATRIX:
+            op = INSTR_STORE_M;
+            break;
         default:
             /* Unknown type */
             return false;
@@ -914,6 +943,12 @@ bool ir_block_create_storep(ir_block *self, ir_value *target, ir_value *what)
             op = INSTR_STOREP_ENT;
 #endif
             break;
+        case TYPE_QUATERNION:
+            op = INSTR_STOREP_Q;
+            break;
+        case TYPE_MATRIX:
+            op = INSTR_STOREP_M;
+            break;
         default:
             /* Unknown type */
             return false;
@@ -1175,7 +1210,6 @@ ir_value* ir_block_create_binop(ir_block *self,
         case INSTR_ADD_V:
         case INSTR_SUB_V:
         case INSTR_MUL_VF:
-        case INSTR_MUL_FV:
 #if 0
         case INSTR_DIV_VF:
         case INSTR_MUL_IV:
@@ -1275,6 +1309,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_QUATERNION: op = INSTR_LOAD_Q; break;
+        case TYPE_MATRIX:     op = INSTR_LOAD_M; break;
         default:
             return NULL;
     }
@@ -1378,12 +1414,22 @@ ir_value* ir_block_create_mul(ir_block *self,
             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_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;
@@ -2363,10 +2409,8 @@ static bool gen_global_function(ir_builder *ir, ir_value *global)
     for (i = 0;i < 8; ++i) {
         if (i >= fun.nargs)
             fun.argsize[i] = 0;
-        else if (irfun->params[i] == TYPE_VECTOR)
-            fun.argsize[i] = 3;
         else
-            fun.argsize[i] = 1;
+            fun.argsize[i] = type_sizeof[irfun->params[i]];
     }
 
     fun.firstlocal = code_globals_elements;
@@ -2453,19 +2497,32 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global)
         return global->code.globaladdr >= 0;
     }
     case TYPE_VECTOR:
+    case TYPE_QUATERNION:
+    case TYPE_MATRIX:
     {
+        size_t d;
         if (code_defs_add(def) < 0)
             return false;
 
         if (global->isconst) {
             iptr = (int32_t*)&global->constval.vvec;
             global->code.globaladdr = code_globals_add(iptr[0]);
-            if (code_globals_add(iptr[1]) < 0 || code_globals_add(iptr[2]) < 0)
+            if (global->code.globaladdr < 0)
                 return false;
+            for (d = 1; d < type_sizeof(global->vtype); ++d)
+            {
+                if (code_globals_add(iptr[d]) < 0)
+                    return false;
+            }
         } else {
             global->code.globaladdr = code_globals_add(0);
-            if (code_globals_add(0) < 0 || code_globals_add(0) < 0)
+            if (global->code.globaladdr < 0)
                 return false;
+            for (d = 1; d < type_sizeof(global->vtype); ++d)
+            {
+                if (code_globals_add(0) < 0)
+                    return false;
+            }
         }
         return global->code.globaladdr >= 0;
     }
@@ -2652,6 +2709,7 @@ void ir_value_dump(ir_value* v, int (*oprintf)(const char*, ...))
 {
        if (v->isconst) {
                switch (v->vtype) {
+                   default:
                        case TYPE_VOID:
                                oprintf("(void)");
                                break;
diff --git a/ir.h b/ir.h
index 7aa889bae7e25ab3ca822c8a562a9d9e90e4447b..721799bd5e71c448f5b526b2cdef7e4f3f1778fd 100644 (file)
--- a/ir.h
+++ b/ir.h
@@ -55,6 +55,8 @@ typedef struct ir_value_s {
         char    *vstring;
         struct ir_value_s *vpointer;
         struct ir_function_s *vfunc;
+        quaternion vquat;
+        matrix     vmat;
     } constval;
 
     struct {
@@ -89,6 +91,8 @@ bool GMQCC_WARN ir_value_set_string(ir_value*, const char *s);
 bool GMQCC_WARN ir_value_set_vector(ir_value*, vector v);
 /*bool   ir_value_set_pointer_v(ir_value*, ir_value* p); */
 /*bool   ir_value_set_pointer_i(ir_value*, int i);       */
+bool GMQCC_WARN ir_value_set_quaternion(ir_value*, quaternion v);
+bool GMQCC_WARN ir_value_set_matrix(ir_value*, matrix v);
 
 MEM_VECTOR_PROTO(ir_value, ir_life_entry_t, life);
 /* merge an instruction into the life-range */