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);
}
// Read the documentation about cr_val in PowerPC.h to understand these
// 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));
MOV(64, R(RAX), Imm64(PPCCRToInternal(CR_EQ)));
continue1 = J();
// NAN: !GT (bit 63 set), !LT (bit 62 not set), SO (bit 61 set), !EQ (bit 0
// set).
SetJumpTarget(pNaN);
MOV(64, R(RAX), Imm64(0xA000000000000001));
MOV(64, R(RAX), Imm64(PPCCRToInternal(CR_SO)));
if (a != b)
{
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);
MOV(64, R(RAX), Imm64(0x0000000000000001));
MOV(64, R(RAX), Imm64(PPCCRToInternal(CR_GT)));
continue3 = J();
// Less Than: !GT (bit 63 set), LT (bit 62 set), !SO (bit 61 not set),
// !EQ (bit 0 set).
SetJumpTarget(pLesser);
MOV(64, R(RAX), Imm64(0xC000000000000001));
MOV(64, R(RAX), Imm64(PPCCRToInternal(CR_LT)));
}
SetJumpTarget(continue1);

View File

@ -315,20 +315,20 @@ void Jit64::cmpXX(UGeckoInstruction inst)
if (signedCompare)
{
if ((s32)gpr.R(a).offset == (s32)comparand.offset)
compareResult = 0x2;
compareResult = CR_EQ;
else if ((s32)gpr.R(a).offset > (s32)comparand.offset)
compareResult = 0x4;
compareResult = CR_GT;
else
compareResult = 0x8;
compareResult = CR_LT;
}
else
{
if ((u32)gpr.R(a).offset == (u32)comparand.offset)
compareResult = 0x2;
compareResult = CR_EQ;
else if ((u32)gpr.R(a).offset > (u32)comparand.offset)
compareResult = 0x4;
compareResult = CR_GT;
else
compareResult = 0x8;
compareResult = CR_LT;
}
MOV(64, R(RAX), Imm64(PPCCRToInternal(compareResult)));
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)
{
case 0: // SO, check bit 61 set
case CR_SO_BIT: // check bit 61 set
MOV(64, R(ABI_PARAM1), Imm64(1ull << 61));
TEST(64, M(&PowerPC::ppcState.cr_val[field]), R(ABI_PARAM1));
SETcc(CC_NZ, R(out));
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));
SETcc(CC_Z, R(out));
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]));
TEST(64, R(ABI_PARAM1), R(ABI_PARAM1));
SETcc(CC_G, R(out));
break;
case 3: // LT, check bit 62 set
case CR_LT_BIT: // check bit 62 set
MOV(64, R(ABI_PARAM1), Imm64(1ull << 62));
TEST(64, M(&PowerPC::ppcState.cr_val[field]), R(ABI_PARAM1));
SETcc(CC_NZ, R(out));
@ -51,21 +51,21 @@ void Jit64::SetCRFieldBit(int field, int bit, Gen::X64Reg in)
// New value is 0.
switch (bit)
{
case 0: // !SO, unset bit 61
case CR_SO_BIT: // unset bit 61
MOV(64, R(ABI_PARAM1), Imm64(~(1ull << 61)));
AND(64, R(ABI_PARAM2), R(ABI_PARAM1));
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));
break;
case 2: // !GT, set bit 63
case CR_GT_BIT: // !GT, set bit 63
MOV(64, R(ABI_PARAM1), Imm64(1ull << 63));
OR(64, R(ABI_PARAM2), R(ABI_PARAM1));
break;
case 3: // !LT, unset bit 62
case CR_LT_BIT: // !LT, unset bit 62
MOV(64, R(ABI_PARAM1), Imm64(~(1ull << 62)));
AND(64, R(ABI_PARAM2), R(ABI_PARAM1));
break;
@ -76,22 +76,22 @@ void Jit64::SetCRFieldBit(int field, int bit, Gen::X64Reg in)
switch (bit)
{
case 0: // SO, set bit 61
case CR_SO_BIT: // set bit 61
MOV(64, R(ABI_PARAM1), Imm64(1ull << 61));
OR(64, R(ABI_PARAM2), R(ABI_PARAM1));
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));
AND(64, R(ABI_PARAM2), R(ABI_PARAM1));
break;
case 2: // GT, unset bit 63
case CR_GT_BIT: // unset bit 63
MOV(64, R(ABI_PARAM1), Imm64(~(1ull << 63)));
AND(64, R(ABI_PARAM2), R(ABI_PARAM1));
break;
case 3: // LT, set bit 62
case CR_LT_BIT: // set bit 62
MOV(64, R(ABI_PARAM1), Imm64(1ull << 62));
OR(64, R(ABI_PARAM2), R(ABI_PARAM1));
break;
@ -107,21 +107,21 @@ FixupBranch Jit64::JumpIfCRFieldBit(int field, int bit, bool jump_if_set)
{
switch (bit)
{
case 0: // SO, check bit 61 set
case CR_SO_BIT: // check bit 61 set
MOV(64, R(RAX), Imm64(1ull << 61));
TEST(64, M(&PowerPC::ppcState.cr_val[field]), R(RAX));
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));
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]));
TEST(64, R(RAX), R(RAX));
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));
TEST(64, M(&PowerPC::ppcState.cr_val[field]), R(RAX));
return J_CC(jump_if_set ? CC_NZ : CC_Z, true);
@ -369,19 +369,19 @@ void Jit64::mtcrf(UGeckoInstruction inst)
// EQ
MOV(64, R(tmp), R(EAX));
NOT(64, R(tmp));
AND(64, R(tmp), Imm8(0x2));
AND(64, R(tmp), Imm8(CR_EQ));
OR(64, R(cr_val), R(tmp));
// GT
MOV(64, R(tmp), R(EAX));
NOT(64, R(tmp));
AND(64, R(tmp), Imm8(0x4));
AND(64, R(tmp), Imm8(CR_GT));
SHL(64, R(tmp), Imm8(63 - 2));
OR(64, R(cr_val), R(tmp));
// LT
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));
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
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.
inline u64 PPCCRToInternal(u8 value)
{
u64 cr_val = 0x100000000;
// SO
cr_val |= (u64)!!(value & 1) << 61;
// EQ
cr_val |= (u64)!(value & 2);
// GT
cr_val |= (u64)!(value & 4) << 63;
// LT
cr_val |= (u64)!!(value & 8) << 62;
cr_val |= (u64)!!(value & CR_SO) << 61;
cr_val |= (u64)!(value & CR_EQ);
cr_val |= (u64)!(value & CR_GT) << 63;
cr_val |= (u64)!!(value & CR_LT) << 62;
return cr_val;
}