commit 4ac7d770d6f064cd49c336c6e88c068a1d1f10c6
parent 2caa26e388b1c904d2f12fb09f84df7e761d8331
Author: Michael Forney <mforney@mforney.org>
Date: Sun, 8 May 2022 12:28:45 -0700
arm64: fix maximum immediate size for small loads/stores
The maximum immediate size for 1, 2, 4, and 8 byte loads/stores is
4095, 8190, 16380, and 32760 respectively[0][1][2].
[0] https://developer.arm.com/documentation/dui0802/a/A64-Data-Transfer-Instructions/LDRB--immediate-
[1] https://developer.arm.com/documentation/dui0802/a/A64-Data-Transfer-Instructions/LDRH--immediate-
[2] https://developer.arm.com/documentation/dui0802/a/A64-Data-Transfer-Instructions/LDR--immediate-
Diffstat:
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arm64/emit.c b/arm64/emit.c
@@ -285,7 +285,7 @@ loadcon(Con *c, int r, int k, FILE *f)
static void emitins(Ins *, E *);
static void
-fixarg(Ref *pr, E *e)
+fixarg(Ref *pr, int sz, E *e)
{
Ins *i;
Ref r;
@@ -294,7 +294,7 @@ fixarg(Ref *pr, E *e)
r = *pr;
if (rtype(r) == RSlot) {
s = slot(r.val, e);
- if (s > 32760) {
+ if (s > sz * 4095u) {
i = &(Ins){Oaddr, Kl, TMP(IP0), {r}};
emitins(i, e);
*pr = TMP(IP0);
@@ -313,9 +313,9 @@ emitins(Ins *i, E *e)
switch (i->op) {
default:
if (isload(i->op))
- fixarg(&i->arg[0], e);
+ fixarg(&i->arg[0], loadsz(i), e);
if (isstore(i->op))
- fixarg(&i->arg[1], e);
+ fixarg(&i->arg[1], storesz(i), e);
Table:
/* most instructions are just pulled out of
* the table omap[], some special cases are