Merge pull request #1939 from Sintendo/dspjit_ccnits
Minor DSP JIT optimizations
This commit is contained in:
commit
66d80b75e2
|
@ -41,8 +41,7 @@ public:
|
||||||
|
|
||||||
// CC Util
|
// CC Util
|
||||||
void Update_SR_Register64(Gen::X64Reg val = Gen::EAX);
|
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_Carry(Gen::X64Reg val, Gen::X64Reg carry_ovfl, bool carry_eq = false);
|
||||||
void Update_SR_Register64_Carry2(Gen::X64Reg val, Gen::X64Reg carry_ovfl);
|
|
||||||
void Update_SR_Register16(Gen::X64Reg val = Gen::EAX);
|
void Update_SR_Register16(Gen::X64Reg val = Gen::EAX);
|
||||||
void Update_SR_Register16_OverS32(Gen::X64Reg val = Gen::EAX);
|
void Update_SR_Register16_OverS32(Gen::X64Reg val = Gen::EAX);
|
||||||
|
|
||||||
|
|
|
@ -179,7 +179,7 @@ void DSPEmitter::cmp(const UDSPInstruction opc)
|
||||||
SUB(64, R(RAX), R(RDX));
|
SUB(64, R(RAX), R(RDX));
|
||||||
// Update_SR_Register64(res, isCarry2(acc0, res), isOverflow(acc0, -acc1, res)); // CF -> influence on ABS/0xa100
|
// Update_SR_Register64(res, isCarry2(acc0, res), isOverflow(acc0, -acc1, res)); // CF -> influence on ABS/0xa100
|
||||||
NEG(64, R(RDX));
|
NEG(64, R(RDX));
|
||||||
Update_SR_Register64_Carry2(EAX, tmp1);
|
Update_SR_Register64_Carry(EAX, tmp1, true);
|
||||||
gpr.putXReg(tmp1);
|
gpr.putXReg(tmp1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -210,7 +210,7 @@ void DSPEmitter::cmpar(const UDSPInstruction opc)
|
||||||
SUB(64, R(RAX), R(RDX));
|
SUB(64, R(RAX), R(RDX));
|
||||||
// Update_SR_Register64(res, isCarry2(sr, res), isOverflow(sr, -rr, res));
|
// Update_SR_Register64(res, isCarry2(sr, res), isOverflow(sr, -rr, res));
|
||||||
NEG(64, R(RDX));
|
NEG(64, R(RDX));
|
||||||
Update_SR_Register64_Carry2(EAX, tmp1);
|
Update_SR_Register64_Carry(EAX, tmp1, true);
|
||||||
gpr.putXReg(tmp1);
|
gpr.putXReg(tmp1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -239,7 +239,7 @@ void DSPEmitter::cmpi(const UDSPInstruction opc)
|
||||||
SUB(64, R(RAX), R(RDX));
|
SUB(64, R(RAX), R(RDX));
|
||||||
// Update_SR_Register64(res, isCarry2(val, res), isOverflow(val, -imm, res));
|
// Update_SR_Register64(res, isCarry2(val, res), isOverflow(val, -imm, res));
|
||||||
NEG(64, R(RDX));
|
NEG(64, R(RDX));
|
||||||
Update_SR_Register64_Carry2(EAX, tmp1);
|
Update_SR_Register64_Carry(EAX, tmp1, true);
|
||||||
gpr.putXReg(tmp1);
|
gpr.putXReg(tmp1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -268,7 +268,7 @@ void DSPEmitter::cmpis(const UDSPInstruction opc)
|
||||||
SUB(64, R(RAX), R(RDX));
|
SUB(64, R(RAX), R(RDX));
|
||||||
// Update_SR_Register64(res, isCarry2(acc, res), isOverflow(acc, -val, res));
|
// Update_SR_Register64(res, isCarry2(acc, res), isOverflow(acc, -val, res));
|
||||||
NEG(64, R(RDX));
|
NEG(64, R(RDX));
|
||||||
Update_SR_Register64_Carry2(EAX, tmp1);
|
Update_SR_Register64_Carry(EAX, tmp1, true);
|
||||||
gpr.putXReg(tmp1);
|
gpr.putXReg(tmp1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -862,7 +862,7 @@ void DSPEmitter::subr(const UDSPInstruction opc)
|
||||||
NEG(64, R(RDX));
|
NEG(64, R(RDX));
|
||||||
MOV(64, R(RCX), R(RAX));
|
MOV(64, R(RCX), R(RAX));
|
||||||
set_long_acc(dreg, RCX);
|
set_long_acc(dreg, RCX);
|
||||||
Update_SR_Register64_Carry2(EAX, tmp1);
|
Update_SR_Register64_Carry(EAX, tmp1, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -898,7 +898,7 @@ void DSPEmitter::subax(const UDSPInstruction opc)
|
||||||
NEG(64, R(RDX));
|
NEG(64, R(RDX));
|
||||||
MOV(64, R(RCX), R(RAX));
|
MOV(64, R(RCX), R(RAX));
|
||||||
set_long_acc(dreg, RCX);
|
set_long_acc(dreg, RCX);
|
||||||
Update_SR_Register64_Carry2(EAX, tmp1);
|
Update_SR_Register64_Carry(EAX, tmp1, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -932,7 +932,7 @@ void DSPEmitter::sub(const UDSPInstruction opc)
|
||||||
NEG(64, R(RDX));
|
NEG(64, R(RDX));
|
||||||
MOV(64, R(RCX), R(RAX));
|
MOV(64, R(RCX), R(RAX));
|
||||||
set_long_acc(dreg, RCX);
|
set_long_acc(dreg, RCX);
|
||||||
Update_SR_Register64_Carry2(EAX, tmp1);
|
Update_SR_Register64_Carry(EAX, tmp1, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -966,7 +966,7 @@ void DSPEmitter::subp(const UDSPInstruction opc)
|
||||||
NEG(64, R(RDX));
|
NEG(64, R(RDX));
|
||||||
MOV(64, R(RCX), R(RAX));
|
MOV(64, R(RCX), R(RAX));
|
||||||
set_long_acc(dreg, RCX);
|
set_long_acc(dreg, RCX);
|
||||||
Update_SR_Register64_Carry2(EAX, tmp1);
|
Update_SR_Register64_Carry(EAX, tmp1, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -999,7 +999,7 @@ void DSPEmitter::decm(const UDSPInstruction opc)
|
||||||
MOV(64, R(RDX), Imm64(-subtract));
|
MOV(64, R(RDX), Imm64(-subtract));
|
||||||
MOV(64, R(RCX), R(RAX));
|
MOV(64, R(RCX), R(RAX));
|
||||||
set_long_acc(dreg, RCX);
|
set_long_acc(dreg, RCX);
|
||||||
Update_SR_Register64_Carry2(EAX, tmp1);
|
Update_SR_Register64_Carry(EAX, tmp1, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1031,7 +1031,7 @@ void DSPEmitter::dec(const UDSPInstruction opc)
|
||||||
MOV(64, R(RDX), Imm64(-1));
|
MOV(64, R(RDX), Imm64(-1));
|
||||||
MOV(64, R(RCX), R(RAX));
|
MOV(64, R(RCX), R(RAX));
|
||||||
set_long_acc(dreg, RCX);
|
set_long_acc(dreg, RCX);
|
||||||
Update_SR_Register64_Carry2(EAX, tmp1);
|
Update_SR_Register64_Carry(EAX, tmp1, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,14 +17,14 @@ void DSPEmitter::Update_SR_Register(Gen::X64Reg val)
|
||||||
gpr.getReg(DSP_REG_SR,sr_reg);
|
gpr.getReg(DSP_REG_SR,sr_reg);
|
||||||
// // 0x04
|
// // 0x04
|
||||||
// if (_Value == 0) g_dsp.r[DSP_REG_SR] |= SR_ARITH_ZERO;
|
// 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);
|
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);
|
SetJumpTarget(notZero);
|
||||||
|
|
||||||
// // 0x08
|
// // 0x08
|
||||||
// if (_Value < 0) g_dsp.r[DSP_REG_SR] |= SR_SIGN;
|
// if (_Value < 0) g_dsp.r[DSP_REG_SR] |= SR_SIGN;
|
||||||
CMP(64, R(val), Imm8(0));
|
|
||||||
FixupBranch greaterThanEqual = J_CC(CC_GE);
|
FixupBranch greaterThanEqual = J_CC(CC_GE);
|
||||||
OR(16, sr_reg, Imm16(SR_SIGN));
|
OR(16, sr_reg, Imm16(SR_SIGN));
|
||||||
SetJumpTarget(greaterThanEqual);
|
SetJumpTarget(greaterThanEqual);
|
||||||
|
@ -39,15 +39,16 @@ void DSPEmitter::Update_SR_Register(Gen::X64Reg val)
|
||||||
|
|
||||||
// // 0x20 - Checks if top bits of m are equal
|
// // 0x20 - Checks if top bits of m are equal
|
||||||
// if (((_Value & 0xc0000000) == 0) || ((_Value & 0xc0000000) == 0xc0000000))
|
// if (((_Value & 0xc0000000) == 0) || ((_Value & 0xc0000000) == 0xc0000000))
|
||||||
AND(32, R(val), Imm32(0xc0000000));
|
MOV(32, R(RDX), Imm32(0xc0000000));
|
||||||
CMP(32, R(val), Imm32(0));
|
AND(32, R(val), R(RDX));
|
||||||
FixupBranch zeroC = J_CC(CC_E);
|
FixupBranch zeroC = J_CC(CC_Z);
|
||||||
CMP(32, R(val), Imm32(0xc0000000));
|
CMP(32, R(val), R(RDX));
|
||||||
FixupBranch cC = J_CC(CC_NE);
|
FixupBranch cC = J_CC(CC_NE);
|
||||||
SetJumpTarget(zeroC);
|
SetJumpTarget(zeroC);
|
||||||
// g_dsp.r[DSP_REG_SR] |= SR_TOP2BITS;
|
// g_dsp.r[DSP_REG_SR] |= SR_TOP2BITS;
|
||||||
OR(16, sr_reg, Imm16(SR_TOP2BITS));
|
OR(16, sr_reg, Imm16(SR_TOP2BITS));
|
||||||
SetJumpTarget(cC);
|
SetJumpTarget(cC);
|
||||||
|
SetJumpTarget(end);
|
||||||
gpr.putReg(DSP_REG_SR);
|
gpr.putReg(DSP_REG_SR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +67,7 @@ void DSPEmitter::Update_SR_Register64(Gen::X64Reg val)
|
||||||
// In: (val): s64 _Value
|
// In: (val): s64 _Value
|
||||||
// In: (carry_ovfl): 1 = carry, 2 = overflow
|
// In: (carry_ovfl): 1 = carry, 2 = overflow
|
||||||
// Clobbers RDX
|
// 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;
|
OpArg sr_reg;
|
||||||
gpr.getReg(DSP_REG_SR,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
|
// 0x01
|
||||||
// g_dsp.r[DSP_REG_SR] |= SR_CARRY;
|
// g_dsp.r[DSP_REG_SR] |= SR_CARRY;
|
||||||
// Carry = (acc>res)
|
// 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));
|
OR(16, sr_reg, Imm16(SR_CARRY));
|
||||||
SetJumpTarget(noCarry);
|
SetJumpTarget(noCarry);
|
||||||
|
|
||||||
|
@ -88,53 +90,23 @@ void DSPEmitter::Update_SR_Register64_Carry(X64Reg val, X64Reg carry_ovfl)
|
||||||
// Overflow = ((acc ^ res) & (ax ^ res)) < 0
|
// Overflow = ((acc ^ res) & (ax ^ res)) < 0
|
||||||
XOR(64, R(carry_ovfl), R(val));
|
XOR(64, R(carry_ovfl), R(val));
|
||||||
XOR(64, R(RDX), R(val));
|
XOR(64, R(RDX), R(val));
|
||||||
AND(64, R(carry_ovfl), R(RDX));
|
TEST(64, R(carry_ovfl), R(RDX));
|
||||||
CMP(64, R(carry_ovfl), Imm8(0));
|
|
||||||
FixupBranch noOverflow = J_CC(CC_GE);
|
FixupBranch noOverflow = J_CC(CC_GE);
|
||||||
OR(16, sr_reg, Imm16(SR_OVERFLOW | SR_OVERFLOW_STICKY));
|
OR(16, sr_reg, Imm16(SR_OVERFLOW | SR_OVERFLOW_STICKY));
|
||||||
SetJumpTarget(noOverflow);
|
SetJumpTarget(noOverflow);
|
||||||
|
|
||||||
gpr.putReg(DSP_REG_SR);
|
gpr.putReg(DSP_REG_SR);
|
||||||
|
if (carry_eq)
|
||||||
|
{
|
||||||
|
Update_SR_Register();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
Update_SR_Register(val);
|
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// In: RAX: s64 _Value
|
// In: RAX: s64 _Value
|
||||||
// Clobbers RDX
|
|
||||||
void DSPEmitter::Update_SR_Register16(X64Reg val)
|
void DSPEmitter::Update_SR_Register16(X64Reg val)
|
||||||
{
|
{
|
||||||
OpArg sr_reg;
|
OpArg sr_reg;
|
||||||
|
@ -143,38 +115,35 @@ void DSPEmitter::Update_SR_Register16(X64Reg val)
|
||||||
|
|
||||||
// // 0x04
|
// // 0x04
|
||||||
// if (_Value == 0) g_dsp.r[DSP_REG_SR] |= SR_ARITH_ZERO;
|
// 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);
|
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);
|
SetJumpTarget(notZero);
|
||||||
|
|
||||||
// // 0x08
|
// // 0x08
|
||||||
// if (_Value < 0) g_dsp.r[DSP_REG_SR] |= SR_SIGN;
|
// if (_Value < 0) g_dsp.r[DSP_REG_SR] |= SR_SIGN;
|
||||||
CMP(64, R(val), Imm8(0));
|
|
||||||
FixupBranch greaterThanEqual = J_CC(CC_GE);
|
FixupBranch greaterThanEqual = J_CC(CC_GE);
|
||||||
OR(16, sr_reg, Imm16(SR_SIGN));
|
OR(16, sr_reg, Imm16(SR_SIGN));
|
||||||
SetJumpTarget(greaterThanEqual);
|
SetJumpTarget(greaterThanEqual);
|
||||||
|
|
||||||
// // 0x20 - Checks if top bits of m are equal
|
// // 0x20 - Checks if top bits of m are equal
|
||||||
// if ((((u16)_Value >> 14) == 0) || (((u16)_Value >> 14) == 3))
|
// if ((((u16)_Value >> 14) == 0) || (((u16)_Value >> 14) == 3))
|
||||||
//AND(32, R(val), Imm32(0xc0000000));
|
|
||||||
SHR(16, R(val), Imm8(14));
|
SHR(16, R(val), Imm8(14));
|
||||||
CMP(16, R(val), Imm16(0));
|
TEST(16, R(val), R(val));
|
||||||
FixupBranch nZero = J_CC(CC_NE);
|
FixupBranch isZero = J_CC(CC_Z);
|
||||||
OR(16, sr_reg, Imm16(SR_TOP2BITS));
|
|
||||||
FixupBranch cC = J();
|
|
||||||
SetJumpTarget(nZero);
|
|
||||||
CMP(16, R(val), Imm16(3));
|
CMP(16, R(val), Imm16(3));
|
||||||
FixupBranch notThree = J_CC(CC_NE);
|
FixupBranch notThree = J_CC(CC_NE);
|
||||||
|
SetJumpTarget(isZero);
|
||||||
// g_dsp.r[DSP_REG_SR] |= SR_TOP2BITS;
|
// g_dsp.r[DSP_REG_SR] |= SR_TOP2BITS;
|
||||||
OR(16, sr_reg, Imm16(SR_TOP2BITS));
|
OR(16, sr_reg, Imm16(SR_TOP2BITS));
|
||||||
SetJumpTarget(notThree);
|
SetJumpTarget(notThree);
|
||||||
SetJumpTarget(cC);
|
SetJumpTarget(end);
|
||||||
gpr.putReg(DSP_REG_SR);
|
gpr.putReg(DSP_REG_SR);
|
||||||
}
|
}
|
||||||
|
|
||||||
// In: RAX: s64 _Value
|
// In: RAX: s64 _Value
|
||||||
// Clobbers RDX
|
// Clobbers RCX
|
||||||
void DSPEmitter::Update_SR_Register16_OverS32(Gen::X64Reg val)
|
void DSPEmitter::Update_SR_Register16_OverS32(Gen::X64Reg val)
|
||||||
{
|
{
|
||||||
OpArg sr_reg;
|
OpArg sr_reg;
|
||||||
|
|
Loading…
Reference in New Issue