Jit: Tailor FixGTBeforeSettingCRFieldBit for EQ

Instead of setting bit 63 conditionally and setting bit 32
unconditionally, we can set just bit 32 conditionally.
This commit is contained in:
JosJuice 2024-05-25 21:43:20 +02:00
parent 01e8d85955
commit 64a7444626
4 changed files with 32 additions and 15 deletions

View File

@ -136,6 +136,7 @@ public:
void ClearCRFieldBit(int field, int bit); void ClearCRFieldBit(int field, int bit);
void SetCRFieldBit(int field, int bit); void SetCRFieldBit(int field, int bit);
void FixGTBeforeSettingCRFieldBit(Gen::X64Reg reg); void FixGTBeforeSettingCRFieldBit(Gen::X64Reg reg);
void FixGTBeforeSettingEQ(Gen::X64Reg reg);
// Generates a branch that will check if a given bit of a CR register part // Generates a branch that will check if a given bit of a CR register part
// is set or not. // is set or not.
Gen::FixupBranch JumpIfCRFieldBit(int field, int bit, bool jump_if_set = true); Gen::FixupBranch JumpIfCRFieldBit(int field, int bit, bool jump_if_set = true);

View File

@ -57,21 +57,19 @@ void Jit64::SetCRFieldBit(int field, int bit, X64Reg in)
MOV(64, R(RSCRATCH2), CROffset(field)); MOV(64, R(RSCRATCH2), CROffset(field));
MOVZX(32, 8, in, R(in)); MOVZX(32, 8, in, R(in));
if (bit != PowerPC::CR_GT_BIT)
FixGTBeforeSettingCRFieldBit(RSCRATCH2);
switch (bit) switch (bit)
{ {
case PowerPC::CR_SO_BIT: // set bit 59 to input case PowerPC::CR_SO_BIT: // set bit 59 to input
FixGTBeforeSettingCRFieldBit(RSCRATCH2);
BTR(64, R(RSCRATCH2), Imm8(PowerPC::CR_EMU_SO_BIT)); BTR(64, R(RSCRATCH2), Imm8(PowerPC::CR_EMU_SO_BIT));
SHL(64, R(in), Imm8(PowerPC::CR_EMU_SO_BIT)); SHL(64, R(in), Imm8(PowerPC::CR_EMU_SO_BIT));
OR(64, R(RSCRATCH2), R(in)); OR(64, R(RSCRATCH2), R(in));
break; break;
case PowerPC::CR_EQ_BIT: // clear low 32 bits, set bit 0 to !input case PowerPC::CR_EQ_BIT: // clear low 32 bits, set bit 0 to !input
FixGTBeforeSettingEQ(RSCRATCH2);
SHR(64, R(RSCRATCH2), Imm8(32)); SHR(64, R(RSCRATCH2), Imm8(32));
SHL(64, R(RSCRATCH2), Imm8(32)); SHL(64, R(RSCRATCH2), Imm8(32));
BTS(64, R(RSCRATCH2), Imm8(32));
XOR(32, R(in), Imm8(1)); XOR(32, R(in), Imm8(1));
OR(64, R(RSCRATCH2), R(in)); OR(64, R(RSCRATCH2), R(in));
break; break;
@ -85,6 +83,7 @@ void Jit64::SetCRFieldBit(int field, int bit, X64Reg in)
break; break;
case PowerPC::CR_LT_BIT: // set bit 62 to input case PowerPC::CR_LT_BIT: // set bit 62 to input
FixGTBeforeSettingCRFieldBit(RSCRATCH2);
BTR(64, R(RSCRATCH2), Imm8(PowerPC::CR_EMU_LT_BIT)); BTR(64, R(RSCRATCH2), Imm8(PowerPC::CR_EMU_LT_BIT));
SHL(64, R(in), Imm8(PowerPC::CR_EMU_LT_BIT)); SHL(64, R(in), Imm8(PowerPC::CR_EMU_LT_BIT));
OR(64, R(RSCRATCH2), R(in)); OR(64, R(RSCRATCH2), R(in));
@ -124,19 +123,18 @@ void Jit64::ClearCRFieldBit(int field, int bit)
void Jit64::SetCRFieldBit(int field, int bit) void Jit64::SetCRFieldBit(int field, int bit)
{ {
MOV(64, R(RSCRATCH), CROffset(field)); MOV(64, R(RSCRATCH), CROffset(field));
if (bit != PowerPC::CR_GT_BIT)
FixGTBeforeSettingCRFieldBit(RSCRATCH);
switch (bit) switch (bit)
{ {
case PowerPC::CR_SO_BIT: case PowerPC::CR_SO_BIT:
FixGTBeforeSettingCRFieldBit(RSCRATCH);
BTS(64, R(RSCRATCH), Imm8(PowerPC::CR_EMU_SO_BIT)); BTS(64, R(RSCRATCH), Imm8(PowerPC::CR_EMU_SO_BIT));
break; break;
case PowerPC::CR_EQ_BIT: case PowerPC::CR_EQ_BIT:
FixGTBeforeSettingEQ(RSCRATCH);
SHR(64, R(RSCRATCH), Imm8(32)); SHR(64, R(RSCRATCH), Imm8(32));
SHL(64, R(RSCRATCH), Imm8(32)); SHL(64, R(RSCRATCH), Imm8(32));
BTS(64, R(RSCRATCH), Imm8(32));
break; break;
case PowerPC::CR_GT_BIT: case PowerPC::CR_GT_BIT:
@ -145,6 +143,7 @@ void Jit64::SetCRFieldBit(int field, int bit)
break; break;
case PowerPC::CR_LT_BIT: case PowerPC::CR_LT_BIT:
FixGTBeforeSettingCRFieldBit(RSCRATCH);
BTS(64, R(RSCRATCH), Imm8(PowerPC::CR_EMU_LT_BIT)); BTS(64, R(RSCRATCH), Imm8(PowerPC::CR_EMU_LT_BIT));
break; break;
} }
@ -164,6 +163,14 @@ void Jit64::FixGTBeforeSettingCRFieldBit(Gen::X64Reg reg)
SetJumpTarget(dont_clear_gt); SetJumpTarget(dont_clear_gt);
} }
void Jit64::FixGTBeforeSettingEQ(Gen::X64Reg reg)
{
TEST(32, R(reg), R(reg));
FixupBranch dont_set_bit_32 = J_CC(CC_Z);
BTS(64, R(reg), Imm8(63));
SetJumpTarget(dont_set_bit_32);
}
FixupBranch Jit64::JumpIfCRFieldBit(int field, int bit, bool jump_if_set) FixupBranch Jit64::JumpIfCRFieldBit(int field, int bit, bool jump_if_set)
{ {
switch (bit) switch (bit)

View File

@ -360,6 +360,7 @@ protected:
void ClearCRFieldBit(int field, int bit); void ClearCRFieldBit(int field, int bit);
void SetCRFieldBit(int field, int bit); void SetCRFieldBit(int field, int bit);
void FixGTBeforeSettingCRFieldBit(Arm64Gen::ARM64Reg reg); void FixGTBeforeSettingCRFieldBit(Arm64Gen::ARM64Reg reg);
void FixGTBeforeSettingEQ(Arm64Gen::ARM64Reg reg);
Arm64Gen::FixupBranch JumpIfCRFieldBit(int field, int bit, bool jump_if_set); Arm64Gen::FixupBranch JumpIfCRFieldBit(int field, int bit, bool jump_if_set);
void UpdateFPExceptionSummary(Arm64Gen::ARM64Reg fpscr); void UpdateFPExceptionSummary(Arm64Gen::ARM64Reg fpscr);

View File

@ -55,20 +55,18 @@ void JitArm64::SetCRFieldBit(int field, int bit, ARM64Reg in, bool negate)
gpr.BindCRToRegister(field, true); gpr.BindCRToRegister(field, true);
ARM64Reg CR = gpr.CR(field); ARM64Reg CR = gpr.CR(field);
if (bit != PowerPC::CR_GT_BIT)
FixGTBeforeSettingCRFieldBit(CR);
switch (bit) switch (bit)
{ {
case PowerPC::CR_SO_BIT: // set bit 59 to input case PowerPC::CR_SO_BIT: // set bit 59 to input
FixGTBeforeSettingCRFieldBit(CR);
BFI(CR, in, PowerPC::CR_EMU_SO_BIT, 1); BFI(CR, in, PowerPC::CR_EMU_SO_BIT, 1);
if (negate) if (negate)
EOR(CR, CR, LogicalImm(1ULL << PowerPC::CR_EMU_SO_BIT, GPRSize::B64)); EOR(CR, CR, LogicalImm(1ULL << PowerPC::CR_EMU_SO_BIT, GPRSize::B64));
break; break;
case PowerPC::CR_EQ_BIT: // clear low 32 bits, set bit 0 to !input case PowerPC::CR_EQ_BIT: // clear low 32 bits, set bit 0 to !input
FixGTBeforeSettingEQ(CR);
AND(CR, CR, LogicalImm(0xFFFF'FFFF'0000'0000, GPRSize::B64)); AND(CR, CR, LogicalImm(0xFFFF'FFFF'0000'0000, GPRSize::B64));
ORR(CR, CR, LogicalImm(1ULL << 32, GPRSize::B64));
ORR(CR, CR, in); ORR(CR, CR, in);
if (!negate) if (!negate)
EOR(CR, CR, LogicalImm(1ULL << 0, GPRSize::B64)); EOR(CR, CR, LogicalImm(1ULL << 0, GPRSize::B64));
@ -82,6 +80,7 @@ void JitArm64::SetCRFieldBit(int field, int bit, ARM64Reg in, bool negate)
break; break;
case PowerPC::CR_LT_BIT: // set bit 62 to input case PowerPC::CR_LT_BIT: // set bit 62 to input
FixGTBeforeSettingCRFieldBit(CR);
BFI(CR, in, PowerPC::CR_EMU_LT_BIT, 1); BFI(CR, in, PowerPC::CR_EMU_LT_BIT, 1);
if (negate) if (negate)
EOR(CR, CR, LogicalImm(1ULL << PowerPC::CR_EMU_LT_BIT, GPRSize::B64)); EOR(CR, CR, LogicalImm(1ULL << PowerPC::CR_EMU_LT_BIT, GPRSize::B64));
@ -121,18 +120,16 @@ void JitArm64::SetCRFieldBit(int field, int bit)
gpr.BindCRToRegister(field, true); gpr.BindCRToRegister(field, true);
ARM64Reg XA = gpr.CR(field); ARM64Reg XA = gpr.CR(field);
if (bit != PowerPC::CR_GT_BIT)
FixGTBeforeSettingCRFieldBit(XA);
switch (bit) switch (bit)
{ {
case PowerPC::CR_SO_BIT: case PowerPC::CR_SO_BIT:
FixGTBeforeSettingCRFieldBit(XA);
ORR(XA, XA, LogicalImm(u64(1) << PowerPC::CR_EMU_SO_BIT, GPRSize::B64)); ORR(XA, XA, LogicalImm(u64(1) << PowerPC::CR_EMU_SO_BIT, GPRSize::B64));
break; break;
case PowerPC::CR_EQ_BIT: case PowerPC::CR_EQ_BIT:
FixGTBeforeSettingEQ(XA);
AND(XA, XA, LogicalImm(0xFFFF'FFFF'0000'0000, GPRSize::B64)); AND(XA, XA, LogicalImm(0xFFFF'FFFF'0000'0000, GPRSize::B64));
ORR(XA, XA, LogicalImm(u64(1) << 32, GPRSize::B64));
break; break;
case PowerPC::CR_GT_BIT: case PowerPC::CR_GT_BIT:
@ -141,6 +138,7 @@ void JitArm64::SetCRFieldBit(int field, int bit)
break; break;
case PowerPC::CR_LT_BIT: case PowerPC::CR_LT_BIT:
FixGTBeforeSettingCRFieldBit(XA);
ORR(XA, XA, LogicalImm(u64(1) << PowerPC::CR_EMU_LT_BIT, GPRSize::B64)); ORR(XA, XA, LogicalImm(u64(1) << PowerPC::CR_EMU_LT_BIT, GPRSize::B64));
break; break;
} }
@ -159,6 +157,16 @@ void JitArm64::FixGTBeforeSettingCRFieldBit(ARM64Reg reg)
CSEL(reg, reg, XA, CC_NEQ); CSEL(reg, reg, XA, CC_NEQ);
} }
void JitArm64::FixGTBeforeSettingEQ(Arm64Gen::ARM64Reg reg)
{
ARM64Reg WA = gpr.GetReg();
ARM64Reg XA = EncodeRegTo64(WA);
ORR(XA, reg, LogicalImm(1ULL << 32, GPRSize::B64));
CMP(EncodeRegTo32(reg), ARM64Reg::WZR);
CSEL(reg, reg, XA, CC_EQ);
gpr.Unlock(WA);
}
FixupBranch JitArm64::JumpIfCRFieldBit(int field, int bit, bool jump_if_set) FixupBranch JitArm64::JumpIfCRFieldBit(int field, int bit, bool jump_if_set)
{ {
ARM64Reg XA = gpr.CR(field); ARM64Reg XA = gpr.CR(field);