PowerPC: Simplify subfic/subfcx carry calculation

This commit is contained in:
JosJuice 2024-08-31 17:38:49 +02:00
parent a293abbfd0
commit 7bb5696d95
3 changed files with 15 additions and 15 deletions

View File

@ -141,10 +141,10 @@ void Interpreter::oris(Interpreter& interpreter, UGeckoInstruction inst)
void Interpreter::subfic(Interpreter& interpreter, UGeckoInstruction inst) void Interpreter::subfic(Interpreter& interpreter, UGeckoInstruction inst)
{ {
auto& ppc_state = interpreter.m_ppc_state; auto& ppc_state = interpreter.m_ppc_state;
const s32 a = s32(ppc_state.gpr[inst.RA]); const u32 a = ppc_state.gpr[inst.RA];
const s32 immediate = inst.SIMM_16; const u32 immediate = u32(s32(inst.SIMM_16));
ppc_state.gpr[inst.RD] = u32(immediate - a); ppc_state.gpr[inst.RD] = immediate - a;
ppc_state.SetCarry((a == 0) || (Helper_Carry(0 - u32(a), u32(immediate)))); ppc_state.SetCarry(immediate >= a);
} }
void Interpreter::twi(Interpreter& interpreter, UGeckoInstruction inst) void Interpreter::twi(Interpreter& interpreter, UGeckoInstruction inst)
@ -622,15 +622,15 @@ void Interpreter::subfx(Interpreter& interpreter, UGeckoInstruction inst)
void Interpreter::subfcx(Interpreter& interpreter, UGeckoInstruction inst) void Interpreter::subfcx(Interpreter& interpreter, UGeckoInstruction inst)
{ {
auto& ppc_state = interpreter.m_ppc_state; auto& ppc_state = interpreter.m_ppc_state;
const u32 a = ~ppc_state.gpr[inst.RA]; const u32 a = ppc_state.gpr[inst.RA];
const u32 b = ppc_state.gpr[inst.RB]; const u32 b = ppc_state.gpr[inst.RB];
const u32 result = a + b + 1; const u32 result = b - a;
ppc_state.gpr[inst.RD] = result; ppc_state.gpr[inst.RD] = result;
ppc_state.SetCarry(a == 0xFFFFFFFF || Helper_Carry(b, a + 1)); ppc_state.SetCarry(b >= a);
if (inst.OE) if (inst.OE)
ppc_state.SetXER_OV(HasAddOverflowed(a, b, result)); ppc_state.SetXER_OV(HasAddOverflowed(~a, b, result));
if (inst.Rc) if (inst.Rc)
Helper_UpdateCR0(ppc_state, result); Helper_UpdateCR0(ppc_state, result);

View File

@ -1104,7 +1104,7 @@ void Jit64::subfic(UGeckoInstruction inst)
{ {
u32 i = imm, j = gpr.Imm32(a); u32 i = imm, j = gpr.Imm32(a);
gpr.SetImmediate32(d, i - j); gpr.SetImmediate32(d, i - j);
FinalizeCarry(j == 0 || (i > j - 1)); FinalizeCarry(i >= j);
return; return;
} }
@ -1165,12 +1165,12 @@ void Jit64::subfx(UGeckoInstruction inst)
} }
else if (gpr.IsImm(a, b)) else if (gpr.IsImm(a, b))
{ {
s32 i = gpr.SImm32(b), j = gpr.SImm32(a); u32 i = gpr.Imm32(b), j = gpr.Imm32(a);
gpr.SetImmediate32(d, i - j); gpr.SetImmediate32(d, i - j);
if (carry) if (carry)
FinalizeCarry(j == 0 || Interpreter::Helper_Carry((u32)i, 0u - (u32)j)); FinalizeCarry(i >= j);
if (inst.OE) if (inst.OE)
GenerateConstantOverflow((s64)i - (s64)j); GenerateConstantOverflow(s64(s32(i)) - s64(s32(j)));
} }
else if (gpr.IsImm(a)) else if (gpr.IsImm(a))
{ {

View File

@ -1310,7 +1310,7 @@ void JitArm64::subfcx(UGeckoInstruction inst)
u32 a_imm = gpr.GetImm(a), b_imm = gpr.GetImm(b); u32 a_imm = gpr.GetImm(a), b_imm = gpr.GetImm(b);
gpr.SetImmediate(d, b_imm - a_imm); gpr.SetImmediate(d, b_imm - a_imm);
ComputeCarry(a_imm == 0 || Interpreter::Helper_Carry(b_imm, 0u - a_imm)); ComputeCarry(b_imm >= a_imm);
if (inst.Rc) if (inst.Rc)
ComputeRC0(gpr.GetImm(d)); ComputeRC0(gpr.GetImm(d));
@ -1381,14 +1381,14 @@ void JitArm64::subfic(UGeckoInstruction inst)
JITDISABLE(bJITIntegerOff); JITDISABLE(bJITIntegerOff);
int a = inst.RA, d = inst.RD; int a = inst.RA, d = inst.RD;
s32 imm = inst.SIMM_16; u32 imm = s32(inst.SIMM_16);
if (gpr.IsImm(a)) if (gpr.IsImm(a))
{ {
u32 a_imm = gpr.GetImm(a); u32 a_imm = gpr.GetImm(a);
gpr.SetImmediate(d, imm - a_imm); gpr.SetImmediate(d, imm - a_imm);
ComputeCarry(a_imm == 0 || Interpreter::Helper_Carry(imm, 0u - a_imm)); ComputeCarry(imm >= a_imm);
} }
else else
{ {