Merge pull request #12431 from JosJuice/jitarm64-rlwnmx-call-rlwinmx

JitArm64: Call rlwinmx implementation from rlwnmx with imm b
This commit is contained in:
Mai
2023-12-17 15:18:00 -05:00
committed by GitHub
2 changed files with 36 additions and 40 deletions

View File

@ -182,6 +182,8 @@ public:
bool IsFPRStoreSafe(size_t guest_reg) const; bool IsFPRStoreSafe(size_t guest_reg) const;
void rlwinmx_internal(UGeckoInstruction inst, u32 sh);
protected: protected:
struct FastmemArea struct FastmemArea
{ {

View File

@ -757,16 +757,14 @@ void JitArm64::cmpli(UGeckoInstruction inst)
SUBI2R(CR, EncodeRegTo64(gpr.R(a)), B, CR); SUBI2R(CR, EncodeRegTo64(gpr.R(a)), B, CR);
} }
void JitArm64::rlwinmx(UGeckoInstruction inst) void JitArm64::rlwinmx_internal(UGeckoInstruction inst, u32 sh)
{ {
INSTRUCTION_START
JITDISABLE(bJITIntegerOff);
u32 a = inst.RA, s = inst.RS; u32 a = inst.RA, s = inst.RS;
const u32 mask = MakeRotationMask(inst.MB, inst.ME); const u32 mask = MakeRotationMask(inst.MB, inst.ME);
if (gpr.IsImm(inst.RS)) if (gpr.IsImm(inst.RS))
{ {
gpr.SetImmediate(a, std::rotl(gpr.GetImm(s), inst.SH) & mask); gpr.SetImmediate(a, std::rotl(gpr.GetImm(s), sh) & mask);
if (inst.Rc) if (inst.Rc)
ComputeRC0(gpr.GetImm(a)); ComputeRC0(gpr.GetImm(a));
return; return;
@ -774,35 +772,35 @@ void JitArm64::rlwinmx(UGeckoInstruction inst)
gpr.BindToRegister(a, a == s); gpr.BindToRegister(a, a == s);
if (!inst.SH && mask == 0xFFFFFFFF) if (sh == 0 && mask == 0xFFFFFFFF)
{ {
if (a != s) if (a != s)
MOV(gpr.R(a), gpr.R(s)); MOV(gpr.R(a), gpr.R(s));
} }
else if (!inst.SH) else if (sh == 0)
{ {
// Immediate mask // Immediate mask
AND(gpr.R(a), gpr.R(s), LogicalImm(mask, GPRSize::B32)); AND(gpr.R(a), gpr.R(s), LogicalImm(mask, GPRSize::B32));
} }
else if (mask == 0xFFFFFFFF) else if (mask == 0xFFFFFFFF)
{ {
ROR(gpr.R(a), gpr.R(s), 32 - inst.SH); ROR(gpr.R(a), gpr.R(s), 32 - sh);
} }
else if (inst.ME == 31 && 31 < inst.SH + inst.MB) else if (inst.ME == 31 && 31 < sh + inst.MB)
{ {
// Bit select of the upper part // Bit select of the upper part
UBFX(gpr.R(a), gpr.R(s), 32 - inst.SH, 32 - inst.MB); UBFX(gpr.R(a), gpr.R(s), 32 - sh, 32 - inst.MB);
} }
else if (inst.ME == 31 - inst.SH && 32 > inst.SH + inst.MB) else if (inst.ME == 31 - sh && 32 > sh + inst.MB)
{ {
// Bit select of the lower part // Bit select of the lower part
UBFIZ(gpr.R(a), gpr.R(s), inst.SH, 32 - inst.SH - inst.MB); UBFIZ(gpr.R(a), gpr.R(s), sh, 32 - sh - inst.MB);
} }
else else
{ {
ARM64Reg WA = gpr.GetReg(); ARM64Reg WA = gpr.GetReg();
MOVI2R(WA, mask); MOVI2R(WA, mask);
AND(gpr.R(a), WA, gpr.R(s), ArithOption(gpr.R(s), ShiftType::ROR, 32 - inst.SH)); AND(gpr.R(a), WA, gpr.R(s), ArithOption(gpr.R(s), ShiftType::ROR, 32 - sh));
gpr.Unlock(WA); gpr.Unlock(WA);
} }
@ -810,41 +808,37 @@ void JitArm64::rlwinmx(UGeckoInstruction inst)
ComputeRC0(gpr.R(a)); ComputeRC0(gpr.R(a));
} }
void JitArm64::rlwinmx(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(bJITIntegerOff);
rlwinmx_internal(inst, inst.SH);
}
void JitArm64::rlwnmx(UGeckoInstruction inst) void JitArm64::rlwnmx(UGeckoInstruction inst)
{ {
INSTRUCTION_START INSTRUCTION_START
JITDISABLE(bJITIntegerOff); JITDISABLE(bJITIntegerOff);
const u32 a = inst.RA, b = inst.RB, s = inst.RS; const u32 a = inst.RA, b = inst.RB, s = inst.RS;
if (gpr.IsImm(b))
{
rlwinmx_internal(inst, gpr.GetImm(b) & 0x1F);
return;
}
const u32 mask = MakeRotationMask(inst.MB, inst.ME); const u32 mask = MakeRotationMask(inst.MB, inst.ME);
if (gpr.IsImm(b) && gpr.IsImm(s)) gpr.BindToRegister(a, a == s || a == b);
{ ARM64Reg WA = gpr.GetReg();
gpr.SetImmediate(a, std::rotl(gpr.GetImm(s), gpr.GetImm(b) & 0x1F) & mask); NEG(WA, gpr.R(b));
if (inst.Rc) RORV(gpr.R(a), gpr.R(s), WA);
ComputeRC0(gpr.GetImm(a)); ANDI2R(gpr.R(a), gpr.R(a), mask, WA);
} gpr.Unlock(WA);
else if (gpr.IsImm(b))
{ if (inst.Rc)
int imm_value = gpr.GetImm(b) & 0x1f; ComputeRC0(gpr.R(a));
gpr.BindToRegister(a, a == s);
ARM64Reg WA = gpr.GetReg();
MOVI2R(WA, mask);
AND(gpr.R(a), WA, gpr.R(s), ArithOption(gpr.R(s), ShiftType::ROR, 32 - imm_value));
gpr.Unlock(WA);
if (inst.Rc)
ComputeRC0(gpr.R(a));
}
else
{
gpr.BindToRegister(a, a == s || a == b);
ARM64Reg WA = gpr.GetReg();
NEG(WA, gpr.R(b));
RORV(gpr.R(a), gpr.R(s), WA);
ANDI2R(gpr.R(a), gpr.R(a), mask, WA);
gpr.Unlock(WA);
if (inst.Rc)
ComputeRC0(gpr.R(a));
}
} }
void JitArm64::srawix(UGeckoInstruction inst) void JitArm64::srawix(UGeckoInstruction inst)