Merge pull request #1130 from Sonicadvance1/AArch64-jit-extXx

[AArch64] Implement instructions.
This commit is contained in:
skidau 2014-09-23 13:52:30 +10:00
commit cbf102794e
4 changed files with 216 additions and 12 deletions

View File

@ -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);

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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}},