mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-24 14:49:42 -06:00
Merge pull request #7113 from lioncash/mask
Gekko: Centralize bitmasking of the FPSCR within UReg_FPSCR
This commit is contained in:
@ -474,8 +474,37 @@ union UReg_FPSCR
|
|||||||
};
|
};
|
||||||
u32 Hex = 0;
|
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;
|
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()
|
void ClearFIFR()
|
||||||
{
|
{
|
||||||
|
@ -62,20 +62,14 @@ void Interpreter::mtfsb0x(UGeckoInstruction inst)
|
|||||||
void Interpreter::mtfsb1x(UGeckoInstruction inst)
|
void Interpreter::mtfsb1x(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
const u32 bit = inst.CRBD;
|
const u32 bit = inst.CRBD;
|
||||||
|
const u32 b = 0x80000000 >> bit;
|
||||||
|
|
||||||
// Bit 20 in the FPSCR is reserved and defined as zero,
|
if (b & FPSCR_ANY_X)
|
||||||
// so we ensure that we don't set it.
|
SetFPException(b);
|
||||||
if (bit != 20)
|
else
|
||||||
{
|
FPSCR |= b;
|
||||||
const u32 b = 0x80000000 >> bit;
|
|
||||||
|
|
||||||
if (b & FPSCR_ANY_X)
|
FPSCRtoFPUSettings(FPSCR);
|
||||||
SetFPException(b);
|
|
||||||
else
|
|
||||||
FPSCR.Hex |= b;
|
|
||||||
|
|
||||||
FPSCRtoFPUSettings(FPSCR);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inst.Rc)
|
if (inst.Rc)
|
||||||
Helper_UpdateCR1();
|
Helper_UpdateCR1();
|
||||||
@ -83,14 +77,12 @@ void Interpreter::mtfsb1x(UGeckoInstruction inst)
|
|||||||
|
|
||||||
void Interpreter::mtfsfix(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 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 mask = (pre_shifted_mask >> (4 * field));
|
||||||
const u32 imm = (inst.hex << 16) & pre_shifted_mask;
|
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);
|
FPSCRtoFPUSettings(FPSCR);
|
||||||
|
|
||||||
@ -108,13 +100,7 @@ void Interpreter::mtfsfx(UGeckoInstruction inst)
|
|||||||
m |= (0xFU << (i * 4));
|
m |= (0xFU << (i * 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bit 20 of the FPSCR is defined as always being zero
|
FPSCR = (FPSCR.Hex & ~m) | (static_cast<u32>(riPS0(inst.FB)) & m);
|
||||||
// (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);
|
|
||||||
FPSCRtoFPUSettings(FPSCR);
|
FPSCRtoFPUSettings(FPSCR);
|
||||||
|
|
||||||
if (inst.Rc)
|
if (inst.Rc)
|
||||||
|
@ -290,7 +290,7 @@ void RegisterWidget::PopulateTable()
|
|||||||
|
|
||||||
// FPSCR
|
// FPSCR
|
||||||
AddRegister(22, 5, RegisterType::fpscr, "FPSCR", [] { return PowerPC::ppcState.fpscr.Hex; },
|
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
|
// MSR
|
||||||
AddRegister(23, 5, RegisterType::msr, "MSR", [] { return PowerPC::ppcState.msr.Hex; },
|
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));
|
PowerPC::SetXER(UReg_XER(value));
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
PowerPC::ppcState.fpscr.Hex = value;
|
PowerPC::ppcState.fpscr = value;
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
PowerPC::ppcState.msr.Hex = value;
|
PowerPC::ppcState.msr.Hex = value;
|
||||||
|
Reference in New Issue
Block a user