diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.h b/Source/Core/Core/Src/PowerPC/Jit64/Jit.h index 32470eba24..09439bb1bb 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.h +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.h @@ -103,6 +103,7 @@ namespace Jit64 void mullwx(UGeckoInstruction inst); void divwux(UGeckoInstruction inst); void srawix(UGeckoInstruction inst); + void srawx(UGeckoInstruction inst); void addex(UGeckoInstruction inst); void extsbx(UGeckoInstruction inst); @@ -174,6 +175,8 @@ namespace Jit64 void subfex(UGeckoInstruction inst); void lbzx(UGeckoInstruction inst); + void lwzx(UGeckoInstruction inst); + void lhax(UGeckoInstruction inst); void lmw(UGeckoInstruction inst); void stmw(UGeckoInstruction inst); diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp index 0bee529785..ac464e55d2 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_Integer.cpp @@ -106,7 +106,7 @@ namespace Jit64 if (gpr.R(a).IsImm() && d != a && a != 0) { gpr.SetImmediate32(d, (u32)gpr.R(a).offset + (u32)(s32)(s16)inst.SIMM_16); } else if (inst.SIMM_16 == 0 && d != a && a != 0) { - gpr.Lock(a); + gpr.Lock(a, d); gpr.LoadToX64(d, false, true); MOV(32, gpr.R(d), gpr.R(a)); gpr.UnlockAll(); @@ -285,15 +285,16 @@ namespace Jit64 } else { - if (a != s && a != b) { - gpr.LoadToX64(a, false, true); - } else { - gpr.LoadToX64(a, true, true); - } gpr.Lock(a, s, b); - MOV(32, R(EAX), gpr.R(s)); - OR(32, R(EAX), gpr.R(b)); - MOV(32, gpr.R(a), R(EAX)); + gpr.LoadToX64(a, (a == s || a == b), true); + if (a == s) + OR(32, gpr.R(a), gpr.R(b)); + else if (a == b) + OR(32, gpr.R(a), gpr.R(s)); + else { + MOV(32, gpr.R(a), gpr.R(b)); + OR(32, gpr.R(a), gpr.R(s)); + } gpr.UnlockAll(); } @@ -597,9 +598,12 @@ namespace Jit64 { gpr.Lock(a, b, d); gpr.LoadToX64(d, false); - gpr.LoadToX64(a, true, false); - gpr.LoadToX64(b, true, false); - LEA(32, gpr.RX(d), MComplex(gpr.RX(a), gpr.RX(b), 1, 0)); + if (gpr.R(a).IsSimpleReg() && gpr.R(b).IsSimpleReg()) { + LEA(32, gpr.RX(d), MComplex(gpr.RX(a), gpr.RX(b), 1, 0)); + } else { + MOV(32, gpr.R(d), gpr.R(a)); + ADD(32, gpr.R(d), gpr.R(b)); + } if (inst.Rc) { MOV(32, R(EAX), gpr.R(d)); @@ -835,7 +839,6 @@ namespace Jit64 gpr.Lock(a, b, s); gpr.LoadToX64(a, a == s || a == b || s == b, true); MOV(32, R(ECX), gpr.R(b)); - AND(32, R(ECX), Imm8(63)); XOR(32, R(EAX), R(EAX)); TEST(32, R(ECX), Imm32(32)); FixupBranch branch = J_CC(CC_NZ); @@ -866,7 +869,6 @@ namespace Jit64 gpr.Lock(a, b, s); gpr.LoadToX64(a, a == s || a == b || s == b, true); MOV(32, R(ECX), gpr.R(b)); - AND(32, R(ECX), Imm8(63)); XOR(32, R(EAX), R(EAX)); TEST(32, R(ECX), Imm32(32)); FixupBranch branch = J_CC(CC_NZ); @@ -883,6 +885,53 @@ namespace Jit64 } } + void srawx(UGeckoInstruction inst) + { +#ifdef JIT_OFF_OPTIONS + if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITIntegerOff) + {Default(inst); return;} // turn off from debugger +#endif + INSTRUCTION_START; + int a = inst.RA; + int b = inst.RB; + int s = inst.RS; + gpr.Lock(a, s); + gpr.FlushLockX(ECX); + gpr.LoadToX64(a, a == s || a == b, true); + MOV(32, R(ECX), gpr.R(b)); + TEST(32, R(ECX), Imm32(32)); + FixupBranch topBitSet = J_CC(CC_NZ); + if (a != s) + MOV(32, gpr.R(a), gpr.R(s)); + MOV(32, R(EAX), Imm32(1)); + SHL(32, R(EAX), R(ECX)); + ADD(32, R(EAX), Imm32(0x7FFFFFFF)); + AND(32, R(EAX), gpr.R(a)); + ADD(32, R(EAX), Imm32(-1)); + CMP(32, R(EAX), Imm32(-1)); + SETcc(CC_L, R(EAX)); + SAR(32, gpr.R(a), R(ECX)); + AND(32, M(&XER), Imm32(~(1 << 29))); + SHL(32, R(EAX), Imm8(29)); + OR(32, M(&XER), R(EAX)); + FixupBranch end = J(); + SetJumpTarget(topBitSet); + MOV(32, R(EAX), gpr.R(s)); + SAR(32, R(EAX), Imm8(31)); + MOV(32, gpr.R(a), R(EAX)); + AND(32, M(&XER), Imm32(~(1 << 29))); + AND(32, R(EAX), Imm32(1<<29)); + OR(32, M(&XER), R(EAX)); + SetJumpTarget(end); + gpr.UnlockAll(); + gpr.UnlockAllX(); + + if (inst.Rc) { + MOV(32, R(EAX), gpr.R(a)); + CALL((u8*)Asm::computeRc); + } + } + void srawix(UGeckoInstruction inst) { #ifdef JIT_OFF_OPTIONS diff --git a/Source/Core/Core/Src/PowerPC/PPCTables.cpp b/Source/Core/Core/Src/PowerPC/PPCTables.cpp index 6733f59375..4f4a67f38d 100644 --- a/Source/Core/Core/Src/PowerPC/PPCTables.cpp +++ b/Source/Core/Core/Src/PowerPC/PPCTables.cpp @@ -288,7 +288,7 @@ GekkoOPTemplate table31[] = {922, Interpreter::extshx, Jit64::extshx, {"extshx", OPTYPE_INTEGER, FL_IN_A | FL_OUT_S | FL_RC_BIT}}, {954, Interpreter::extsbx, Jit64::extsbx, {"extsbx", OPTYPE_INTEGER, FL_IN_A | FL_OUT_S | FL_RC_BIT}}, {536, Interpreter::srwx, Jit64::srwx, {"srwx", OPTYPE_INTEGER, FL_RC_BIT}}, - {792, Interpreter::srawx, Jit64::Default, {"srawx", OPTYPE_INTEGER, FL_RC_BIT}}, + {792, Interpreter::srawx, Jit64::srawx, {"srawx", OPTYPE_INTEGER, FL_RC_BIT}}, {824, Interpreter::srawix, Jit64::srawix, {"srawix", OPTYPE_INTEGER, FL_RC_BIT}}, {24, Interpreter::slwx, Jit64::slwx, {"slwx", OPTYPE_INTEGER, FL_RC_BIT}},