aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/t_aarch64_emit.c
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2026-03-22 19:25:46 +0100
committerlemon <lsof@mailbox.org>2026-03-22 19:25:46 +0100
commitcbca5355c0c0b1910735b1430e2552855a2aa5c7 (patch)
tree7a0e0452f8dba566a5c7c0ed20dc4a60084bbea8 /src/t_aarch64_emit.c
parent2d0b096a8c2f45370ef2535e1c500a008b949611 (diff)
aarch64: rem/urem, bswap*, arg bugfix
Diffstat (limited to 'src/t_aarch64_emit.c')
-rw-r--r--src/t_aarch64_emit.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/src/t_aarch64_emit.c b/src/t_aarch64_emit.c
index 4679569..abf1f3e 100644
--- a/src/t_aarch64_emit.c
+++ b/src/t_aarch64_emit.c
@@ -227,6 +227,9 @@ encode(uchar **pcode, const EncDesc *tab, int ntab, enum irclass k, Oper o[3])
case EN_ADDSUBSHFT3R: case EN_LOGSHFT3R:
ins |= sf<<31 | o[2].shft<<22 | o[2].reg<<16 | o[2].shamt<<10 | o[1].reg<<5 | o[0].reg;
break;
+ case EN_ARITH2R:
+ ins |= sf<<31 | o[1].reg<<5 | o[0].reg;
+ break;
case EN_ARITH3R:
ins |= sf<<31 | o[2].reg<<16 | o[1].reg<<5 | o[0].reg;
break;
@@ -352,6 +355,15 @@ Xmadd(uchar **pcode, enum irclass k, Oper d, Oper n, Oper m, Oper a)
W32(0x1B000000 | sf<<31 | m.reg<<16 | a.reg<<10 | n.reg<<5 | d.reg);
}
+static void
+Xmsub(uchar **pcode, enum irclass k, Oper d, Oper n, Oper m, Oper a)
+{
+ assert(opermatch(PGPRZ, k, d) && opermatch(PGPRZ, k, n)
+ && opermatch(PGPRZ, k, a) && opermatch(PGPRZ, k, m));
+ uint sf = k > KI32;
+ W32(0x1B008000 | sf<<31 | m.reg<<16 | a.reg<<10 | n.reg<<5 | d.reg);
+}
+
DEFINSTR3(Xsdiv, {4|8, {PGPRZ, PGPRZ, PGPRZ}, 0x1AC00C00, EN_ARITH3R})
DEFINSTR3(Xudiv, {4|8, {PGPRZ, PGPRZ, PGPRZ}, 0x1AC00800, EN_ARITH3R})
@@ -515,6 +527,10 @@ DEFINSTR2(Xfcmp,
{4|8, {PFPR, PZERO}, 0x1E602008, EN_FPCMPZ},
{4|8, {PFPR, PFPR}, 0x1E602000, EN_FPCMP},
)
+DEFINSTR2(Xrev,
+ {4 , {PGPRZ, PGPRZ}, 0x5AC00800, EN_ARITH2R},
+ { 8, {PGPRZ, PGPRZ}, 0xDAC00C00, EN_ARITH2R},
+)
static void
gencopy(uchar **pcode, enum irclass cls, Block *blk, int curi, Oper dst, Ref val)
@@ -744,12 +760,18 @@ emitinstr(uchar **pcode, Function *fn, Block *blk, int curi, Instr *ins)
Cvt:
X2(pcode, cls, reg2oper(ins->reg-1), ref2oper(ins->l));
break;
+ case Obswap32: case Obswap64:
+ Xrev(pcode, cls, reg2oper(ins->reg-1), ref2oper(ins->l));
+ break;
case Oadd: X3 = kisint(cls) ? Xadd : Xfadd; goto ALU3;
case Osub: X3 = kisint(cls) ? Xsub : Xfsub; goto ALU3;
case Omul: if (kisflt(cls)) { X3 = Xfmul; goto ALU3; }
/* MUL Rd,Rn,Rm ==> MADD Rd,Rn,Rm,zr */
Xmadd(pcode, cls, reg2oper(ins->reg-1), ref2oper(ins->l), ref2oper(ins->r), REGZR);
break;
+ case Omsub:
+ Xmsub(pcode, cls, reg2oper(ins->reg-1), ref2oper(ins->l), ref2oper(ins->r), ref2oper(ins->oper[2]));
+ break;
case Odiv: X3 = kisint(cls) ? Xsdiv : Xfdiv; goto ALU3;
case Oudiv: X3 = Xudiv; goto ALU3;
case Oand: X3 = Xand; goto ALU3;