mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-07 15:40:18 +00:00
Gekko: Centralize bitmasking of the FPSCR within UReg_FPSCR
Rather than introduce this handling in every system instruction that modifies the FPSCR directly, we can instead just handle it within the data structure instead, which avoids duplicating mask handling across instructions. This also allows handling proper masking from the debugger register windows themselves without duplicating masking behavior there either.
This commit is contained in:
parent
8a3679bebc
commit
0049ef3a2a
@ -474,8 +474,37 @@ union UReg_FPSCR
|
||||
};
|
||||
u32 Hex = 0;
|
||||
|
||||
// The FPSCR's 20th bit (11th from a little endian perspective)
|
||||
// is defined as reserved and set to zero. Attempts to modify it
|
||||
// are ignored by hardware, so we do the same.
|
||||
static constexpr u32 mask = 0xFFFFF7FF;
|
||||
|
||||
UReg_FPSCR() = default;
|
||||
explicit UReg_FPSCR(u32 hex_) : Hex{hex_} {}
|
||||
explicit UReg_FPSCR(u32 hex_) : Hex{hex_ & mask} {}
|
||||
|
||||
UReg_FPSCR& operator=(u32 value)
|
||||
{
|
||||
Hex = value & mask;
|
||||
return *this;
|
||||
}
|
||||
|
||||
UReg_FPSCR& operator|=(u32 value)
|
||||
{
|
||||
Hex |= value & mask;
|
||||
return *this;
|
||||
}
|
||||
|
||||
UReg_FPSCR& operator&=(u32 value)
|
||||
{
|
||||
Hex &= value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
UReg_FPSCR& operator^=(u32 value)
|
||||
{
|
||||
Hex ^= value & mask;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void ClearFIFR()
|
||||
{
|
||||
|
@ -62,20 +62,14 @@ void Interpreter::mtfsb0x(UGeckoInstruction inst)
|
||||
void Interpreter::mtfsb1x(UGeckoInstruction inst)
|
||||
{
|
||||
const u32 bit = inst.CRBD;
|
||||
const u32 b = 0x80000000 >> bit;
|
||||
|
||||
// Bit 20 in the FPSCR is reserved and defined as zero,
|
||||
// so we ensure that we don't set it.
|
||||
if (bit != 20)
|
||||
{
|
||||
const u32 b = 0x80000000 >> bit;
|
||||
if (b & FPSCR_ANY_X)
|
||||
SetFPException(b);
|
||||
else
|
||||
FPSCR |= b;
|
||||
|
||||
if (b & FPSCR_ANY_X)
|
||||
SetFPException(b);
|
||||
else
|
||||
FPSCR.Hex |= b;
|
||||
|
||||
FPSCRtoFPUSettings(FPSCR);
|
||||
}
|
||||
FPSCRtoFPUSettings(FPSCR);
|
||||
|
||||
if (inst.Rc)
|
||||
Helper_UpdateCR1();
|
||||
@ -83,14 +77,12 @@ void Interpreter::mtfsb1x(UGeckoInstruction inst)
|
||||
|
||||
void Interpreter::mtfsfix(UGeckoInstruction inst)
|
||||
{
|
||||
// Bit 20 of the FPSCR is reserved and defined as zero on hardware,
|
||||
// so ensure that we don't set it.
|
||||
const u32 field = inst.CRFD;
|
||||
const u32 pre_shifted_mask = field == 4 ? 0x70000000 : 0xF0000000;
|
||||
const u32 pre_shifted_mask = 0xF0000000;
|
||||
const u32 mask = (pre_shifted_mask >> (4 * field));
|
||||
const u32 imm = (inst.hex << 16) & pre_shifted_mask;
|
||||
|
||||
FPSCR.Hex = (FPSCR.Hex & ~mask) | (imm >> (4 * field));
|
||||
FPSCR = (FPSCR.Hex & ~mask) | (imm >> (4 * field));
|
||||
|
||||
FPSCRtoFPUSettings(FPSCR);
|
||||
|
||||
@ -108,13 +100,7 @@ void Interpreter::mtfsfx(UGeckoInstruction inst)
|
||||
m |= (0xFU << (i * 4));
|
||||
}
|
||||
|
||||
// Bit 20 of the FPSCR is defined as always being zero
|
||||
// (bit 11 in a little endian context), so ensure that
|
||||
// we don't actually set that bit.
|
||||
if ((fm & 0b100) != 0)
|
||||
m &= 0xFFFFF7FF;
|
||||
|
||||
FPSCR.Hex = (FPSCR.Hex & ~m) | (static_cast<u32>(riPS0(inst.FB)) & m);
|
||||
FPSCR = (FPSCR.Hex & ~m) | (static_cast<u32>(riPS0(inst.FB)) & m);
|
||||
FPSCRtoFPUSettings(FPSCR);
|
||||
|
||||
if (inst.Rc)
|
||||
|
@ -290,7 +290,7 @@ void RegisterWidget::PopulateTable()
|
||||
|
||||
// FPSCR
|
||||
AddRegister(22, 5, RegisterType::fpscr, "FPSCR", [] { return PowerPC::ppcState.fpscr.Hex; },
|
||||
[](u64 value) { PowerPC::ppcState.fpscr.Hex = value; });
|
||||
[](u64 value) { PowerPC::ppcState.fpscr = static_cast<u32>(value); });
|
||||
|
||||
// MSR
|
||||
AddRegister(23, 5, RegisterType::msr, "MSR", [] { return PowerPC::ppcState.msr.Hex; },
|
||||
|
@ -124,7 +124,7 @@ void SetSpecialRegValue(int reg, u32 value)
|
||||
PowerPC::SetXER(UReg_XER(value));
|
||||
break;
|
||||
case 5:
|
||||
PowerPC::ppcState.fpscr.Hex = value;
|
||||
PowerPC::ppcState.fpscr = value;
|
||||
break;
|
||||
case 6:
|
||||
PowerPC::ppcState.msr.Hex = value;
|
||||
|
Loading…
x
Reference in New Issue
Block a user