aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/t_aarch64_isel.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/t_aarch64_isel.c')
-rw-r--r--src/t_aarch64_isel.c40
1 files changed, 36 insertions, 4 deletions
diff --git a/src/t_aarch64_isel.c b/src/t_aarch64_isel.c
index 381a57d..29056bc 100644
--- a/src/t_aarch64_isel.c
+++ b/src/t_aarch64_isel.c
@@ -137,7 +137,15 @@ fixarg(Ref *r, Instr *ins, Block *blk, int *curi)
else
*r = insertinstr(blk, (*curi)++, adr);
} else if (r->t != RTMP) Reg: {
- regarg(r, r->t == RTMP ? instrtab[r->i].cls : ins->cls ? ins->cls : KI32, blk, curi);
+ enum irclass k;
+ if (r->t == RTMP) k = insrescls(instrtab[r->i]);
+ else if (ins->op == Oarg) {
+ IRType ty = ref2type(ins->l);
+ k = ty.isagg ? KPTR : ty.cls;
+ } else {
+ k = ins->cls;
+ }
+ regarg(r, k, blk, curi);
}
}
@@ -351,8 +359,9 @@ loadstoreaddr(Block *blk, Ref *r, int *curi, enum op op)
static void
sel(Function *fn, Instr *ins, Block *blk, int *curi)
{
- enum op op = ins->op;
+ Ref tmp;
enum irclass cls;
+ enum op op = ins->op;
if (oisarith(ins->op) && arithfold(ins)) {
fixarg(&ins->l, ins, blk, curi);
@@ -390,6 +399,18 @@ sel(Function *fn, Instr *ins, Block *blk, int *curi)
regarg(&ins->l, ins->cls, blk, curi);
ins->op = Ocopy;
break;
+ case Obswap32: case Obswap64:
+ regarg(&ins->l, ins->cls, blk, curi);
+ break;
+ case Obswap16:
+ /* %tmp = rev %x
+ * %res = lsr %tmp, 16 */
+ regarg(&ins->l, ins->cls, blk, curi);
+ tmp = insertinstr(blk, (*curi)++, mkinstr1(Obswap32, KI32, ins->l));
+ ins->op = Oslr;
+ ins->l = tmp;
+ ins->r = mkref(RICON, 16);
+ break;
case Oadd:
if (isnumcon(ins->l)) {
/* swap to have const in rhs */
@@ -409,7 +430,7 @@ sel(Function *fn, Instr *ins, Block *blk, int *curi)
case Oand: case Oior: case Oxor:
if (isnumcon(ins->l)) {
/* swap to have const in rhs */
- Ref tmp = ins->l;
+ tmp = ins->l;
ins->l = ins->r;
ins->r = tmp;
}
@@ -421,9 +442,20 @@ sel(Function *fn, Instr *ins, Block *blk, int *curi)
regarg(&ins->l, ins->cls, blk, curi);
fixarg(&ins->r, ins, blk, curi);
break;
- case Omul: case Odiv: case Oudiv: case Ourem:
+ case Omul: case Odiv: case Oudiv:
+ regarg(&ins->l, ins->cls, blk, curi);
+ regarg(&ins->r, ins->cls, blk, curi);
+ break;
+ case Orem: case Ourem:
regarg(&ins->l, ins->cls, blk, curi);
regarg(&ins->r, ins->cls, blk, curi);
+ /* %tmp = div %l, %r
+ * %res = msub %tmp, %r, %l */
+ tmp = insertinstr(blk, (*curi)++,
+ mkinstr2(op == Orem ? Odiv : Oudiv, ins->cls, ins->l, ins->r));
+ ins->op = Omsub;
+ ins->oper[2] = ins->l;
+ ins->oper[0] = tmp;
break;
case Oarg:
fixarg(&ins->r, ins, blk, curi);