mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-26 14:20:59 +00:00
[qfcc] Correct handling of 64-bit comparisons
While the progs engine itself implements the instructions correctly, the opcode specs (and thus qfcc) treated the results as 32-bit (which was, really, a hidden fixme, it seems).
This commit is contained in:
parent
8a0246c910
commit
29a57b7128
6 changed files with 62 additions and 52 deletions
|
@ -155,11 +155,12 @@ compare_formats = {
|
|||
"mnemonic": "{op_cmp[ccc]}.{cmp_type[tt]}",
|
||||
"opname": "{op_cmp[ccc]}",
|
||||
"widths": "{ss+1}, {ss+1}, {ss+1}",
|
||||
"types": "{cmp_types[tt]}, {cmp_types[tt]}, ev_int",
|
||||
"types": "{cmp_types[tt]}, {cmp_types[tt]}, {res_types[tt & 2]}",
|
||||
"args": {
|
||||
"op_cmp": compare_ccc,
|
||||
"cmp_type": type_tt,
|
||||
"cmp_types": etype_tt,
|
||||
"res_types": etype_tt,
|
||||
},
|
||||
}
|
||||
compare2_formats = {
|
||||
|
|
|
@ -323,7 +323,7 @@ do_op_double (int op, expr_t *e, expr_t *e1, expr_t *e2)
|
|||
e->e.expr.e2 = e2 = conv;
|
||||
}
|
||||
if (is_compare (op) || is_logic (op)) {
|
||||
type = &type_int;
|
||||
type = int_type (get_type (e));
|
||||
}
|
||||
e->e.expr.type = type;
|
||||
|
||||
|
@ -1736,8 +1736,10 @@ fold_constants (expr_t *e)
|
|||
t2 = extract_type (e2);
|
||||
|
||||
if (t1 >= ev_type_count || t2 >= ev_type_count
|
||||
|| !do_op[t1] || !do_op[t1][t2])
|
||||
internal_error (e, "invalid type %d %d", t1, t2);
|
||||
|| !do_op[t1] || !do_op[t1][t2]) {
|
||||
debug (e, "unhandled type %d %d", t1, t2);
|
||||
return e;
|
||||
}
|
||||
return do_op[t1][t2] (op, e, e1, e2);
|
||||
}
|
||||
return e;
|
||||
|
|
|
@ -348,12 +348,12 @@ static expr_type_t int_double[] = {
|
|||
{'/', &type_double, &type_double, 0},
|
||||
{'%', &type_double, &type_double, 0},
|
||||
{MOD, &type_double, &type_double, 0},
|
||||
{EQ, &type_int, &type_double, 0},
|
||||
{NE, &type_int, &type_double, 0},
|
||||
{LE, &type_int, &type_double, 0},
|
||||
{GE, &type_int, &type_double, 0},
|
||||
{LT, &type_int, &type_double, 0},
|
||||
{GT, &type_int, &type_double, 0},
|
||||
{EQ, &type_long, &type_double, 0},
|
||||
{NE, &type_long, &type_double, 0},
|
||||
{LE, &type_long, &type_double, 0},
|
||||
{GE, &type_long, &type_double, 0},
|
||||
{LT, &type_long, &type_double, 0},
|
||||
{GT, &type_long, &type_double, 0},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
|
@ -526,12 +526,12 @@ static expr_type_t double_double[] = {
|
|||
{'/', &type_double},
|
||||
{'%', &type_double},
|
||||
{MOD, &type_double},
|
||||
{EQ, &type_int},
|
||||
{NE, &type_int},
|
||||
{LE, &type_int},
|
||||
{GE, &type_int},
|
||||
{LT, &type_int},
|
||||
{GT, &type_int},
|
||||
{EQ, &type_long},
|
||||
{NE, &type_long},
|
||||
{LE, &type_long},
|
||||
{GE, &type_long},
|
||||
{LT, &type_long},
|
||||
{GT, &type_long},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
|
@ -547,33 +547,33 @@ static expr_type_t long_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},
|
||||
{EQ, &type_long},
|
||||
{NE, &type_long},
|
||||
{LE, &type_long},
|
||||
{GE, &type_long},
|
||||
{LT, &type_long},
|
||||
{GT, &type_long},
|
||||
{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},
|
||||
{'+', &type_ulong},
|
||||
{'-', &type_ulong},
|
||||
{'*', &type_ulong},
|
||||
{'/', &type_ulong},
|
||||
{'&', &type_ulong},
|
||||
{'|', &type_ulong},
|
||||
{'^', &type_ulong},
|
||||
{'%', &type_ulong},
|
||||
{MOD, &type_ulong},
|
||||
{SHL, &type_ulong},
|
||||
{SHR, &type_ulong},
|
||||
{EQ, &type_long},
|
||||
{NE, &type_long},
|
||||
{LE, &type_long},
|
||||
{GE, &type_long},
|
||||
{LT, &type_long},
|
||||
{GT, &type_long},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
|
@ -908,7 +908,7 @@ double_compare (int op, expr_t *e1, expr_t *e2)
|
|||
e1 = cast_expr (&type_double, e1);
|
||||
}
|
||||
e = new_binary_expr (op, e1, e2);
|
||||
e->e.expr.type = &type_int;
|
||||
e->e.expr.type = &type_long;
|
||||
return e;
|
||||
}
|
||||
|
||||
|
@ -1221,6 +1221,9 @@ binary_expr (int op, expr_t *e1, expr_t *e2)
|
|||
// both widths are the same at this point
|
||||
if (t1->width > 1) {
|
||||
e = new_binary_expr (op, e1, e2);
|
||||
if (is_compare (op)) {
|
||||
t1 = int_type (t1);
|
||||
}
|
||||
e->e.expr.type = t1;
|
||||
return e;
|
||||
}
|
||||
|
|
|
@ -96,8 +96,10 @@ test_expr (expr_t *e)
|
|||
break;
|
||||
case ev_long:
|
||||
case ev_ulong:
|
||||
e = new_alias_expr (&type_ivec2, e);
|
||||
return new_horizontal_expr ('|', e, &type_int);
|
||||
case ev_ushort:
|
||||
internal_error (e, "long not implemented");
|
||||
internal_error (e, "ushort not implemented");
|
||||
case ev_uint:
|
||||
case ev_int:
|
||||
case ev_short:
|
||||
|
@ -123,8 +125,9 @@ test_expr (expr_t *e)
|
|||
new = new_float_expr (0);
|
||||
break;
|
||||
case ev_double:
|
||||
new = new_double_expr (0);
|
||||
break;
|
||||
new = expr_file_line (new_double_expr (0), e);
|
||||
new = expr_file_line (binary_expr (NE, e, new), e);
|
||||
return test_expr (new);
|
||||
case ev_vector:
|
||||
new = new_vector_expr (zero);
|
||||
break;
|
||||
|
|
|
@ -138,7 +138,8 @@ cast_expr (type_t *dstType, expr_t *e)
|
|||
}
|
||||
if (is_constant (e) && is_math (dstType) && is_math (srcType)) {
|
||||
return cast_math (dstType, srcType, e);
|
||||
} else if (is_integral (dstType) && is_integral (srcType)) {
|
||||
} else if (is_integral (dstType) && is_integral (srcType)
|
||||
&& type_size (dstType) == type_size (srcType)) {
|
||||
c = new_alias_expr (dstType, e);
|
||||
} else if (is_scalar (dstType) && is_scalar (srcType)) {
|
||||
c = new_unary_expr ('C', e);
|
||||
|
|
|
@ -6,7 +6,7 @@ union {
|
|||
int i[2];
|
||||
} type_pun;
|
||||
|
||||
int
|
||||
long
|
||||
test_format ()
|
||||
{
|
||||
int fail = 0;
|
||||
|
@ -17,10 +17,10 @@ test_format ()
|
|||
return fail;
|
||||
}
|
||||
|
||||
int
|
||||
long
|
||||
test_constant ()
|
||||
{
|
||||
int fail = 0;
|
||||
long fail = 0;
|
||||
double a, b, c, d, e;
|
||||
a = 1;
|
||||
b = 2.0;
|
||||
|
@ -40,10 +40,10 @@ double greater_equal = 3;
|
|||
double less_equal = 5;
|
||||
double greater = 5;
|
||||
|
||||
int
|
||||
long
|
||||
test_copare ()
|
||||
{
|
||||
int fail = 0;
|
||||
long fail = 0;
|
||||
|
||||
fail |= !(less < greater);
|
||||
fail |= (less > greater);
|
||||
|
@ -75,10 +75,10 @@ test_copare ()
|
|||
return fail;
|
||||
}
|
||||
|
||||
int
|
||||
long
|
||||
test_ops ()
|
||||
{
|
||||
int fail = 0;
|
||||
long fail = 0;
|
||||
double a = 6.25, b = 2.375;
|
||||
double c;
|
||||
|
||||
|
@ -98,7 +98,7 @@ test_ops ()
|
|||
int
|
||||
main ()
|
||||
{
|
||||
int fail = 0;
|
||||
long fail = 0;
|
||||
fail |= test_format ();
|
||||
fail |= test_constant ();
|
||||
fail |= test_ops ();
|
||||
|
|
Loading…
Reference in a new issue