cproc

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/cproc
Log | Files | Refs | Submodules | README | LICENSE

commit 22338bdfd0346e85a0e88ca5470302a4775e9054
parent 3206949a9f5fda4683362ca2adead62cc3de508b
Author: Michael Forney <mforney@mforney.org>
Date:   Thu, 14 Feb 2019 01:18:40 -0800

When subtracting pointers, divide after subtraction

The pointers might be global addresses, and it doesn't make sense to
divide them before subtracting.

Diffstat:
Mexpr.c | 6+++---
Mtests/subtract-pointer.qbe | 9++++-----
2 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/expr.c b/expr.c @@ -327,9 +327,9 @@ mkbinaryexpr(struct location *loc, enum tokenkind op, struct expression *l, stru t = l->type; r = mkbinaryexpr(loc, TMUL, exprconvert(r, &typeulong), mkconstexpr(&typeulong, t->base->size)); } else if (l->type->kind == TYPEPOINTER && r->type->kind == TYPEPOINTER && typecompatible(typeunqual(l->type->base, NULL), typeunqual(r->type->base, NULL))) { - l = mkbinaryexpr(loc, TDIV, exprconvert(l, &typeulong), mkconstexpr(&typeulong, l->type->base->size)); - r = mkbinaryexpr(loc, TDIV, exprconvert(r, &typeulong), mkconstexpr(&typeulong, r->type->base->size)); - t = &typelong; + /* XXX: when is the appropriate place to convert to signed integer */ + e = mkbinaryexpr(loc, TSUB, exprconvert(l, &typelong), exprconvert(r, &typelong)); + return mkbinaryexpr(loc, TDIV, e, mkconstexpr(&typelong, l->type->base->size)); } else { error(loc, "invalid operands to '-' operator"); } diff --git a/tests/subtract-pointer.qbe b/tests/subtract-pointer.qbe @@ -8,10 +8,9 @@ function $f(l %.1, l %.3) { @body.2 %.5 =l loadl %.2 %.6 =l copy %.5 - %.7 =l udiv %.6, 4 - %.8 =l loadl %.4 - %.9 =l copy %.8 - %.10 =l udiv %.9, 4 - %.11 =l sub %.7, %.10 + %.7 =l loadl %.4 + %.8 =l copy %.7 + %.9 =l sub %.6, %.8 + %.10 =l div %.9, 4 ret }