aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Forney <mforney@mforney.org>2019-04-24 13:06:00 -0700
committerMichael Forney <mforney@mforney.org>2019-04-24 13:09:54 -0700
commit11ba42eccc2bd0ce6d893b583a37dc0b46d09adf (patch)
treee555c86302fa540b44aeaa3be9f54a020d14abe6
parenta98385a607aafe373c14d2a6fb2778d21a600c30 (diff)
downloadcproc-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.c8
-rw-r--r--test/bitfield-compound-assign.qbe8
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