Jit_Integer: Use RORX where possible

This commit is contained in:
MerryMage 2020-12-26 22:47:08 +00:00
parent ce599f9f46
commit e1024fc6ba
2 changed files with 53 additions and 31 deletions

View File

@ -103,6 +103,8 @@ public:
void ComputeRC(preg_t preg, bool needs_test = true, bool needs_sext = true);
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;
void DoMergedBranch();
void DoMergedBranchCondition();

View File

@ -202,6 +202,27 @@ void Jit64::AndWithMask(X64Reg reg, u32 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
static u32 Add(u32 a, u32 b)
{
@ -1560,34 +1581,34 @@ void Jit64::rlwinmx(UGeckoInstruction inst)
SHL(32, Ra, Imm8(inst.SH));
needs_sext = inst.SH + mask_size >= 32;
}
else
else if (left_shift)
{
if (a != s)
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));
}
else if (right_shift)
{
SHR(32, Ra, Imm8(inst.MB));
needs_sext = 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;
}
// 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;
}
}
@ -1627,10 +1648,7 @@ void Jit64::rlwimix(UGeckoInstruction inst)
RCOpArg Rs = gpr.Use(s, RCMode::Read);
RCX64Reg Ra = gpr.Bind(a, RCMode::Read);
RegCache::Realize(Rs, Ra);
if (a != s)
MOV(32, Ra, Rs);
if (inst.SH)
ROL(32, Ra, Imm8(inst.SH));
RotateLeft(32, Ra, Rs, inst.SH);
needs_test = true;
}
else if (gpr.IsImm(s))
@ -1652,18 +1670,19 @@ void Jit64::rlwimix(UGeckoInstruction inst)
RCX64Reg Ra = gpr.Bind(a, RCMode::Write);
RegCache::Realize(Rs, Ra);
MOV(32, Ra, Rs);
if (isLeftShift)
{
MOV(32, Ra, Rs);
SHL(32, Ra, Imm8(inst.SH));
}
else if (isRightShift)
{
MOV(32, Ra, Rs);
SHR(32, Ra, Imm8(32 - inst.SH));
}
else
{
ROL(32, Ra, Imm8(inst.SH));
RotateLeft(32, Ra, Rs, inst.SH);
AND(32, Ra, Imm32(mask));
}
OR(32, Ra, Imm32(maskA));
@ -1675,22 +1694,23 @@ void Jit64::rlwimix(UGeckoInstruction inst)
RCX64Reg Ra = gpr.Bind(a, RCMode::ReadWrite);
RegCache::Realize(Rs, Ra);
MOV(32, R(RSCRATCH), Rs);
if (isLeftShift)
{
MOV(32, R(RSCRATCH), Rs);
SHL(32, R(RSCRATCH), Imm8(inst.SH));
AndWithMask(Ra, ~mask);
OR(32, Ra, R(RSCRATCH));
}
else if (isRightShift)
{
MOV(32, R(RSCRATCH), Rs);
SHR(32, R(RSCRATCH), Imm8(32 - inst.SH));
AndWithMask(Ra, ~mask);
OR(32, Ra, R(RSCRATCH));
}
else
{
ROL(32, R(RSCRATCH), Imm8(inst.SH));
RotateLeft(32, RSCRATCH, Rs, inst.SH);
XOR(32, R(RSCRATCH), Ra);
AndWithMask(RSCRATCH, mask);
XOR(32, Ra, R(RSCRATCH));