summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorskidau <skidau@gmail.com>2015-02-06 13:53:09 +1100
committerskidau <skidau@gmail.com>2015-02-06 13:53:09 +1100
commit66d80b75e29ccf453d5efa127eedc91af9da24ec (patch)
tree5ef8e96279942b8e7d4e492e2f1464f8d53d0174 /Source/Core
parent550dc273f3f362c635385d971e31d862817c1f4c (diff)
parent46df8a5358435107354fa39c96d7ded36ee13274 (diff)
Merge pull request #1939 from Sintendo/dspjit_ccnits
Minor DSP JIT optimizations
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/DSP/DSPEmitter.h3
-rw-r--r--Source/Core/Core/DSP/Jit/DSPJitArithmetic.cpp20
-rw-r--r--Source/Core/Core/DSP/Jit/DSPJitCCUtil.cpp87
3 files changed, 39 insertions, 71 deletions
diff --git a/Source/Core/Core/DSP/DSPEmitter.h b/Source/Core/Core/DSP/DSPEmitter.h
index e392fbf42d..c0dfa6aedf 100644
--- a/Source/Core/Core/DSP/DSPEmitter.h
+++ b/Source/Core/Core/DSP/DSPEmitter.h
@@ -41,8 +41,7 @@ public:
// CC Util
void Update_SR_Register64(Gen::X64Reg val = Gen::EAX);
- void Update_SR_Register64_Carry(Gen::X64Reg val, Gen::X64Reg carry_ovfl);
- void Update_SR_Register64_Carry2(Gen::X64Reg val, Gen::X64Reg carry_ovfl);
+ void Update_SR_Register64_Carry(Gen::X64Reg val, Gen::X64Reg carry_ovfl, bool carry_eq = false);
void Update_SR_Register16(Gen::X64Reg val = Gen::EAX);
void Update_SR_Register16_OverS32(Gen::X64Reg val = Gen::EAX);
diff --git a/Source/Core/Core/DSP/Jit/DSPJitArithmetic.cpp b/Source/Core/Core/DSP/Jit/DSPJitArithmetic.cpp
index 2e1a88890b..a56d75a5b1 100644
--- a/Source/Core/Core/DSP/Jit/DSPJitArithmetic.cpp
+++ b/Source/Core/Core/DSP/Jit/DSPJitArithmetic.cpp
@@ -179,7 +179,7 @@ void DSPEmitter::cmp(const UDSPInstruction opc)
SUB(64, R(RAX), R(RDX));
// Update_SR_Register64(res, isCarry2(acc0, res), isOverflow(acc0, -acc1, res)); // CF -> influence on ABS/0xa100
NEG(64, R(RDX));
- Update_SR_Register64_Carry2(EAX, tmp1);
+ Update_SR_Register64_Carry(EAX, tmp1, true);
gpr.putXReg(tmp1);
}
}
@@ -210,7 +210,7 @@ void DSPEmitter::cmpar(const UDSPInstruction opc)
SUB(64, R(RAX), R(RDX));
// Update_SR_Register64(res, isCarry2(sr, res), isOverflow(sr, -rr, res));
NEG(64, R(RDX));
- Update_SR_Register64_Carry2(EAX, tmp1);
+ Update_SR_Register64_Carry(EAX, tmp1, true);
gpr.putXReg(tmp1);
}
}
@@ -239,7 +239,7 @@ void DSPEmitter::cmpi(const UDSPInstruction opc)
SUB(64, R(RAX), R(RDX));
// Update_SR_Register64(res, isCarry2(val, res), isOverflow(val, -imm, res));
NEG(64, R(RDX));
- Update_SR_Register64_Carry2(EAX, tmp1);
+ Update_SR_Register64_Carry(EAX, tmp1, true);
gpr.putXReg(tmp1);
}
}
@@ -268,7 +268,7 @@ void DSPEmitter::cmpis(const UDSPInstruction opc)
SUB(64, R(RAX), R(RDX));
// Update_SR_Register64(res, isCarry2(acc, res), isOverflow(acc, -val, res));
NEG(64, R(RDX));
- Update_SR_Register64_Carry2(EAX, tmp1);
+ Update_SR_Register64_Carry(EAX, tmp1, true);
gpr.putXReg(tmp1);
}
}
@@ -862,7 +862,7 @@ void DSPEmitter::subr(const UDSPInstruction opc)
NEG(64, R(RDX));
MOV(64, R(RCX), R(RAX));
set_long_acc(dreg, RCX);
- Update_SR_Register64_Carry2(EAX, tmp1);
+ Update_SR_Register64_Carry(EAX, tmp1, true);
}
else
{
@@ -898,7 +898,7 @@ void DSPEmitter::subax(const UDSPInstruction opc)
NEG(64, R(RDX));
MOV(64, R(RCX), R(RAX));
set_long_acc(dreg, RCX);
- Update_SR_Register64_Carry2(EAX, tmp1);
+ Update_SR_Register64_Carry(EAX, tmp1, true);
}
else
{
@@ -932,7 +932,7 @@ void DSPEmitter::sub(const UDSPInstruction opc)
NEG(64, R(RDX));
MOV(64, R(RCX), R(RAX));
set_long_acc(dreg, RCX);
- Update_SR_Register64_Carry2(EAX, tmp1);
+ Update_SR_Register64_Carry(EAX, tmp1, true);
}
else
{
@@ -966,7 +966,7 @@ void DSPEmitter::subp(const UDSPInstruction opc)
NEG(64, R(RDX));
MOV(64, R(RCX), R(RAX));
set_long_acc(dreg, RCX);
- Update_SR_Register64_Carry2(EAX, tmp1);
+ Update_SR_Register64_Carry(EAX, tmp1, true);
}
else
{
@@ -999,7 +999,7 @@ void DSPEmitter::decm(const UDSPInstruction opc)
MOV(64, R(RDX), Imm64(-subtract));
MOV(64, R(RCX), R(RAX));
set_long_acc(dreg, RCX);
- Update_SR_Register64_Carry2(EAX, tmp1);
+ Update_SR_Register64_Carry(EAX, tmp1, true);
}
else
{
@@ -1031,7 +1031,7 @@ void DSPEmitter::dec(const UDSPInstruction opc)
MOV(64, R(RDX), Imm64(-1));
MOV(64, R(RCX), R(RAX));
set_long_acc(dreg, RCX);
- Update_SR_Register64_Carry2(EAX, tmp1);
+ Update_SR_Register64_Carry(EAX, tmp1, true);
}
else
{
diff --git a/Source/Core/Core/DSP/Jit/DSPJitCCUtil.cpp b/Source/Core/Core/DSP/Jit/DSPJitCCUtil.cpp
index 8e9d86aed8..00e641328e 100644
--- a/Source/Core/Core/DSP/Jit/DSPJitCCUtil.cpp
+++ b/Source/Core/Core/DSP/Jit/DSPJitCCUtil.cpp
@@ -17,14 +17,14 @@ void DSPEmitter::Update_SR_Register(Gen::X64Reg val)
gpr.getReg(DSP_REG_SR,sr_reg);
// // 0x04
// if (_Value == 0) g_dsp.r[DSP_REG_SR] |= SR_ARITH_ZERO;
- CMP(64, R(val), Imm8(0));
+ TEST(64, R(val), R(val));
FixupBranch notZero = J_CC(CC_NZ);
- OR(16, sr_reg, Imm16(SR_ARITH_ZERO));
+ OR(16, sr_reg, Imm16(SR_ARITH_ZERO | SR_TOP2BITS));
+ FixupBranch end = J();
SetJumpTarget(notZero);
// // 0x08
// if (_Value < 0) g_dsp.r[DSP_REG_SR] |= SR_SIGN;
- CMP(64, R(val), Imm8(0));
FixupBranch greaterThanEqual = J_CC(CC_GE);
OR(16, sr_reg, Imm16(SR_SIGN));
SetJumpTarget(greaterThanEqual);
@@ -39,15 +39,16 @@ void DSPEmitter::Update_SR_Register(Gen::X64Reg val)
// // 0x20 - Checks if top bits of m are equal
// if (((_Value & 0xc0000000) == 0) || ((_Value & 0xc0000000) == 0xc0000000))
- AND(32, R(val), Imm32(0xc0000000));
- CMP(32, R(val), Imm32(0));
- FixupBranch zeroC = J_CC(CC_E);
- CMP(32, R(val), Imm32(0xc0000000));
+ MOV(32, R(RDX), Imm32(0xc0000000));
+ AND(32, R(val), R(RDX));
+ FixupBranch zeroC = J_CC(CC_Z);
+ CMP(32, R(val), R(RDX));
FixupBranch cC = J_CC(CC_NE);
SetJumpTarget(zeroC);
// g_dsp.r[DSP_REG_SR] |= SR_TOP2BITS;
OR(16, sr_reg, Imm16(SR_TOP2BITS));
SetJumpTarget(cC);
+ SetJumpTarget(end);
gpr.putReg(DSP_REG_SR);
}
@@ -66,7 +67,7 @@ void DSPEmitter::Update_SR_Register64(Gen::X64Reg val)
// In: (val): s64 _Value
// In: (carry_ovfl): 1 = carry, 2 = overflow
// Clobbers RDX
-void DSPEmitter::Update_SR_Register64_Carry(X64Reg val, X64Reg carry_ovfl)
+void DSPEmitter::Update_SR_Register64_Carry(X64Reg val, X64Reg carry_ovfl, bool carry_eq)
{
OpArg sr_reg;
gpr.getReg(DSP_REG_SR,sr_reg);
@@ -78,7 +79,8 @@ void DSPEmitter::Update_SR_Register64_Carry(X64Reg val, X64Reg carry_ovfl)
// 0x01
// g_dsp.r[DSP_REG_SR] |= SR_CARRY;
// Carry = (acc>res)
- FixupBranch noCarry = J_CC(CC_BE);
+ // Carry2 = (acc>=res)
+ FixupBranch noCarry = J_CC(carry_eq ? CC_B : CC_BE);
OR(16, sr_reg, Imm16(SR_CARRY));
SetJumpTarget(noCarry);
@@ -88,53 +90,23 @@ void DSPEmitter::Update_SR_Register64_Carry(X64Reg val, X64Reg carry_ovfl)
// Overflow = ((acc ^ res) & (ax ^ res)) < 0
XOR(64, R(carry_ovfl), R(val));
XOR(64, R(RDX), R(val));
- AND(64, R(carry_ovfl), R(RDX));
- CMP(64, R(carry_ovfl), Imm8(0));
+ TEST(64, R(carry_ovfl), R(RDX));
FixupBranch noOverflow = J_CC(CC_GE);
OR(16, sr_reg, Imm16(SR_OVERFLOW | SR_OVERFLOW_STICKY));
SetJumpTarget(noOverflow);
gpr.putReg(DSP_REG_SR);
- Update_SR_Register(val);
-}
-
-// In: (val): s64 _Value
-// In: (carry_ovfl): 1 = carry, 2 = overflow
-// Clobbers RDX
-void DSPEmitter::Update_SR_Register64_Carry2(X64Reg val, X64Reg carry_ovfl)
-{
- OpArg sr_reg;
- gpr.getReg(DSP_REG_SR,sr_reg);
- // g_dsp.r[DSP_REG_SR] &= ~SR_CMP_MASK;
- AND(16, sr_reg, Imm16(~SR_CMP_MASK));
-
- CMP(64, R(carry_ovfl), R(val));
-
- // 0x01
- // g_dsp.r[DSP_REG_SR] |= SR_CARRY;
- // Carry2 = (acc>=res)
- FixupBranch noCarry2 = J_CC(CC_B);
- OR(16, sr_reg, Imm16(SR_CARRY));
- SetJumpTarget(noCarry2);
-
- // 0x02 and 0x80
- // g_dsp.r[DSP_REG_SR] |= SR_OVERFLOW;
- // g_dsp.r[DSP_REG_SR] |= SR_OVERFLOW_STICKY;
- // Overflow = ((acc ^ res) & (ax ^ res)) < 0
- XOR(64, R(carry_ovfl), R(val));
- XOR(64, R(RDX), R(val));
- AND(64, R(carry_ovfl), R(RDX));
- CMP(64, R(carry_ovfl), Imm8(0));
- FixupBranch noOverflow = J_CC(CC_GE);
- OR(16, sr_reg, Imm16(SR_OVERFLOW | SR_OVERFLOW_STICKY));
- SetJumpTarget(noOverflow);
- gpr.putReg(DSP_REG_SR);
-
- Update_SR_Register();
+ if (carry_eq)
+ {
+ Update_SR_Register();
+ }
+ else
+ {
+ Update_SR_Register(val);
+ }
}
// In: RAX: s64 _Value
-// Clobbers RDX
void DSPEmitter::Update_SR_Register16(X64Reg val)
{
OpArg sr_reg;
@@ -143,38 +115,35 @@ void DSPEmitter::Update_SR_Register16(X64Reg val)
// // 0x04
// if (_Value == 0) g_dsp.r[DSP_REG_SR] |= SR_ARITH_ZERO;
- CMP(64, R(val), Imm8(0));
+ TEST(64, R(val), R(val));
FixupBranch notZero = J_CC(CC_NZ);
- OR(16, sr_reg, Imm16(SR_ARITH_ZERO));
+ OR(16, sr_reg, Imm16(SR_ARITH_ZERO | SR_TOP2BITS));
+ FixupBranch end = J();
SetJumpTarget(notZero);
// // 0x08
// if (_Value < 0) g_dsp.r[DSP_REG_SR] |= SR_SIGN;
- CMP(64, R(val), Imm8(0));
FixupBranch greaterThanEqual = J_CC(CC_GE);
OR(16, sr_reg, Imm16(SR_SIGN));
SetJumpTarget(greaterThanEqual);
// // 0x20 - Checks if top bits of m are equal
// if ((((u16)_Value >> 14) == 0) || (((u16)_Value >> 14) == 3))
- //AND(32, R(val), Imm32(0xc0000000));
SHR(16, R(val), Imm8(14));
- CMP(16, R(val), Imm16(0));
- FixupBranch nZero = J_CC(CC_NE);
- OR(16, sr_reg, Imm16(SR_TOP2BITS));
- FixupBranch cC = J();
- SetJumpTarget(nZero);
+ TEST(16, R(val), R(val));
+ FixupBranch isZero = J_CC(CC_Z);
CMP(16, R(val), Imm16(3));
FixupBranch notThree = J_CC(CC_NE);
+ SetJumpTarget(isZero);
// g_dsp.r[DSP_REG_SR] |= SR_TOP2BITS;
OR(16, sr_reg, Imm16(SR_TOP2BITS));
SetJumpTarget(notThree);
- SetJumpTarget(cC);
+ SetJumpTarget(end);
gpr.putReg(DSP_REG_SR);
}
// In: RAX: s64 _Value
-// Clobbers RDX
+// Clobbers RCX
void DSPEmitter::Update_SR_Register16_OverS32(Gen::X64Reg val)
{
OpArg sr_reg;