Merge pull request #6878 from lioncash/type

PowerPC/Interpreter: Avoid sign conversion with utility functions
This commit is contained in:
Markus Wick 2018-05-17 10:04:26 +02:00 committed by GitHub
commit 3e6a706858
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 41 additions and 39 deletions

View File

@ -37,9 +37,9 @@ void Interpreter::bcx(UGeckoInstruction inst)
const bool true_false = ((inst.BO >> 3) & 1); const bool true_false = ((inst.BO >> 3) & 1);
const bool only_counter_check = ((inst.BO >> 4) & 1); const bool only_counter_check = ((inst.BO >> 4) & 1);
const bool only_condition_check = ((inst.BO >> 2) & 1); const bool only_condition_check = ((inst.BO >> 2) & 1);
int ctr_check = ((CTR != 0) ^ (inst.BO >> 1)) & 1; const u32 ctr_check = ((CTR != 0) ^ (inst.BO >> 1)) & 1;
bool counter = only_condition_check || ctr_check; const bool counter = only_condition_check || ctr_check;
bool condition = only_counter_check || (PowerPC::GetCRBit(inst.BI) == u32(true_false)); const bool condition = only_counter_check || (PowerPC::GetCRBit(inst.BI) == u32(true_false));
if (counter && condition) if (counter && condition)
{ {
@ -78,7 +78,8 @@ void Interpreter::bcctrx(UGeckoInstruction inst)
DEBUG_ASSERT_MSG(POWERPC, inst.BO_2 & BO_DONT_DECREMENT_FLAG, DEBUG_ASSERT_MSG(POWERPC, inst.BO_2 & BO_DONT_DECREMENT_FLAG,
"bcctrx with decrement and test CTR option is invalid!"); "bcctrx with decrement and test CTR option is invalid!");
int condition = ((inst.BO_2 >> 4) | (PowerPC::GetCRBit(inst.BI_2) == ((inst.BO_2 >> 3) & 1))) & 1; const u32 condition =
((inst.BO_2 >> 4) | (PowerPC::GetCRBit(inst.BI_2) == ((inst.BO_2 >> 3) & 1))) & 1;
if (condition) if (condition)
{ {
@ -95,8 +96,9 @@ void Interpreter::bclrx(UGeckoInstruction inst)
if ((inst.BO_2 & BO_DONT_DECREMENT_FLAG) == 0) if ((inst.BO_2 & BO_DONT_DECREMENT_FLAG) == 0)
CTR--; CTR--;
int counter = ((inst.BO_2 >> 2) | ((CTR != 0) ^ (inst.BO_2 >> 1))) & 1; const u32 counter = ((inst.BO_2 >> 2) | ((CTR != 0) ^ (inst.BO_2 >> 1))) & 1;
int condition = ((inst.BO_2 >> 4) | (PowerPC::GetCRBit(inst.BI_2) == ((inst.BO_2 >> 3) & 1))) & 1; const u32 condition =
((inst.BO_2 >> 4) | (PowerPC::GetCRBit(inst.BI_2) == ((inst.BO_2 >> 3) & 1))) & 1;
if (counter & condition) if (counter & condition)
{ {

View File

@ -83,9 +83,9 @@ void Interpreter::andis_rc(UGeckoInstruction inst)
void Interpreter::cmpi(UGeckoInstruction inst) void Interpreter::cmpi(UGeckoInstruction inst)
{ {
s32 a = rGPR[inst.RA]; const s32 a = static_cast<s32>(rGPR[inst.RA]);
s32 b = inst.SIMM_16; const s32 b = inst.SIMM_16;
int f; u32 f;
if (a < b) if (a < b)
f = 0x8; f = 0x8;
@ -102,9 +102,9 @@ void Interpreter::cmpi(UGeckoInstruction inst)
void Interpreter::cmpli(UGeckoInstruction inst) void Interpreter::cmpli(UGeckoInstruction inst)
{ {
u32 a = rGPR[inst.RA]; const u32 a = rGPR[inst.RA];
u32 b = inst.UIMM; const u32 b = inst.UIMM;
int f; u32 f;
if (a < b) if (a < b)
f = 0x8; f = 0x8;
@ -213,40 +213,40 @@ void Interpreter::andcx(UGeckoInstruction inst)
void Interpreter::cmp(UGeckoInstruction inst) void Interpreter::cmp(UGeckoInstruction inst)
{ {
s32 a = (s32)rGPR[inst.RA]; const s32 a = static_cast<s32>(rGPR[inst.RA]);
s32 b = (s32)rGPR[inst.RB]; const s32 b = static_cast<s32>(rGPR[inst.RB]);
int fTemp; u32 temp;
if (a < b) if (a < b)
fTemp = 0x8; temp = 0x8;
else if (a > b) else if (a > b)
fTemp = 0x4; temp = 0x4;
else // Equals else // Equals
fTemp = 0x2; temp = 0x2;
if (PowerPC::GetXER_SO()) if (PowerPC::GetXER_SO())
fTemp |= 0x1; temp |= 0x1;
PowerPC::SetCRField(inst.CRFD, fTemp); PowerPC::SetCRField(inst.CRFD, temp);
} }
void Interpreter::cmpl(UGeckoInstruction inst) void Interpreter::cmpl(UGeckoInstruction inst)
{ {
u32 a = rGPR[inst.RA]; const u32 a = rGPR[inst.RA];
u32 b = rGPR[inst.RB]; const u32 b = rGPR[inst.RB];
u32 fTemp; u32 temp;
if (a < b) if (a < b)
fTemp = 0x8; temp = 0x8;
else if (a > b) else if (a > b)
fTemp = 0x4; temp = 0x4;
else // Equals else // Equals
fTemp = 0x2; temp = 0x2;
if (PowerPC::GetXER_SO()) if (PowerPC::GetXER_SO())
fTemp |= 0x1; temp |= 0x1;
PowerPC::SetCRField(inst.CRFD, fTemp); PowerPC::SetCRField(inst.CRFD, temp);
} }
void Interpreter::cntlzwx(UGeckoInstruction inst) void Interpreter::cntlzwx(UGeckoInstruction inst)

View File

@ -447,7 +447,7 @@ void Interpreter::crxor(UGeckoInstruction inst)
void Interpreter::mcrf(UGeckoInstruction inst) void Interpreter::mcrf(UGeckoInstruction inst)
{ {
int cr_f = PowerPC::GetCRField(inst.CRFS); const u32 cr_f = PowerPC::GetCRField(inst.CRFS);
PowerPC::SetCRField(inst.CRFD, cr_f); PowerPC::SetCRField(inst.CRFD, cr_f);
} }

View File

@ -47,7 +47,7 @@ static void InvalidateCacheThreadSafe(u64 userdata, s64 cyclesLate)
u32 CompactCR() u32 CompactCR()
{ {
u32 new_cr = 0; u32 new_cr = 0;
for (int i = 0; i < 8; i++) for (u32 i = 0; i < 8; i++)
{ {
new_cr |= GetCRField(i) << (28 - i * 4); new_cr |= GetCRField(i) << (28 - i * 4);
} }
@ -56,7 +56,7 @@ u32 CompactCR()
void ExpandCR(u32 cr) void ExpandCR(u32 cr)
{ {
for (int i = 0; i < 8; i++) for (u32 i = 0; i < 8; i++)
{ {
SetCRField(i, (cr >> (28 - i * 4)) & 0xF); SetCRField(i, (cr >> (28 - i * 4)) & 0xF);
} }

View File

@ -347,14 +347,14 @@ extern const std::array<u64, 16> m_crTable;
// Warning: these CR operations are fairly slow since they need to convert from // Warning: these CR operations are fairly slow since they need to convert from
// PowerPC format (4 bit) to our internal 64 bit format. See the definition of // PowerPC format (4 bit) to our internal 64 bit format. See the definition of
// ppcState.cr_val for more explanations. // ppcState.cr_val for more explanations.
inline void SetCRField(int cr_field, int value) inline void SetCRField(u32 cr_field, u32 value)
{ {
PowerPC::ppcState.cr_val[cr_field] = m_crTable[value]; PowerPC::ppcState.cr_val[cr_field] = m_crTable[value];
} }
inline u32 GetCRField(int cr_field) inline u32 GetCRField(u32 cr_field)
{ {
u64 cr_val = PowerPC::ppcState.cr_val[cr_field]; const u64 cr_val = PowerPC::ppcState.cr_val[cr_field];
u32 ppc_cr = 0; u32 ppc_cr = 0;
// SO // SO
@ -362,19 +362,19 @@ inline u32 GetCRField(int cr_field)
// EQ // EQ
ppc_cr |= ((cr_val & 0xFFFFFFFF) == 0) << 1; ppc_cr |= ((cr_val & 0xFFFFFFFF) == 0) << 1;
// GT // GT
ppc_cr |= ((s64)cr_val > 0) << 2; ppc_cr |= (static_cast<s64>(cr_val) > 0) << 2;
// LT // LT
ppc_cr |= !!(cr_val & (1ull << 62)) << 3; ppc_cr |= !!(cr_val & (1ull << 62)) << 3;
return ppc_cr; return ppc_cr;
} }
inline u32 GetCRBit(int bit) inline u32 GetCRBit(u32 bit)
{ {
return (GetCRField(bit >> 2) >> (3 - (bit & 3))) & 1; return (GetCRField(bit >> 2) >> (3 - (bit & 3))) & 1;
} }
inline void SetCRBit(int bit, int value) inline void SetCRBit(u32 bit, u32 value)
{ {
if (value & 1) if (value & 1)
SetCRField(bit >> 2, GetCRField(bit >> 2) | (0x8 >> (bit & 3))); SetCRField(bit >> 2, GetCRField(bit >> 2) | (0x8 >> (bit & 3)));
@ -393,12 +393,12 @@ inline u32 GetCR()
return PowerPC::CompactCR(); return PowerPC::CompactCR();
} }
inline void SetCarry(int ca) inline void SetCarry(u32 ca)
{ {
PowerPC::ppcState.xer_ca = ca; PowerPC::ppcState.xer_ca = ca;
} }
inline int GetCarry() inline u32 GetCarry()
{ {
return PowerPC::ppcState.xer_ca; return PowerPC::ppcState.xer_ca;
} }