rendered paste bodyIndex: Source/Core/Core/Src/PowerPC/JitCommon/JitAsmCommon.h===================================================================--- Source/Core/Core/Src/PowerPC/JitCommon/JitAsmCommon.h (revision 5178)+++ Source/Core/Core/Src/PowerPC/JitCommon/JitAsmCommon.h (working copy)@@ -46,6 +46,7 @@ const u8 *fpException; const u8 *computeRc;+ const u8 *computeCr; const u8 *testExceptions; const u8 *dispatchPcInEAX; const u8 *doTiming;Index: Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp===================================================================--- Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp (revision 5178)+++ Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp (working copy)@@ -24,15 +24,6 @@ #include "JitRegCache.h" #include "JitAsm.h" -// Assumes that the flags were just set through an addition.-void Jit64::GenerateCarry(Gen::X64Reg temp_reg) {- // USES_XER- SETcc(CC_C, R(temp_reg));- AND(32, M(&PowerPC::ppcState.spr[SPR_XER]), Imm32(~(1 << 29)));- SHL(32, R(temp_reg), Imm8(29));- OR(32, M(&PowerPC::ppcState.spr[SPR_XER]), R(temp_reg));-}- u32 Add(u32 a, u32 b) {return a + b;} u32 Or (u32 a, u32 b) {return a | b;} u32 And(u32 a, u32 b) {return a & b;}@@ -55,7 +46,13 @@ gpr.LoadToX64(d, false); (this->*op)(32, gpr.R(d), Imm32(value)); //m_GPR[d] = m_GPR[_inst.RA] + _inst.SIMM_16; if (carry)- GenerateCarry(EAX);+ {+ // USES_XER+ SETcc(CC_C, R(EAX));+ AND(32, M(&PowerPC::ppcState.spr[SPR_XER]), Imm32(~(1 << 29)));+ SHL(32, R(EAX), Imm8(29));+ OR(32, M(&PowerPC::ppcState.spr[SPR_XER]), R(EAX));+ } } } else@@ -64,7 +61,13 @@ MOV(32, gpr.R(d), gpr.R(a)); (this->*op)(32, gpr.R(d), Imm32(value)); //m_GPR[d] = m_GPR[_inst.RA] + _inst.SIMM_16; if (carry)- GenerateCarry(EAX);+ {+ // USES_XER+ SETcc(CC_C, R(EAX));+ AND(32, M(&PowerPC::ppcState.spr[SPR_XER]), Imm32(~(1 << 29)));+ SHL(32, R(EAX), Imm8(29));+ OR(32, M(&PowerPC::ppcState.spr[SPR_XER]), R(EAX));+ } } } else if (doop == Add)@@ -79,8 +82,11 @@ if (Rc) { // Todo - special case immediates.+ //if (gpr.R(d).IsImm())+ // gpr.LoadToX64(d, false); MOV(32, R(EAX), gpr.R(d)); CALL((u8*)asm_routines.computeRc);+ CALL((u8*)asm_routines.computeCr); } gpr.UnlockAll(); }@@ -116,8 +122,8 @@ case 29: regimmop(a, s, true, inst.UIMM << 16, And, &XEmitter::AND, true); break; case 26: regimmop(a, s, true, inst.UIMM, Xor, &XEmitter::XOR, false); break; //xori case 27: regimmop(a, s, true, inst.UIMM << 16, Xor, &XEmitter::XOR, false); break; //xoris- case 12: //regimmop(d, a, false, (u32)(s32)inst.SIMM_16, Add, XEmitter::ADD, false, true); //addic- case 13: //regimmop(d, a, true, (u32)(s32)inst.SIMM_16, Add, XEmitter::ADD, true, true); //addic_rc+ case 12: regimmop(d, a, false, (u32)(s32)inst.SIMM_16, Add, &XEmitter::ADD, false, true);break; //addic+ case 13: regimmop(d, a, true, (u32)(s32)inst.SIMM_16, Add, &XEmitter::ADD, true, false);break; //addic_rc default: Default(inst); break;@@ -379,7 +385,13 @@ NOT(32, R(EAX)); ADD(32, R(EAX), Imm32(imm + 1)); MOV(32, gpr.R(d), R(EAX));- GenerateCarry(ECX);+ //+ // USES_XER+ SETcc(CC_C, R(ECX));+ AND(32, M(&PowerPC::ppcState.spr[SPR_XER]), Imm32(~(1 << 29)));+ SHL(32, R(ECX), Imm8(29));+ OR(32, M(&PowerPC::ppcState.spr[SPR_XER]), R(ECX));+ // gpr.UnlockAll(); gpr.UnlockAllX(); // This instruction has no RC flag@@ -388,17 +400,70 @@ void Jit64::subfcx(UGeckoInstruction inst) { INSTRUCTION_START;- Default(inst);- return;- /*- u32 a = m_GPR[_inst.RA];- u32 b = m_GPR[_inst.RB];- m_GPR[_inst.RD] = b - a;- SetCarry(a == 0 || Helper_Carry(b, 0-a));-- if (_inst.OE) PanicAlert("OE: subfcx");- if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);- */+ JITDISABLE(Integer)+ int a = inst.RA, b = inst.RB, d = inst.RD;+ gpr.FlushLockX(ECX);+ gpr.Lock(a, b, d);+ + if(d != a && d != b)+ gpr.LoadToX64(d, false, true);+ else+ gpr.LoadToX64(d, true, true);+ + MOV(32, R(EAX), gpr.R(b));+ SUB(32, R(EAX), gpr.R(a));+ MOV(32, gpr.R(d), R(EAX));+ + MOV(32, R(EAX), gpr.R(a));+ MOV(32, R(ECX), gpr.R(b));+ + CMP(32, R(EAX), Imm8(0));+ FixupBranch cpLesser = J_CC(CC_L);+ FixupBranch cpGreater = J_CC(CC_G);+ + // Equal+ JitSetCA();+ FixupBranch continue3 = J();+ + // Lesser and greater+ 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 continue1 = J();+ + // Greater+ SetJumpTarget(pGreater);+ JitSetCA();+ FixupBranch continue2 = J();+ + // Less than+ SetJumpTarget(pLesser);+ JitClearCA();+ + SetJumpTarget(continue1);+ SetJumpTarget(continue2);+ SetJumpTarget(continue3);+ + //SetCarry(a == 0 || Helper_Carry(b, 0-a));+ //return -a > (~b);+ + gpr.UnlockAll();+ gpr.UnlockAllX();+ if (inst.OE) PanicAlert("OE: subfcx");+ if (inst.Rc) {+ MOV(32, R(EAX), gpr.R(d));+ CALL((u8*)asm_routines.computeRc);+ CALL((u8*)asm_routines.computeCr);+ } } void Jit64::subfex(UGeckoInstruction inst) @@ -599,7 +664,13 @@ MOV(32, R(EAX), gpr.R(a)); ADC(32, R(EAX), gpr.R(b)); MOV(32, gpr.R(d), R(EAX));- GenerateCarry(ECX);+ //+ // USES_XER+ SETcc(CC_C, R(ECX));+ AND(32, M(&PowerPC::ppcState.spr[SPR_XER]), Imm32(~(1 << 29)));+ SHL(32, R(ECX), Imm8(29));+ OR(32, M(&PowerPC::ppcState.spr[SPR_XER]), R(ECX));+ // gpr.UnlockAll(); gpr.UnlockAllX(); if (inst.Rc)Index: Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp===================================================================--- Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp (revision 5178)+++ Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp (working copy)@@ -216,15 +216,44 @@ CMP(32, R(EAX), Imm8(0)); FixupBranch pLesser = J_CC(CC_L); FixupBranch pGreater = J_CC(CC_G);+ MOV(8, M(&PowerPC::ppcState.cr_fast[0]), Imm8(0x2)); // _x86Reg == 0 RET();+ SetJumpTarget(pGreater); MOV(8, M(&PowerPC::ppcState.cr_fast[0]), Imm8(0x4)); // _x86Reg > 0 RET();+ SetJumpTarget(pLesser); MOV(8, M(&PowerPC::ppcState.cr_fast[0]), Imm8(0x8)); // _x86Reg < 0 RET(); + computeCr = AlignCode16();+ //MOV(32, R(EAX), M(&PowerPC::ppcState.spr[SPR_XER]));+ + //AND(32, R(EAX), Imm32( 1 << 31 ));+ //MOVSX(32, 8, ECX, M(&PowerPC::ppcState.cr_fast[0]));+ //OR(32, R(ECX), R(EAX));+ //MOV(8, M(&PowerPC::ppcState.cr_fast[0]), R(ECX));+ //WriteToConstRamAddress(8, R(ECX), (u32)&PowerPC::ppcState.cr_fast[0]);+ RET();+ + // Do the OR here+ + /*[02:40:00] <skidau> mov eax, spr_xer+ [02:40:00] <skidau> and eax, 1+ [02:40:00] <skidau> mov ecx, cr_fast[0]+ [02:40:00] <skidau> or ecx, eax+ [02:40:00] <skidau> mov cr_fast[0], ecx*/+ + + /*MOV(32, R(EAX), M(&(PowerPC::ppcState.spr[SPR_XER])));+ SHR(32, R(EAX), Imm8( 31 ));+ AND(32, R(EAX), Imm8( 1 << 4 ));+ + OR(8, M(&(PowerPC::ppcState.cr_fast[0])), R(EAX));*/+ //RET();+ fifoDirectWrite8 = AlignCode4(); GenFifoWrite(8); fifoDirectWrite16 = AlignCode4();Index: Source/Core/Core/Src/PowerPC/Jit64/Jit.h===================================================================--- Source/Core/Core/Src/PowerPC/Jit64/Jit.h (revision 5178)+++ Source/Core/Core/Src/PowerPC/Jit64/Jit.h (working copy)@@ -137,8 +137,6 @@ void WriteCallInterpreter(UGeckoInstruction _inst); void Cleanup(); - void GenerateCarry(Gen::X64Reg temp_reg);- void tri_op(int d, int a, int b, bool reversible, void (XEmitter::*op)(Gen::X64Reg, Gen::OpArg)); typedef u32 (*Operation)(u32 a, u32 b); void regimmop(int d, int a, bool binary, u32 value, Operation doop, void (XEmitter::*op)(int, const Gen::OpArg&, const Gen::OpArg&), bool Rc = false, bool carry = false);