]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - ir.c
gcc style long option support and -std=foo added
[xonotic/gmqcc.git] / ir.c
diff --git a/ir.c b/ir.c
index 0c0517a54d791cfdd248efcd98d8b4433fa8e9f4..f32f9d49492c2ae3efa4b58ec3d3df44e78a42f0 100644 (file)
--- a/ir.c
+++ b/ir.c
@@ -1169,6 +1169,39 @@ ir_value* ir_block_create_binop(ir_block *self,
     return ir_block_create_general_instr(self, label, opcode, left, right, ot);
 }
 
+ir_value* ir_block_create_unary(ir_block *self,
+                                const char *label, int opcode,
+                                ir_value *operand)
+{
+    int ot = TYPE_FLOAT;
+    switch (opcode) {
+        case INSTR_NOT_F:
+        case INSTR_NOT_V:
+        case INSTR_NOT_S:
+        case INSTR_NOT_ENT:
+        case INSTR_NOT_FNC:
+#if 0
+        case INSTR_NOT_I:
+#endif
+            ot = TYPE_FLOAT;
+            break;
+        /* QC doesn't have other unary operations. We expect extensions to fill
+         * the above list, otherwise we assume out-type = in-type, eg for an
+         * unary minus
+         */
+        default:
+            ot = operand->vtype;
+            break;
+    };
+    if (ot == TYPE_VOID) {
+        /* The AST or parser were supposed to check this! */
+        return NULL;
+    }
+
+    /* let's use the general instruction creator and pass NULL for OPB */
+    return ir_block_create_general_instr(self, label, opcode, operand, NULL, ot);
+}
+
 ir_value* ir_block_create_general_instr(ir_block *self, const char *label,
                                         int op, ir_value *a, ir_value *b, int outype)
 {
@@ -2254,10 +2287,8 @@ tailcall:
             stmt.o1.u1 = stmt.o3.u1;
             stmt.o3.u1 = 0;
         }
-        else if ((stmt.opcode >= INSTR_STORE_F    &&
-                  stmt.opcode <= INSTR_STORE_FNC)    ||
-                 (stmt.opcode >= INSTR_NOT_F      &&
-                  stmt.opcode <= INSTR_NOT_FNC))
+        else if (stmt.opcode >= INSTR_STORE_F &&
+                 stmt.opcode <= INSTR_STORE_FNC)
         {
             /* 2-operand instructions with A -> B */
             stmt.o2.u1 = stmt.o3.u1;
@@ -2371,6 +2402,7 @@ static bool gen_global_function(ir_builder *ir, ir_value *global)
 
 static bool ir_builder_gen_global(ir_builder *self, ir_value *global)
 {
+    size_t           i;
     int32_t         *iptr;
     prog_section_def def;
 
@@ -2450,8 +2482,8 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global)
     case TYPE_VARIANT:
         /* assume biggest type */
             global->code.globaladdr = code_globals_add(0);
-            code_globals_add(0);
-            code_globals_add(0);
+            for (i = 1; i < type_sizeof[TYPE_VARIANT]; ++i)
+                code_globals_add(0);
             return true;
     default:
         /* refuse to create 'void' type or any other fancy business. */