diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h index 5ea96c8774..a32b1df494 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h +++ b/Source/Core/Core/Src/PowerPC/JitArm32/Jit.h @@ -116,6 +116,7 @@ public: void GenerateRC(int cr = 0); void ComputeRC(int cr = 0); + void ComputeRC(s32 value, int cr); // OPCODES void unknown_instruction(UGeckoInstruction _inst); diff --git a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Integer.cpp b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Integer.cpp index 62fff5d0f6..b109882196 100644 --- a/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Integer.cpp +++ b/Source/Core/Core/Src/PowerPC/JitArm32/JitArm_Integer.cpp @@ -54,7 +54,19 @@ void JitArm::ComputeRC(int cr) { STRB(rB, R9, PPCSTATE_OFF(cr_fast) + cr); gpr.Unlock(rB); } +void JitArm::ComputeRC(s32 value, int cr) { + ARMReg rB = gpr.GetReg(); + if (value < 0) + MOV(rB, 0x8); + else if (value > 0) + MOV(rB, 0x4); + else + MOV(rB, 0x2); + + STRB(rB, R9, PPCSTATE_OFF(cr_fast) + cr); + gpr.Unlock(rB); +} void JitArm::addi(UGeckoInstruction inst) { INSTRUCTION_START @@ -103,10 +115,17 @@ void JitArm::addx(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) - - ARMReg RA = gpr.R(inst.RA); - ARMReg RB = gpr.R(inst.RB); - ARMReg RD = gpr.R(inst.RD); + u32 a = inst.RA, b = inst.RB, d = inst.RD; + + if (gpr.IsImm(a) && gpr.IsImm(b)) + { + gpr.SetImmediate(d, gpr.GetImm(a) + gpr.GetImm(b)); + if (inst.Rc) ComputeRC(gpr.GetImm(d), 0); + return; + } + ARMReg RA = gpr.R(a); + ARMReg RB = gpr.R(b); + ARMReg RD = gpr.R(d); ADDS(RD, RA, RB); if (inst.Rc) ComputeRC(); } @@ -115,11 +134,20 @@ void JitArm::subfx(UGeckoInstruction inst) INSTRUCTION_START JITDISABLE(Integer) - ARMReg RA = gpr.R(inst.RA); - ARMReg RB = gpr.R(inst.RB); - ARMReg RD = gpr.R(inst.RD); - SUBS(RD, RB, RA); + u32 a = inst.RA, b = inst.RB, d = inst.RD; + if (inst.OE) PanicAlert("OE: subfx"); + + if (gpr.IsImm(a) && gpr.IsImm(b)) + { + gpr.SetImmediate(d, gpr.GetImm(b) - gpr.GetImm(a)); + if (inst.Rc) ComputeRC(gpr.GetImm(d), 0); + return; + } + ARMReg RA = gpr.R(a); + ARMReg RB = gpr.R(b); + ARMReg RD = gpr.R(d); + SUBS(RD, RB, RA); if (inst.Rc) GenerateRC(); } void JitArm::mulli(UGeckoInstruction inst) @@ -163,9 +191,15 @@ void JitArm::oris(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) + u32 a = inst.RA, s = inst.RS; - ARMReg RA = gpr.R(inst.RA); - ARMReg RS = gpr.R(inst.RS); + if (gpr.IsImm(s)) + { + gpr.SetImmediate(a, gpr.GetImm(s) | (inst.UIMM << 16)); + return; + } + ARMReg RA = gpr.R(a); + ARMReg RS = gpr.R(s); ARMReg rA = gpr.GetReg(); MOVI2R(rA, inst.UIMM << 16); ORR(RA, RS, rA); @@ -176,10 +210,17 @@ void JitArm::orx(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) + u32 a = inst.RA, b = inst.RB, s = inst.RS; - ARMReg rA = gpr.R(inst.RA); - ARMReg rS = gpr.R(inst.RS); - ARMReg rB = gpr.R(inst.RB); + if (gpr.IsImm(b) && gpr.IsImm(s)) + { + gpr.SetImmediate(a, gpr.GetImm(s) | gpr.GetImm(b)); + if (inst.Rc) ComputeRC(gpr.GetImm(a), 0); + return; + } + ARMReg rA = gpr.R(a); + ARMReg rB = gpr.R(b); + ARMReg rS = gpr.R(s); ORRS(rA, rS, rB); if (inst.Rc) ComputeRC(); @@ -190,9 +231,17 @@ void JitArm::xorx(UGeckoInstruction inst) INSTRUCTION_START JITDISABLE(Integer) - ARMReg rA = gpr.R(inst.RA); - ARMReg rS = gpr.R(inst.RS); - ARMReg rB = gpr.R(inst.RB); + u32 a = inst.RA, b = inst.RB, s = inst.RS; + + if (gpr.IsImm(b) && gpr.IsImm(s)) + { + gpr.SetImmediate(a, gpr.GetImm(s) ^ gpr.GetImm(b)); + if (inst.Rc) ComputeRC(gpr.GetImm(a), 0); + return; + } + ARMReg rA = gpr.R(a); + ARMReg rB = gpr.R(b); + ARMReg rS = gpr.R(s); EORS(rA, rS, rB); if (inst.Rc) ComputeRC(); @@ -201,12 +250,19 @@ void JitArm::extshx(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) - ARMReg RA, RS; - RA = gpr.R(inst.RA); - RS = gpr.R(inst.RS); - SXTH(RA, RS); + u32 a = inst.RA, s = inst.RS; + + if (gpr.IsImm(s)) + { + gpr.SetImmediate(a, (u32)(s32)(s16)gpr.GetImm(s)); + if (inst.Rc) ComputeRC(gpr.GetImm(a), 0); + return; + } + ARMReg rA = gpr.R(a); + ARMReg rS = gpr.R(s); + SXTH(rA, rS); if (inst.Rc){ - CMP(RA, 0); + CMP(rA, 0); ComputeRC(); } } @@ -214,12 +270,19 @@ void JitArm::extsbx(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) - ARMReg RA, RS; - RA = gpr.R(inst.RA); - RS = gpr.R(inst.RS); - SXTB(RA, RS); + u32 a = inst.RA, s = inst.RS; + + if (gpr.IsImm(s)) + { + gpr.SetImmediate(a, (u32)(s32)(s8)gpr.GetImm(s)); + if (inst.Rc) ComputeRC(gpr.GetImm(a), 0); + return; + } + ARMReg rA = gpr.R(a); + ARMReg rS = gpr.R(s); + SXTB(rA, rS); if (inst.Rc){ - CMP(RA, 0); + CMP(rA, 0); ComputeRC(); } } @@ -228,31 +291,43 @@ void JitArm::cmp (UGeckoInstruction inst) INSTRUCTION_START JITDISABLE(Integer) - ARMReg RA = gpr.R(inst.RA); - ARMReg RB = gpr.R(inst.RB); int crf = inst.CRFD; + u32 a = inst.RA, b = inst.RB; + + if (gpr.IsImm(a) && gpr.IsImm(b)) + { + ComputeRC((s32)gpr.GetImm(a) - (s32)gpr.GetImm(b), crf); + return; + } + + ARMReg RA = gpr.R(a); + ARMReg RB = gpr.R(b); CMP(RA, RB); + ComputeRC(crf); } void JitArm::cmpi(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(Integer) - - ARMReg RA = gpr.R(inst.RA); + u32 a = inst.RA; int crf = inst.CRFD; - if (inst.SIMM_16 >= 0 && inst.SIMM_16 < 256) - { - CMP(RA, inst.SIMM_16); - } + if (gpr.IsImm(a)) + ComputeRC((s32)gpr.GetImm(a) - inst.SIMM_16, crf); else { - ARMReg rA = gpr.GetReg(); - MOVI2R(rA, inst.SIMM_16); - CMP(RA, rA); - gpr.Unlock(rA); + ARMReg RA = gpr.R(a); + if (inst.SIMM_16 >= 0 && inst.SIMM_16 < 256) + CMP(RA, inst.SIMM_16); + else + { + ARMReg rA = gpr.GetReg(); + MOVI2R(rA, inst.SIMM_16); + CMP(RA, rA); + gpr.Unlock(rA); + } + ComputeRC(crf); } - ComputeRC(crf); } void JitArm::cmpl(UGeckoInstruction inst) {