From 9ed465f4ac6cc9723824cb5e6b2e32b99b9e50cb Mon Sep 17 00:00:00 2001 From: degasus Date: Fri, 4 Mar 2016 21:58:17 +0100 Subject: [PATCH] JitArm64: Implement mulhwx --- Source/Core/Common/Arm64Emitter.cpp | 4 ++ Source/Core/Common/Arm64Emitter.h | 1 + Source/Core/Core/PowerPC/JitArm64/Jit.h | 2 + .../PowerPC/JitArm64/JitArm64_Integer.cpp | 50 +++++++++++++++++++ .../Core/PowerPC/JitArm64/JitArm64_Tables.cpp | 4 +- 5 files changed, 59 insertions(+), 2 deletions(-) diff --git a/Source/Core/Common/Arm64Emitter.cpp b/Source/Core/Common/Arm64Emitter.cpp index 2c2ede99ea..d7c53ba289 100644 --- a/Source/Core/Common/Arm64Emitter.cpp +++ b/Source/Core/Common/Arm64Emitter.cpp @@ -1389,6 +1389,10 @@ void ARM64XEmitter::UMADDL(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm, ARM64Reg Ra) { EncodeData3SrcInst(5, Rd, Rn, Rm, Ra); } +void ARM64XEmitter::UMULL(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm) +{ + UMADDL(Rd, Rn, Rm, SP); +} void ARM64XEmitter::UMSUBL(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm, ARM64Reg Ra) { EncodeData3SrcInst(6, Rd, Rn, Rm, Ra); diff --git a/Source/Core/Common/Arm64Emitter.h b/Source/Core/Common/Arm64Emitter.h index 9041cd32bb..098b48fd25 100644 --- a/Source/Core/Common/Arm64Emitter.h +++ b/Source/Core/Common/Arm64Emitter.h @@ -517,6 +517,7 @@ public: void SMSUBL(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm, ARM64Reg Ra); void SMULH(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm); void UMADDL(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm, ARM64Reg Ra); + void UMULL(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm); void UMSUBL(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm, ARM64Reg Ra); void UMULH(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm); void MUL(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm); diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.h b/Source/Core/Core/PowerPC/JitArm64/Jit.h index 02064515a5..cb6162ba87 100644 --- a/Source/Core/Core/PowerPC/JitArm64/Jit.h +++ b/Source/Core/Core/PowerPC/JitArm64/Jit.h @@ -87,6 +87,8 @@ public: void rlwnmx(UGeckoInstruction inst); void srawix(UGeckoInstruction inst); void mullwx(UGeckoInstruction inst); + void mulhwx(UGeckoInstruction inst); + void mulhwux(UGeckoInstruction inst); void addic(UGeckoInstruction inst); void mulli(UGeckoInstruction inst); void addzex(UGeckoInstruction inst); diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp index d9eb780d28..058341b1cf 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp @@ -747,6 +747,56 @@ void JitArm64::mullwx(UGeckoInstruction inst) } } +void JitArm64::mulhwx(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(bJITIntegerOff); + + int a = inst.RA, b = inst.RB, d = inst.RD; + + if (gpr.IsImm(a) && gpr.IsImm(b)) + { + s32 i = (s32)gpr.GetImm(a), j = (s32)gpr.GetImm(b); + gpr.SetImmediate(d, (u32)((u64)(((s64)i * (s64)j) ) >> 32)); + if (inst.Rc) + ComputeRC(gpr.GetImm(d), 0); + } + else + { + gpr.BindToRegister(d, d == a || d == b); + SMULL(EncodeRegTo64(gpr.R(d)), gpr.R(a), gpr.R(b)); + LSR(EncodeRegTo64(gpr.R(d)), EncodeRegTo64(gpr.R(d)), 32); + + if (inst.Rc) + ComputeRC(gpr.R(d), 0); + } +} + +void JitArm64::mulhwux(UGeckoInstruction inst) +{ + INSTRUCTION_START + JITDISABLE(bJITIntegerOff); + + 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.SetImmediate(d, (u32)( ( (u64)i * (u64)j) >> 32) ); + if (inst.Rc) + ComputeRC(gpr.GetImm(d), 0); + } + else + { + gpr.BindToRegister(d, d == a || d == b); + UMULL(EncodeRegTo64(gpr.R(d)), gpr.R(a), gpr.R(b)); + LSR(EncodeRegTo64(gpr.R(d)), EncodeRegTo64(gpr.R(d)), 32); + + if (inst.Rc) + ComputeRC(gpr.R(d), 0); + } +} + void JitArm64::addzex(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 96b3f9046f..09fdd271ce 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp @@ -184,8 +184,8 @@ static GekkoOPTemplate table31[] = {1003, &JitArm64::FallBackToInterpreter}, // divwox {459, &JitArm64::divwux}, // divwux {971, &JitArm64::divwux}, // divwuox - {75, &JitArm64::FallBackToInterpreter}, // mulhwx - {11, &JitArm64::FallBackToInterpreter}, // mulhwux + {75, &JitArm64::mulhwx}, // mulhwx + {11, &JitArm64::mulhwux}, // mulhwux {235, &JitArm64::mullwx}, // mullwx {747, &JitArm64::mullwx}, // mullwox {104, &JitArm64::negx}, // negx