diff --git a/tools/qfcc/source/expr_binary.c b/tools/qfcc/source/expr_binary.c index 3d347c676..f6de06397 100644 --- a/tools/qfcc/source/expr_binary.c +++ b/tools/qfcc/source/expr_binary.c @@ -48,6 +48,7 @@ typedef struct { bool (*commutative) (void); bool (*anticommute) (void); bool (*associative) (void); + int true_op; } expr_type_t; static const expr_t *pointer_arithmetic (int op, const expr_t *e1, @@ -272,7 +273,12 @@ static expr_type_t quat_float[] = { }; static expr_type_t quat_vector[] = { - {'*', &type_vector}, + {'*', &type_vector, .true_op = QVMUL}, + {0, 0} +}; + +static expr_type_t vector_quat[] = { + {'*', &type_vector, .true_op = VQMUL}, {0, 0} }; @@ -281,7 +287,7 @@ static expr_type_t quat_quat[] = { .commutative = fp_com_add, .associative = fp_ass_add}, {'-', &type_quaternion, .anticommute = fp_com_add}, - {'*', &type_quaternion, .associative = always}, + {'*', &type_quaternion, .associative = always, .true_op = QMUL}, {EQ, &type_int}, {NE, &type_int}, {0, 0} @@ -727,6 +733,7 @@ static expr_type_t *float_x[ev_type_count] = { static expr_type_t *vector_x[ev_type_count] = { [ev_float] = vector_float, [ev_vector] = vector_vector, + [ev_quaternion] = vector_quat, [ev_int] = vector_int, [ev_uint] = vector_uint, [ev_short] = vector_short, @@ -1463,6 +1470,10 @@ binary_expr (int op, const expr_t *e1, const expr_t *e2) if ((e = reimplement_binary_expr (op, e1, e2))) return edag_add_expr (fold_constants (e)); + if (expr_type->true_op) { + op = expr_type->true_op; + } + auto ne = new_binary_expr (op, e1, e2); ne->expr.type = expr_type->result_type; if (expr_type->commutative) { diff --git a/tools/qfcc/source/qc-parse.y b/tools/qfcc/source/qc-parse.y index b33751b88..aa4011aff 100644 --- a/tools/qfcc/source/qc-parse.y +++ b/tools/qfcc/source/qc-parse.y @@ -143,7 +143,7 @@ int yylex (void); %left SHL SHR %left '+' '-' -%left '*' '/' '%' MOD SCALE GEOMETRIC +%left '*' '/' '%' MOD SCALE GEOMETRIC QMUL QVMUL VQMUL %left HADAMARD CROSS DOT WEDGE REGRESSIVE %right SIZEOF UNARY INCOP REVERSE STAR DUAL %left HYPERUNARY diff --git a/tools/qfcc/source/statements.c b/tools/qfcc/source/statements.c index 52364bebd..ef07cef8c 100644 --- a/tools/qfcc/source/statements.c +++ b/tools/qfcc/source/statements.c @@ -602,6 +602,9 @@ convert_op (int op) case DOT: return "dot"; case HADAMARD: return "mul"; case SCALE: return "scale"; + case QMUL: return "qmul"; + case QVMUL: return "qvmul"; + case VQMUL: return "vqmul"; default: return 0; }