diff options
| author | Lioncash <mathew1800@gmail.com> | 2018-04-05 00:22:57 -0400 |
|---|---|---|
| committer | Lioncash <mathew1800@gmail.com> | 2018-04-05 00:30:53 -0400 |
| commit | 912c9490c0e7225cdc7fa3581d8eb10e2b592259 (patch) | |
| tree | 3506ed03710f7997bfdc8542cb6f6b862b5185bb /Source/Core | |
| parent | 9be505fde2c695c90314b07a0ad90f537301f034 (diff) | |
Interpreter_LoadStore: Generate alignment exceptions if an FP load/store instruction's effective address is not word aligned
This is one of the conditions for an alignment exception documented in
the 750CL architecture reference manual in section 4.5.6, which also
applies to the Gekko microprocessor.
Diffstat (limited to 'Source/Core')
| -rw-r--r-- | Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp | 138 |
1 files changed, 130 insertions, 8 deletions
diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp index 4ada0b3c3c..98b04f4bc2 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp @@ -74,7 +74,15 @@ void Interpreter::lbzu(UGeckoInstruction inst) void Interpreter::lfd(UGeckoInstruction inst) { - const u64 temp = PowerPC::Read_U64(Helper_Get_EA(inst)); + const u32 address = Helper_Get_EA(inst); + + if ((address & 0b11) != 0) + { + GenerateAlignmentException(address); + return; + } + + const u64 temp = PowerPC::Read_U64(address); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) riPS0(inst.FD) = temp; @@ -83,6 +91,13 @@ void Interpreter::lfd(UGeckoInstruction inst) void Interpreter::lfdu(UGeckoInstruction inst) { const u32 address = Helper_Get_EA_U(inst); + + if ((address & 0b11) != 0) + { + GenerateAlignmentException(address); + return; + } + const u64 temp = PowerPC::Read_U64(address); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) @@ -95,6 +110,13 @@ void Interpreter::lfdu(UGeckoInstruction inst) void Interpreter::lfdux(UGeckoInstruction inst) { const u32 address = Helper_Get_EA_UX(inst); + + if ((address & 0b11) != 0) + { + GenerateAlignmentException(address); + return; + } + const u64 temp = PowerPC::Read_U64(address); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) @@ -106,7 +128,15 @@ void Interpreter::lfdux(UGeckoInstruction inst) void Interpreter::lfdx(UGeckoInstruction inst) { - const u64 temp = PowerPC::Read_U64(Helper_Get_EA_X(inst)); + const u32 address = Helper_Get_EA_X(inst); + + if ((address & 0b11) != 0) + { + GenerateAlignmentException(address); + return; + } + + const u64 temp = PowerPC::Read_U64(address); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) riPS0(inst.FD) = temp; @@ -114,7 +144,15 @@ void Interpreter::lfdx(UGeckoInstruction inst) void Interpreter::lfs(UGeckoInstruction inst) { - const u32 temp = PowerPC::Read_U32(Helper_Get_EA(inst)); + const u32 address = Helper_Get_EA(inst); + + if ((address & 0b11) != 0) + { + GenerateAlignmentException(address); + return; + } + + const u32 temp = PowerPC::Read_U32(address); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { @@ -127,6 +165,13 @@ void Interpreter::lfs(UGeckoInstruction inst) void Interpreter::lfsu(UGeckoInstruction inst) { const u32 address = Helper_Get_EA_U(inst); + + if ((address & 0b11) != 0) + { + GenerateAlignmentException(address); + return; + } + const u32 temp = PowerPC::Read_U32(address); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) @@ -141,6 +186,13 @@ void Interpreter::lfsu(UGeckoInstruction inst) void Interpreter::lfsux(UGeckoInstruction inst) { const u32 address = Helper_Get_EA_UX(inst); + + if ((address & 0b11) != 0) + { + GenerateAlignmentException(address); + return; + } + const u32 temp = PowerPC::Read_U32(address); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) @@ -154,7 +206,15 @@ void Interpreter::lfsux(UGeckoInstruction inst) void Interpreter::lfsx(UGeckoInstruction inst) { - const u32 temp = PowerPC::Read_U32(Helper_Get_EA_X(inst)); + const u32 address = Helper_Get_EA_X(inst); + + if ((address & 0b11) != 0) + { + GenerateAlignmentException(address); + return; + } + + const u32 temp = PowerPC::Read_U32(address); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { @@ -300,13 +360,27 @@ void Interpreter::stbu(UGeckoInstruction inst) void Interpreter::stfd(UGeckoInstruction inst) { - PowerPC::Write_U64(riPS0(inst.FS), Helper_Get_EA(inst)); + const u32 address = Helper_Get_EA(inst); + + if ((address & 0b11) != 0) + { + GenerateAlignmentException(address); + return; + } + + PowerPC::Write_U64(riPS0(inst.FS), address); } void Interpreter::stfdu(UGeckoInstruction inst) { const u32 address = Helper_Get_EA_U(inst); + if ((address & 0b11) != 0) + { + GenerateAlignmentException(address); + return; + } + PowerPC::Write_U64(riPS0(inst.FS), address); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { @@ -316,13 +390,27 @@ void Interpreter::stfdu(UGeckoInstruction inst) void Interpreter::stfs(UGeckoInstruction inst) { - PowerPC::Write_U32(ConvertToSingle(riPS0(inst.FS)), Helper_Get_EA(inst)); + const u32 address = Helper_Get_EA(inst); + + if ((address & 0b11) != 0) + { + GenerateAlignmentException(address); + return; + } + + PowerPC::Write_U32(ConvertToSingle(riPS0(inst.FS)), address); } void Interpreter::stfsu(UGeckoInstruction inst) { const u32 address = Helper_Get_EA_U(inst); + if ((address & 0b11) != 0) + { + GenerateAlignmentException(address); + return; + } + PowerPC::Write_U32(ConvertToSingle(riPS0(inst.FS)), address); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { @@ -646,6 +734,12 @@ void Interpreter::stfdux(UGeckoInstruction inst) { const u32 address = Helper_Get_EA_UX(inst); + if ((address & 0b11) != 0) + { + GenerateAlignmentException(address); + return; + } + PowerPC::Write_U64(riPS0(inst.FS), address); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { @@ -655,7 +749,15 @@ void Interpreter::stfdux(UGeckoInstruction inst) void Interpreter::stfdx(UGeckoInstruction inst) { - PowerPC::Write_U64(riPS0(inst.FS), Helper_Get_EA_X(inst)); + const u32 address = Helper_Get_EA_X(inst); + + if ((address & 0b11) != 0) + { + GenerateAlignmentException(address); + return; + } + + PowerPC::Write_U64(riPS0(inst.FS), address); } // Stores Floating points into Integers indeXed @@ -663,6 +765,12 @@ void Interpreter::stfiwx(UGeckoInstruction inst) { const u32 address = Helper_Get_EA_X(inst); + if ((address & 0b11) != 0) + { + GenerateAlignmentException(address); + return; + } + PowerPC::Write_U32((u32)riPS0(inst.FS), address); } @@ -670,6 +778,12 @@ void Interpreter::stfsux(UGeckoInstruction inst) { const u32 address = Helper_Get_EA_UX(inst); + if ((address & 0b11) != 0) + { + GenerateAlignmentException(address); + return; + } + PowerPC::Write_U32(ConvertToSingle(riPS0(inst.FS)), address); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) { @@ -679,7 +793,15 @@ void Interpreter::stfsux(UGeckoInstruction inst) void Interpreter::stfsx(UGeckoInstruction inst) { - PowerPC::Write_U32(ConvertToSingle(riPS0(inst.FS)), Helper_Get_EA_X(inst)); + const u32 address = Helper_Get_EA_X(inst); + + if ((address & 0b11) != 0) + { + GenerateAlignmentException(address); + return; + } + + PowerPC::Write_U32(ConvertToSingle(riPS0(inst.FS)), address); } void Interpreter::sthbrx(UGeckoInstruction inst) |
