diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.h b/Source/Core/Core/PowerPC/Jit64/Jit.h index 1c6e082fd1..635c0a1099 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit.h +++ b/Source/Core/Core/PowerPC/Jit64/Jit.h @@ -137,7 +137,7 @@ public: void addx(UGeckoInstruction inst); void addcx(UGeckoInstruction inst); void mulli(UGeckoInstruction inst); - void mulhwux(UGeckoInstruction inst); + void mulhwXx(UGeckoInstruction inst); void mullwx(UGeckoInstruction inst); void divwux(UGeckoInstruction inst); void divwx(UGeckoInstruction inst); diff --git a/Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp b/Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp index c64cbdca66..17bb75d184 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp @@ -304,8 +304,8 @@ static GekkoOPTemplate table31_2[] = {1003, &Jit64::divwx}, //"divwox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 39}}, {459, &Jit64::divwux}, //"divwux", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 39}}, {971, &Jit64::divwux}, //"divwuox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 39}}, - {75, &Jit64::FallBackToInterpreter}, //"mulhwx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 4}}, - {11, &Jit64::mulhwux}, //"mulhwux", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 4}}, + {75, &Jit64::mulhwXx}, //"mulhwx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 4}}, + {11, &Jit64::mulhwXx}, //"mulhwux", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 4}}, {235, &Jit64::mullwx}, //"mullwx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 4}}, {747, &Jit64::mullwx}, //"mullwox", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT, 4}}, {104, &Jit64::negx}, //"negx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_AB | FL_RC_BIT}}, diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp index dc43cbe5a9..ad30883018 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp @@ -1154,15 +1154,19 @@ void Jit64::mullwx(UGeckoInstruction inst) } } -void Jit64::mulhwux(UGeckoInstruction inst) +void Jit64::mulhwXx(UGeckoInstruction inst) { INSTRUCTION_START JITDISABLE(bJITIntegerOff); int a = inst.RA, b = inst.RB, d = inst.RD; + bool sign = inst.SUBOP10 == 75; if (gpr.R(a).IsImm() && gpr.R(b).IsImm()) { - gpr.SetImmediate32(d, (u32)(((u64)gpr.R(a).offset * (u64)gpr.R(b).offset) >> 32)); + if (sign) + gpr.SetImmediate32(d, (u32)((u64)(((s64)(s32)gpr.R(a).offset * (s64)(s32)gpr.R(b).offset)) >> 32)); + else + gpr.SetImmediate32(d, (u32)((gpr.R(a).offset * gpr.R(b).offset) >> 32)); } else { @@ -1173,16 +1177,17 @@ void Jit64::mulhwux(UGeckoInstruction inst) PanicAlert("mulhwux : WTF"); MOV(32, R(EAX), gpr.R(a)); gpr.KillImmediate(b, true, false); - MUL(32, gpr.R(b)); + if (sign) + IMUL(32, gpr.R(b)); + else + MUL(32, gpr.R(b)); gpr.UnlockAll(); gpr.UnlockAllX(); MOV(32, gpr.R(d), R(EDX)); } if (inst.Rc) - { ComputeRC(gpr.R(d)); - } } void Jit64::divwux(UGeckoInstruction inst)