aboutsummaryrefslogtreecommitdiffhomepage
path: root/aarch64/isel.c
diff options
context:
space:
mode:
Diffstat (limited to 'aarch64/isel.c')
-rw-r--r--aarch64/isel.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/aarch64/isel.c b/aarch64/isel.c
index b65f87a..65e61cf 100644
--- a/aarch64/isel.c
+++ b/aarch64/isel.c
@@ -69,11 +69,18 @@ aarch64_logimm(uint *enc, enum irclass k, uvlong x)
}
+static void fixarg(union ref *r, struct instr *ins, struct block *blk, int *curi);
static void
regarg(union ref *r, enum irclass k, struct block *blk, int *curi)
{
- if (r->t != RTMP)
+ if (r->t != RTMP) {
*r = insertinstr(blk, (*curi)++, mkinstr(Ocopy, k, *r));
+ if (kisflt(k) || instrtab[r->i].l.t == RSTACK) {
+ int iprev = *curi-1;
+ fixarg(&instrtab[r->i].l, &instrtab[r->i], blk, &iprev);
+ *curi = iprev+1;
+ }
+ }
}
static void
@@ -110,7 +117,7 @@ fixarg(union ref *r, struct instr *ins, struct block *blk, int *curi)
*r = insertinstr(blk, (*curi)++, mkinstr(Ocopy, k, *r));
}
} else if (r->t == RSTACK) {
- struct instr adr = mkinstr(Oadd, KPTR, mkref(RREG, FP), mkintcon(KI32, -r->i));
+ struct instr adr = mkinstr(Osub, KPTR, mkref(RREG, FP), mkintcon(KI32, r->i));
if (op == Ocopy)
*ins = adr;
else
@@ -354,6 +361,9 @@ sel(struct function *fn, struct instr *ins, struct block *blk, int *curi)
else /* stack */
*ins = mkinstr(Oadd, KPTR, mkref(RREG, FP), mkref(RICON, 16+fn->abiarg[ins->l.i].stk));
break;
+ case Oneg: case Onot:
+ regarg(&ins->l, ins->cls, blk, curi);
+ break;
case Oadd:
if (isnumcon(ins->l)) {
/* swap to have const in rhs */
@@ -400,7 +410,7 @@ sel(struct function *fn, struct instr *ins, struct block *blk, int *curi)
selcall(fn, ins, blk, curi);
break;
case Oloads8: case Oloadu8: case Oloads16: case Oloadu16:
- case Oloads32: case Oloadu32: case Oloadi64:
+ case Oloads32: case Oloadu32: case Oloadi64: case Oloadf32: case Oloadf64:
loadstoreaddr(blk, &ins->l, curi, op);
break;
case Ostorei8: case Ostorei16: case Ostorei32: cls = KI32; goto Store;