]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - ir.cpp
ir: fix generation of multi-op vinstrs
[xonotic/gmqcc.git] / ir.cpp
diff --git a/ir.cpp b/ir.cpp
index 5df12449362846ac36e9ca3e19a608c257c185b6..0f7989f328e2f8501f4158e73751cd28742548b7 100644 (file)
--- a/ir.cpp
+++ b/ir.cpp
@@ -1474,6 +1474,7 @@ ir_instr* ir_block_create_call(ir_block *self, lex_ctx_t ctx, const char *label,
         !ir_instr_op(in, 1, func, false))
     {
         delete in;
+        delete out;
         return nullptr;
     }
     self->m_instr.push_back(in);
@@ -1643,7 +1644,7 @@ ir_value* ir_block_create_unary(ir_block *self, lex_ctx_t ctx,
         case VINSTR_NEG_F:
             return ir_block_create_general_instr(self, ctx, label, INSTR_SUB_F, nullptr, operand, ot);
         case VINSTR_NEG_V:
-            return ir_block_create_general_instr(self, ctx, label, INSTR_SUB_V, nullptr, operand, TYPE_VECTOR);
+            return ir_block_create_general_instr(self, ctx, label, INSTR_SUB_V, self->m_owner->m_owner->m_nil, operand, TYPE_VECTOR);
 
         default:
             ot = operand->m_vtype;
@@ -2514,7 +2515,7 @@ static bool gen_blocks_recursive(code_t *code, ir_function *func, ir_block *bloc
             stmt.opcode = INSTR_BITOR;
             stmt.o1.s1 = instr->_m_ops[1]->codeAddress();
             stmt.o2.s1 = instr->_m_ops[2]->codeAddress();
-            stmt.o3.s1 = instr->_m_ops[0]->codeAddress();
+            stmt.o3.s1 = func->m_owner->m_vinstr_temp[1]->codeAddress();
             code_push_statement(code, &stmt, instr->m_context);
             stmt.opcode = INSTR_BITAND;
             stmt.o1.s1 = instr->_m_ops[1]->codeAddress();
@@ -2522,7 +2523,7 @@ static bool gen_blocks_recursive(code_t *code, ir_function *func, ir_block *bloc
             stmt.o3.s1 = func->m_owner->m_vinstr_temp[0]->codeAddress();
             code_push_statement(code, &stmt, instr->m_context);
             stmt.opcode = INSTR_SUB_F;
-            stmt.o1.s1 = instr->_m_ops[0]->codeAddress();
+            stmt.o1.s1 = func->m_owner->m_vinstr_temp[1]->codeAddress();
             stmt.o2.s1 = func->m_owner->m_vinstr_temp[0]->codeAddress();
             stmt.o3.s1 = instr->_m_ops[0]->codeAddress();
             code_push_statement(code, &stmt, instr->m_context);
@@ -2574,7 +2575,7 @@ static bool gen_blocks_recursive(code_t *code, ir_function *func, ir_block *bloc
                 stmt.opcode = INSTR_BITOR;
                 stmt.o1.s1 = instr->_m_ops[1]->codeAddress() + j;
                 stmt.o2.s1 = instr->_m_ops[2]->codeAddress() + j;
-                stmt.o3.s1 = instr->_m_ops[0]->codeAddress() + j;
+                stmt.o3.s1 = func->m_owner->m_vinstr_temp[1]->codeAddress() + j;
                 code_push_statement(code, &stmt, instr->m_context);
                 stmt.opcode = INSTR_BITAND;
                 stmt.o1.s1 = instr->_m_ops[1]->codeAddress() + j;
@@ -2583,7 +2584,7 @@ static bool gen_blocks_recursive(code_t *code, ir_function *func, ir_block *bloc
                 code_push_statement(code, &stmt, instr->m_context);
             }
             stmt.opcode = INSTR_SUB_V;
-            stmt.o1.s1 = instr->_m_ops[0]->codeAddress();
+            stmt.o1.s1 = func->m_owner->m_vinstr_temp[1]->codeAddress();
             stmt.o2.s1 = func->m_owner->m_vinstr_temp[0]->codeAddress();
             stmt.o3.s1 = instr->_m_ops[0]->codeAddress();
             code_push_statement(code, &stmt, instr->m_context);
@@ -2631,7 +2632,7 @@ static bool gen_blocks_recursive(code_t *code, ir_function *func, ir_block *bloc
                 stmt.opcode = INSTR_BITOR;
                 stmt.o1.s1 = instr->_m_ops[1]->codeAddress() + j;
                 stmt.o2.s1 = instr->_m_ops[2]->codeAddress();
-                stmt.o3.s1 = instr->_m_ops[0]->codeAddress() + j;
+                stmt.o3.s1 = func->m_owner->m_vinstr_temp[1]->codeAddress() + j;
                 code_push_statement(code, &stmt, instr->m_context);
                 stmt.opcode = INSTR_BITAND;
                 stmt.o1.s1 = instr->_m_ops[1]->codeAddress() + j;
@@ -2640,7 +2641,7 @@ static bool gen_blocks_recursive(code_t *code, ir_function *func, ir_block *bloc
                 code_push_statement(code, &stmt, instr->m_context);
             }
             stmt.opcode = INSTR_SUB_V;
-            stmt.o1.s1 = instr->_m_ops[0]->codeAddress();
+            stmt.o1.s1 = func->m_owner->m_vinstr_temp[1]->codeAddress();
             stmt.o2.s1 = func->m_owner->m_vinstr_temp[0]->codeAddress();
             stmt.o3.s1 = instr->_m_ops[0]->codeAddress();
             code_push_statement(code, &stmt, instr->m_context);
@@ -2654,7 +2655,7 @@ static bool gen_blocks_recursive(code_t *code, ir_function *func, ir_block *bloc
             for (j = 0; j < 3; ++j) {
                 stmt.o1.s1 = instr->_m_ops[1]->codeAddress() + (j + 1) % 3;
                 stmt.o2.s1 = instr->_m_ops[2]->codeAddress() + (j + 2) % 3;
-                stmt.o3.s1 = instr->_m_ops[0]->codeAddress() + j;
+                stmt.o3.s1 = func->m_owner->m_vinstr_temp[1]->codeAddress() + j;
                 code_push_statement(code, &stmt, instr->m_context);
                 stmt.o1.s1 = instr->_m_ops[1]->codeAddress() + (j + 2) % 3;
                 stmt.o2.s1 = instr->_m_ops[2]->codeAddress() + (j + 1) % 3;
@@ -2662,7 +2663,7 @@ static bool gen_blocks_recursive(code_t *code, ir_function *func, ir_block *bloc
                 code_push_statement(code, &stmt, instr->m_context);
             }
             stmt.opcode = INSTR_SUB_V;
-            stmt.o1.s1 = instr->_m_ops[0]->codeAddress();
+            stmt.o1.s1 = func->m_owner->m_vinstr_temp[1]->codeAddress();
             stmt.o2.s1 = func->m_owner->m_vinstr_temp[0]->codeAddress();
             stmt.o3.s1 = instr->_m_ops[0]->codeAddress();
             code_push_statement(code, &stmt, instr->m_context);
@@ -3239,7 +3240,7 @@ bool ir_builder::generateGlobalFunctionCode(ir_value *global)
     return true;
 }
 
-static void gen_vector_defs(code_t *code, prog_section_def_t def, const char *name)
+static void gen_vector_defs(code_t *code, prog_section_def_t def, const char *name, int type)
 {
     char  *component;
     size_t len, i;
@@ -3247,7 +3248,7 @@ static void gen_vector_defs(code_t *code, prog_section_def_t def, const char *na
     if (!name || name[0] == '#' || OPTS_FLAG(SINGLE_VECTOR_DEFS))
         return;
 
-    def.type = TYPE_FLOAT;
+    def.type = type;
 
     len = strlen(name);
 
@@ -3347,9 +3348,9 @@ bool ir_builder::generateGlobal(ir_value *global, bool islocal)
             def.offset = global->codeAddress();
             m_code->defs.push_back(def);
             if (global->m_vtype == TYPE_VECTOR)
-                gen_vector_defs(m_code.get(), def, global->m_name.c_str());
+                gen_vector_defs(m_code.get(), def, global->m_name.c_str(), TYPE_FLOAT);
             else if (global->m_vtype == TYPE_FIELD && global->m_fieldtype == TYPE_VECTOR)
-                gen_vector_defs(m_code.get(), def, global->m_name.c_str());
+                gen_vector_defs(m_code.get(), def, global->m_name.c_str(), TYPE_FIELD);
             return true;
         }
     }
@@ -3391,7 +3392,7 @@ bool ir_builder::generateGlobal(ir_value *global, bool islocal)
         if (pushdef) {
             m_code->defs.push_back(def);
             if (global->m_fieldtype == TYPE_VECTOR)
-                gen_vector_defs(m_code.get(), def, global->m_name.c_str());
+                gen_vector_defs(m_code.get(), def, global->m_name.c_str(), TYPE_FIELD);
         }
         return gen_global_field(m_code.get(), global);
     case TYPE_ENTITY:
@@ -3457,7 +3458,7 @@ bool ir_builder::generateGlobal(ir_value *global, bool islocal)
         if (pushdef) {
             m_code->defs.push_back(def);
             def.type &= ~DEF_SAVEGLOBAL;
-            gen_vector_defs(m_code.get(), def, global->m_name.c_str());
+            gen_vector_defs(m_code.get(), def, global->m_name.c_str(), TYPE_FLOAT);
         }
         return global->m_code.globaladdr >= 0;
     }
@@ -3560,7 +3561,7 @@ static bool ir_builder_gen_field(ir_builder *self, ir_value *field)
     }
 
     if (field->m_fieldtype == TYPE_VECTOR) {
-        gen_vector_defs  (self->m_code.get(), def, field->m_name.c_str());
+        gen_vector_defs  (self->m_code.get(), def, field->m_name.c_str(), TYPE_FIELD);
         gen_vector_fields(self->m_code.get(), fld, field->m_name.c_str());
     }
 
@@ -4053,10 +4054,11 @@ void ir_value::dump(int (*oprintf)(const char*, ...)) const
                 oprintf("fn:%s", m_name.c_str());
                 break;
             case TYPE_FLOAT:
-                oprintf("%g", m_constval.vfloat);
+                // %.9g is lossless for IEEE single precision.
+                oprintf("%.9g", m_constval.vfloat);
                 break;
             case TYPE_VECTOR:
-                oprintf("'%g %g %g'",
+                oprintf("'%.9g %.9g %.9g'",
                         m_constval.vvec.x,
                         m_constval.vvec.y,
                         m_constval.vvec.z);