From 95be17772fdb05fa3a921da2cde96a17d06f83b7 Mon Sep 17 00:00:00 2001 From: degasus Date: Sun, 23 Aug 2015 11:46:11 +0200 Subject: [PATCH] JitArm64: Implement addex --- Source/Core/Core/PowerPC/JitArm64/Jit.h | 1 + .../PowerPC/JitArm64/JitArm64_Integer.cpp | 55 +++++++++++++++++++ .../Core/PowerPC/JitArm64/JitArm64_Tables.cpp | 4 +- 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.h b/Source/Core/Core/PowerPC/JitArm64/Jit.h index 6022e9eb64..244a58db05 100644 --- a/Source/Core/Core/PowerPC/JitArm64/Jit.h +++ b/Source/Core/Core/PowerPC/JitArm64/Jit.h @@ -101,6 +101,7 @@ public: void rlwimix(UGeckoInstruction inst); void subfex(UGeckoInstruction inst); void subfcx(UGeckoInstruction inst); + void addex(UGeckoInstruction inst); // System Registers void mtmsr(UGeckoInstruction inst); diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp index 8c27c56ad8..119cc099c3 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp @@ -816,6 +816,61 @@ void JitArm64::subfcx(UGeckoInstruction inst) } } +void JitArm64::addex(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(bJITIntegerOff); + FALLBACK_IF(inst.OE); + + int a = inst.RA, b = inst.RB, d = inst.RD; + + if (gpr.IsImm(a) && gpr.IsImm(b)) + { + u32 i = gpr.GetImm(a), j = gpr.GetImm(b); + + gpr.BindToRegister(d, false); + MOVI2R(gpr.R(d), i + j); + ARM64Reg WA = gpr.GetReg(); + LDRB(INDEX_UNSIGNED, WA, X29, PPCSTATE_OFF(xer_ca)); + ADD(gpr.R(d), gpr.R(d), WA); + gpr.Unlock(WA); + + bool must_have_carry = Interpreter::Helper_Carry(i, j); + bool might_have_carry = (i + j) == 0xFFFFFFFF; + + if (must_have_carry) + { + ComputeCarry(true); + } + else if (might_have_carry) + { + // carry stay as it is + } + else + { + ComputeCarry(false); + } + } + else + { + gpr.BindToRegister(d, d == a || d == b); + + // upload the carry state + ARM64Reg WA = gpr.GetReg(); + LDRB(INDEX_UNSIGNED, WA, X29, PPCSTATE_OFF(xer_ca)); + CMP(WA, 1); + gpr.Unlock(WA); + + // d = a + b + carry; + ADCS(gpr.R(d), gpr.R(a), gpr.R(b)); + + ComputeCarry(); + } + + if (inst.Rc) + ComputeRC(gpr.R(d), 0); +} + void JitArm64::addcx(UGeckoInstruction inst) { INSTRUCTION_START diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp index 6111e33e5a..1cec717685 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp @@ -174,8 +174,8 @@ static GekkoOPTemplate table31[] = {778, &JitArm64::addx}, // addox {10, &JitArm64::addcx}, // addcx {522, &JitArm64::addcx}, // addcox - {138, &JitArm64::FallBackToInterpreter}, // addex - {650, &JitArm64::FallBackToInterpreter}, // addeox + {138, &JitArm64::addex}, // addex + {650, &JitArm64::addex}, // addeox {234, &JitArm64::FallBackToInterpreter}, // addmex {746, &JitArm64::FallBackToInterpreter}, // addmeox {202, &JitArm64::addzex}, // addzex