From 11ba42eccc2bd0ce6d893b583a37dc0b46d09adf Mon Sep 17 00:00:00 2001 From: Michael Forney Date: Wed, 24 Apr 2019 13:06:00 -0700 Subject: qbe: Make sure generated code doesn't depend on argument evaluation order It would be correct in any order, but this is a bit simpler and guarantees the same output. --- qbe.c | 8 +++----- test/bitfield-compound-assign.qbe | 8 ++++---- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/qbe.c b/qbe.c index 68bc1b3..6dc7ff1 100644 --- a/qbe.c +++ b/qbe.c @@ -290,15 +290,13 @@ funcstore(struct func *f, struct type *t, enum typequal tq, struct lvalue lval, } if (lval.bits.before || lval.bits.after) { mask = 0xffffffffffffffffu >> lval.bits.after + 64 - t->size * 8 ^ (1 << lval.bits.before) - 1; - v = funcinst(f, IOR, t->repr, + v = funcinst(f, ISHL, t->repr, v, mkintconst(&i32, lval.bits.before)); + v = funcinst(f, IAND, t->repr, v, mkintconst(t->repr, mask)); + v = funcinst(f, IOR, t->repr, v, funcinst(f, IAND, t->repr, funcinst(f, loadop, t->repr, lval.addr), mkintconst(t->repr, ~mask), ), - funcinst(f, IAND, t->repr, - funcinst(f, ISHL, t->repr, v, mkintconst(&i32, lval.bits.before)), - mkintconst(t->repr, mask), - ), ); } funcinst(f, storeop, NULL, v, lval.addr); diff --git a/test/bitfield-compound-assign.qbe b/test/bitfield-compound-assign.qbe index 829f5f6..5cc38de 100644 --- a/test/bitfield-compound-assign.qbe +++ b/test/bitfield-compound-assign.qbe @@ -10,10 +10,10 @@ function $f() { %.6 =w shl %.5, 19 %.7 =w sar %.6, 23 %.8 =w add %.7, 3 - %.9 =w loaduw %.4 - %.10 =w and %.9, 18446744073709543439 - %.11 =w shl %.8, 4 - %.12 =w and %.11, 8176 + %.9 =w shl %.8, 4 + %.10 =w and %.9, 8176 + %.11 =w loaduw %.4 + %.12 =w and %.11, 18446744073709543439 %.13 =w or %.10, %.12 storew %.13, %.4 ret -- cgit v1.2.3