Merge pull request #9363 from MerryMage/rorx

Jit_Integer: Use RORX where possible
This commit is contained in:
LC 2020-12-27 22:25:03 -05:00 committed by GitHub
commit 28a666a35f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 32 deletions

View File

@ -103,6 +103,8 @@ public:
void ComputeRC(preg_t preg, bool needs_test = true, bool needs_sext = true); void ComputeRC(preg_t preg, bool needs_test = true, bool needs_sext = true);
void AndWithMask(Gen::X64Reg reg, u32 mask); void AndWithMask(Gen::X64Reg reg, u32 mask);
void RotateLeft(int bits, Gen::X64Reg regOp, const Gen::OpArg& arg, u8 rotate);
bool CheckMergedBranch(u32 crf) const; bool CheckMergedBranch(u32 crf) const;
void DoMergedBranch(); void DoMergedBranch();
void DoMergedBranchCondition(); void DoMergedBranchCondition();

View File

@ -207,6 +207,27 @@ void Jit64::AndWithMask(X64Reg reg, u32 mask)
AND(32, R(reg), Imm32(mask)); AND(32, R(reg), Imm32(mask));
} }
void Jit64::RotateLeft(int bits, X64Reg regOp, const OpArg& arg, u8 rotate)
{
const bool is_same_reg = arg.IsSimpleReg(regOp);
if (cpu_info.bBMI2 && !is_same_reg && rotate != 0)
{
RORX(bits, regOp, arg, bits - rotate);
return;
}
if (!is_same_reg)
{
MOV(bits, R(regOp), arg);
}
if (rotate != 0)
{
ROL(bits, R(regOp), Imm8(rotate));
}
}
// Following static functions are used in conjunction with regimmop // Following static functions are used in conjunction with regimmop
static u32 Add(u32 a, u32 b) static u32 Add(u32 a, u32 b)
{ {
@ -1582,34 +1603,34 @@ void Jit64::rlwinmx(UGeckoInstruction inst)
BEXTR(32, Ra, Rs, RSCRATCH); BEXTR(32, Ra, Rs, RSCRATCH);
needs_sext = false; needs_sext = false;
} }
else else if (left_shift)
{ {
if (a != s) if (a != s)
MOV(32, Ra, Rs); MOV(32, Ra, Rs);
if (left_shift) SHL(32, Ra, Imm8(inst.SH));
}
else if (right_shift)
{
if (a != s)
MOV(32, Ra, Rs);
SHR(32, Ra, Imm8(inst.MB));
needs_sext = false;
}
else
{
RotateLeft(32, Ra, Rs, inst.SH);
if (!(inst.MB == 0 && inst.ME == 31))
{ {
SHL(32, Ra, Imm8(inst.SH)); // we need flags if we're merging the branch
} if (inst.Rc && CheckMergedBranch(0))
else if (right_shift) AND(32, Ra, Imm32(mask));
{ else
SHR(32, Ra, Imm8(inst.MB)); AndWithMask(Ra, mask);
needs_sext = false; needs_sext = inst.MB == 0;
} needs_test = false;
else
{
if (inst.SH != 0)
ROL(32, Ra, Imm8(inst.SH));
if (!(inst.MB == 0 && inst.ME == 31))
{
// we need flags if we're merging the branch
if (inst.Rc && CheckMergedBranch(0))
AND(32, Ra, Imm32(mask));
else
AndWithMask(Ra, mask);
needs_sext = inst.MB == 0;
needs_test = false;
}
} }
} }
@ -1649,10 +1670,7 @@ void Jit64::rlwimix(UGeckoInstruction inst)
RCOpArg Rs = gpr.Use(s, RCMode::Read); RCOpArg Rs = gpr.Use(s, RCMode::Read);
RCX64Reg Ra = gpr.Bind(a, RCMode::Read); RCX64Reg Ra = gpr.Bind(a, RCMode::Read);
RegCache::Realize(Rs, Ra); RegCache::Realize(Rs, Ra);
if (a != s) RotateLeft(32, Ra, Rs, inst.SH);
MOV(32, Ra, Rs);
if (inst.SH)
ROL(32, Ra, Imm8(inst.SH));
needs_test = true; needs_test = true;
} }
else if (gpr.IsImm(s)) else if (gpr.IsImm(s))
@ -1674,19 +1692,20 @@ void Jit64::rlwimix(UGeckoInstruction inst)
RCX64Reg Ra = gpr.Bind(a, RCMode::Write); RCX64Reg Ra = gpr.Bind(a, RCMode::Write);
RegCache::Realize(Rs, Ra); RegCache::Realize(Rs, Ra);
MOV(32, Ra, Rs);
if (isLeftShift) if (isLeftShift)
{ {
MOV(32, Ra, Rs);
SHL(32, Ra, Imm8(inst.SH)); SHL(32, Ra, Imm8(inst.SH));
} }
else if (isRightShift) else if (isRightShift)
{ {
MOV(32, Ra, Rs);
SHR(32, Ra, Imm8(32 - inst.SH)); SHR(32, Ra, Imm8(32 - inst.SH));
} }
else else
{ {
ROL(32, Ra, Imm8(inst.SH)); RotateLeft(32, Ra, Rs, inst.SH);
AND(32, Ra, Imm32(mask)); AndWithMask(Ra, mask);
} }
OR(32, Ra, Imm32(maskA)); OR(32, Ra, Imm32(maskA));
} }
@ -1697,22 +1716,23 @@ void Jit64::rlwimix(UGeckoInstruction inst)
RCX64Reg Ra = gpr.Bind(a, RCMode::ReadWrite); RCX64Reg Ra = gpr.Bind(a, RCMode::ReadWrite);
RegCache::Realize(Rs, Ra); RegCache::Realize(Rs, Ra);
MOV(32, R(RSCRATCH), Rs);
if (isLeftShift) if (isLeftShift)
{ {
MOV(32, R(RSCRATCH), Rs);
SHL(32, R(RSCRATCH), Imm8(inst.SH)); SHL(32, R(RSCRATCH), Imm8(inst.SH));
AndWithMask(Ra, ~mask); AndWithMask(Ra, ~mask);
OR(32, Ra, R(RSCRATCH)); OR(32, Ra, R(RSCRATCH));
} }
else if (isRightShift) else if (isRightShift)
{ {
MOV(32, R(RSCRATCH), Rs);
SHR(32, R(RSCRATCH), Imm8(32 - inst.SH)); SHR(32, R(RSCRATCH), Imm8(32 - inst.SH));
AndWithMask(Ra, ~mask); AndWithMask(Ra, ~mask);
OR(32, Ra, R(RSCRATCH)); OR(32, Ra, R(RSCRATCH));
} }
else else
{ {
ROL(32, R(RSCRATCH), Imm8(inst.SH)); RotateLeft(32, RSCRATCH, Rs, inst.SH);
XOR(32, R(RSCRATCH), Ra); XOR(32, R(RSCRATCH), Ra);
AndWithMask(RSCRATCH, mask); AndWithMask(RSCRATCH, mask);
XOR(32, Ra, R(RSCRATCH)); XOR(32, Ra, R(RSCRATCH));