mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-13 00:24:12 +00:00
[qfcc] Simplify offset_cast for correctness
I don't know why I didn't think to do it this way before, but simply recursing into each operand for + or - expressions makes it much easier to generate correct code. Fixes the motor-point test.
This commit is contained in:
parent
7646f6b51e
commit
068f685fde
2 changed files with 24 additions and 17 deletions
|
@ -601,11 +601,19 @@ print_extend (dstring_t *dstr, expr_t *e, int level, int id, expr_t *next)
|
|||
{
|
||||
int indent = level * 2 + 2;
|
||||
ex_extend_t extend = e->e.extend;
|
||||
int ext = extend.extend;
|
||||
|
||||
if (ext < 0 || ext > 3) {
|
||||
ext = 4;
|
||||
}
|
||||
_print_expr (dstr, extend.src, level, id, next);
|
||||
dasprintf (dstr, "%*se_%p -> \"e_%p\";\n", indent, "", e, extend.src);
|
||||
dasprintf (dstr, "%*se_%p [label=\"extend %d\\n%d\"];\n", indent, "", e,
|
||||
extend.extend, e->line);
|
||||
dasprintf (dstr, "%*se_%p [label=\"extend [%d>%d%s:%s]\\n%d\"];\n",
|
||||
indent, "", e,
|
||||
type_width (get_type (extend.src)), type_width (extend.type),
|
||||
extend.reverse ? ":r" : "",
|
||||
((const char *[]){"0", "1", "c", "-1", "?"})[ext],
|
||||
e->line);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -144,24 +144,23 @@ offset_cast (type_t *type, expr_t *expr, int offset)
|
|||
if (type->meta != ty_basic) {
|
||||
internal_error (expr, "offset cast to non-basic type");
|
||||
}
|
||||
if (expr->type == ex_expr && expr->e.expr.op == '+') {
|
||||
auto e1 = expr->e.expr.e1;
|
||||
auto e2 = expr->e.expr.e2;
|
||||
if (e1->type == ex_extend) {
|
||||
auto ext = e1->e.extend;
|
||||
if (type_width (get_type (ext.src)) == type_width (type)) {
|
||||
return alias_expr (type, ext.src, 0);
|
||||
if (expr->type == ex_expr
|
||||
&& (expr->e.expr.op == '+' || expr->e.expr.op == '-')) {
|
||||
auto e1 = offset_cast (type, expr->e.expr.e1, offset);
|
||||
auto e2 = offset_cast (type, expr->e.expr.e2, offset);
|
||||
int op = expr->e.expr.op;
|
||||
if (!e1) {
|
||||
if (op == '-') {
|
||||
e2 = neg_expr (e2);
|
||||
}
|
||||
return e2;
|
||||
}
|
||||
if (e2->type == ex_extend) {
|
||||
auto ext = e2->e.extend;
|
||||
if (type_width (get_type (ext.src)) == type_width (type)) {
|
||||
return alias_expr (type, ext.src, 0);
|
||||
}
|
||||
if (offset >= type_width (get_type (ext.src))) {
|
||||
return 0;
|
||||
}
|
||||
if (!e2) {
|
||||
return e1;
|
||||
}
|
||||
auto cast = new_binary_expr (op, e1, e2);
|
||||
cast->e.expr.type = type;
|
||||
return cast;
|
||||
}
|
||||
if (expr->type == ex_extend) {
|
||||
auto ext = expr->e.extend;
|
||||
|
|
Loading…
Reference in a new issue