summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorLioncash <mathew1800@gmail.com>2018-04-05 00:22:57 -0400
committerLioncash <mathew1800@gmail.com>2018-04-05 00:30:53 -0400
commit912c9490c0e7225cdc7fa3581d8eb10e2b592259 (patch)
tree3506ed03710f7997bfdc8542cb6f6b862b5185bb /Source/Core
parent9be505fde2c695c90314b07a0ad90f537301f034 (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.cpp138
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)