JitArm64: Implement srawx.

This commit is contained in:
degasus 2015-08-23 17:40:39 +02:00
parent 41563c55cd
commit a8b1347ea9
3 changed files with 104 additions and 17 deletions

View File

@ -85,6 +85,7 @@ public:
void addcx(UGeckoInstruction inst);
void slwx(UGeckoInstruction inst);
void srwx(UGeckoInstruction inst);
void srawx(UGeckoInstruction inst);
void rlwimix(UGeckoInstruction inst);
void subfex(UGeckoInstruction inst);
void subfcx(UGeckoInstruction inst);

View File

@ -1104,6 +1104,92 @@ void JitArm64::srwx(UGeckoInstruction inst)
}
}
void JitArm64::srawx(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(bJITIntegerOff);
int a = inst.RA, b = inst.RB, s = inst.RS;
if (gpr.IsImm(b) && gpr.IsImm(s))
{
s32 i = gpr.GetImm(s), amount = gpr.GetImm(b);
if (amount & 0x20)
{
gpr.SetImmediate(a, i & 0x80000000 ? 0xFFFFFFFF : 0);
ComputeCarry(i & 0x80000000 ? true : false);
}
else
{
amount &= 0x1F;
gpr.SetImmediate(a, i >> amount);
ComputeCarry(amount != 0 && i < 0 && (i << (32 - amount)));
}
if (inst.Rc)
ComputeRC(gpr.GetImm(a), 0);
return;
}
else if (gpr.IsImm(b) && (gpr.GetImm(b) & 0x20) == 0 && !js.op->wantsCA)
{
gpr.BindToRegister(a, a == s);
ASR(gpr.R(a), gpr.R(a), gpr.GetImm(b) & 0x1F);
}
else if (!js.op->wantsCA)
{
gpr.BindToRegister(a, a == b || a == s);
ARM64Reg WA = gpr.GetReg();
LSL(EncodeRegTo64(WA), EncodeRegTo64(gpr.R(s)), 32);
ASRV(EncodeRegTo64(WA), EncodeRegTo64(WA), EncodeRegTo64(gpr.R(b)));
LSR(EncodeRegTo64(gpr.R(a)), EncodeRegTo64(WA), 32);
gpr.Unlock(WA);
}
else
{
gpr.BindToRegister(a, a == b || a == s);
ARM64Reg WA = gpr.GetReg();
ARM64Reg WB = gpr.GetReg();
ARM64Reg WC = gpr.GetReg();
ANDI2R(WA, gpr.R(b), 32);
FixupBranch bit_is_not_zero = TBNZ(gpr.R(b), 5);
ANDSI2R(WC, gpr.R(b), 31);
MOV(WB, gpr.R(s));
FixupBranch is_zero = B(CC_EQ);
ASRV(WB, gpr.R(s), WC);
FixupBranch bit_is_zero = TBZ(gpr.R(s), 31);
MOVI2R(WA, 32);
SUB(WC, WA, WC);
LSL(WC, gpr.R(s), WC);
CMP(WC, 0);
CSET(WA, CC_NEQ);
FixupBranch end = B();
SetJumpTarget(bit_is_not_zero);
CMP(gpr.R(s), 0);
CSET(WA, CC_LT);
CSINV(WB, WZR, WZR, CC_GE);
SetJumpTarget(is_zero);
SetJumpTarget(bit_is_zero);
SetJumpTarget(end);
MOV(gpr.R(a), WB);
STRB(INDEX_UNSIGNED, WA, PPC_REG, PPCSTATE_OFF(xer_ca));
gpr.Unlock(WA, WB, WC);
}
if (inst.Rc)
ComputeRC(gpr.R(a), 0);
}
void JitArm64::rlwimix(UGeckoInstruction inst)
{
INSTRUCTION_START

View File

@ -209,23 +209,23 @@ static GekkoOPTemplate table31[] = {
{200, &JitArm64::FallBackToInterpreter}, // subfzex
{712, &JitArm64::FallBackToInterpreter}, // subfzeox
{28, &JitArm64::boolX}, // andx
{60, &JitArm64::boolX}, // andcx
{444, &JitArm64::boolX}, // orx
{124, &JitArm64::boolX}, // norx
{316, &JitArm64::boolX}, // xorx
{412, &JitArm64::boolX}, // orcx
{476, &JitArm64::boolX}, // nandx
{284, &JitArm64::boolX}, // eqvx
{0, &JitArm64::cmp}, // cmp
{32, &JitArm64::cmpl}, // cmpl
{26, &JitArm64::cntlzwx}, // cntlzwx
{922, &JitArm64::extsXx}, // extshx
{954, &JitArm64::extsXx}, // extsbx
{536, &JitArm64::srwx}, // srwx
{792, &JitArm64::FallBackToInterpreter}, // srawx
{824, &JitArm64::srawix}, // srawix
{24, &JitArm64::slwx}, // slwx
{28, &JitArm64::boolX}, // andx
{60, &JitArm64::boolX}, // andcx
{444, &JitArm64::boolX}, // orx
{124, &JitArm64::boolX}, // norx
{316, &JitArm64::boolX}, // xorx
{412, &JitArm64::boolX}, // orcx
{476, &JitArm64::boolX}, // nandx
{284, &JitArm64::boolX}, // eqvx
{0, &JitArm64::cmp}, // cmp
{32, &JitArm64::cmpl}, // cmpl
{26, &JitArm64::cntlzwx}, // cntlzwx
{922, &JitArm64::extsXx}, // extshx
{954, &JitArm64::extsXx}, // extsbx
{536, &JitArm64::srwx}, // srwx
{792, &JitArm64::srawx}, // srawx
{824, &JitArm64::srawix}, // srawix
{24, &JitArm64::slwx}, // slwx
{54, &JitArm64::dcbx}, // dcbst
{86, &JitArm64::dcbx}, // dcbf