Jit: Move mullwx, mulhwx, mulhwux to ConstantPropagation

This commit is contained in:
JosJuice 2024-08-31 11:33:23 +02:00
parent b469981c72
commit 7456ba3d3d
3 changed files with 24 additions and 55 deletions

View File

@ -1271,14 +1271,7 @@ void Jit64::mullwx(UGeckoInstruction inst)
JITDISABLE(bJITIntegerOff); JITDISABLE(bJITIntegerOff);
int a = inst.RA, b = inst.RB, d = inst.RD; int a = inst.RA, b = inst.RB, d = inst.RD;
if (gpr.IsImm(a, b)) if (gpr.IsImm(a) || gpr.IsImm(b))
{
s32 i = gpr.SImm32(a), j = gpr.SImm32(b);
gpr.SetImmediate32(d, i * j);
if (inst.OE)
GenerateConstantOverflow((s64)i * (s64)j);
}
else if (gpr.IsImm(a) || gpr.IsImm(b))
{ {
u32 imm = gpr.IsImm(a) ? gpr.Imm32(a) : gpr.Imm32(b); u32 imm = gpr.IsImm(a) ? gpr.Imm32(a) : gpr.Imm32(b);
int src = gpr.IsImm(a) ? b : a; int src = gpr.IsImm(a) ? b : a;
@ -1320,14 +1313,7 @@ void Jit64::mulhwXx(UGeckoInstruction inst)
int a = inst.RA, b = inst.RB, d = inst.RD; int a = inst.RA, b = inst.RB, d = inst.RD;
bool sign = inst.SUBOP10 == 75; bool sign = inst.SUBOP10 == 75;
if (gpr.IsImm(a, b)) if (sign)
{
if (sign)
gpr.SetImmediate32(d, (u32)((u64)(((s64)gpr.SImm32(a) * (s64)gpr.SImm32(b))) >> 32));
else
gpr.SetImmediate32(d, (u32)(((u64)gpr.Imm32(a) * (u64)gpr.Imm32(b)) >> 32));
}
else if (sign)
{ {
RCOpArg Ra = gpr.Use(a, RCMode::Read); RCOpArg Ra = gpr.Use(a, RCMode::Read);
RCOpArg Rb = gpr.UseNoImm(b, RCMode::Read); RCOpArg Rb = gpr.UseNoImm(b, RCMode::Read);

View File

@ -984,15 +984,8 @@ void JitArm64::mullwx(UGeckoInstruction inst)
int a = inst.RA, b = inst.RB, d = inst.RD; int a = inst.RA, b = inst.RB, d = inst.RD;
if (gpr.IsImm(a) && gpr.IsImm(b)) if ((gpr.IsImm(a) && MultiplyImmediate(gpr.GetImm(a), b, d, inst.Rc)) ||
{ (gpr.IsImm(b) && MultiplyImmediate(gpr.GetImm(b), a, d, inst.Rc)))
s32 i = (s32)gpr.GetImm(a), j = (s32)gpr.GetImm(b);
gpr.SetImmediate(d, i * j);
if (inst.Rc)
ComputeRC0(gpr.GetImm(d));
}
else if ((gpr.IsImm(a) && MultiplyImmediate(gpr.GetImm(a), b, d, inst.Rc)) ||
(gpr.IsImm(b) && MultiplyImmediate(gpr.GetImm(b), a, d, inst.Rc)))
{ {
// Code is generated inside MultiplyImmediate, nothing to be done here. // Code is generated inside MultiplyImmediate, nothing to be done here.
} }
@ -1012,22 +1005,12 @@ void JitArm64::mulhwx(UGeckoInstruction inst)
int a = inst.RA, b = inst.RB, d = inst.RD; int a = inst.RA, b = inst.RB, d = inst.RD;
if (gpr.IsImm(a) && gpr.IsImm(b)) gpr.BindToRegister(d, d == a || d == b);
{ SMULL(EncodeRegTo64(gpr.R(d)), gpr.R(a), gpr.R(b));
s32 i = (s32)gpr.GetImm(a), j = (s32)gpr.GetImm(b); LSR(EncodeRegTo64(gpr.R(d)), EncodeRegTo64(gpr.R(d)), 32);
gpr.SetImmediate(d, (u32)((u64)(((s64)i * (s64)j)) >> 32));
if (inst.Rc)
ComputeRC0(gpr.GetImm(d));
}
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) if (inst.Rc)
ComputeRC0(gpr.R(d)); ComputeRC0(gpr.R(d));
}
} }
void JitArm64::mulhwux(UGeckoInstruction inst) void JitArm64::mulhwux(UGeckoInstruction inst)
@ -1037,22 +1020,12 @@ void JitArm64::mulhwux(UGeckoInstruction inst)
int a = inst.RA, b = inst.RB, d = inst.RD; int a = inst.RA, b = inst.RB, d = inst.RD;
if (gpr.IsImm(a) && gpr.IsImm(b)) gpr.BindToRegister(d, d == a || d == b);
{ UMULL(EncodeRegTo64(gpr.R(d)), gpr.R(a), gpr.R(b));
u32 i = gpr.GetImm(a), j = gpr.GetImm(b); LSR(EncodeRegTo64(gpr.R(d)), EncodeRegTo64(gpr.R(d)), 32);
gpr.SetImmediate(d, (u32)(((u64)i * (u64)j) >> 32));
if (inst.Rc)
ComputeRC0(gpr.GetImm(d));
}
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) if (inst.Rc)
ComputeRC0(gpr.R(d)); ComputeRC0(gpr.R(d));
}
} }
void JitArm64::addzex(UGeckoInstruction inst) void JitArm64::addzex(UGeckoInstruction inst)

View File

@ -219,6 +219,16 @@ ConstantPropagationResult ConstantPropagation::EvaluateTable31AB(UGeckoInstructi
d = u64(a) + u64(b); d = u64(a) + u64(b);
d_overflow = s64(s32(a)) + s64(s32(b)); d_overflow = s64(s32(a)) + s64(s32(b));
break; break;
case 11: // mulhwux
d = d_overflow = (u64(a) * u64(b)) >> 32;
break;
case 75: // mulhwx
d = d_overflow = u64(s64(s32(a)) * s64(s32(b))) >> 32;
break;
case 235: // mullwx
case 747: // mullwox
d = d_overflow = s64(s32(a)) * s64(s32(b));
break;
default: default:
return {}; return {};
} }