summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorMerryMage <MerryMage@users.noreply.github.com>2020-12-26 22:47:08 +0000
committerMerryMage <MerryMage@users.noreply.github.com>2020-12-26 23:00:04 +0000
commite1024fc6ba5067b213fd51edd53bd2a048f425ca (patch)
treef6260a4195f14bd3ca9660c13bb097f5e9248421 /Source
parentce599f9f46ed6dd80c894a30479cb4eae444ac29 (diff)
Jit_Integer: Use RORX where possible
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit.h2
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp82
2 files changed, 53 insertions, 31 deletions
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.h b/Source/Core/Core/PowerPC/Jit64/Jit.h
index a41ce65375..c1237463d8 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit.h
+++ b/Source/Core/Core/PowerPC/Jit64/Jit.h
@@ -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();
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp
index 74362c12c1..5a8d25bbac 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp
@@ -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)
- {
- SHR(32, Ra, Imm8(inst.MB));
- needs_sext = false;
- }
- else
+ 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))
{
- 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));