[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;
vec3_t v, float_vec;
static int valid[] = {'+', '-', '*', EQ, NE, 0};
static int valid[] = {'+', '-', '*', SCALE, EQ, NE, 0};
expr_t *t;
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))) {
e->e.expr.e2 = e2 = convert_to_float (e2);
if (op != '*' && op != '/')
if (op != SCALE && op != '/')
return error (e1, "invalid operator for vector");
} else {
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 *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_scale (int op, expr_t *e1, expr_t *e2);
static expr_type_t string_string[] = {
{'+', &type_string},
@ -89,7 +90,7 @@ static expr_type_t float_float[] = {
};
static expr_type_t float_vector[] = {
{'*', &type_vector},
{'*', .process = vector_scale },
{0, 0}
};
@ -138,7 +139,7 @@ static expr_type_t float_double[] = {
};
static expr_type_t vector_float[] = {
{'*', &type_vector},
{'*', .process = vector_scale },
{'/', 0, 0, 0, inverse_multiply},
{0, 0}
};
@ -755,6 +756,21 @@ static expr_t *vector_multiply (int op, expr_t *e1, expr_t *e2)
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 *
double_compare (int op, expr_t *e1, expr_t *e2)
{

View file

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

View file

@ -606,6 +606,7 @@ convert_op (int op)
case '.': return "load";
case CROSS: return "cross";
case DOT: return "dot";
case SCALE: return "scale";
default:
return 0;
}