summaryrefslogtreecommitdiff
path: root/amd64
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin@c9x.me>2021-07-28 01:15:51 +0200
committerQuentin Carbonneaux <quentin@c9x.me>2021-07-28 01:57:05 +0200
commitb543ffed71497fb079bfdca53934870a1189c325 (patch)
tree6443ecd62d9fd42ed6203529bd15316ff2082a6c /amd64
parent5a4369dd279b1ee50779ae4ab16daaa035eeeb69 (diff)
downloadroux-b543ffed71497fb079bfdca53934870a1189c325.tar.gz
handle fast locals in amd64 shifts (afl)
Reported by Alessandro Mantovani. Although unlikely in real programs it was found that using the address of a fast local in amd64 shifts triggers assertion failures. We now err when the shift count is given by an address; but we allow shifting an address.
Diffstat (limited to 'amd64')
-rw-r--r--amd64/isel.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/amd64/isel.c b/amd64/isel.c
index 31199da..e8a78f3 100644
--- a/amd64/isel.c
+++ b/amd64/isel.c
@@ -244,13 +244,18 @@ sel(Ins i, ANum *an, Fn *fn)
case Osar:
case Oshr:
case Oshl:
- if (rtype(i.arg[1]) == RCon)
- goto Emit;
r0 = i.arg[1];
+ if (rtype(r0) == RCon)
+ goto Emit;
+ if (fn->tmp[r0.val].slot != -1)
+ err("unlikely argument %%%s in %s",
+ fn->tmp[r0.val].name, optab[i.op].name);
i.arg[1] = TMP(RCX);
emit(Ocopy, Kw, R, TMP(RCX), R);
emiti(i);
+ i1 = curi;
emit(Ocopy, Kw, TMP(RCX), r0, R);
+ fixarg(&i1->arg[0], argcls(&i, 0), i1, fn);
break;
case Onop:
break;
@@ -336,7 +341,7 @@ Emit:
die("unknown instruction %s", optab[i.op].name);
}
- while (i0 > curi && --i0) {
+ while (i0>curi && --i0) {
assert(rslot(i0->arg[0], fn) == -1);
assert(rslot(i0->arg[1], fn) == -1);
}