]> git.rm.cloudns.org Git - xonotic/gmqcc.git/commitdiff
Vector cross product virtual instruction, now >< operator works for non-constant...
authorDale Weiler <killfieldengine@gmail.com>
Sat, 31 Aug 2013 18:49:06 +0000 (14:49 -0400)
committerDale Weiler <killfieldengine@gmail.com>
Sat, 31 Aug 2013 18:49:06 +0000 (14:49 -0400)
gmqcc.h
ir.c
parser.c
tests/vec_ops.qc
tests/vec_ops.tmpl

diff --git a/gmqcc.h b/gmqcc.h
index 0ecd55f0e2a838e57d83cdfb8957a09795b9f603..d8ad37465ef0525ea2298a9eb484f7a6e9220f04 100644 (file)
--- a/gmqcc.h
+++ b/gmqcc.h
@@ -725,7 +725,8 @@ enum {
     VINSTR_BITOR_VF,
     VINSTR_BITXOR,
     VINSTR_BITXOR_V,
-    VINSTR_BITXOR_VF /* BITXOR_VF must be the last emulated bitop */
+    VINSTR_BITXOR_VF,
+    VINSTR_CROSS
 };
 
 /* TODO: elide */
diff --git a/ir.c b/ir.c
index 3efad3da81164b9064c882e5c11179ace81e9463..4b7442e9ccf1a73fb714ee7be4554039b0f293b2 100644 (file)
--- a/ir.c
+++ b/ir.c
@@ -613,7 +613,7 @@ static bool instr_is_operation(uint16_t op)
              (op >= INSTR_NOT_F  && op <= INSTR_NOT_FNC) ||
              (op >= INSTR_AND    && op <= INSTR_BITOR) ||
              (op >= INSTR_CALL0  && op <= INSTR_CALL8) ||
-             (op >= VINSTR_BITAND_V && op <= VINSTR_BITXOR_VF) );
+             (op >= VINSTR_BITAND_V && op <= VINSTR_CROSS) );
 }
 
 static bool ir_function_pass_peephole(ir_function *self)
@@ -1815,6 +1815,7 @@ ir_value* ir_block_create_binop(ir_block *self, lex_ctx_t ctx,
         case VINSTR_BITAND_VF:
         case VINSTR_BITOR_VF:
         case VINSTR_BITXOR_VF:
+        case VINSTR_CROSS:
 #if 0
         case INSTR_DIV_VF:
         case INSTR_MUL_IV:
@@ -2518,7 +2519,8 @@ static bool ir_block_life_propagate(ir_block *self, bool *changed)
             instr->opcode == VINSTR_BITOR_VF ||
             instr->opcode == VINSTR_BITXOR ||
             instr->opcode == VINSTR_BITXOR_VF ||
-            instr->opcode == VINSTR_BITXOR_V)
+            instr->opcode == VINSTR_BITXOR_V ||
+            instr->opcode == VINSTR_CROSS)
         {
             value = instr->_ops[2];
             /* the float source will get an additional lifetime */
@@ -2532,7 +2534,8 @@ static bool ir_block_life_propagate(ir_block *self, bool *changed)
             instr->opcode == INSTR_LOAD_V ||
             instr->opcode == VINSTR_BITXOR ||
             instr->opcode == VINSTR_BITXOR_VF ||
-            instr->opcode == VINSTR_BITXOR_V)
+            instr->opcode == VINSTR_BITXOR_V ||
+            instr->opcode == VINSTR_CROSS)
         {
             value = instr->_ops[1];
             /* the float source will get an additional lifetime */
@@ -2960,6 +2963,28 @@ static bool gen_blocks_recursive(code_t *code, ir_function *func, ir_block *bloc
             continue;
         }
 
+        if (instr->opcode == VINSTR_CROSS) {
+            stmt.opcode = INSTR_MUL_F;
+            for (j = 0; j < 3; ++j) {
+                stmt.o1.s1 = ir_value_code_addr(instr->_ops[1]) + (j + 1) % 3;
+                stmt.o2.s1 = ir_value_code_addr(instr->_ops[2]) + (j + 2) % 3;
+                stmt.o3.s1 = ir_value_code_addr(instr->_ops[0]) + j;
+                code_push_statement(code, &stmt, instr->context);
+                stmt.o1.s1 = ir_value_code_addr(instr->_ops[1]) + (j + 2) % 3;
+                stmt.o2.s1 = ir_value_code_addr(instr->_ops[2]) + (j + 1) % 3;
+                stmt.o3.s1 = ir_value_code_addr(func->owner->vinstr_temp[0]) + j;
+                code_push_statement(code, &stmt, instr->context);
+            }
+            stmt.opcode = INSTR_SUB_V;
+            stmt.o1.s1 = ir_value_code_addr(instr->_ops[0]);
+            stmt.o2.s1 = ir_value_code_addr(func->owner->vinstr_temp[0]);
+            stmt.o3.s1 = ir_value_code_addr(instr->_ops[0]);
+            code_push_statement(code, &stmt, instr->context);
+
+            /* instruction generated */
+            continue;
+        }
+
         if (instr->opcode == VINSTR_COND) {
             ontrue  = instr->bops[0];
             onfalse = instr->bops[1];
@@ -3959,6 +3984,7 @@ static const char *qc_opname(int op)
         case VINSTR_BITAND_VF: return "BITAND_VF";
         case VINSTR_BITOR_VF:  return "BITOR_VF";
         case VINSTR_BITXOR_VF: return "BITXOR_VF";
+        case VINSTR_CROSS:     return "CROSS";
         default:               return "<UNK>";
     }
 }
index 3c29399d203f1ff5fc55caafda7b3eee11984e18..d65eafe714eb6c8a78a752e896642cb95eb7b2cb 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -772,8 +772,12 @@ static bool parser_sy_apply_operator(parser_t *parser, shunt *sy)
             }
 
             if (!(out = fold_op(parser->fold, op, exprs))) {
-                compile_error(ctx, "cross product for non-constant vectors unimplemented");
-                return false;
+                out = (ast_expression*)ast_binary_new(
+                        parser_ctx(parser),
+                        VINSTR_CROSS,
+                        exprs[0],
+                        exprs[1]
+                );
             }
 
             break;
index 29ecbae5004286ddad860fcf5639bbf8e678ed01..d06d5799dd0e39819756ffe048010e1d997ce34d 100644 (file)
@@ -8,5 +8,5 @@ void main(vector v) {
     print(vtos(v & 16), "\n");
     print(vtos(v | '25 42 51'), "\n");
     print(vtos(v & '25 42 51'), "\n");
-    print(vtos('1 2 3' >< '3 2 1'));
+    print(vtos(v >< '3 2 1'));
 }
index 0eaf045a5a70504abb10229f837f369229fc9af7..738ec46ba97a44116005c235d19a379b25958b88 100644 (file)
@@ -11,4 +11,4 @@ M: '20 24 16'
 M: '0 0 16'
 M: '29 42 51'
 M: '0 8 16'
-M: '-4 8 -4'
+M: '-24 44 -16'