PowerPC: add enum values for emulator SO and LT shifts

This commit is contained in:
Tillmann Karras 2021-06-28 03:20:22 +01:00
parent 25a701aa1b
commit a68c1bf648
5 changed files with 35 additions and 30 deletions

View File

@ -20,6 +20,9 @@ enum CRBits
CR_EQ_BIT = 1, CR_EQ_BIT = 1,
CR_GT_BIT = 2, CR_GT_BIT = 2,
CR_LT_BIT = 3, CR_LT_BIT = 3,
CR_EMU_SO_BIT = 59,
CR_EMU_LT_BIT = 62,
}; };
// Optimized CR implementation. Instead of storing CR in its PowerPC format // Optimized CR implementation. Instead of storing CR in its PowerPC format
@ -46,10 +49,10 @@ struct ConditionRegister
static u64 PPCToInternal(u8 value) static u64 PPCToInternal(u8 value)
{ {
u64 cr_val = 0x100000000; u64 cr_val = 0x100000000;
cr_val |= (u64) !!(value & CR_SO) << 59; cr_val |= (u64) !!(value & CR_SO) << CR_EMU_SO_BIT;
cr_val |= (u64) !(value & CR_EQ); cr_val |= (u64) !(value & CR_EQ);
cr_val |= (u64) !(value & CR_GT) << 63; cr_val |= (u64) !(value & CR_GT) << 63;
cr_val |= (u64) !!(value & CR_LT) << 62; cr_val |= (u64) !!(value & CR_LT) << CR_EMU_LT_BIT;
return cr_val; return cr_val;
} }
@ -64,7 +67,8 @@ struct ConditionRegister
u32 ppc_cr = 0; u32 ppc_cr = 0;
// LT/SO // LT/SO
ppc_cr |= (cr_val >> 59) & (PowerPC::CR_LT | PowerPC::CR_SO); static_assert(CR_EMU_LT_BIT - CR_EMU_SO_BIT == CR_LT_BIT - CR_SO_BIT);
ppc_cr |= (cr_val >> CR_EMU_SO_BIT) & (PowerPC::CR_LT | PowerPC::CR_SO);
// EQ // EQ
ppc_cr |= ((cr_val & 0xFFFFFFFF) == 0) << PowerPC::CR_EQ_BIT; ppc_cr |= ((cr_val & 0xFFFFFFFF) == 0) << PowerPC::CR_EQ_BIT;
// GT // GT

View File

@ -13,7 +13,8 @@ void Interpreter::Helper_UpdateCR0(u32 value)
{ {
s64 sign_extended = (s64)(s32)value; s64 sign_extended = (s64)(s32)value;
u64 cr_val = (u64)sign_extended; u64 cr_val = (u64)sign_extended;
cr_val = (cr_val & ~(1ull << 59)) | ((u64)PowerPC::GetXER_SO() << 59); cr_val = (cr_val & ~(1ull << PowerPC::CR_EMU_SO_BIT)) |
((u64)PowerPC::GetXER_SO() << PowerPC::CR_EMU_SO_BIT);
PowerPC::ppcState.cr.fields[0] = cr_val; PowerPC::ppcState.cr.fields[0] = cr_val;
} }

View File

@ -25,7 +25,7 @@ void Jit64::GetCRFieldBit(int field, int bit, X64Reg out, bool negate)
switch (bit) switch (bit)
{ {
case PowerPC::CR_SO_BIT: // check bit 59 set case PowerPC::CR_SO_BIT: // check bit 59 set
BT(64, CROffset(field), Imm8(59)); BT(64, CROffset(field), Imm8(PowerPC::CR_EMU_SO_BIT));
SETcc(negate ? CC_NC : CC_C, R(out)); SETcc(negate ? CC_NC : CC_C, R(out));
break; break;
@ -40,7 +40,7 @@ void Jit64::GetCRFieldBit(int field, int bit, X64Reg out, bool negate)
break; break;
case PowerPC::CR_LT_BIT: // check bit 62 set case PowerPC::CR_LT_BIT: // check bit 62 set
BT(64, CROffset(field), Imm8(62)); BT(64, CROffset(field), Imm8(PowerPC::CR_EMU_LT_BIT));
SETcc(negate ? CC_NC : CC_C, R(out)); SETcc(negate ? CC_NC : CC_C, R(out));
break; break;
@ -60,8 +60,8 @@ void Jit64::SetCRFieldBit(int field, int bit, X64Reg in)
switch (bit) switch (bit)
{ {
case PowerPC::CR_SO_BIT: // set bit 59 to input case PowerPC::CR_SO_BIT: // set bit 59 to input
BTR(64, R(RSCRATCH2), Imm8(59)); BTR(64, R(RSCRATCH2), Imm8(PowerPC::CR_EMU_SO_BIT));
SHL(64, R(in), Imm8(59)); SHL(64, R(in), Imm8(PowerPC::CR_EMU_SO_BIT));
OR(64, R(RSCRATCH2), R(in)); OR(64, R(RSCRATCH2), R(in));
break; break;
@ -80,8 +80,8 @@ 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
BTR(64, R(RSCRATCH2), Imm8(62)); BTR(64, R(RSCRATCH2), Imm8(PowerPC::CR_EMU_LT_BIT));
SHL(64, R(in), Imm8(62)); SHL(64, R(in), Imm8(PowerPC::CR_EMU_LT_BIT));
OR(64, R(RSCRATCH2), R(in)); OR(64, R(RSCRATCH2), R(in));
break; break;
} }
@ -95,7 +95,7 @@ void Jit64::ClearCRFieldBit(int field, int bit)
switch (bit) switch (bit)
{ {
case PowerPC::CR_SO_BIT: case PowerPC::CR_SO_BIT:
BTR(64, CROffset(field), Imm8(59)); BTR(64, CROffset(field), Imm8(PowerPC::CR_EMU_SO_BIT));
break; break;
case PowerPC::CR_EQ_BIT: case PowerPC::CR_EQ_BIT:
@ -110,7 +110,7 @@ void Jit64::ClearCRFieldBit(int field, int bit)
break; break;
case PowerPC::CR_LT_BIT: case PowerPC::CR_LT_BIT:
BTR(64, CROffset(field), Imm8(62)); BTR(64, CROffset(field), Imm8(PowerPC::CR_EMU_LT_BIT));
break; break;
} }
// We don't need to set bit 32; the cases where that's needed only come up when setting bits, not // We don't need to set bit 32; the cases where that's needed only come up when setting bits, not
@ -126,7 +126,7 @@ void Jit64::SetCRFieldBit(int field, int bit)
switch (bit) switch (bit)
{ {
case PowerPC::CR_SO_BIT: case PowerPC::CR_SO_BIT:
BTS(64, R(RSCRATCH), Imm8(59)); BTS(64, R(RSCRATCH), Imm8(PowerPC::CR_EMU_SO_BIT));
break; break;
case PowerPC::CR_EQ_BIT: case PowerPC::CR_EQ_BIT:
@ -139,7 +139,7 @@ void Jit64::SetCRFieldBit(int field, int bit)
break; break;
case PowerPC::CR_LT_BIT: case PowerPC::CR_LT_BIT:
BTS(64, R(RSCRATCH), Imm8(62)); BTS(64, R(RSCRATCH), Imm8(PowerPC::CR_EMU_LT_BIT));
break; break;
} }
@ -163,7 +163,7 @@ FixupBranch Jit64::JumpIfCRFieldBit(int field, int bit, bool jump_if_set)
switch (bit) switch (bit)
{ {
case PowerPC::CR_SO_BIT: // check bit 59 set case PowerPC::CR_SO_BIT: // check bit 59 set
BT(64, CROffset(field), Imm8(59)); BT(64, CROffset(field), Imm8(PowerPC::CR_EMU_SO_BIT));
return J_CC(jump_if_set ? CC_C : CC_NC, true); return J_CC(jump_if_set ? CC_C : CC_NC, true);
case PowerPC::CR_EQ_BIT: // check bits 31-0 == 0 case PowerPC::CR_EQ_BIT: // check bits 31-0 == 0
@ -175,7 +175,7 @@ FixupBranch Jit64::JumpIfCRFieldBit(int field, int bit, bool jump_if_set)
return J_CC(jump_if_set ? CC_G : CC_LE, true); return J_CC(jump_if_set ? CC_G : CC_LE, true);
case PowerPC::CR_LT_BIT: // check bit 62 set case PowerPC::CR_LT_BIT: // check bit 62 set
BT(64, CROffset(field), Imm8(62)); BT(64, CROffset(field), Imm8(PowerPC::CR_EMU_LT_BIT));
return J_CC(jump_if_set ? CC_C : CC_NC, true); return J_CC(jump_if_set ? CC_C : CC_NC, true);
default: default:

View File

@ -322,7 +322,7 @@ void CommonAsmRoutines::GenMfcr()
// SO: Bit 59 set; set flag bit 0 // SO: Bit 59 set; set flag bit 0
// LT: Bit 62 set; set flag bit 3 // LT: Bit 62 set; set flag bit 3
SHR(64, R(cr_val), Imm8(59)); SHR(64, R(cr_val), Imm8(PowerPC::CR_EMU_SO_BIT));
AND(32, R(cr_val), Imm8(PowerPC::CR_LT | PowerPC::CR_SO)); AND(32, R(cr_val), Imm8(PowerPC::CR_LT | PowerPC::CR_SO));
OR(32, R(dst), R(cr_val)); OR(32, R(dst), R(cr_val));
} }

View File

@ -22,14 +22,14 @@ FixupBranch JitArm64::JumpIfCRFieldBit(int field, int bit, bool jump_if_set)
switch (bit) switch (bit)
{ {
case PowerPC::CR_SO_BIT: // check bit 59 set case PowerPC::CR_SO_BIT: // check bit 59 set
return jump_if_set ? TBNZ(XA, 59) : TBZ(XA, 59); return jump_if_set ? TBNZ(XA, PowerPC::CR_EMU_SO_BIT) : TBZ(XA, PowerPC::CR_EMU_SO_BIT);
case PowerPC::CR_EQ_BIT: // check bits 31-0 == 0 case PowerPC::CR_EQ_BIT: // check bits 31-0 == 0
return jump_if_set ? CBZ(WA) : CBNZ(WA); return jump_if_set ? CBZ(WA) : CBNZ(WA);
case PowerPC::CR_GT_BIT: // check val > 0 case PowerPC::CR_GT_BIT: // check val > 0
CMP(XA, ARM64Reg::SP); CMP(XA, ARM64Reg::SP);
return B(jump_if_set ? CC_GT : CC_LE); return B(jump_if_set ? CC_GT : CC_LE);
case PowerPC::CR_LT_BIT: // check bit 62 set case PowerPC::CR_LT_BIT: // check bit 62 set
return jump_if_set ? TBNZ(XA, 62) : TBZ(XA, 62); return jump_if_set ? TBNZ(XA, PowerPC::CR_EMU_LT_BIT) : TBZ(XA, PowerPC::CR_EMU_LT_BIT);
default: default:
ASSERT_MSG(DYNA_REC, false, "Invalid CR bit"); ASSERT_MSG(DYNA_REC, false, "Invalid CR bit");
return {}; return {};
@ -441,7 +441,7 @@ void JitArm64::crXXX(UGeckoInstruction inst)
switch (bit) switch (bit)
{ {
case PowerPC::CR_SO_BIT: case PowerPC::CR_SO_BIT:
ANDI2R(XA, XA, ~(u64(1) << 59)); ANDI2R(XA, XA, ~(u64(1) << PowerPC::CR_EMU_SO_BIT));
break; break;
case PowerPC::CR_EQ_BIT: case PowerPC::CR_EQ_BIT:
@ -454,7 +454,7 @@ void JitArm64::crXXX(UGeckoInstruction inst)
break; break;
case PowerPC::CR_LT_BIT: case PowerPC::CR_LT_BIT:
ANDI2R(XA, XA, ~(u64(1) << 62)); ANDI2R(XA, XA, ~(u64(1) << PowerPC::CR_EMU_LT_BIT));
break; break;
} }
return; return;
@ -476,7 +476,7 @@ void JitArm64::crXXX(UGeckoInstruction inst)
switch (bit) switch (bit)
{ {
case PowerPC::CR_SO_BIT: case PowerPC::CR_SO_BIT:
ORRI2R(XA, XA, u64(1) << 59); ORRI2R(XA, XA, u64(1) << PowerPC::CR_EMU_SO_BIT);
break; break;
case PowerPC::CR_EQ_BIT: case PowerPC::CR_EQ_BIT:
@ -488,7 +488,7 @@ void JitArm64::crXXX(UGeckoInstruction inst)
break; break;
case PowerPC::CR_LT_BIT: case PowerPC::CR_LT_BIT:
ORRI2R(XA, XA, u64(1) << 62); ORRI2R(XA, XA, u64(1) << PowerPC::CR_EMU_LT_BIT);
break; break;
} }
@ -520,7 +520,7 @@ void JitArm64::crXXX(UGeckoInstruction inst)
switch (bit) switch (bit)
{ {
case PowerPC::CR_SO_BIT: // check bit 59 set case PowerPC::CR_SO_BIT: // check bit 59 set
UBFX(out, XC, 59, 1); UBFX(out, XC, PowerPC::CR_EMU_SO_BIT, 1);
if (negate) if (negate)
EOR(out, out, 0, 0, true); // XC ^ 1 EOR(out, out, 0, 0, true); // XC ^ 1
break; break;
@ -536,7 +536,7 @@ void JitArm64::crXXX(UGeckoInstruction inst)
break; break;
case PowerPC::CR_LT_BIT: // check bit 62 set case PowerPC::CR_LT_BIT: // check bit 62 set
UBFX(out, XC, 62, 1); UBFX(out, XC, PowerPC::CR_EMU_LT_BIT, 1);
if (negate) if (negate)
EOR(out, out, 0, 0, true); // XC ^ 1 EOR(out, out, 0, 0, true); // XC ^ 1
break; break;
@ -582,7 +582,7 @@ void JitArm64::crXXX(UGeckoInstruction inst)
switch (bit) switch (bit)
{ {
case PowerPC::CR_SO_BIT: // set bit 59 to input case PowerPC::CR_SO_BIT: // set bit 59 to input
BFI(XB, XA, 59, 1); BFI(XB, XA, PowerPC::CR_EMU_SO_BIT, 1);
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
@ -597,7 +597,7 @@ void JitArm64::crXXX(UGeckoInstruction inst)
break; break;
case PowerPC::CR_LT_BIT: // set bit 62 to input case PowerPC::CR_LT_BIT: // set bit 62 to input
BFI(XB, XA, 62, 1); BFI(XB, XA, PowerPC::CR_EMU_LT_BIT, 1);
break; break;
} }
@ -625,11 +625,11 @@ void JitArm64::mfcr(UGeckoInstruction inst)
// SO // SO
if (i == 0) if (i == 0)
{ {
UBFX(XA, CR, 59, 1); UBFX(XA, CR, PowerPC::CR_EMU_SO_BIT, 1);
} }
else else
{ {
UBFX(XC, CR, 59, 1); UBFX(XC, CR, PowerPC::CR_EMU_SO_BIT, 1);
ORR(XA, XC, XA, ArithOption(XA, ShiftType::LSL, 4)); ORR(XA, XC, XA, ArithOption(XA, ShiftType::LSL, 4));
} }
@ -644,7 +644,7 @@ void JitArm64::mfcr(UGeckoInstruction inst)
CSEL(WA, WC, WA, CC_GT); CSEL(WA, WC, WA, CC_GT);
// LT // LT
UBFX(XC, CR, 62, 1); UBFX(XC, CR, PowerPC::CR_EMU_LT_BIT, 1);
ORR(WA, WA, WC, ArithOption(WC, ShiftType::LSL, 3)); ORR(WA, WA, WC, ArithOption(WC, ShiftType::LSL, 3));
} }