[ARM] Implement tw/twi
This commit is contained in:
parent
d8b7f4d73f
commit
c8cdc81ce3
|
@ -187,6 +187,7 @@ public:
|
||||||
void mtsr(UGeckoInstruction _inst);
|
void mtsr(UGeckoInstruction _inst);
|
||||||
void mfsr(UGeckoInstruction _inst);
|
void mfsr(UGeckoInstruction _inst);
|
||||||
void mcrxr(UGeckoInstruction _inst);
|
void mcrxr(UGeckoInstruction _inst);
|
||||||
|
void twx(UGeckoInstruction _inst);
|
||||||
|
|
||||||
// LoadStore
|
// LoadStore
|
||||||
void stX(UGeckoInstruction _inst);
|
void stX(UGeckoInstruction _inst);
|
||||||
|
|
|
@ -90,7 +90,6 @@ void JitArm::ComputeCarry(bool Carry)
|
||||||
BIC(tmp, tmp, mask);
|
BIC(tmp, tmp, mask);
|
||||||
STR(tmp, R9, PPCSTATE_OFF(spr[SPR_XER]));
|
STR(tmp, R9, PPCSTATE_OFF(spr[SPR_XER]));
|
||||||
gpr.Unlock(tmp);
|
gpr.Unlock(tmp);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm::GetCarryAndClear(ARMReg reg)
|
void JitArm::GetCarryAndClear(ARMReg reg)
|
||||||
|
@ -802,7 +801,6 @@ void JitArm::cmpli(UGeckoInstruction inst)
|
||||||
|
|
||||||
STRB(rA, R9, PPCSTATE_OFF(cr_fast) + crf);
|
STRB(rA, R9, PPCSTATE_OFF(cr_fast) + crf);
|
||||||
gpr.Unlock(rA);
|
gpr.Unlock(rA);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitArm::negx(UGeckoInstruction inst)
|
void JitArm::negx(UGeckoInstruction inst)
|
||||||
|
@ -950,3 +948,74 @@ void JitArm::srawix(UGeckoInstruction inst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JitArm::twx(UGeckoInstruction inst)
|
||||||
|
{
|
||||||
|
INSTRUCTION_START
|
||||||
|
JITDISABLE(bJITIntegerOff)
|
||||||
|
|
||||||
|
s32 a = inst.RA;
|
||||||
|
|
||||||
|
gpr.Flush();
|
||||||
|
fpr.Flush();
|
||||||
|
|
||||||
|
ARMReg RA = gpr.GetReg();
|
||||||
|
ARMReg RB = gpr.GetReg();
|
||||||
|
MOV(RA, inst.TO);
|
||||||
|
|
||||||
|
if (inst.OPCD == 3) // twi
|
||||||
|
CMP(gpr.R(a), gpr.R(inst.RB));
|
||||||
|
else // tw
|
||||||
|
{
|
||||||
|
MOVI2R(RB, (s32)(s16)inst.SIMM_16);
|
||||||
|
CMP(gpr.R(a), RB);
|
||||||
|
}
|
||||||
|
|
||||||
|
FixupBranch al = B_CC(CC_LT);
|
||||||
|
FixupBranch ag = B_CC(CC_GT);
|
||||||
|
FixupBranch ae = B_CC(CC_EQ);
|
||||||
|
// FIXME: will never be reached. But also no known code uses it...
|
||||||
|
FixupBranch ll = B_CC(CC_VC);
|
||||||
|
FixupBranch lg = B_CC(CC_VS);
|
||||||
|
|
||||||
|
SetJumpTarget(al);
|
||||||
|
TST(RA, 16);
|
||||||
|
FixupBranch exit1 = B_CC(CC_NEQ);
|
||||||
|
FixupBranch take1 = B();
|
||||||
|
SetJumpTarget(ag);
|
||||||
|
TST(RA, 8);
|
||||||
|
FixupBranch exit2 = B_CC(CC_NEQ);
|
||||||
|
FixupBranch take2 = B();
|
||||||
|
SetJumpTarget(ae);
|
||||||
|
TST(RA, 4);
|
||||||
|
FixupBranch exit3 = B_CC(CC_NEQ);
|
||||||
|
FixupBranch take3 = B();
|
||||||
|
SetJumpTarget(ll);
|
||||||
|
TST(RA, 2);
|
||||||
|
FixupBranch exit4 = B_CC(CC_NEQ);
|
||||||
|
FixupBranch take4 = B();
|
||||||
|
SetJumpTarget(lg);
|
||||||
|
TST(RA, 1);
|
||||||
|
FixupBranch exit5 = B_CC(CC_NEQ);
|
||||||
|
FixupBranch take5 = B();
|
||||||
|
|
||||||
|
SetJumpTarget(take1);
|
||||||
|
SetJumpTarget(take2);
|
||||||
|
SetJumpTarget(take3);
|
||||||
|
SetJumpTarget(take4);
|
||||||
|
SetJumpTarget(take5);
|
||||||
|
|
||||||
|
LDR(RA, R9, PPCSTATE_OFF(Exceptions));
|
||||||
|
MOVI2R(RB, EXCEPTION_PROGRAM); // XXX: Can be optimized
|
||||||
|
ORR(RA, RA, RB);
|
||||||
|
STR(RA, R9, PPCSTATE_OFF(Exceptions));
|
||||||
|
WriteExceptionExit();
|
||||||
|
|
||||||
|
SetJumpTarget(exit1);
|
||||||
|
SetJumpTarget(exit2);
|
||||||
|
SetJumpTarget(exit3);
|
||||||
|
SetJumpTarget(exit4);
|
||||||
|
SetJumpTarget(exit5);
|
||||||
|
WriteExit(js.compilerPC + 4, 1);
|
||||||
|
|
||||||
|
gpr.Unlock(RA, RB);
|
||||||
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ static GekkoOPTemplate primarytable[] =
|
||||||
|
|
||||||
{1, &JitArm::HLEFunction}, //"HLEFunction", OPTYPE_SYSTEM, FL_ENDBLOCK}},
|
{1, &JitArm::HLEFunction}, //"HLEFunction", OPTYPE_SYSTEM, FL_ENDBLOCK}},
|
||||||
{2, &JitArm::Default}, //"DynaBlock", OPTYPE_SYSTEM, 0}},
|
{2, &JitArm::Default}, //"DynaBlock", OPTYPE_SYSTEM, 0}},
|
||||||
{3, &JitArm::Break}, //"twi", OPTYPE_SYSTEM, FL_ENDBLOCK}},
|
{3, &JitArm::twx}, //"twi", OPTYPE_SYSTEM, FL_ENDBLOCK}},
|
||||||
{17, &JitArm::sc}, //"sc", OPTYPE_SYSTEM, FL_ENDBLOCK, 1}},
|
{17, &JitArm::sc}, //"sc", OPTYPE_SYSTEM, FL_ENDBLOCK, 1}},
|
||||||
|
|
||||||
{7, &JitArm::arith}, //"mulli", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_RC_BIT, 2}},
|
{7, &JitArm::arith}, //"mulli", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_RC_BIT, 2}},
|
||||||
|
@ -292,7 +292,7 @@ static GekkoOPTemplate table31[] =
|
||||||
{595, &JitArm::mfsr}, //"mfsr", OPTYPE_SYSTEM, FL_OUT_D, 2}},
|
{595, &JitArm::mfsr}, //"mfsr", OPTYPE_SYSTEM, FL_OUT_D, 2}},
|
||||||
{659, &JitArm::Default}, //"mfsrin", OPTYPE_SYSTEM, FL_OUT_D, 2}},
|
{659, &JitArm::Default}, //"mfsrin", OPTYPE_SYSTEM, FL_OUT_D, 2}},
|
||||||
|
|
||||||
{4, &JitArm::Break}, //"tw", OPTYPE_SYSTEM, FL_ENDBLOCK, 1}},
|
{4, &JitArm::twx}, //"tw", OPTYPE_SYSTEM, FL_ENDBLOCK, 1}},
|
||||||
{598, &JitArm::DoNothing}, //"sync", OPTYPE_SYSTEM, 0, 2}},
|
{598, &JitArm::DoNothing}, //"sync", OPTYPE_SYSTEM, 0, 2}},
|
||||||
{982, &JitArm::icbi}, //"icbi", OPTYPE_SYSTEM, FL_ENDBLOCK, 3}},
|
{982, &JitArm::icbi}, //"icbi", OPTYPE_SYSTEM, FL_ENDBLOCK, 3}},
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue