From e36dc296f50cb2d60d3b27ce62217762b9655313 Mon Sep 17 00:00:00 2001 From: Michael Forney Date: Wed, 29 Sep 2021 15:03:15 -0700 Subject: eval: Allow subtraction in address constants --- eval.c | 14 +++++++------- test/initializer-address-subtract.c | 2 ++ test/initializer-address-subtract.qbe | 2 ++ 3 files changed, 11 insertions(+), 7 deletions(-) create mode 100644 test/initializer-address-subtract.c create mode 100644 test/initializer-address-subtract.qbe diff --git a/eval.c b/eval.c index 958f517..0c68051 100644 --- a/eval.c +++ b/eval.c @@ -157,19 +157,19 @@ eval(struct expr *expr, enum evalkind kind) case TADD: if (r->kind == EXPRBINARY) c = l, l = r, r = c; + /* fallthrough */ + case TSUB: if (r->kind != EXPRCONST) break; if (l->kind == EXPRCONST) { binary(expr, expr->op, l, r); - } else if (l->kind == EXPRBINARY && l->type->kind == TYPEPOINTER && l->binary.r->kind == EXPRCONST) { - if (l->op == TADD || l->op == TSUB) { - /* (P ± C1) + C2 -> P + (C2 ± C1) */ - expr->binary.l = l->binary.l; - binary(expr->binary.r, l->op, r, l->binary.r); - } + } else if (l->kind == EXPRBINARY && l->type->kind == TYPEPOINTER && l->op == TADD && l->binary.r->kind == EXPRCONST) { + /* (P + C1) ± C2 -> P + (C1 ± C2) */ + binary(expr->binary.r, expr->op, l->binary.r, r); + expr->op = TADD; + expr->binary.l = l->binary.l; } break; - /* TODO: TSUB pointer handling */ case TLOR: if (l->kind != EXPRCONST) break; diff --git a/test/initializer-address-subtract.c b/test/initializer-address-subtract.c new file mode 100644 index 0000000..f273d33 --- /dev/null +++ b/test/initializer-address-subtract.c @@ -0,0 +1,2 @@ +int a[4]; +int *p = a + 2 - 1; diff --git a/test/initializer-address-subtract.qbe b/test/initializer-address-subtract.qbe new file mode 100644 index 0000000..e6aa8cd --- /dev/null +++ b/test/initializer-address-subtract.qbe @@ -0,0 +1,2 @@ +export data $p = align 8 { l $a + 4, } +export data $a = align 4 { z 16 } -- cgit v1.2.3