From b2c8f3ebc5066a0c68d202b94f1e052e59eb1af4 Mon Sep 17 00:00:00 2001 From: Dale Weiler Date: Sat, 31 Aug 2013 14:49:06 -0400 Subject: [PATCH] Vector cross product virtual instruction, now >< operator works for non-constant vectors. Thanks divVerent for the help. --- gmqcc.h | 3 ++- ir.c | 32 +++++++++++++++++++++++++++++--- parser.c | 8 ++++++-- tests/vec_ops.qc | 2 +- tests/vec_ops.tmpl | 2 +- 5 files changed, 39 insertions(+), 8 deletions(-) diff --git a/gmqcc.h b/gmqcc.h index 0ecd55f..d8ad374 100644 --- 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 3efad3d..4b7442e 100644 --- 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 ""; } } diff --git a/parser.c b/parser.c index 3c29399..d65eafe 100644 --- 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; diff --git a/tests/vec_ops.qc b/tests/vec_ops.qc index 29ecbae..d06d579 100644 --- a/tests/vec_ops.qc +++ b/tests/vec_ops.qc @@ -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')); } diff --git a/tests/vec_ops.tmpl b/tests/vec_ops.tmpl index 0eaf045..738ec46 100644 --- a/tests/vec_ops.tmpl +++ b/tests/vec_ops.tmpl @@ -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' -- 2.39.2