[qfcc] Implement vector scaling for Ruamoko

With this, qfcc-tests builds (can't run yet due to unsigned not having
any tests and thus the rest the Ruamoko code in QF not building yet).
This commit is contained in:
Bill Currie 2022-01-30 14:48:49 +09:00
parent 4871717fae
commit 4b8fdf3696
4 changed files with 22 additions and 5 deletions

View file

@ -446,7 +446,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[] = {'+', '-', '*', EQ, NE, 0}; static int valid[] = {'+', '-', '*', SCALE, EQ, NE, 0};
expr_t *t; expr_t *t;
if (!is_vector(get_type (e1))) { if (!is_vector(get_type (e1))) {
@ -460,7 +460,7 @@ do_op_vector (int op, expr_t *e, expr_t *e1, expr_t *e2)
} }
if (!is_vector(get_type (e2))) { if (!is_vector(get_type (e2))) {
e->e.expr.e2 = e2 = convert_to_float (e2); e->e.expr.e2 = e2 = convert_to_float (e2);
if (op != '*' && op != '/') if (op != SCALE && op != '/')
return error (e1, "invalid operator for vector"); return error (e1, "invalid operator for vector");
} else { } else {
if (!valid_op (op, valid)) if (!valid_op (op, valid))

View file

@ -53,6 +53,7 @@ static expr_t *inverse_multiply (int op, expr_t *e1, expr_t *e2);
static expr_t *double_compare (int op, expr_t *e1, expr_t *e2); static expr_t *double_compare (int op, expr_t *e1, expr_t *e2);
static expr_t *vector_compare (int op, expr_t *e1, expr_t *e2); static expr_t *vector_compare (int op, expr_t *e1, expr_t *e2);
static expr_t *vector_multiply (int op, expr_t *e1, expr_t *e2); static expr_t *vector_multiply (int op, expr_t *e1, expr_t *e2);
static expr_t *vector_scale (int op, expr_t *e1, expr_t *e2);
static expr_type_t string_string[] = { static expr_type_t string_string[] = {
{'+', &type_string}, {'+', &type_string},
@ -89,7 +90,7 @@ static expr_type_t float_float[] = {
}; };
static expr_type_t float_vector[] = { static expr_type_t float_vector[] = {
{'*', &type_vector}, {'*', .process = vector_scale },
{0, 0} {0, 0}
}; };
@ -138,7 +139,7 @@ static expr_type_t float_double[] = {
}; };
static expr_type_t vector_float[] = { static expr_type_t vector_float[] = {
{'*', &type_vector}, {'*', .process = vector_scale },
{'/', 0, 0, 0, inverse_multiply}, {'/', 0, 0, 0, inverse_multiply},
{0, 0} {0, 0}
}; };
@ -755,6 +756,21 @@ static expr_t *vector_multiply (int op, expr_t *e1, expr_t *e2)
return e; return e;
} }
static expr_t *vector_scale (int op, expr_t *e1, expr_t *e2)
{
// Ensure the expression is always vector * scalar. The operation is
// always commutative, and the Ruamoko ISA supports only vector * scalar
// (though v6 does support scalar * vector, one less if).
if (is_scalar (get_type (e1))) {
expr_t *t = e1;
e1 = e2;
e2 = t;
}
expr_t *e = new_binary_expr (SCALE, e1, e2);
e->e.expr.type = get_type (e1);
return e;
}
static expr_t * static expr_t *
double_compare (int op, expr_t *e1, expr_t *e2) double_compare (int op, expr_t *e1, expr_t *e2)
{ {

View file

@ -138,7 +138,7 @@ int yylex (void);
%left SHL SHR %left SHL SHR
%left '+' '-' %left '+' '-'
%left '*' '/' '%' MOD %left '*' '/' '%' MOD SCALE
%left CROSS DOT %left CROSS DOT
%right <op> SIZEOF UNARY INCOP %right <op> SIZEOF UNARY INCOP
%left HYPERUNARY %left HYPERUNARY

View file

@ -606,6 +606,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 SCALE: return "scale";
default: default:
return 0; return 0;
} }