Merge pull request #1130 from Sonicadvance1/AArch64-jit-extXx
[AArch64] Implement instructions.
This commit is contained in:
commit
cbf102794e
|
@ -80,9 +80,19 @@ public:
|
|||
// Integer
|
||||
void arith_imm(UGeckoInstruction inst);
|
||||
void boolX(UGeckoInstruction inst);
|
||||
void extsXx(UGeckoInstruction inst);
|
||||
void cntlzwx(UGeckoInstruction inst);
|
||||
void negx(UGeckoInstruction inst);
|
||||
|
||||
// System Registers
|
||||
void mtmsr(UGeckoInstruction inst);
|
||||
void mfmsr(UGeckoInstruction inst);
|
||||
void mcrf(UGeckoInstruction inst);
|
||||
void mfsr(UGeckoInstruction inst);
|
||||
void mtsr(UGeckoInstruction inst);
|
||||
void mfsrin(UGeckoInstruction inst);
|
||||
void mtsrin(UGeckoInstruction inst);
|
||||
void twx(UGeckoInstruction inst);
|
||||
|
||||
// LoadStore
|
||||
void icbi(UGeckoInstruction inst);
|
||||
|
|
|
@ -227,3 +227,64 @@ void JitArm64::boolX(UGeckoInstruction inst)
|
|||
ComputeRC(a);
|
||||
}
|
||||
}
|
||||
|
||||
void JitArm64::extsXx(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(bJITIntegerOff);
|
||||
int a = inst.RA, s = inst.RS;
|
||||
int size = inst.SUBOP10 == 922 ? 16 : 8;
|
||||
|
||||
if (gpr.IsImm(s))
|
||||
gpr.SetImmediate(a, (u32)(s32)(size == 16 ? (s16)gpr.GetImm(s) : (s8)gpr.GetImm(s)));
|
||||
else
|
||||
SBFM(gpr.R(a), gpr.R(s), 0, size - 1);
|
||||
|
||||
if (inst.Rc)
|
||||
ComputeRC(a);
|
||||
}
|
||||
|
||||
void JitArm64::cntlzwx(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(bJITIntegerOff);
|
||||
int a = inst.RA;
|
||||
int s = inst.RS;
|
||||
|
||||
if (gpr.IsImm(s))
|
||||
{
|
||||
u32 mask = 0x80000000;
|
||||
u32 i = 0;
|
||||
for (; i < 32; i++, mask >>= 1)
|
||||
{
|
||||
if ((u32)gpr.GetImm(s) & mask)
|
||||
break;
|
||||
}
|
||||
gpr.SetImmediate(a, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
CLZ(gpr.R(a), gpr.R(s));
|
||||
}
|
||||
|
||||
if (inst.Rc)
|
||||
ComputeRC(a);
|
||||
}
|
||||
|
||||
void JitArm64::negx(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(bJITIntegerOff);
|
||||
int a = inst.RA;
|
||||
int d = inst.RD;
|
||||
|
||||
FALLBACK_IF(inst.OE);
|
||||
|
||||
if (gpr.IsImm(a))
|
||||
gpr.SetImmediate(d, ~((u32)gpr.GetImm(a)) + 1);
|
||||
else
|
||||
SUB(gpr.R(d), WSP, gpr.R(a), ArithOption(gpr.R(a), ST_LSL, 0));
|
||||
|
||||
if (inst.Rc)
|
||||
ComputeRC(d);
|
||||
}
|
||||
|
|
|
@ -58,3 +58,136 @@ void JitArm64::mtmsr(UGeckoInstruction inst)
|
|||
|
||||
WriteExit(js.compilerPC + 4);
|
||||
}
|
||||
|
||||
void JitArm64::mfmsr(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(bJITSystemRegistersOff);
|
||||
|
||||
LDR(INDEX_UNSIGNED, gpr.R(inst.RD), X29, PPCSTATE_OFF(msr));
|
||||
}
|
||||
|
||||
void JitArm64::mcrf(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(bJITSystemRegistersOff);
|
||||
|
||||
if (inst.CRFS != inst.CRFD)
|
||||
{
|
||||
ARM64Reg WA = gpr.GetReg();
|
||||
ARM64Reg XA = EncodeRegTo64(WA);
|
||||
LDR(INDEX_UNSIGNED, XA, X29, PPCSTATE_OFF(cr_val[inst.CRFS]));
|
||||
STR(INDEX_UNSIGNED, XA, X29, PPCSTATE_OFF(cr_val[inst.CRFD]));
|
||||
gpr.Unlock(WA);
|
||||
}
|
||||
}
|
||||
|
||||
void JitArm64::mfsr(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(bJITSystemRegistersOff);
|
||||
|
||||
LDR(INDEX_UNSIGNED, gpr.R(inst.RD), X29, PPCSTATE_OFF(sr[inst.SR]));
|
||||
}
|
||||
|
||||
void JitArm64::mtsr(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(bJITSystemRegistersOff);
|
||||
|
||||
STR(INDEX_UNSIGNED, gpr.R(inst.RS), X29, PPCSTATE_OFF(sr[inst.SR]));
|
||||
}
|
||||
|
||||
void JitArm64::mfsrin(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(bJITSystemRegistersOff);
|
||||
|
||||
ARM64Reg index = gpr.GetReg();
|
||||
ARM64Reg index64 = EncodeRegTo64(index);
|
||||
ARM64Reg RB = gpr.R(inst.RB);
|
||||
|
||||
UBFM(index, RB, 28, 31);
|
||||
ADD(index64, X29, index64, ArithOption(index64, ST_LSL, 2));
|
||||
LDR(INDEX_UNSIGNED, gpr.R(inst.RD), index64, PPCSTATE_OFF(sr[0]));
|
||||
|
||||
gpr.Unlock(index);
|
||||
}
|
||||
|
||||
void JitArm64::mtsrin(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(bJITSystemRegistersOff);
|
||||
|
||||
ARM64Reg index = gpr.GetReg();
|
||||
ARM64Reg index64 = EncodeRegTo64(index);
|
||||
ARM64Reg RB = gpr.R(inst.RB);
|
||||
|
||||
UBFM(index, RB, 28, 31);
|
||||
ADD(index64, X29, index64, ArithOption(index64, ST_LSL, 2));
|
||||
STR(INDEX_UNSIGNED, gpr.R(inst.RD), index64, PPCSTATE_OFF(sr[0]));
|
||||
|
||||
gpr.Unlock(index);
|
||||
}
|
||||
|
||||
void JitArm64::twx(UGeckoInstruction inst)
|
||||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(bJITIntegerOff);
|
||||
|
||||
gpr.Flush(FlushMode::FLUSH_ALL);
|
||||
fpr.Flush(FlushMode::FLUSH_ALL);
|
||||
|
||||
s32 a = inst.RA;
|
||||
|
||||
ARM64Reg WA = gpr.GetReg();
|
||||
|
||||
if (inst.OPCD == 3) // twi
|
||||
{
|
||||
if (inst.SIMM_16 >= 0 && inst.SIMM_16 < 4096)
|
||||
{
|
||||
// Can fit in immediate in to the instruction encoding
|
||||
CMP(gpr.R(a), inst.SIMM_16);
|
||||
}
|
||||
else
|
||||
{
|
||||
MOVI2R(WA, (s32)(s16)inst.SIMM_16);
|
||||
CMP(gpr.R(a), WA);
|
||||
}
|
||||
}
|
||||
else // tw
|
||||
{
|
||||
CMP(gpr.R(a), gpr.R(inst.RB));
|
||||
}
|
||||
|
||||
std::vector<FixupBranch> fixups;
|
||||
CCFlags conditions[] = { CC_LT, CC_GT, CC_EQ, CC_VC, CC_VS };
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
if (inst.TO & (1 << i))
|
||||
{
|
||||
FixupBranch f = B(conditions[i]);
|
||||
fixups.push_back(f);
|
||||
}
|
||||
}
|
||||
FixupBranch dont_trap = B();
|
||||
|
||||
for (const FixupBranch& fixup : fixups)
|
||||
{
|
||||
SetJumpTarget(fixup);
|
||||
}
|
||||
|
||||
LDR(INDEX_UNSIGNED, WA, X29, PPCSTATE_OFF(Exceptions));
|
||||
ORR(WA, WA, 24, 0); // Same as WA | EXCEPTION_PROGRAM
|
||||
STR(INDEX_UNSIGNED, WA, X29, PPCSTATE_OFF(Exceptions));
|
||||
|
||||
MOVI2R(WA, js.compilerPC);
|
||||
|
||||
// WA is unlocked in this function
|
||||
WriteExceptionExit(WA);
|
||||
|
||||
SetJumpTarget(dont_trap);
|
||||
|
||||
WriteExit(js.compilerPC + 4);
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ static GekkoOPTemplate primarytable[] =
|
|||
|
||||
{1, &JitArm64::HLEFunction}, //"HLEFunction", OPTYPE_SYSTEM, FL_ENDBLOCK}},
|
||||
{2, &JitArm64::FallBackToInterpreter}, //"DynaBlock", OPTYPE_SYSTEM, 0}},
|
||||
{3, &JitArm64::Break}, //"twi", OPTYPE_SYSTEM, FL_ENDBLOCK}},
|
||||
{3, &JitArm64::twx}, //"twi", OPTYPE_SYSTEM, FL_ENDBLOCK}},
|
||||
{17, &JitArm64::sc}, //"sc", OPTYPE_SYSTEM, FL_ENDBLOCK, 1}},
|
||||
|
||||
{7, &JitArm64::FallBackToInterpreter}, //"mulli", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_RC_BIT, 2}},
|
||||
|
@ -172,7 +172,7 @@ static GekkoOPTemplate table19[] =
|
|||
{193, &JitArm64::FallBackToInterpreter}, //"crxor", OPTYPE_CR, FL_EVIL}},
|
||||
|
||||
{150, &JitArm64::DoNothing}, //"isync", OPTYPE_ICACHE, FL_EVIL}},
|
||||
{0, &JitArm64::FallBackToInterpreter}, //"mcrf", OPTYPE_SYSTEM, FL_EVIL}},
|
||||
{0, &JitArm64::mcrf}, //"mcrf", OPTYPE_SYSTEM, FL_EVIL}},
|
||||
|
||||
{50, &JitArm64::rfi}, //"rfi", OPTYPE_SYSTEM, FL_ENDBLOCK | FL_CHECKEXCEPTIONS, 1}},
|
||||
{18, &JitArm64::Break}, //"rfid", OPTYPE_SYSTEM, FL_ENDBLOCK | FL_CHECKEXCEPTIONS}}
|
||||
|
@ -191,9 +191,9 @@ static GekkoOPTemplate table31[] =
|
|||
{284, &JitArm64::boolX}, //"eqvx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_SB | FL_RC_BIT}},
|
||||
{0, &JitArm64::FallBackToInterpreter}, //"cmp", OPTYPE_INTEGER, FL_IN_AB | FL_SET_CRn}},
|
||||
{32, &JitArm64::FallBackToInterpreter}, //"cmpl", OPTYPE_INTEGER, FL_IN_AB | FL_SET_CRn}},
|
||||
{26, &JitArm64::FallBackToInterpreter}, //"cntlzwx",OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}},
|
||||
{922, &JitArm64::FallBackToInterpreter}, //"extshx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}},
|
||||
{954, &JitArm64::FallBackToInterpreter}, //"extsbx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}},
|
||||
{26, &JitArm64::cntlzwx}, //"cntlzwx",OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}},
|
||||
{922, &JitArm64::extsXx}, //"extshx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}},
|
||||
{954, &JitArm64::extsXx}, //"extsbx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_S | FL_RC_BIT}},
|
||||
{536, &JitArm64::FallBackToInterpreter}, //"srwx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}},
|
||||
{792, &JitArm64::FallBackToInterpreter}, //"srawx", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}},
|
||||
{824, &JitArm64::FallBackToInterpreter}, //"srawix", OPTYPE_INTEGER, FL_OUT_A | FL_IN_B | FL_IN_S | FL_RC_BIT}},
|
||||
|
@ -267,19 +267,19 @@ static GekkoOPTemplate table31[] =
|
|||
{983, &JitArm64::FallBackToInterpreter}, //"stfiwx", OPTYPE_STOREFP, FL_IN_A0 | FL_IN_B}},
|
||||
|
||||
{19, &JitArm64::FallBackToInterpreter}, //"mfcr", OPTYPE_SYSTEM, FL_OUT_D}},
|
||||
{83, &JitArm64::FallBackToInterpreter}, //"mfmsr", OPTYPE_SYSTEM, FL_OUT_D}},
|
||||
{83, &JitArm64::mfmsr}, //"mfmsr", OPTYPE_SYSTEM, FL_OUT_D}},
|
||||
{144, &JitArm64::FallBackToInterpreter}, //"mtcrf", OPTYPE_SYSTEM, 0}},
|
||||
{146, &JitArm64::mtmsr}, //"mtmsr", OPTYPE_SYSTEM, FL_ENDBLOCK}},
|
||||
{210, &JitArm64::FallBackToInterpreter}, //"mtsr", OPTYPE_SYSTEM, 0}},
|
||||
{242, &JitArm64::FallBackToInterpreter}, //"mtsrin", OPTYPE_SYSTEM, 0}},
|
||||
{210, &JitArm64::mtsr}, //"mtsr", OPTYPE_SYSTEM, 0}},
|
||||
{242, &JitArm64::mtsrin}, //"mtsrin", OPTYPE_SYSTEM, 0}},
|
||||
{339, &JitArm64::FallBackToInterpreter}, //"mfspr", OPTYPE_SPR, FL_OUT_D}},
|
||||
{467, &JitArm64::FallBackToInterpreter}, //"mtspr", OPTYPE_SPR, 0, 2}},
|
||||
{371, &JitArm64::FallBackToInterpreter}, //"mftb", OPTYPE_SYSTEM, FL_OUT_D | FL_TIMER}},
|
||||
{512, &JitArm64::FallBackToInterpreter}, //"mcrxr", OPTYPE_SYSTEM, 0}},
|
||||
{595, &JitArm64::FallBackToInterpreter}, //"mfsr", OPTYPE_SYSTEM, FL_OUT_D, 2}},
|
||||
{659, &JitArm64::FallBackToInterpreter}, //"mfsrin", OPTYPE_SYSTEM, FL_OUT_D, 2}},
|
||||
{595, &JitArm64::mfsr}, //"mfsr", OPTYPE_SYSTEM, FL_OUT_D, 2}},
|
||||
{659, &JitArm64::mfsrin}, //"mfsrin", OPTYPE_SYSTEM, FL_OUT_D, 2}},
|
||||
|
||||
{4, &JitArm64::Break}, //"tw", OPTYPE_SYSTEM, FL_ENDBLOCK, 1}},
|
||||
{4, &JitArm64::twx}, //"tw", OPTYPE_SYSTEM, FL_ENDBLOCK, 1}},
|
||||
{598, &JitArm64::DoNothing}, //"sync", OPTYPE_SYSTEM, 0, 2}},
|
||||
{982, &JitArm64::icbi}, //"icbi", OPTYPE_SYSTEM, FL_ENDBLOCK, 3}},
|
||||
|
||||
|
@ -310,7 +310,7 @@ static GekkoOPTemplate table31_2[] =
|
|||
{11, &JitArm64::FallBackToInterpreter}, //"mulhwux", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 4}},
|
||||
{235, &JitArm64::FallBackToInterpreter}, //"mullwx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 4}},
|
||||
{747, &JitArm64::FallBackToInterpreter}, //"mullwox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 4}},
|
||||
{104, &JitArm64::FallBackToInterpreter}, //"negx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}},
|
||||
{104, &JitArm64::negx}, //"negx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}},
|
||||
{40, &JitArm64::FallBackToInterpreter}, //"subfx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}},
|
||||
{552, &JitArm64::FallBackToInterpreter}, //"subox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}},
|
||||
{8, &JitArm64::FallBackToInterpreter}, //"subfcx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_SET_CA | FL_RC_BIT}},
|
||||
|
|
Loading…
Reference in New Issue