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:
Shawn Hoffman
2010-03-27 23:55:12 +00:00
parent 672132eb84
commit f0f7bf13c2

View File

@ -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);