aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
diff options
context:
space:
mode:
authorGravatar Lioncash <mathew1800@gmail.com>2015-03-11 16:10:14 -0400
committerGravatar Lioncash <mathew1800@gmail.com>2015-03-17 15:13:32 -0400
commit9fdb311d6e2d636c4599ddc3d4cb9adad6cec540 (patch)
tree358501f8f2e31c7c27ee17c62996ef01e21354c7 /src/core/arm/dyncom/arm_dyncom_interpreter.cpp
parentf28080621477d7e6a6caaf6bf93da7f448159562 (diff)
dyncom: Make Load/Store instructions support big endian
Diffstat (limited to 'src/core/arm/dyncom/arm_dyncom_interpreter.cpp')
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp114
1 files changed, 62 insertions, 52 deletions
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
index 4dd54165..cfa6de8f 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -4362,30 +4362,30 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
if (BIT(inst, 22) && !BIT(inst, 15)) {
for (int i = 0; i < 13; i++) {
if(BIT(inst, i)) {
- cpu->Reg[i] = Memory::Read32(addr);
+ cpu->Reg[i] = ReadMemory32(cpu, addr);
addr += 4;
}
}
if (BIT(inst, 13)) {
if (cpu->Mode == USER32MODE)
- cpu->Reg[13] = Memory::Read32(addr);
+ cpu->Reg[13] = ReadMemory32(cpu, addr);
else
- cpu->Reg_usr[0] = Memory::Read32(addr);
+ cpu->Reg_usr[0] = ReadMemory32(cpu, addr);
addr += 4;
}
if (BIT(inst, 14)) {
if (cpu->Mode == USER32MODE)
- cpu->Reg[14] = Memory::Read32(addr);
+ cpu->Reg[14] = ReadMemory32(cpu, addr);
else
- cpu->Reg_usr[1] = Memory::Read32(addr);
+ cpu->Reg_usr[1] = ReadMemory32(cpu, addr);
addr += 4;
}
} else if (!BIT(inst, 22)) {
for(int i = 0; i < 16; i++ ){
if(BIT(inst, i)){
- unsigned int ret = Memory::Read32(addr);
+ unsigned int ret = ReadMemory32(cpu, addr);
// For armv5t, should enter thumb when bits[0] is non-zero.
if(i == 15){
@@ -4400,7 +4400,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
} else if (BIT(inst, 22) && BIT(inst, 15)) {
for(int i = 0; i < 15; i++ ){
if(BIT(inst, i)){
- cpu->Reg[i] = Memory::Read32(addr);
+ cpu->Reg[i] = ReadMemory32(cpu, addr);
addr += 4;
}
}
@@ -4411,7 +4411,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
LOAD_NZCVT;
}
- cpu->Reg[15] = Memory::Read32(addr);
+ cpu->Reg[15] = ReadMemory32(cpu, addr);
}
if (BIT(inst, 15)) {
@@ -4445,20 +4445,18 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
LDR_INST:
{
ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
- //if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- inst_cream->get_addr(cpu, inst_cream->inst, addr, 1);
+ inst_cream->get_addr(cpu, inst_cream->inst, addr, 1);
- unsigned int value = Memory::Read32(addr);
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
+ unsigned int value = ReadMemory32(cpu, addr);
+ cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
- if (BITS(inst_cream->inst, 12, 15) == 15) {
- // For armv5t, should enter thumb when bits[0] is non-zero.
- cpu->TFlag = value & 0x1;
- cpu->Reg[15] &= 0xFFFFFFFE;
- INC_PC(sizeof(ldst_inst));
- goto DISPATCH;
- }
- //}
+ if (BITS(inst_cream->inst, 12, 15) == 15) {
+ // For armv5t, should enter thumb when bits[0] is non-zero.
+ cpu->TFlag = value & 0x1;
+ cpu->Reg[15] &= 0xFFFFFFFE;
+ INC_PC(sizeof(ldst_inst));
+ goto DISPATCH;
+ }
cpu->Reg[15] += GET_INST_SIZE(cpu);
INC_PC(sizeof(ldst_inst));
@@ -4471,7 +4469,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
inst_cream->get_addr(cpu, inst_cream->inst, addr, 1);
- unsigned int value = Memory::Read32(addr);
+ unsigned int value = ReadMemory32(cpu, addr);
cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
if (BITS(inst_cream->inst, 12, 15) == 15) {
@@ -4554,8 +4552,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
// Should check if RD is even-numbered, Rd != 14, addr[0:1] == 0, (CP15_reg1_U == 1 || addr[2] == 0)
inst_cream->get_addr(cpu, inst_cream->inst, addr, 1);
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = Memory::Read32(addr);
- cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = Memory::Read32(addr + 4);
+ // The 3DS doesn't have LPAE (Large Physical Access Extension), so it
+ // wouldn't do this as a single read.
+ cpu->Reg[BITS(inst_cream->inst, 12, 15) + 0] = ReadMemory32(cpu, addr);
+ cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = ReadMemory32(cpu, addr + 4);
// No dispatch since this operation should not modify R15
}
@@ -4574,7 +4574,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
add_exclusive_addr(cpu, read_addr);
cpu->exclusive_state = 1;
- RD = Memory::Read32(read_addr);
+ RD = ReadMemory32(cpu, read_addr);
if (inst_cream->Rd == 15) {
INC_PC(sizeof(generic_arm_inst));
goto DISPATCH;
@@ -4614,7 +4614,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
add_exclusive_addr(cpu, read_addr);
cpu->exclusive_state = 1;
- RD = Memory::Read16(read_addr);
+ RD = ReadMemory16(cpu, read_addr);
if (inst_cream->Rd == 15) {
INC_PC(sizeof(generic_arm_inst));
goto DISPATCH;
@@ -4634,8 +4634,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
add_exclusive_addr(cpu, read_addr);
cpu->exclusive_state = 1;
- RD = Memory::Read32(read_addr);
- RD2 = Memory::Read32(read_addr + 4);
+ RD = ReadMemory32(cpu, read_addr);
+ RD2 = ReadMemory32(cpu, read_addr + 4);
if (inst_cream->Rd == 15) {
INC_PC(sizeof(generic_arm_inst));
@@ -4652,7 +4652,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
inst_cream->get_addr(cpu, inst_cream->inst, addr, 1);
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = Memory::Read16(addr);
+
+ cpu->Reg[BITS(inst_cream->inst, 12, 15)] = ReadMemory16(cpu, addr);
if (BITS(inst_cream->inst, 12, 15) == 15) {
INC_PC(sizeof(ldst_inst));
goto DISPATCH;
@@ -4688,7 +4689,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
inst_cream->get_addr(cpu, inst_cream->inst, addr, 1);
- unsigned int value = Memory::Read16(addr);
+
+ unsigned int value = ReadMemory16(cpu, addr);
if (BIT(value, 15)) {
value |= 0xffff0000;
}
@@ -4709,7 +4711,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
inst_cream->get_addr(cpu, inst_cream->inst, addr, 1);
- unsigned int value = Memory::Read32(addr);
+ unsigned int value = ReadMemory32(cpu, addr);
cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
if (BITS(inst_cream->inst, 12, 15) == 15) {
@@ -6010,36 +6012,36 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
if (BIT(inst_cream->inst, 22) == 1) {
for (int i = 0; i < 13; i++) {
if (BIT(inst_cream->inst, i)) {
- Memory::Write32(addr, cpu->Reg[i]);
+ WriteMemory32(cpu, addr, cpu->Reg[i]);
addr += 4;
}
}
if (BIT(inst_cream->inst, 13)) {
if (cpu->Mode == USER32MODE)
- Memory::Write32(addr, cpu->Reg[13]);
+ WriteMemory32(cpu, addr, cpu->Reg[13]);
else
- Memory::Write32(addr, cpu->Reg_usr[0]);
+ WriteMemory32(cpu, addr, cpu->Reg_usr[0]);
addr += 4;
}
if (BIT(inst_cream->inst, 14)) {
if (cpu->Mode == USER32MODE)
- Memory::Write32(addr, cpu->Reg[14]);
+ WriteMemory32(cpu, addr, cpu->Reg[14]);
else
- Memory::Write32(addr, cpu->Reg_usr[1]);
+ WriteMemory32(cpu, addr, cpu->Reg_usr[1]);
addr += 4;
}
if (BIT(inst_cream->inst, 15)) {
- Memory::Write32(addr, cpu->Reg_usr[1] + 8);
+ WriteMemory32(cpu, addr, cpu->Reg_usr[1] + 8);
}
} else {
for (int i = 0; i < 15; i++) {
if (BIT(inst_cream->inst, i)) {
if (i == Rn)
- Memory::Write32(addr, old_RN);
+ WriteMemory32(cpu, addr, old_RN);
else
- Memory::Write32(addr, cpu->Reg[i]);
+ WriteMemory32(cpu, addr, cpu->Reg[i]);
addr += 4;
}
@@ -6047,7 +6049,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
// Check PC reg
if (BIT(inst_cream->inst, 15))
- Memory::Write32(addr, cpu->Reg_usr[1] + 8);
+ WriteMemory32(cpu, addr, cpu->Reg_usr[1] + 8);
}
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
@@ -6080,7 +6082,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
inst_cream->get_addr(cpu, inst_cream->inst, addr, 0);
unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)];
- Memory::Write32(addr, value);
+ WriteMemory32(cpu, addr, value);
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
INC_PC(sizeof(ldst_inst));
@@ -6143,10 +6145,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
inst_cream->get_addr(cpu, inst_cream->inst, addr, 0);
- unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)];
- Memory::Write32(addr, value);
- value = cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1];
- Memory::Write32(addr + 4, value);
+ // The 3DS doesn't have the Large Physical Access Extension (LPAE)
+ // so STRD wouldn't store these as a single write.
+ WriteMemory32(cpu, addr + 0, cpu->Reg[BITS(inst_cream->inst, 12, 15)]);
+ WriteMemory32(cpu, addr + 4, cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1]);
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
INC_PC(sizeof(ldst_inst));
@@ -6163,7 +6165,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
remove_exclusive(cpu, write_addr);
cpu->exclusive_state = 0;
- Memory::Write32(write_addr, cpu->Reg[inst_cream->Rm]);
+ WriteMemory32(cpu, write_addr, RM);
RD = 0;
} else {
// Failed to write due to mutex access
@@ -6207,8 +6209,16 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
remove_exclusive(cpu, write_addr);
cpu->exclusive_state = 0;
- Memory::Write32(write_addr, cpu->Reg[inst_cream->Rm]);
- Memory::Write32(write_addr + 4, cpu->Reg[inst_cream->Rm + 1]);
+ const u32 rt = cpu->Reg[inst_cream->Rm + 0];
+ const u32 rt2 = cpu->Reg[inst_cream->Rm + 1];
+ u64 value;
+
+ if (InBigEndianMode(cpu))
+ value = (((u64)rt << 32) | rt2);
+ else
+ value = (((u64)rt2 << 32) | rt);
+
+ WriteMemory64(cpu, write_addr, value);
RD = 0;
}
else {
@@ -6231,7 +6241,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
remove_exclusive(cpu, write_addr);
cpu->exclusive_state = 0;
- Memory::Write16(write_addr, cpu->Reg[inst_cream->Rm]);
+ WriteMemory16(cpu, write_addr, RM);
RD = 0;
} else {
// Failed to write due to mutex access
@@ -6250,7 +6260,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
inst_cream->get_addr(cpu, inst_cream->inst, addr, 0);
unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xffff;
- Memory::Write16(addr, value);
+ WriteMemory16(cpu, addr, value);
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
INC_PC(sizeof(ldst_inst));
@@ -6264,7 +6274,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
inst_cream->get_addr(cpu, inst_cream->inst, addr, 0);
unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)];
- Memory::Write32(addr, value);
+ WriteMemory32(cpu, addr, value);
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
INC_PC(sizeof(ldst_inst));
@@ -6323,8 +6333,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
swp_inst* inst_cream = (swp_inst*)inst_base->component;
addr = RN;
- unsigned int value = Memory::Read32(addr);
- Memory::Write32(addr, RM);
+ unsigned int value = ReadMemory32(cpu, addr);
+ WriteMemory32(cpu, addr, RM);
RD = value;
}