Jit: Skip setting bit 32 of CRs when possible

Setting SO and LT can be done without setting bit 32. Setting bit 32 is
required in situations where clearing bits in the host representation of
a CR could otherwise cause the host representation to become all zeroes,
but it's impossible to generate a host representation whose SO and/or LT
bits are set without any other bits being set. (Any attempt to do so
would require either starting with a host representation of all zeroes
and then setting the SO or LT bit, which results in bit 63 getting set,
or clearing bit 63 by setting the emulated GT bit, which results in bit
32 getting set, or clearing the lower 32 bits by setting the emulated EQ
bit, which results in bit 32 getting set.)
This commit is contained in:
JosJuice 2024-05-25 21:05:31 +02:00
parent 9b3b6bea9d
commit 01e8d85955
2 changed files with 8 additions and 5 deletions

View File

@ -71,6 +71,7 @@ void Jit64::SetCRFieldBit(int field, int bit, X64Reg in)
case PowerPC::CR_EQ_BIT: // clear low 32 bits, set bit 0 to !input
SHR(64, R(RSCRATCH2), Imm8(32));
SHL(64, R(RSCRATCH2), Imm8(32));
BTS(64, R(RSCRATCH2), Imm8(32));
XOR(32, R(in), Imm8(1));
OR(64, R(RSCRATCH2), R(in));
break;
@ -78,6 +79,7 @@ void Jit64::SetCRFieldBit(int field, int bit, X64Reg in)
case PowerPC::CR_GT_BIT: // set bit 63 to !input
BTR(64, R(RSCRATCH2), Imm8(63));
NOT(32, R(in));
BTS(64, R(RSCRATCH2), Imm8(32));
SHL(64, R(in), Imm8(63));
OR(64, R(RSCRATCH2), R(in));
break;
@ -89,7 +91,6 @@ void Jit64::SetCRFieldBit(int field, int bit, X64Reg in)
break;
}
BTS(64, R(RSCRATCH2), Imm8(32));
MOV(64, CROffset(field), R(RSCRATCH2));
}
@ -135,10 +136,12 @@ void Jit64::SetCRFieldBit(int field, int bit)
case PowerPC::CR_EQ_BIT:
SHR(64, R(RSCRATCH), Imm8(32));
SHL(64, R(RSCRATCH), Imm8(32));
BTS(64, R(RSCRATCH), Imm8(32));
break;
case PowerPC::CR_GT_BIT:
BTR(64, R(RSCRATCH), Imm8(63));
BTS(64, R(RSCRATCH), Imm8(32));
break;
case PowerPC::CR_LT_BIT:
@ -146,7 +149,6 @@ void Jit64::SetCRFieldBit(int field, int bit)
break;
}
BTS(64, R(RSCRATCH), Imm8(32));
MOV(64, CROffset(field), R(RSCRATCH));
}

View File

@ -68,12 +68,14 @@ void JitArm64::SetCRFieldBit(int field, int bit, ARM64Reg in, bool negate)
case PowerPC::CR_EQ_BIT: // clear low 32 bits, set bit 0 to !input
AND(CR, CR, LogicalImm(0xFFFF'FFFF'0000'0000, GPRSize::B64));
ORR(CR, CR, LogicalImm(1ULL << 32, GPRSize::B64));
ORR(CR, CR, in);
if (!negate)
EOR(CR, CR, LogicalImm(1ULL << 0, GPRSize::B64));
break;
case PowerPC::CR_GT_BIT: // set bit 63 to !input
ORR(CR, CR, LogicalImm(1ULL << 32, GPRSize::B64));
BFI(CR, in, 63, 1);
if (!negate)
EOR(CR, CR, LogicalImm(1ULL << 63, GPRSize::B64));
@ -86,7 +88,6 @@ void JitArm64::SetCRFieldBit(int field, int bit, ARM64Reg in, bool negate)
break;
}
ORR(CR, CR, LogicalImm(1ULL << 32, GPRSize::B64));
}
void JitArm64::ClearCRFieldBit(int field, int bit)
@ -131,18 +132,18 @@ void JitArm64::SetCRFieldBit(int field, int bit)
case PowerPC::CR_EQ_BIT:
AND(XA, XA, LogicalImm(0xFFFF'FFFF'0000'0000, GPRSize::B64));
ORR(XA, XA, LogicalImm(u64(1) << 32, GPRSize::B64));
break;
case PowerPC::CR_GT_BIT:
AND(XA, XA, LogicalImm(~(u64(1) << 63), GPRSize::B64));
ORR(XA, XA, LogicalImm(u64(1) << 32, GPRSize::B64));
break;
case PowerPC::CR_LT_BIT:
ORR(XA, XA, LogicalImm(u64(1) << PowerPC::CR_EMU_LT_BIT, GPRSize::B64));
break;
}
ORR(XA, XA, LogicalImm(u64(1) << 32, GPRSize::B64));
}
void JitArm64::FixGTBeforeSettingCRFieldBit(ARM64Reg reg)