diff options
author | Michael Forney <mforney@mforney.org> | 2019-04-24 13:06:00 -0700 |
---|---|---|
committer | Michael Forney <mforney@mforney.org> | 2019-04-24 13:09:54 -0700 |
commit | 11ba42eccc2bd0ce6d893b583a37dc0b46d09adf (patch) | |
tree | e555c86302fa540b44aeaa3be9f54a020d14abe6 | |
parent | a98385a607aafe373c14d2a6fb2778d21a600c30 (diff) | |
download | cproc-11ba42eccc2bd0ce6d893b583a37dc0b46d09adf.tar.xz |
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.
-rw-r--r-- | qbe.c | 8 | ||||
-rw-r--r-- | test/bitfield-compound-assign.qbe | 8 |
2 files changed, 7 insertions, 9 deletions
@@ -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 |