JIT: optimize crclr special case of crxor
This commit is contained in:
parent
97fba41860
commit
1ec1a9c33a
|
@ -137,6 +137,7 @@ public:
|
||||||
void GetCRFieldBit(int field, int bit, Gen::X64Reg out, bool negate = false);
|
void GetCRFieldBit(int field, int bit, Gen::X64Reg out, bool negate = false);
|
||||||
// Clobbers RDX.
|
// Clobbers RDX.
|
||||||
void SetCRFieldBit(int field, int bit, Gen::X64Reg in);
|
void SetCRFieldBit(int field, int bit, Gen::X64Reg in);
|
||||||
|
void ClearCRFieldBit(int field, int bit);
|
||||||
|
|
||||||
// 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.
|
||||||
|
|
|
@ -89,6 +89,42 @@ void Jit64::SetCRFieldBit(int field, int bit, Gen::X64Reg in)
|
||||||
MOV(64, PPCSTATE(cr_val[field]), R(RSCRATCH2));
|
MOV(64, PPCSTATE(cr_val[field]), R(RSCRATCH2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Jit64::ClearCRFieldBit(int field, int bit)
|
||||||
|
{
|
||||||
|
MOV(64, R(RSCRATCH2), PPCSTATE(cr_val[field]));
|
||||||
|
|
||||||
|
if (bit != CR_GT_BIT)
|
||||||
|
{
|
||||||
|
TEST(64, R(RSCRATCH2), R(RSCRATCH2));
|
||||||
|
FixupBranch dont_clear_gt = J_CC(CC_NZ);
|
||||||
|
BTS(64, R(RSCRATCH2), Imm8(63));
|
||||||
|
SetJumpTarget(dont_clear_gt);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (bit)
|
||||||
|
{
|
||||||
|
case CR_SO_BIT: // set bit 61 to input
|
||||||
|
BTR(64, R(RSCRATCH2), Imm8(61));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CR_EQ_BIT: // clear low 32 bits, set bit 0 to !input
|
||||||
|
SHR(64, R(RSCRATCH2), Imm8(32));
|
||||||
|
SHL(64, R(RSCRATCH2), Imm8(32));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CR_GT_BIT: // set bit 63 to !input
|
||||||
|
BTR(64, R(RSCRATCH2), Imm8(63));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CR_LT_BIT: // set bit 62 to input
|
||||||
|
BTR(64, R(RSCRATCH2), Imm8(62));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
BTS(64, R(RSCRATCH2), Imm8(32));
|
||||||
|
MOV(64, PPCSTATE(cr_val[field]), R(RSCRATCH2));
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
@ -476,6 +512,13 @@ void Jit64::crXXX(UGeckoInstruction inst)
|
||||||
JITDISABLE(bJITSystemRegistersOff);
|
JITDISABLE(bJITSystemRegistersOff);
|
||||||
_dbg_assert_msg_(DYNA_REC, inst.OPCD == 19, "Invalid crXXX");
|
_dbg_assert_msg_(DYNA_REC, inst.OPCD == 19, "Invalid crXXX");
|
||||||
|
|
||||||
|
// Special case: crclr
|
||||||
|
if (inst.CRBA == inst.CRBB && inst.CRBA == inst.CRBD && inst.SUBOP10 == 193)
|
||||||
|
{
|
||||||
|
ClearCRFieldBit(inst.CRBD >> 2, 3 - (inst.CRBD & 3));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(delroth): Potential optimizations could be applied here. For
|
// TODO(delroth): Potential optimizations could be applied here. For
|
||||||
// instance, if the two CR bits being loaded are the same, two loads are
|
// instance, if the two CR bits being loaded are the same, two loads are
|
||||||
// not required.
|
// not required.
|
||||||
|
|
Loading…
Reference in New Issue