JitArm64: Implement mulhwx

This commit is contained in:
degasus 2016-03-04 21:58:17 +01:00
parent 889a0d396d
commit 9ed465f4ac
5 changed files with 59 additions and 2 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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