mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-25 23:29:44 -06:00
fixup Jit64::subfcx and Jit64::subfex
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5245 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
@ -387,67 +387,33 @@ void Jit64::subfic(UGeckoInstruction inst)
|
|||||||
|
|
||||||
void Jit64::subfcx(UGeckoInstruction inst)
|
void Jit64::subfcx(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
INSTRUCTION_START;
|
INSTRUCTION_START;
|
||||||
JITDISABLE(Integer)
|
JITDISABLE(Integer)
|
||||||
Default(inst);
|
|
||||||
return;
|
|
||||||
int a = inst.RA, b = inst.RB, d = inst.RD;
|
int a = inst.RA, b = inst.RB, d = inst.RD;
|
||||||
gpr.FlushLockX(ECX);
|
|
||||||
gpr.Lock(a, b, d);
|
gpr.Lock(a, b, d);
|
||||||
|
|
||||||
if(d != a && d != b)
|
if(d != a && d != b)
|
||||||
gpr.LoadToX64(d, false, true);
|
gpr.LoadToX64(d, false, true);
|
||||||
else
|
else
|
||||||
gpr.LoadToX64(d, true, true);
|
gpr.LoadToX64(d, true, true);
|
||||||
|
|
||||||
MOV(32, R(EAX), gpr.R(b));
|
// For some reason, I could not get the jit versions of sub*
|
||||||
SUB(32, R(EAX), gpr.R(a));
|
// working with x86 sub...so we use the ~a + b + 1 method
|
||||||
MOV(32, gpr.R(d), R(EAX));
|
JitClearCA();
|
||||||
|
|
||||||
MOV(32, R(EAX), gpr.R(a));
|
MOV(32, R(EAX), gpr.R(a));
|
||||||
MOV(32, R(ECX), gpr.R(b));
|
NOT(32, R(EAX));
|
||||||
|
ADD(32, R(EAX), gpr.R(b));
|
||||||
CMP(32, R(EAX), Imm8(0));
|
FixupBranch carry1 = J_CC(CC_NC);
|
||||||
FixupBranch cpLesser = J_CC(CC_L);
|
|
||||||
FixupBranch cpGreater = J_CC(CC_G);
|
|
||||||
|
|
||||||
// Equal
|
|
||||||
JitSetCA();
|
JitSetCA();
|
||||||
FixupBranch continue1 = J();
|
SetJumpTarget(carry1);
|
||||||
|
ADD(32, R(EAX), Imm32(1));
|
||||||
// Lesser and greater
|
FixupBranch carry2 = J_CC(CC_NC);
|
||||||
SetJumpTarget(cpGreater);
|
|
||||||
SetJumpTarget(cpLesser);
|
|
||||||
|
|
||||||
NEG(32, R(EAX));
|
|
||||||
NOT(32, R(ECX));
|
|
||||||
|
|
||||||
CMP(32, R(EAX), R(ECX));
|
|
||||||
FixupBranch pLesser = J_CC(CC_L);
|
|
||||||
FixupBranch pGreater = J_CC(CC_G);
|
|
||||||
|
|
||||||
// Equal
|
|
||||||
JitClearCA();
|
|
||||||
FixupBranch continue2 = J();
|
|
||||||
|
|
||||||
// Greater
|
|
||||||
SetJumpTarget(pGreater);
|
|
||||||
JitSetCA();
|
JitSetCA();
|
||||||
FixupBranch continue3 = J();
|
SetJumpTarget(carry2);
|
||||||
|
MOV(32, gpr.R(d), R(EAX));
|
||||||
// Less than
|
|
||||||
SetJumpTarget(pLesser);
|
|
||||||
JitClearCA();
|
|
||||||
|
|
||||||
SetJumpTarget(continue1);
|
|
||||||
SetJumpTarget(continue2);
|
|
||||||
SetJumpTarget(continue3);
|
|
||||||
|
|
||||||
gpr.UnlockAll();
|
gpr.UnlockAll();
|
||||||
gpr.UnlockAllX();
|
|
||||||
if (inst.OE) PanicAlert("OE: subfcx");
|
if (inst.OE) PanicAlert("OE: subfcx");
|
||||||
if (inst.Rc) {
|
if (inst.Rc) {
|
||||||
MOV(32, R(EAX), gpr.R(d));
|
|
||||||
CALL((u8*)asm_routines.computeRc);
|
CALL((u8*)asm_routines.computeRc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -455,8 +421,7 @@ void Jit64::subfcx(UGeckoInstruction inst)
|
|||||||
void Jit64::subfex(UGeckoInstruction inst)
|
void Jit64::subfex(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
INSTRUCTION_START;
|
INSTRUCTION_START;
|
||||||
Default(inst);
|
JITDISABLE(Integer)
|
||||||
return;
|
|
||||||
int a = inst.RA, b = inst.RB, d = inst.RD;
|
int a = inst.RA, b = inst.RB, d = inst.RD;
|
||||||
gpr.FlushLockX(ECX);
|
gpr.FlushLockX(ECX);
|
||||||
gpr.Lock(a, b, d);
|
gpr.Lock(a, b, d);
|
||||||
@ -464,85 +429,36 @@ void Jit64::subfex(UGeckoInstruction inst)
|
|||||||
gpr.LoadToX64(d, false, true);
|
gpr.LoadToX64(d, false, true);
|
||||||
else
|
else
|
||||||
gpr.LoadToX64(d, true, true);
|
gpr.LoadToX64(d, true, true);
|
||||||
|
|
||||||
|
// Get CA
|
||||||
|
MOV(32, R(ECX), M(&PowerPC::ppcState.spr[SPR_XER]));
|
||||||
|
SHR(32, R(ECX), Imm8(29));
|
||||||
|
AND(32, R(ECX), Imm32(1));
|
||||||
|
// Don't need it anymore
|
||||||
|
JitClearCA();
|
||||||
|
|
||||||
|
// ~a + b
|
||||||
MOV(32, R(EAX), gpr.R(a));
|
MOV(32, R(EAX), gpr.R(a));
|
||||||
NOT(32, R(EAX));
|
NOT(32, R(EAX));
|
||||||
ADD(32, R(EAX), gpr.R(b));
|
ADD(32, R(EAX), gpr.R(b));
|
||||||
|
FixupBranch carry1 = J_CC(CC_NC);
|
||||||
MOV(32, R(ECX), M(&PowerPC::ppcState.spr[SPR_XER]));
|
JitSetCA();
|
||||||
SHR(32, R(ECX), Imm8(2));
|
SetJumpTarget(carry1);
|
||||||
AND(32, R(ECX), Imm32(1));
|
|
||||||
|
// + CA
|
||||||
ADD(32, R(EAX), R(ECX));
|
ADD(32, R(EAX), R(ECX));
|
||||||
|
FixupBranch carry2 = J_CC(CC_NC);
|
||||||
|
JitSetCA();
|
||||||
|
SetJumpTarget(carry2);
|
||||||
|
|
||||||
MOV(32, gpr.R(d), R(EAX));
|
MOV(32, gpr.R(d), R(EAX));
|
||||||
|
|
||||||
//u32 Helper_Carry(u32 _uValue1, u32 _uValue2)
|
|
||||||
/*{
|
|
||||||
return _uValue2 > (~_uValue1);
|
|
||||||
}*/
|
|
||||||
// return b > ~(~a)
|
|
||||||
// return carry > (a + ~b)
|
|
||||||
|
|
||||||
CMP(32, gpr.R(b), gpr.R(a));
|
|
||||||
|
|
||||||
FixupBranch cpLesser = J_CC(CC_L);
|
|
||||||
FixupBranch cpGreater = J_CC(CC_G);
|
|
||||||
|
|
||||||
// Equal
|
|
||||||
FixupBranch continue1 = J();
|
|
||||||
|
|
||||||
// Lesser and greater
|
|
||||||
SetJumpTarget(cpGreater);
|
|
||||||
JitSetCA();
|
|
||||||
FixupBranch continue2 = J();
|
|
||||||
|
|
||||||
SetJumpTarget(cpLesser);
|
|
||||||
SetJumpTarget(continue1);
|
|
||||||
|
|
||||||
// Was false, do our second check
|
|
||||||
MOV(32, R(EAX), gpr.R(b));
|
|
||||||
NOT(32, R(EAX));
|
|
||||||
ADD(32, R(EAX), gpr.R(a));
|
|
||||||
|
|
||||||
// Carry bit is in ECX from above
|
|
||||||
CMP(32, R(ECX), R(EAX));
|
|
||||||
|
|
||||||
FixupBranch cpLesser2 = J_CC(CC_L);
|
|
||||||
FixupBranch cpGreater2 = J_CC(CC_G);
|
|
||||||
|
|
||||||
// Equal
|
|
||||||
JitClearCA();
|
|
||||||
FixupBranch continue3 = J();
|
|
||||||
|
|
||||||
// Lesser and greater
|
|
||||||
SetJumpTarget(cpGreater2);
|
|
||||||
JitSetCA();
|
|
||||||
FixupBranch continue4 = J();
|
|
||||||
|
|
||||||
SetJumpTarget(cpLesser2);
|
|
||||||
JitClearCA();
|
|
||||||
|
|
||||||
|
|
||||||
SetJumpTarget(continue2);
|
|
||||||
SetJumpTarget(continue3);
|
|
||||||
SetJumpTarget(continue4);
|
|
||||||
gpr.UnlockAll();
|
gpr.UnlockAll();
|
||||||
gpr.UnlockAllX();
|
gpr.UnlockAllX();
|
||||||
if (inst.OE) PanicAlert("OE: subfex");
|
if (inst.OE) PanicAlert("OE: subfex");
|
||||||
if (inst.Rc) {
|
if (inst.Rc) {
|
||||||
MOV(32, R(EAX), gpr.R(d));
|
|
||||||
CALL((u8*)asm_routines.computeRc);
|
CALL((u8*)asm_routines.computeRc);
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
u32 a = m_GPR[_inst.RA];
|
|
||||||
u32 b = m_GPR[_inst.RB];
|
|
||||||
int carry = GetCarry();
|
|
||||||
m_GPR[_inst.RD] = (~a) + b + carry;
|
|
||||||
SetCarry(Helper_Carry(~a, b) || Helper_Carry((~a) + b, carry));
|
|
||||||
|
|
||||||
if (_inst.OE) PanicAlert("OE: subfex");
|
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Jit64::subfx(UGeckoInstruction inst)
|
void Jit64::subfx(UGeckoInstruction inst)
|
||||||
@ -645,10 +561,10 @@ void Jit64::divwux(UGeckoInstruction inst)
|
|||||||
MOV(32, R(EAX), gpr.R(a));
|
MOV(32, R(EAX), gpr.R(a));
|
||||||
XOR(32, R(EDX), R(EDX));
|
XOR(32, R(EDX), R(EDX));
|
||||||
gpr.KillImmediate(b);
|
gpr.KillImmediate(b);
|
||||||
CMP(32, gpr.R(b), R(EDX));
|
CMP(32, gpr.R(b), Imm32(0));
|
||||||
// doesn't handle if OE is set, but int doesn't either...
|
// doesn't handle if OE is set, but int doesn't either...
|
||||||
FixupBranch not_div_by_zero = J_CC(CC_NZ);
|
FixupBranch not_div_by_zero = J_CC(CC_NZ);
|
||||||
MOV(32, gpr.R(d), Imm32(0));
|
MOV(32, gpr.R(d), R(EDX));
|
||||||
MOV(32, R(EAX), gpr.R(d));
|
MOV(32, R(EAX), gpr.R(d));
|
||||||
FixupBranch end = J();
|
FixupBranch end = J();
|
||||||
SetJumpTarget(not_div_by_zero);
|
SetJumpTarget(not_div_by_zero);
|
||||||
|
Reference in New Issue
Block a user