Merge pull request #6760 from lioncash/msr

PowerPC: Make the PowerPCState's msr member variable a UReg_MSR instance
This commit is contained in:
Léo Lam 2018-05-06 12:02:39 +02:00 committed by GitHub
commit 3f087e2ed5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 105 additions and 107 deletions

View File

@ -269,10 +269,9 @@ bool CBoot::Load_BS2(const std::string& boot_rom_filename)
PowerPC::ppcState.gpr[4] = 0x00002030;
PowerPC::ppcState.gpr[5] = 0x0000009c;
UReg_MSR& m_MSR = ((UReg_MSR&)PowerPC::ppcState.msr);
m_MSR.FP = 1;
m_MSR.DR = 1;
m_MSR.IR = 1;
MSR.FP = 1;
MSR.DR = 1;
MSR.IR = 1;
PowerPC::ppcState.spr[SPR_HID0] = 0x0011c464;
PowerPC::ppcState.spr[SPR_IBAT3U] = 0xfff0001f;

View File

@ -55,11 +55,10 @@ void CBoot::RunFunction(u32 address)
void CBoot::SetupMSR()
{
UReg_MSR& m_MSR = ((UReg_MSR&)PowerPC::ppcState.msr);
m_MSR.FP = 1;
m_MSR.DR = 1;
m_MSR.IR = 1;
m_MSR.EE = 1;
MSR.FP = 1;
MSR.DR = 1;
MSR.IR = 1;
MSR.EE = 1;
}
void CBoot::SetupBAT(bool is_wii)

View File

@ -428,7 +428,7 @@ void FifoPlayer::LoadMemory()
UReg_MSR newMSR;
newMSR.DR = 1;
newMSR.IR = 1;
MSR = newMSR.Hex;
MSR.Hex = newMSR.Hex;
PowerPC::ppcState.spr[SPR_IBAT0U] = 0x80001fff;
PowerPC::ppcState.spr[SPR_IBAT0L] = 0x00000002;
PowerPC::ppcState.spr[SPR_DBAT0U] = 0x80001fff;

View File

@ -284,7 +284,7 @@ bool Kernel::BootstrapPPC(const std::string& boot_content_path)
// NAND titles start with address translation off at 0x3400 (via the PPC bootstub)
// The state of other CPU registers (like the BAT registers) doesn't matter much
// because the realmode code at 0x3400 initializes everything itself anyway.
MSR = 0;
MSR.Hex = 0;
PC = 0x3400;
return true;

View File

@ -65,7 +65,7 @@ bool Load()
const PowerPC::CoreMode core_mode = PowerPC::GetMode();
PowerPC::SetMode(PowerPC::CoreMode::Interpreter);
MSR = 0;
MSR.Hex = 0;
PC = 0x3400;
NOTICE_LOG(IOS, "Loaded MIOS and bootstrapped PPC.");

View File

@ -196,7 +196,7 @@ static void ApplyPatches(const std::vector<Patch>& patches)
// We require at least 2 stack frames, if the stack is shallower than that then it won't work.
static bool IsStackSane()
{
DEBUG_ASSERT(UReg_MSR(MSR).DR && UReg_MSR(MSR).IR);
DEBUG_ASSERT(MSR.DR && MSR.IR);
// Check the stack pointer
u32 SP = GPR(1);
@ -220,13 +220,12 @@ bool ApplyFramePatches()
// callback hook we can end up catching the game in an exception vector.
// We deal with this by returning false so that SystemTimers will reschedule us in a few cycles
// where we can try again after the CPU hopefully returns back to the normal instruction flow.
UReg_MSR msr = MSR;
if (!msr.DR || !msr.IR || !IsStackSane())
if (!MSR.DR || !MSR.IR || !IsStackSane())
{
DEBUG_LOG(
ACTIONREPLAY,
"Need to retry later. CPU configuration is currently incorrect. PC = 0x%08X, MSR = 0x%08X",
PC, MSR);
PC, MSR.Hex);
return false;
}

View File

@ -150,8 +150,7 @@ static void WriteBrokenBlockNPC(UGeckoInstruction data)
static bool CheckFPU(u32 data)
{
UReg_MSR msr{MSR};
if (!msr.FP)
if (!MSR.FP)
{
PowerPC::ppcState.Exceptions |= EXCEPTION_FPU_UNAVAILABLE;
PowerPC::CheckExceptions();

View File

@ -446,7 +446,7 @@ static void gdb_read_register()
wbe32hex(reply, PC);
break;
case 65:
wbe32hex(reply, MSR);
wbe32hex(reply, MSR.Hex);
break;
case 66:
wbe32hex(reply, PowerPC::GetCR());
@ -531,7 +531,7 @@ static void gdb_write_register()
PC = re32hex(bufptr);
break;
case 65:
MSR = re32hex(bufptr);
MSR.Hex = re32hex(bufptr);
break;
case 66:
PowerPC::SetCR(re32hex(bufptr));

View File

@ -378,7 +378,7 @@ union UReg_MSR
u32 Hex = 0;
UReg_MSR() = default;
UReg_MSR(u32 hex_) : Hex{hex_} {}
explicit UReg_MSR(u32 hex_) : Hex{hex_} {}
};
#define FPRF_SHIFT 12

View File

@ -96,8 +96,7 @@ static void Trace(UGeckoInstruction& inst)
"INTER PC: %08x SRR0: %08x SRR1: %08x CRval: %016lx FPSCR: %08x MSR: %08x LR: "
"%08x %s %08x %s",
PC, SRR0, SRR1, (unsigned long)PowerPC::ppcState.cr_val[0], PowerPC::ppcState.fpscr,
PowerPC::ppcState.msr, PowerPC::ppcState.spr[8], regs.c_str(), inst.hex,
ppc_inst.c_str());
MSR.Hex, PowerPC::ppcState.spr[8], regs.c_str(), inst.hex, ppc_inst.c_str());
}
int Interpreter::SingleStepInner()
@ -153,8 +152,7 @@ int Interpreter::SingleStepInner()
if (m_prev_inst.hex != 0)
{
const UReg_MSR msr{MSR};
if (msr.FP) // If FPU is enabled, just execute
if (MSR.FP) // If FPU is enabled, just execute
{
m_op_table[m_prev_inst.OPCD](m_prev_inst);
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)

View File

@ -119,9 +119,9 @@ void Interpreter::rfi(UGeckoInstruction inst)
// Restore saved bits from SRR1 to MSR.
// Gecko/Broadway can save more bits than explicitly defined in ppc spec
const int mask = 0x87C0FFFF;
MSR = (MSR & ~mask) | (SRR1 & mask);
MSR.Hex = (MSR.Hex & ~mask) | (SRR1 & mask);
// MSR[13] is set to 0.
MSR &= 0xFFFBFFFF;
MSR.Hex &= 0xFFFBFFFF;
// Here we should check if there are pending exceptions, and if their corresponding enable bits
// are set
// if above is true, we'd do:

View File

@ -278,7 +278,7 @@ void Interpreter::lmw(UGeckoInstruction inst)
{
u32 address = Helper_Get_EA(inst);
if ((address & 0b11) != 0 || UReg_MSR{MSR}.LE)
if ((address & 0b11) != 0 || MSR.LE)
{
GenerateAlignmentException(address);
return;
@ -306,7 +306,7 @@ void Interpreter::stmw(UGeckoInstruction inst)
{
u32 address = Helper_Get_EA(inst);
if ((address & 0b11) != 0 || UReg_MSR{MSR}.LE)
if ((address & 0b11) != 0 || MSR.LE)
{
GenerateAlignmentException(address);
return;
@ -685,7 +685,7 @@ void Interpreter::lswx(UGeckoInstruction inst)
{
u32 EA = Helper_Get_EA_X(inst);
if (UReg_MSR{MSR}.LE)
if (MSR.LE)
{
GenerateAlignmentException(EA);
return;
@ -867,7 +867,7 @@ void Interpreter::lswi(UGeckoInstruction inst)
else
EA = rGPR[inst.RA];
if (UReg_MSR{MSR}.LE)
if (MSR.LE)
{
GenerateAlignmentException(EA);
return;
@ -918,7 +918,7 @@ void Interpreter::stswi(UGeckoInstruction inst)
else
EA = rGPR[inst.RA];
if (UReg_MSR{MSR}.LE)
if (MSR.LE)
{
GenerateAlignmentException(EA);
return;
@ -958,7 +958,7 @@ void Interpreter::stswx(UGeckoInstruction inst)
{
u32 EA = Helper_Get_EA_X(inst);
if (UReg_MSR{MSR}.LE)
if (MSR.LE)
{
GenerateAlignmentException(EA);
return;

View File

@ -136,7 +136,7 @@ void Interpreter::mtcrf(UGeckoInstruction inst)
void Interpreter::mfmsr(UGeckoInstruction inst)
{
// Privileged?
rGPR[inst.RD] = MSR;
rGPR[inst.RD] = MSR.Hex;
}
void Interpreter::mfsr(UGeckoInstruction inst)
@ -153,7 +153,7 @@ void Interpreter::mfsrin(UGeckoInstruction inst)
void Interpreter::mtmsr(UGeckoInstruction inst)
{
// Privileged?
MSR = rGPR[inst.RS];
MSR.Hex = rGPR[inst.RS];
PowerPC::CheckExceptions();
m_end_block = true;
}

View File

@ -565,8 +565,8 @@ void Jit64::Trace()
#endif
DEBUG_LOG(DYNA_REC, "JIT64 PC: %08x SRR0: %08x SRR1: %08x FPSCR: %08x MSR: %08x LR: %08x %s %s",
PC, SRR0, SRR1, PowerPC::ppcState.fpscr, PowerPC::ppcState.msr,
PowerPC::ppcState.spr[8], regs.c_str(), fregs.c_str());
PC, SRR0, SRR1, PowerPC::ppcState.fpscr, MSR.Hex, PowerPC::ppcState.spr[8],
regs.c_str(), fregs.c_str());
}
void Jit64::Jit(u32 em_address)

View File

@ -342,7 +342,7 @@ void Jit64::dcbz(UGeckoInstruction inst)
ADD(32, R(RSCRATCH), gpr.R(a));
AND(32, R(RSCRATCH), Imm32(~31));
if (UReg_MSR(MSR).DR)
if (MSR.DR)
{
// Perform lookup to see if we can use fast path.
MOV(64, R(RSCRATCH2), ImmPtr(&PowerPC::dbat_table[0]));
@ -367,7 +367,7 @@ void Jit64::dcbz(UGeckoInstruction inst)
ABI_CallFunctionR(PowerPC::ClearCacheLine, RSCRATCH);
ABI_PopRegistersAndAdjustStack(registersInUse, 0);
if (UReg_MSR(MSR).DR)
if (MSR.DR)
{
FixupBranch end = J(true);
SwitchToNearCode();

View File

@ -24,7 +24,7 @@ void Jit64::psq_stXX(UGeckoInstruction inst)
JITDISABLE(bJITLoadStorePairedOff);
// For performance, the AsmCommon routines assume address translation is on.
FALLBACK_IF(!UReg_MSR(MSR).DR);
FALLBACK_IF(!MSR.DR);
s32 offset = inst.SIMM_12;
bool indexed = inst.OPCD == 4;
@ -114,7 +114,7 @@ void Jit64::psq_lXX(UGeckoInstruction inst)
JITDISABLE(bJITLoadStorePairedOff);
// For performance, the AsmCommon routines assume address translation is on.
FALLBACK_IF(!UReg_MSR(MSR).DR);
FALLBACK_IF(!MSR.DR);
s32 offset = inst.SIMM_12;
bool indexed = inst.OPCD == 4;

View File

@ -364,8 +364,8 @@ void EmuCodeBlock::SafeLoadToReg(X64Reg reg_value, const Gen::OpArg& opAddress,
}
FixupBranch exit;
bool dr_set = (flags & SAFE_LOADSTORE_DR_ON) || UReg_MSR(MSR).DR;
bool fast_check_address = !slowmem && dr_set;
const bool dr_set = (flags & SAFE_LOADSTORE_DR_ON) || MSR.DR;
const bool fast_check_address = !slowmem && dr_set;
if (fast_check_address)
{
FixupBranch slow = CheckIfSafeAddress(R(reg_value), reg_addr, registersInUse);
@ -526,8 +526,8 @@ void EmuCodeBlock::SafeWriteRegToReg(OpArg reg_value, X64Reg reg_addr, int acces
}
FixupBranch exit;
bool dr_set = (flags & SAFE_LOADSTORE_DR_ON) || UReg_MSR(MSR).DR;
bool fast_check_address = !slowmem && dr_set;
const bool dr_set = (flags & SAFE_LOADSTORE_DR_ON) || MSR.DR;
const bool fast_check_address = !slowmem && dr_set;
if (fast_check_address)
{
FixupBranch slow = CheckIfSafeAddress(reg_value, reg_addr, registersInUse);

View File

@ -23,7 +23,7 @@ void JitArm64::psq_l(UGeckoInstruction inst)
FALLBACK_IF(jo.memcheck || !jo.fastmem);
// The asm routines assume address translation is on.
FALLBACK_IF(!UReg_MSR(MSR).DR);
FALLBACK_IF(!MSR.DR);
// X30 is LR
// X0 contains the scale
@ -106,7 +106,7 @@ void JitArm64::psq_st(UGeckoInstruction inst)
FALLBACK_IF(jo.memcheck || !jo.fastmem);
// The asm routines assume address translation is on.
FALLBACK_IF(!UReg_MSR(MSR).DR);
FALLBACK_IF(!MSR.DR);
// X30 is LR
// X0 contains the scale

View File

@ -51,6 +51,6 @@ bool JitBase::CanMergeNextInstructions(int count) const
void JitBase::UpdateMemoryOptions()
{
bool any_watchpoints = PowerPC::memchecks.HasAny();
jo.fastmem = SConfig::GetInstance().bFastmem && (UReg_MSR(MSR).DR || !any_watchpoints);
jo.fastmem = SConfig::GetInstance().bFastmem && (MSR.DR || !any_watchpoints);
jo.memcheck = SConfig::GetInstance().bMMU || any_watchpoints;
}

View File

@ -100,7 +100,7 @@ JitBlock* JitBaseBlockCache::AllocateBlock(u32 em_address)
JitBlock& b = block_map.emplace(physicalAddress, JitBlock())->second;
b.effectiveAddress = em_address;
b.physicalAddress = physicalAddress;
b.msrBits = MSR & JIT_CACHE_MSR_MASK;
b.msrBits = MSR.Hex & JIT_CACHE_MSR_MASK;
b.linkData.clear();
b.fast_block_map_index = 0;
return &b;
@ -174,8 +174,8 @@ const u8* JitBaseBlockCache::Dispatch()
{
JitBlock* block = fast_block_map[FastLookupIndexForAddress(PC)];
if (!block || block->effectiveAddress != PC || block->msrBits != (MSR & JIT_CACHE_MSR_MASK))
block = MoveBlockIntoFastCache(PC, MSR & JIT_CACHE_MSR_MASK);
if (!block || block->effectiveAddress != PC || block->msrBits != (MSR.Hex & JIT_CACHE_MSR_MASK))
block = MoveBlockIntoFastCache(PC, MSR.Hex & JIT_CACHE_MSR_MASK);
if (!block)
return nullptr;

View File

@ -141,12 +141,12 @@ int GetHostCode(u32* address, const u8** code, u32* code_size)
return 1;
}
JitBlock* block = g_jit->GetBlockCache()->GetBlockFromStartAddress(*address, MSR);
JitBlock* block = g_jit->GetBlockCache()->GetBlockFromStartAddress(*address, MSR.Hex);
if (!block)
{
for (int i = 0; i < 500; i++)
{
block = g_jit->GetBlockCache()->GetBlockFromStartAddress(*address - 4 * i, MSR);
block = g_jit->GetBlockCache()->GetBlockFromStartAddress(*address - 4 * i, MSR.Hex);
if (block)
break;
}

View File

@ -168,7 +168,7 @@ static void GenerateDSIException(u32 _EffectiveAddress, bool _bWrite);
template <XCheckTLBFlag flag, typename T, bool never_translate = false>
static T ReadFromHardware(u32 em_address)
{
if (!never_translate && UReg_MSR(MSR).DR)
if (!never_translate && MSR.DR)
{
auto translated_addr = TranslateAddress<flag>(em_address);
if (!translated_addr.Success())
@ -256,7 +256,7 @@ static T ReadFromHardware(u32 em_address)
template <XCheckTLBFlag flag, typename T, bool never_translate = false>
static void WriteToHardware(u32 em_address, const T data)
{
if (!never_translate && UReg_MSR(MSR).DR)
if (!never_translate && MSR.DR)
{
auto translated_addr = TranslateAddress<flag>(em_address);
if (!translated_addr.Success())
@ -393,7 +393,7 @@ u32 Read_Opcode(u32 address)
TryReadInstResult TryReadInstruction(u32 address)
{
bool from_bat = true;
if (UReg_MSR(MSR).IR)
if (MSR.IR)
{
auto tlb_addr = TranslateAddress<XCheckTLBFlag::Opcode>(address);
if (!tlb_addr.Success())
@ -658,7 +658,7 @@ bool IsOptimizableRAMAddress(const u32 address)
if (PowerPC::memchecks.HasAny())
return false;
if (!UReg_MSR(MSR).DR)
if (!MSR.DR)
return false;
// TODO: This API needs to take an access size
@ -694,14 +694,13 @@ static bool IsRAMAddress(u32 address, bool translate)
bool HostIsRAMAddress(u32 address)
{
return IsRAMAddress<XCheckTLBFlag::NoException>(address, UReg_MSR(MSR).DR);
return IsRAMAddress<XCheckTLBFlag::NoException>(address, MSR.DR);
}
bool HostIsInstructionRAMAddress(u32 address)
{
// Instructions are always 32bit aligned.
return !(address & 3) &&
IsRAMAddress<XCheckTLBFlag::OpcodeNoException>(address, UReg_MSR(MSR).IR);
return !(address & 3) && IsRAMAddress<XCheckTLBFlag::OpcodeNoException>(address, MSR.IR);
}
void DMA_LCToMemory(const u32 memAddr, const u32 cacheAddr, const u32 numBlocks)
@ -779,7 +778,7 @@ void DMA_MemoryToLC(const u32 cacheAddr, const u32 memAddr, const u32 numBlocks)
void ClearCacheLine(u32 address)
{
DEBUG_ASSERT((address & 0x1F) == 0);
if (UReg_MSR(MSR).DR)
if (MSR.DR)
{
auto translated_address = TranslateAddress<XCheckTLBFlag::Write>(address);
if (translated_address.result == TranslateAddressResult::DIRECT_STORE_SEGMENT)
@ -809,7 +808,7 @@ u32 IsOptimizableMMIOAccess(u32 address, u32 accessSize)
if (PowerPC::memchecks.HasAny())
return 0;
if (!UReg_MSR(MSR).DR)
if (!MSR.DR)
return 0;
// Translate address
@ -831,7 +830,7 @@ bool IsOptimizableGatherPipeWrite(u32 address)
if (PowerPC::memchecks.HasAny())
return false;
if (!UReg_MSR(MSR).DR)
if (!MSR.DR)
return false;
// Translate address, only check BAT mapping.
@ -846,7 +845,7 @@ bool IsOptimizableGatherPipeWrite(u32 address)
TranslateResult JitCache_TranslateAddress(u32 address)
{
if (!UReg_MSR(MSR).IR)
if (!MSR.IR)
return TranslateResult{true, true, address};
// TODO: We shouldn't use FLAG_OPCODE if the caller is the debugger.

View File

@ -144,7 +144,7 @@ static void ResetRegisters()
SystemTimers::TimeBaseSet();
// MSR should be 0x40, but we don't emulate BS1, so it would never be turned off :}
ppcState.msr = 0;
ppcState.msr.Hex = 0;
rDEC = 0xFFFFFFFF;
SystemTimers::DecrementerSet();
}
@ -394,15 +394,19 @@ void CheckExceptions()
u32 exceptions = ppcState.Exceptions;
// Example procedure:
// set SRR0 to either PC or NPC
// Set SRR0 to either PC or NPC
// SRR0 = NPC;
// save specified MSR bits
// SRR1 = MSR & 0x87C0FFFF;
// copy ILE bit to LE
// MSR |= (MSR >> 16) & 1;
// clear MSR as specified
// MSR &= ~0x04EF36; // 0x04FF36 also clears ME (only for machine check exception)
// set to exception type entry point
//
// Save specified MSR bits
// SRR1 = MSR.Hex & 0x87C0FFFF;
//
// Copy ILE bit to LE
// MSR.LE |= MSR.ILE;
//
// Clear MSR as specified
// MSR.Hex &= ~0x04EF36; // 0x04FF36 also clears ME (only for machine check exception)
//
// Set to exception type entry point
// NPC = 0x00000x00;
// TODO(delroth): Exception priority is completely wrong here: depending on
@ -414,9 +418,9 @@ void CheckExceptions()
{
SRR0 = NPC;
// Page fault occurred
SRR1 = (MSR & 0x87C0FFFF) | (1 << 30);
MSR |= (MSR >> 16) & 1;
MSR &= ~0x04EF36;
SRR1 = (MSR.Hex & 0x87C0FFFF) | (1 << 30);
MSR.LE |= MSR.ILE;
MSR.Hex &= ~0x04EF36;
PC = NPC = 0x00000400;
DEBUG_LOG(POWERPC, "EXCEPTION_ISI");
@ -426,9 +430,9 @@ void CheckExceptions()
{
SRR0 = PC;
// say that it's a trap exception
SRR1 = (MSR & 0x87C0FFFF) | 0x20000;
MSR |= (MSR >> 16) & 1;
MSR &= ~0x04EF36;
SRR1 = (MSR.Hex & 0x87C0FFFF) | 0x20000;
MSR.LE |= MSR.ILE;
MSR.Hex &= ~0x04EF36;
PC = NPC = 0x00000700;
DEBUG_LOG(POWERPC, "EXCEPTION_PROGRAM");
@ -437,9 +441,9 @@ void CheckExceptions()
else if (exceptions & EXCEPTION_SYSCALL)
{
SRR0 = NPC;
SRR1 = MSR & 0x87C0FFFF;
MSR |= (MSR >> 16) & 1;
MSR &= ~0x04EF36;
SRR1 = MSR.Hex & 0x87C0FFFF;
MSR.LE |= MSR.ILE;
MSR.Hex &= ~0x04EF36;
PC = NPC = 0x00000C00;
DEBUG_LOG(POWERPC, "EXCEPTION_SYSCALL (PC=%08x)", PC);
@ -449,9 +453,9 @@ void CheckExceptions()
{
// This happens a lot - GameCube OS uses deferred FPU context switching
SRR0 = PC; // re-execute the instruction
SRR1 = MSR & 0x87C0FFFF;
MSR |= (MSR >> 16) & 1;
MSR &= ~0x04EF36;
SRR1 = MSR.Hex & 0x87C0FFFF;
MSR.LE |= MSR.ILE;
MSR.Hex &= ~0x04EF36;
PC = NPC = 0x00000800;
DEBUG_LOG(POWERPC, "EXCEPTION_FPU_UNAVAILABLE");
@ -464,9 +468,9 @@ void CheckExceptions()
else if (exceptions & EXCEPTION_DSI)
{
SRR0 = PC;
SRR1 = MSR & 0x87C0FFFF;
MSR |= (MSR >> 16) & 1;
MSR &= ~0x04EF36;
SRR1 = MSR.Hex & 0x87C0FFFF;
MSR.LE |= MSR.ILE;
MSR.Hex &= ~0x04EF36;
PC = NPC = 0x00000300;
// DSISR and DAR regs are changed in GenerateDSIException()
@ -476,9 +480,9 @@ void CheckExceptions()
else if (exceptions & EXCEPTION_ALIGNMENT)
{
SRR0 = PC;
SRR1 = MSR & 0x87C0FFFF;
MSR |= (MSR >> 16) & 1;
MSR &= ~0x04EF36;
SRR1 = MSR.Hex & 0x87C0FFFF;
MSR.LE |= MSR.ILE;
MSR.Hex &= ~0x04EF36;
PC = NPC = 0x00000600;
// TODO crazy amount of DSISR options to check out
@ -499,15 +503,16 @@ void CheckExternalExceptions()
u32 exceptions = ppcState.Exceptions;
// EXTERNAL INTERRUPT
if (exceptions && (MSR & 0x0008000)) // Handling is delayed until MSR.EE=1.
// Handling is delayed until MSR.EE=1.
if (exceptions && MSR.EE)
{
if (exceptions & EXCEPTION_EXTERNAL_INT)
{
// Pokemon gets this "too early", it hasn't a handler yet
SRR0 = NPC;
SRR1 = MSR & 0x87C0FFFF;
MSR |= (MSR >> 16) & 1;
MSR &= ~0x04EF36;
SRR1 = MSR.Hex & 0x87C0FFFF;
MSR.LE |= MSR.ILE;
MSR.Hex &= ~0x04EF36;
PC = NPC = 0x00000500;
DEBUG_LOG(POWERPC, "EXCEPTION_EXTERNAL_INT");
@ -518,9 +523,9 @@ void CheckExternalExceptions()
else if (exceptions & EXCEPTION_PERFORMANCE_MONITOR)
{
SRR0 = NPC;
SRR1 = MSR & 0x87C0FFFF;
MSR |= (MSR >> 16) & 1;
MSR &= ~0x04EF36;
SRR1 = MSR.Hex & 0x87C0FFFF;
MSR.LE |= MSR.ILE;
MSR.Hex &= ~0x04EF36;
PC = NPC = 0x00000F00;
DEBUG_LOG(POWERPC, "EXCEPTION_PERFORMANCE_MONITOR");
@ -529,9 +534,9 @@ void CheckExternalExceptions()
else if (exceptions & EXCEPTION_DECREMENTER)
{
SRR0 = NPC;
SRR1 = MSR & 0x87C0FFFF;
MSR |= (MSR >> 16) & 1;
MSR &= ~0x04EF36;
SRR1 = MSR.Hex & 0x87C0FFFF;
MSR.LE |= MSR.ILE;
MSR.Hex &= ~0x04EF36;
PC = NPC = 0x00000900;
DEBUG_LOG(POWERPC, "EXCEPTION_DECREMENTER");

View File

@ -75,8 +75,8 @@ struct PowerPCState
// be manipulated bit by bit fairly easily.
u64 cr_val[8];
u32 msr; // machine specific register
u32 fpscr; // floating point flags/status bits
UReg_MSR msr; // machine state register
u32 fpscr; // floating point flags/status bits
// Exception management.
u32 Exceptions;

View File

@ -296,8 +296,8 @@ void RegisterWidget::PopulateTable()
[](u64 value) { PowerPC::ppcState.fpscr = value; });
// MSR
AddRegister(23, 5, RegisterType::msr, "MSR", [] { return PowerPC::ppcState.msr; },
[](u64 value) { PowerPC::ppcState.msr = value; });
AddRegister(23, 5, RegisterType::msr, "MSR", [] { return PowerPC::ppcState.msr.Hex; },
[](u64 value) { PowerPC::ppcState.msr.Hex = value; });
// SRR 0-1
AddRegister(24, 5, RegisterType::srr, "SRR0", [] { return PowerPC::ppcState.spr[SPR_SRR0]; },

View File

@ -82,7 +82,7 @@ u32 GetSpecialRegValue(int reg)
case 5:
return PowerPC::ppcState.fpscr;
case 6:
return PowerPC::ppcState.msr;
return PowerPC::ppcState.msr.Hex;
case 7:
return PowerPC::ppcState.spr[SPR_SRR0];
case 8:
@ -127,7 +127,7 @@ void SetSpecialRegValue(int reg, u32 value)
PowerPC::ppcState.fpscr = value;
break;
case 6:
PowerPC::ppcState.msr = value;
PowerPC::ppcState.msr.Hex = value;
break;
case 7:
PowerPC::ppcState.spr[SPR_SRR0] = value;