mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-15 05:47:56 -07:00
Jit64: divwx - Eliminate XOR for constant dividend
We normally check for division by zero to know if we should set the destination register to zero with a XOR. However, when the divisor and destination registers are the same the explicit zeroing can be omitted. In addition, some of the surrounding branching can be simplified as well. Before: 45 85 FF test r15d,r15d 75 05 jne normal_path 45 33 FF xor r15d,r15d EB 0C jmp done normal_path: B8 5A 00 00 00 mov eax,5Ah 99 cdq 41 F7 FF idiv eax,r15d 44 8B F8 mov r15d,eax done: After: 45 85 FF test r15d,r15d 74 0C je done B8 5A 00 00 00 mov eax,5Ah 99 cdq 41 F7 FF idiv eax,r15d 44 8B F8 mov r15d,eax done:
This commit is contained in:
parent
abc4c8f601
commit
47e16133e5
@ -1375,38 +1375,49 @@ void Jit64::divwx(UGeckoInstruction inst)
|
||||
// Check for divisor == 0
|
||||
TEST(32, Rb, Rb);
|
||||
|
||||
FixupBranch normal_path;
|
||||
FixupBranch done;
|
||||
|
||||
if (dividend == 0x80000000)
|
||||
if (d == b && (dividend & 0x80000000) == 0 && !inst.OE)
|
||||
{
|
||||
// Divisor is 0, proceed to overflow case
|
||||
const FixupBranch overflow = J_CC(CC_Z);
|
||||
// Otherwise, check for divisor == -1
|
||||
CMP(32, Rb, Imm32(0xFFFFFFFF));
|
||||
normal_path = J_CC(CC_NE);
|
||||
|
||||
SetJumpTarget(overflow);
|
||||
// Divisor is 0, skip to the end
|
||||
// No need to explicitly set destination to 0 due to overlapping registers
|
||||
done = J_CC(CC_Z);
|
||||
// Otherwise, proceed to normal path
|
||||
}
|
||||
else
|
||||
{
|
||||
// Divisor is not 0, take normal path
|
||||
normal_path = J_CC(CC_NZ);
|
||||
// Otherwise, proceed to overflow case
|
||||
FixupBranch normal_path;
|
||||
if (dividend == 0x80000000)
|
||||
{
|
||||
// Divisor is 0, proceed to overflow case
|
||||
const FixupBranch overflow = J_CC(CC_Z);
|
||||
// Otherwise, check for divisor == -1
|
||||
CMP(32, Rb, Imm32(0xFFFFFFFF));
|
||||
normal_path = J_CC(CC_NE);
|
||||
|
||||
SetJumpTarget(overflow);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Divisor is not 0, take normal path
|
||||
normal_path = J_CC(CC_NZ);
|
||||
// Otherwise, proceed to overflow case
|
||||
}
|
||||
|
||||
// Set Rd to all ones or all zeroes
|
||||
if (dividend & 0x80000000)
|
||||
MOV(32, Rd, Imm32(0xFFFFFFFF));
|
||||
else if (d != b)
|
||||
XOR(32, Rd, Rd);
|
||||
|
||||
if (inst.OE)
|
||||
GenerateConstantOverflow(true);
|
||||
|
||||
done = J();
|
||||
|
||||
SetJumpTarget(normal_path);
|
||||
}
|
||||
|
||||
// Set Rd to all ones or all zeroes
|
||||
if (dividend & 0x80000000)
|
||||
MOV(32, Rd, Imm32(0xFFFFFFFF));
|
||||
else
|
||||
XOR(32, Rd, Rd);
|
||||
|
||||
if (inst.OE)
|
||||
GenerateConstantOverflow(true);
|
||||
|
||||
const FixupBranch done = J();
|
||||
|
||||
SetJumpTarget(normal_path);
|
||||
|
||||
MOV(32, eax, Imm32(dividend));
|
||||
CDQ();
|
||||
IDIV(32, Rb);
|
||||
|
Loading…
Reference in New Issue
Block a user