CR: Replace some magic values with constants.

This commit is contained in:
Pierre Bourdon
2014-06-22 17:14:31 +02:00
parent 0ff1481494
commit 5506e57ab8
4 changed files with 46 additions and 48 deletions

View File

@ -237,33 +237,22 @@ void Jit64::fcmpx(UGeckoInstruction inst)
pGreater = J_CC(CC_B); pGreater = J_CC(CC_B);
} }
// Read the documentation about cr_val in PowerPC.h to understand these MOV(64, R(RAX), Imm64(PPCCRToInternal(CR_EQ)));
// magic values.
// Equal: !GT (bit 63 set), !LT (bit 62 not set), !SO (bit 61 not set), EQ
// (bits 31-0 not set).
MOV(64, R(RAX), Imm64(0x8000000000000000));
continue1 = J(); continue1 = J();
// NAN: !GT (bit 63 set), !LT (bit 62 not set), SO (bit 61 set), !EQ (bit 0
// set).
SetJumpTarget(pNaN); SetJumpTarget(pNaN);
MOV(64, R(RAX), Imm64(0xA000000000000001)); MOV(64, R(RAX), Imm64(PPCCRToInternal(CR_SO)));
if (a != b) if (a != b)
{ {
continue2 = J(); continue2 = J();
// Greater Than: GT (bit 63 not set), !LT (bit 62 not set), !SO (bit 61
// not set), !EQ (bit 0 set).
SetJumpTarget(pGreater); SetJumpTarget(pGreater);
MOV(64, R(RAX), Imm64(0x0000000000000001)); MOV(64, R(RAX), Imm64(PPCCRToInternal(CR_GT)));
continue3 = J(); continue3 = J();
// Less Than: !GT (bit 63 set), LT (bit 62 set), !SO (bit 61 not set),
// !EQ (bit 0 set).
SetJumpTarget(pLesser); SetJumpTarget(pLesser);
MOV(64, R(RAX), Imm64(0xC000000000000001)); MOV(64, R(RAX), Imm64(PPCCRToInternal(CR_LT)));
} }
SetJumpTarget(continue1); SetJumpTarget(continue1);

View File

@ -315,20 +315,20 @@ void Jit64::cmpXX(UGeckoInstruction inst)
if (signedCompare) if (signedCompare)
{ {
if ((s32)gpr.R(a).offset == (s32)comparand.offset) if ((s32)gpr.R(a).offset == (s32)comparand.offset)
compareResult = 0x2; compareResult = CR_EQ;
else if ((s32)gpr.R(a).offset > (s32)comparand.offset) else if ((s32)gpr.R(a).offset > (s32)comparand.offset)
compareResult = 0x4; compareResult = CR_GT;
else else
compareResult = 0x8; compareResult = CR_LT;
} }
else else
{ {
if ((u32)gpr.R(a).offset == (u32)comparand.offset) if ((u32)gpr.R(a).offset == (u32)comparand.offset)
compareResult = 0x2; compareResult = CR_EQ;
else if ((u32)gpr.R(a).offset > (u32)comparand.offset) else if ((u32)gpr.R(a).offset > (u32)comparand.offset)
compareResult = 0x4; compareResult = CR_GT;
else else
compareResult = 0x8; compareResult = CR_LT;
} }
MOV(64, R(RAX), Imm64(PPCCRToInternal(compareResult))); MOV(64, R(RAX), Imm64(PPCCRToInternal(compareResult)));
MOV(64, M(&PowerPC::ppcState.cr_val[crf]), R(RAX)); MOV(64, M(&PowerPC::ppcState.cr_val[crf]), R(RAX));

View File

@ -14,24 +14,24 @@ void Jit64::GetCRFieldBit(int field, int bit, Gen::X64Reg out)
{ {
switch (bit) switch (bit)
{ {
case 0: // SO, check bit 61 set case CR_SO_BIT: // check bit 61 set
MOV(64, R(ABI_PARAM1), Imm64(1ull << 61)); MOV(64, R(ABI_PARAM1), Imm64(1ull << 61));
TEST(64, M(&PowerPC::ppcState.cr_val[field]), R(ABI_PARAM1)); TEST(64, M(&PowerPC::ppcState.cr_val[field]), R(ABI_PARAM1));
SETcc(CC_NZ, R(out)); SETcc(CC_NZ, R(out));
break; break;
case 1: // EQ, check bits 31-0 == 0 case CR_EQ_BIT: // check bits 31-0 == 0
CMP(32, M(&PowerPC::ppcState.cr_val[field]), Imm32(0)); CMP(32, M(&PowerPC::ppcState.cr_val[field]), Imm32(0));
SETcc(CC_Z, R(out)); SETcc(CC_Z, R(out));
break; break;
case 2: // GT, check val > 0 case CR_GT_BIT: // check val > 0
MOV(64, R(ABI_PARAM1), M(&PowerPC::ppcState.cr_val[field])); MOV(64, R(ABI_PARAM1), M(&PowerPC::ppcState.cr_val[field]));
TEST(64, R(ABI_PARAM1), R(ABI_PARAM1)); TEST(64, R(ABI_PARAM1), R(ABI_PARAM1));
SETcc(CC_G, R(out)); SETcc(CC_G, R(out));
break; break;
case 3: // LT, check bit 62 set case CR_LT_BIT: // check bit 62 set
MOV(64, R(ABI_PARAM1), Imm64(1ull << 62)); MOV(64, R(ABI_PARAM1), Imm64(1ull << 62));
TEST(64, M(&PowerPC::ppcState.cr_val[field]), R(ABI_PARAM1)); TEST(64, M(&PowerPC::ppcState.cr_val[field]), R(ABI_PARAM1));
SETcc(CC_NZ, R(out)); SETcc(CC_NZ, R(out));
@ -51,21 +51,21 @@ void Jit64::SetCRFieldBit(int field, int bit, Gen::X64Reg in)
// New value is 0. // New value is 0.
switch (bit) switch (bit)
{ {
case 0: // !SO, unset bit 61 case CR_SO_BIT: // unset bit 61
MOV(64, R(ABI_PARAM1), Imm64(~(1ull << 61))); MOV(64, R(ABI_PARAM1), Imm64(~(1ull << 61)));
AND(64, R(ABI_PARAM2), R(ABI_PARAM1)); AND(64, R(ABI_PARAM2), R(ABI_PARAM1));
break; break;
case 1: // !EQ, set bit 0 to 1 case CR_EQ_BIT: // set bit 0 to 1
OR(8, R(ABI_PARAM2), Imm8(1)); OR(8, R(ABI_PARAM2), Imm8(1));
break; break;
case 2: // !GT, set bit 63 case CR_GT_BIT: // !GT, set bit 63
MOV(64, R(ABI_PARAM1), Imm64(1ull << 63)); MOV(64, R(ABI_PARAM1), Imm64(1ull << 63));
OR(64, R(ABI_PARAM2), R(ABI_PARAM1)); OR(64, R(ABI_PARAM2), R(ABI_PARAM1));
break; break;
case 3: // !LT, unset bit 62 case CR_LT_BIT: // !LT, unset bit 62
MOV(64, R(ABI_PARAM1), Imm64(~(1ull << 62))); MOV(64, R(ABI_PARAM1), Imm64(~(1ull << 62)));
AND(64, R(ABI_PARAM2), R(ABI_PARAM1)); AND(64, R(ABI_PARAM2), R(ABI_PARAM1));
break; break;
@ -76,22 +76,22 @@ void Jit64::SetCRFieldBit(int field, int bit, Gen::X64Reg in)
switch (bit) switch (bit)
{ {
case 0: // SO, set bit 61 case CR_SO_BIT: // set bit 61
MOV(64, R(ABI_PARAM1), Imm64(1ull << 61)); MOV(64, R(ABI_PARAM1), Imm64(1ull << 61));
OR(64, R(ABI_PARAM2), R(ABI_PARAM1)); OR(64, R(ABI_PARAM2), R(ABI_PARAM1));
break; break;
case 1: // EQ, set bits 31-0 to 0 case CR_EQ_BIT: // set bits 31-0 to 0
MOV(64, R(ABI_PARAM1), Imm64(0xFFFFFFFF00000000)); MOV(64, R(ABI_PARAM1), Imm64(0xFFFFFFFF00000000));
AND(64, R(ABI_PARAM2), R(ABI_PARAM1)); AND(64, R(ABI_PARAM2), R(ABI_PARAM1));
break; break;
case 2: // GT, unset bit 63 case CR_GT_BIT: // unset bit 63
MOV(64, R(ABI_PARAM1), Imm64(~(1ull << 63))); MOV(64, R(ABI_PARAM1), Imm64(~(1ull << 63)));
AND(64, R(ABI_PARAM2), R(ABI_PARAM1)); AND(64, R(ABI_PARAM2), R(ABI_PARAM1));
break; break;
case 3: // LT, set bit 62 case CR_LT_BIT: // set bit 62
MOV(64, R(ABI_PARAM1), Imm64(1ull << 62)); MOV(64, R(ABI_PARAM1), Imm64(1ull << 62));
OR(64, R(ABI_PARAM2), R(ABI_PARAM1)); OR(64, R(ABI_PARAM2), R(ABI_PARAM1));
break; break;
@ -107,21 +107,21 @@ FixupBranch Jit64::JumpIfCRFieldBit(int field, int bit, bool jump_if_set)
{ {
switch (bit) switch (bit)
{ {
case 0: // SO, check bit 61 set case CR_SO_BIT: // check bit 61 set
MOV(64, R(RAX), Imm64(1ull << 61)); MOV(64, R(RAX), Imm64(1ull << 61));
TEST(64, M(&PowerPC::ppcState.cr_val[field]), R(RAX)); TEST(64, M(&PowerPC::ppcState.cr_val[field]), R(RAX));
return J_CC(jump_if_set ? CC_NZ : CC_Z, true); return J_CC(jump_if_set ? CC_NZ : CC_Z, true);
case 1: // EQ, check bits 31-0 == 0 case CR_EQ_BIT: // check bits 31-0 == 0
CMP(32, M(&PowerPC::ppcState.cr_val[field]), Imm32(0)); CMP(32, M(&PowerPC::ppcState.cr_val[field]), Imm32(0));
return J_CC(jump_if_set ? CC_Z : CC_NZ, true); return J_CC(jump_if_set ? CC_Z : CC_NZ, true);
case 2: // GT, check val > 0 case CR_GT_BIT: // check val > 0
MOV(64, R(RAX), M(&PowerPC::ppcState.cr_val[field])); MOV(64, R(RAX), M(&PowerPC::ppcState.cr_val[field]));
TEST(64, R(RAX), R(RAX)); TEST(64, R(RAX), R(RAX));
return J_CC(jump_if_set ? CC_G : CC_LE, true); return J_CC(jump_if_set ? CC_G : CC_LE, true);
case 3: // LT, check bit 62 set case CR_LT_BIT: // check bit 62 set
MOV(64, R(RAX), Imm64(1ull << 62)); MOV(64, R(RAX), Imm64(1ull << 62));
TEST(64, M(&PowerPC::ppcState.cr_val[field]), R(RAX)); TEST(64, M(&PowerPC::ppcState.cr_val[field]), R(RAX));
return J_CC(jump_if_set ? CC_NZ : CC_Z, true); return J_CC(jump_if_set ? CC_NZ : CC_Z, true);
@ -369,19 +369,19 @@ void Jit64::mtcrf(UGeckoInstruction inst)
// EQ // EQ
MOV(64, R(tmp), R(EAX)); MOV(64, R(tmp), R(EAX));
NOT(64, R(tmp)); NOT(64, R(tmp));
AND(64, R(tmp), Imm8(0x2)); AND(64, R(tmp), Imm8(CR_EQ));
OR(64, R(cr_val), R(tmp)); OR(64, R(cr_val), R(tmp));
// GT // GT
MOV(64, R(tmp), R(EAX)); MOV(64, R(tmp), R(EAX));
NOT(64, R(tmp)); NOT(64, R(tmp));
AND(64, R(tmp), Imm8(0x4)); AND(64, R(tmp), Imm8(CR_GT));
SHL(64, R(tmp), Imm8(63 - 2)); SHL(64, R(tmp), Imm8(63 - 2));
OR(64, R(cr_val), R(tmp)); OR(64, R(cr_val), R(tmp));
// LT // LT
MOV(64, R(tmp), R(EAX)); MOV(64, R(tmp), R(EAX));
AND(64, R(tmp), Imm8(0x8)); AND(64, R(tmp), Imm8(CR_LT));
SHL(64, R(tmp), Imm8(62 - 3)); SHL(64, R(tmp), Imm8(62 - 3));
OR(64, R(cr_val), R(tmp)); OR(64, R(cr_val), R(tmp));

View File

@ -162,18 +162,27 @@ void UpdatePerformanceMonitor(u32 cycles, u32 num_load_stores, u32 num_fp_inst);
} // namespace } // namespace
enum CRBits
{
CR_SO = 1,
CR_EQ = 2,
CR_GT = 4,
CR_LT = 8,
CR_SO_BIT = 0,
CR_EQ_BIT = 1,
CR_GT_BIT = 2,
CR_LT_BIT = 3,
};
// Convert between PPC and internal representation of CR. // Convert between PPC and internal representation of CR.
inline u64 PPCCRToInternal(u8 value) inline u64 PPCCRToInternal(u8 value)
{ {
u64 cr_val = 0x100000000; u64 cr_val = 0x100000000;
// SO cr_val |= (u64)!!(value & CR_SO) << 61;
cr_val |= (u64)!!(value & 1) << 61; cr_val |= (u64)!(value & CR_EQ);
// EQ cr_val |= (u64)!(value & CR_GT) << 63;
cr_val |= (u64)!(value & 2); cr_val |= (u64)!!(value & CR_LT) << 62;
// GT
cr_val |= (u64)!(value & 4) << 63;
// LT
cr_val |= (u64)!!(value & 8) << 62;
return cr_val; return cr_val;
} }