[qfcc] Add basic support for (u)long expressions

It's woefully incomplete, but sufficient to test initializing
non-scalars from ivec constants.

Fixes #36
This commit is contained in:
Bill Currie 2022-11-16 20:48:58 +09:00
parent 23469029ca
commit de2cc21c7e
3 changed files with 102 additions and 5 deletions

View file

@ -533,6 +533,48 @@ static expr_type_t double_double[] = {
{0, 0}
};
static expr_type_t long_long[] = {
{'+', &type_long},
{'-', &type_long},
{'*', &type_long},
{'/', &type_long},
{'&', &type_long},
{'|', &type_long},
{'^', &type_long},
{'%', &type_long},
{MOD, &type_long},
{SHL, &type_long},
{SHR, &type_long},
{EQ, &type_int},
{NE, &type_int},
{LE, &type_int},
{GE, &type_int},
{LT, &type_int},
{GT, &type_int},
{0, 0}
};
static expr_type_t ulong_ulong[] = {
{'+', &type_long},
{'-', &type_long},
{'*', &type_long},
{'/', &type_long},
{'&', &type_long},
{'|', &type_long},
{'^', &type_long},
{'%', &type_long},
{MOD, &type_long},
{SHL, &type_long},
{SHR, &type_long},
{EQ, &type_int},
{NE, &type_int},
{LE, &type_int},
{GE, &type_int},
{LT, &type_int},
{GT, &type_int},
{0, 0}
};
static expr_type_t *string_x[ev_type_count] = {
[ev_string] = string_string,
};
@ -628,6 +670,14 @@ static expr_type_t *double_x[ev_type_count] = {
[ev_double] = double_double,
};
static expr_type_t *long_x[ev_type_count] = {
[ev_long] = long_long,
};
static expr_type_t *ulong_x[ev_type_count] = {
[ev_ulong] = ulong_ulong,
};
static expr_type_t **binary_expr_types[ev_type_count] = {
[ev_string] = string_x,
[ev_float] = float_x,
@ -640,7 +690,9 @@ static expr_type_t **binary_expr_types[ev_type_count] = {
[ev_int] = int_x,
[ev_uint] = uint_x,
[ev_short] = short_x,
[ev_double] = double_x
[ev_double] = double_x,
[ev_long] = long_x,
[ev_ulong] = ulong_x,
};
// supported operators for scalar-vector expressions

View file

@ -637,7 +637,7 @@ convert_value (ex_value_t *value, type_t *type)
int conv = TYPE_CAST_CODE (from, to, width);
int addr = value_functions[vf_convert].first_statement;
value_statements[addr + 0].b = conv;
value_statements[addr + 1].c = width; // width is actual width - 1
value_statements[addr + 1].c = type_size (type) - 1;
memcpy (value_globals, &value->v,
type_size (value->type) * sizeof (pr_type_t));
value_pr.pr_trace = options.verbosity > 1;
@ -697,6 +697,8 @@ emit_value (ex_value_t *value, def_t *def)
case ev_vector:
case ev_quaternion:
case ev_double:
case ev_long:
case ev_ulong:
tab = value_imm_defs;
type = val.type;
break;

View file

@ -1,17 +1,60 @@
vector mins = '-16 -16 -24';
vector maxs = '16 16 32';
ivec4 i4 = '1 2 -3 4';
vec4 v4 = '1 2 -3 4';
lvec4 l4 = '1 2 -3 4';
uivec4 ui4 = '1 2 -3 4';
dvec4 d4 = '1 2 -3 4';
ulvec4 ul4 = '1 2 -3 4';
int
check (vector v, float x, float y, float z)
check_v (vector v, float x, float y, float z)
{
return v.x != x || v.y != y || v.z != z;
}
int check_ivec4 (ivec4 v, int x, int y, int z, int w)
{
return v.x != x || v.y != y || v.z != z || v.w != w;
}
int check_vec4 (vec4 v, float x, float y, float z, float w)
{
return v.x != x || v.y != y || v.z != z || v.w != w;
}
int check_lvec4 (lvec4 v, long x, long y, long z, long w)
{
return v.x != x || v.y != y || v.z != z || v.w != w;
}
int check_uivec4 (uivec4 v, unsigned x, unsigned y, unsigned z, unsigned w)
{
return v.x != x || v.y != y || v.z != z || v.w != w;
}
int check_dvec4 (dvec4 v, double x, double y, double z, double w)
{
return v.x != x || v.y != y || v.z != z || v.w != w;
}
int check_ulvec4 (ulvec4 v, unsigned long x, unsigned long y, unsigned long z,
unsigned long w)
{
return v.x != x || v.y != y || v.z != z || v.w != w;
}
int
main ()
{
int ret = 0;
ret |= check (mins, -16, -16, -24);
ret |= check (maxs, 16, 16, 32);
ret |= check_v (mins, -16, -16, -24);
ret |= check_v (maxs, 16, 16, 32);
ret |= check_ivec4 (i4, 1, 2, -3, 4);
ret |= check_vec4 (v4, 1, 2, -3, 4);
ret |= check_lvec4 (l4, 1, 2, -3, 4);
ret |= check_uivec4 (ui4, 1, 2, -3, 4);
ret |= check_dvec4 (d4, 1, 2, -3, 4);
ret |= check_ulvec4 (ul4, 1, 2, -3, 4);
return ret;
}