mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-29 15:41:59 +00:00
[qfcc] Add an explicit hadamard operator
While the option to make '*' mean dot product for vectors is important, it breaks vector scaling in ruamoko progs as the resultant vector op becomes a dot product instead of the indented hadamard product (ie, component-wise).
This commit is contained in:
parent
387f17dc0c
commit
f323401c10
7 changed files with 14 additions and 3 deletions
|
@ -394,7 +394,7 @@ do_op_vector (int op, expr_t *e, expr_t *e1, expr_t *e2)
|
||||||
{
|
{
|
||||||
const float *v1, *v2;
|
const float *v1, *v2;
|
||||||
vec3_t v, float_vec;
|
vec3_t v, float_vec;
|
||||||
static int valid[] = {'+', '-', '*', SCALE, EQ, NE, 0};
|
static int valid[] = {'+', '-', '*', HADAMARD, SCALE, EQ, NE, 0};
|
||||||
expr_t *t;
|
expr_t *t;
|
||||||
|
|
||||||
if (!is_vector(get_type (e1))) {
|
if (!is_vector(get_type (e1))) {
|
||||||
|
|
|
@ -94,6 +94,7 @@ get_op_string (int op)
|
||||||
case 'C': return "<cast>";
|
case 'C': return "<cast>";
|
||||||
case CROSS: return "@cross";
|
case CROSS: return "@cross";
|
||||||
case DOT: return "@dot";
|
case DOT: return "@dot";
|
||||||
|
case HADAMARD: return "@hadamard";
|
||||||
case SCALE: return "@scale";
|
case SCALE: return "@scale";
|
||||||
default:
|
default:
|
||||||
return "unknown";
|
return "unknown";
|
||||||
|
|
|
@ -150,6 +150,7 @@ static expr_type_t vector_vector[] = {
|
||||||
{'-', &type_vector},
|
{'-', &type_vector},
|
||||||
{DOT, &type_vector},
|
{DOT, &type_vector},
|
||||||
{CROSS, &type_vector},
|
{CROSS, &type_vector},
|
||||||
|
{HADAMARD, &type_vector},
|
||||||
{'*', 0, 0, 0, vector_multiply},
|
{'*', 0, 0, 0, vector_multiply},
|
||||||
{EQ, 0, 0, 0, vector_compare},
|
{EQ, 0, 0, 0, vector_compare},
|
||||||
{NE, 0, 0, 0, vector_compare},
|
{NE, 0, 0, 0, vector_compare},
|
||||||
|
@ -1100,11 +1101,13 @@ binary_expr (int op, expr_t *e1, expr_t *e2)
|
||||||
t2 = pt2;
|
t2 = pt2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
int scalar_op = 0;
|
||||||
if (type_width (t1) == 1) {
|
if (type_width (t1) == 1) {
|
||||||
// scalar op vec
|
// scalar op vec
|
||||||
if (!(e = convert_scalar (e1, op, e2))) {
|
if (!(e = convert_scalar (e1, op, e2))) {
|
||||||
return invalid_binary_expr (op, e1, e2);
|
return invalid_binary_expr (op, e1, e2);
|
||||||
}
|
}
|
||||||
|
scalar_op = 1;
|
||||||
e1 = e;
|
e1 = e;
|
||||||
t1 = get_type (e1);
|
t1 = get_type (e1);
|
||||||
}
|
}
|
||||||
|
@ -1113,9 +1116,13 @@ binary_expr (int op, expr_t *e1, expr_t *e2)
|
||||||
if (!(e = convert_scalar (e2, op, e1))) {
|
if (!(e = convert_scalar (e2, op, e1))) {
|
||||||
return invalid_binary_expr (op, e1, e2);
|
return invalid_binary_expr (op, e1, e2);
|
||||||
}
|
}
|
||||||
|
scalar_op = 1;
|
||||||
e2 = e;
|
e2 = e;
|
||||||
t2 = get_type (e2);
|
t2 = get_type (e2);
|
||||||
}
|
}
|
||||||
|
if (scalar_op && op == '*') {
|
||||||
|
op = HADAMARD;
|
||||||
|
}
|
||||||
if (type_width (t1) != type_width (t2)) {
|
if (type_width (t1) != type_width (t2)) {
|
||||||
// vec op vec of different widths
|
// vec op vec of different widths
|
||||||
return invalid_binary_expr (op, e1, e2);
|
return invalid_binary_expr (op, e1, e2);
|
||||||
|
|
|
@ -742,7 +742,7 @@ DecodeArgs (int argc, char **argv)
|
||||||
if (options.code.vector_components == (qboolean) -1)
|
if (options.code.vector_components == (qboolean) -1)
|
||||||
options.code.vector_components = false;
|
options.code.vector_components = false;
|
||||||
if (options.math.vector_mult == 0)
|
if (options.math.vector_mult == 0)
|
||||||
options.math.vector_mult = options.advanced == 1 ? DOT : '*';
|
options.math.vector_mult = options.advanced == 1 ? DOT : HADAMARD;
|
||||||
} else {
|
} else {
|
||||||
options.code.promote_float = 0;
|
options.code.promote_float = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -428,6 +428,7 @@ static keyword_t qf_keywords[] = {
|
||||||
|
|
||||||
{"@cross", CROSS, 0 },
|
{"@cross", CROSS, 0 },
|
||||||
{"@dot", DOT, 0 },
|
{"@dot", DOT, 0 },
|
||||||
|
{"@hadamard", HADAMARD, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
// These keywors are always available. Other than the @ keywords, they
|
// These keywors are always available. Other than the @ keywords, they
|
||||||
|
|
|
@ -141,7 +141,7 @@ int yylex (void);
|
||||||
%left SHL SHR
|
%left SHL SHR
|
||||||
%left '+' '-'
|
%left '+' '-'
|
||||||
%left '*' '/' '%' MOD SCALE
|
%left '*' '/' '%' MOD SCALE
|
||||||
%left CROSS DOT
|
%left CROSS DOT HADAMARD
|
||||||
%right <op> SIZEOF UNARY INCOP
|
%right <op> SIZEOF UNARY INCOP
|
||||||
%left HYPERUNARY
|
%left HYPERUNARY
|
||||||
%left '.' '(' '['
|
%left '.' '(' '['
|
||||||
|
@ -1672,6 +1672,7 @@ expr
|
||||||
| expr MOD expr { $$ = binary_expr (MOD, $1, $3); }
|
| expr MOD expr { $$ = binary_expr (MOD, $1, $3); }
|
||||||
| expr CROSS expr { $$ = binary_expr (CROSS, $1, $3); }
|
| expr CROSS expr { $$ = binary_expr (CROSS, $1, $3); }
|
||||||
| expr DOT expr { $$ = binary_expr (DOT, $1, $3); }
|
| expr DOT expr { $$ = binary_expr (DOT, $1, $3); }
|
||||||
|
| expr HADAMARD expr { $$ = binary_expr (HADAMARD, $1, $3); }
|
||||||
;
|
;
|
||||||
|
|
||||||
texpr
|
texpr
|
||||||
|
|
|
@ -538,6 +538,7 @@ convert_op (int op)
|
||||||
case '.': return "load";
|
case '.': return "load";
|
||||||
case CROSS: return "cross";
|
case CROSS: return "cross";
|
||||||
case DOT: return "dot";
|
case DOT: return "dot";
|
||||||
|
case HADAMARD: return "mul";
|
||||||
case SCALE: return "scale";
|
case SCALE: return "scale";
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in a new issue