summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp114
-rw-r--r--src/core/arm/interpreter/armsupp.cpp6
-rw-r--r--src/core/arm/skyeye_common/armdefs.h3
-rw-r--r--src/core/arm/skyeye_common/armmmu.h55
-rw-r--r--src/core/arm/skyeye_common/vfp/vfpinstr.cpp102
-rw-r--r--src/core/mem_map.h1
-rw-r--r--src/core/mem_map_funcs.cpp6
7 files changed, 205 insertions, 82 deletions
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
index 4dd541656..cfa6de8fc 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) {
4362 if (BIT(inst, 22) && !BIT(inst, 15)) { 4362 if (BIT(inst, 22) && !BIT(inst, 15)) {
4363 for (int i = 0; i < 13; i++) { 4363 for (int i = 0; i < 13; i++) {
4364 if(BIT(inst, i)) { 4364 if(BIT(inst, i)) {
4365 cpu->Reg[i] = Memory::Read32(addr); 4365 cpu->Reg[i] = ReadMemory32(cpu, addr);
4366 addr += 4; 4366 addr += 4;
4367 } 4367 }
4368 } 4368 }
4369 if (BIT(inst, 13)) { 4369 if (BIT(inst, 13)) {
4370 if (cpu->Mode == USER32MODE) 4370 if (cpu->Mode == USER32MODE)
4371 cpu->Reg[13] = Memory::Read32(addr); 4371 cpu->Reg[13] = ReadMemory32(cpu, addr);
4372 else 4372 else
4373 cpu->Reg_usr[0] = Memory::Read32(addr); 4373 cpu->Reg_usr[0] = ReadMemory32(cpu, addr);
4374 4374
4375 addr += 4; 4375 addr += 4;
4376 } 4376 }
4377 if (BIT(inst, 14)) { 4377 if (BIT(inst, 14)) {
4378 if (cpu->Mode == USER32MODE) 4378 if (cpu->Mode == USER32MODE)
4379 cpu->Reg[14] = Memory::Read32(addr); 4379 cpu->Reg[14] = ReadMemory32(cpu, addr);
4380 else 4380 else
4381 cpu->Reg_usr[1] = Memory::Read32(addr); 4381 cpu->Reg_usr[1] = ReadMemory32(cpu, addr);
4382 4382
4383 addr += 4; 4383 addr += 4;
4384 } 4384 }
4385 } else if (!BIT(inst, 22)) { 4385 } else if (!BIT(inst, 22)) {
4386 for(int i = 0; i < 16; i++ ){ 4386 for(int i = 0; i < 16; i++ ){
4387 if(BIT(inst, i)){ 4387 if(BIT(inst, i)){
4388 unsigned int ret = Memory::Read32(addr); 4388 unsigned int ret = ReadMemory32(cpu, addr);
4389 4389
4390 // For armv5t, should enter thumb when bits[0] is non-zero. 4390 // For armv5t, should enter thumb when bits[0] is non-zero.
4391 if(i == 15){ 4391 if(i == 15){
@@ -4400,7 +4400,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
4400 } else if (BIT(inst, 22) && BIT(inst, 15)) { 4400 } else if (BIT(inst, 22) && BIT(inst, 15)) {
4401 for(int i = 0; i < 15; i++ ){ 4401 for(int i = 0; i < 15; i++ ){
4402 if(BIT(inst, i)){ 4402 if(BIT(inst, i)){
4403 cpu->Reg[i] = Memory::Read32(addr); 4403 cpu->Reg[i] = ReadMemory32(cpu, addr);
4404 addr += 4; 4404 addr += 4;
4405 } 4405 }
4406 } 4406 }
@@ -4411,7 +4411,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
4411 LOAD_NZCVT; 4411 LOAD_NZCVT;
4412 } 4412 }
4413 4413
4414 cpu->Reg[15] = Memory::Read32(addr); 4414 cpu->Reg[15] = ReadMemory32(cpu, addr);
4415 } 4415 }
4416 4416
4417 if (BIT(inst, 15)) { 4417 if (BIT(inst, 15)) {
@@ -4445,20 +4445,18 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
4445 LDR_INST: 4445 LDR_INST:
4446 { 4446 {
4447 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 4447 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4448 //if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 4448 inst_cream->get_addr(cpu, inst_cream->inst, addr, 1);
4449 inst_cream->get_addr(cpu, inst_cream->inst, addr, 1);
4450 4449
4451 unsigned int value = Memory::Read32(addr); 4450 unsigned int value = ReadMemory32(cpu, addr);
4452 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; 4451 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4453 4452
4454 if (BITS(inst_cream->inst, 12, 15) == 15) { 4453 if (BITS(inst_cream->inst, 12, 15) == 15) {
4455 // For armv5t, should enter thumb when bits[0] is non-zero. 4454 // For armv5t, should enter thumb when bits[0] is non-zero.
4456 cpu->TFlag = value & 0x1; 4455 cpu->TFlag = value & 0x1;
4457 cpu->Reg[15] &= 0xFFFFFFFE; 4456 cpu->Reg[15] &= 0xFFFFFFFE;
4458 INC_PC(sizeof(ldst_inst)); 4457 INC_PC(sizeof(ldst_inst));
4459 goto DISPATCH; 4458 goto DISPATCH;
4460 } 4459 }
4461 //}
4462 4460
4463 cpu->Reg[15] += GET_INST_SIZE(cpu); 4461 cpu->Reg[15] += GET_INST_SIZE(cpu);
4464 INC_PC(sizeof(ldst_inst)); 4462 INC_PC(sizeof(ldst_inst));
@@ -4471,7 +4469,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
4471 ldst_inst *inst_cream = (ldst_inst *)inst_base->component; 4469 ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
4472 inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); 4470 inst_cream->get_addr(cpu, inst_cream->inst, addr, 1);
4473 4471
4474 unsigned int value = Memory::Read32(addr); 4472 unsigned int value = ReadMemory32(cpu, addr);
4475 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; 4473 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4476 4474
4477 if (BITS(inst_cream->inst, 12, 15) == 15) { 4475 if (BITS(inst_cream->inst, 12, 15) == 15) {
@@ -4554,8 +4552,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
4554 // Should check if RD is even-numbered, Rd != 14, addr[0:1] == 0, (CP15_reg1_U == 1 || addr[2] == 0) 4552 // Should check if RD is even-numbered, Rd != 14, addr[0:1] == 0, (CP15_reg1_U == 1 || addr[2] == 0)
4555 inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); 4553 inst_cream->get_addr(cpu, inst_cream->inst, addr, 1);
4556 4554
4557 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = Memory::Read32(addr); 4555 // The 3DS doesn't have LPAE (Large Physical Access Extension), so it
4558 cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = Memory::Read32(addr + 4); 4556 // wouldn't do this as a single read.
4557 cpu->Reg[BITS(inst_cream->inst, 12, 15) + 0] = ReadMemory32(cpu, addr);
4558 cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = ReadMemory32(cpu, addr + 4);
4559 4559
4560 // No dispatch since this operation should not modify R15 4560 // No dispatch since this operation should not modify R15
4561 } 4561 }
@@ -4574,7 +4574,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
4574 add_exclusive_addr(cpu, read_addr); 4574 add_exclusive_addr(cpu, read_addr);
4575 cpu->exclusive_state = 1; 4575 cpu->exclusive_state = 1;
4576 4576
4577 RD = Memory::Read32(read_addr); 4577 RD = ReadMemory32(cpu, read_addr);
4578 if (inst_cream->Rd == 15) { 4578 if (inst_cream->Rd == 15) {
4579 INC_PC(sizeof(generic_arm_inst)); 4579 INC_PC(sizeof(generic_arm_inst));
4580 goto DISPATCH; 4580 goto DISPATCH;
@@ -4614,7 +4614,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
4614 add_exclusive_addr(cpu, read_addr); 4614 add_exclusive_addr(cpu, read_addr);
4615 cpu->exclusive_state = 1; 4615 cpu->exclusive_state = 1;
4616 4616
4617 RD = Memory::Read16(read_addr); 4617 RD = ReadMemory16(cpu, read_addr);
4618 if (inst_cream->Rd == 15) { 4618 if (inst_cream->Rd == 15) {
4619 INC_PC(sizeof(generic_arm_inst)); 4619 INC_PC(sizeof(generic_arm_inst));
4620 goto DISPATCH; 4620 goto DISPATCH;
@@ -4634,8 +4634,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
4634 add_exclusive_addr(cpu, read_addr); 4634 add_exclusive_addr(cpu, read_addr);
4635 cpu->exclusive_state = 1; 4635 cpu->exclusive_state = 1;
4636 4636
4637 RD = Memory::Read32(read_addr); 4637 RD = ReadMemory32(cpu, read_addr);
4638 RD2 = Memory::Read32(read_addr + 4); 4638 RD2 = ReadMemory32(cpu, read_addr + 4);
4639 4639
4640 if (inst_cream->Rd == 15) { 4640 if (inst_cream->Rd == 15) {
4641 INC_PC(sizeof(generic_arm_inst)); 4641 INC_PC(sizeof(generic_arm_inst));
@@ -4652,7 +4652,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
4652 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { 4652 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
4653 ldst_inst* inst_cream = (ldst_inst*)inst_base->component; 4653 ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
4654 inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); 4654 inst_cream->get_addr(cpu, inst_cream->inst, addr, 1);
4655 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = Memory::Read16(addr); 4655
4656 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = ReadMemory16(cpu, addr);
4656 if (BITS(inst_cream->inst, 12, 15) == 15) { 4657 if (BITS(inst_cream->inst, 12, 15) == 15) {
4657 INC_PC(sizeof(ldst_inst)); 4658 INC_PC(sizeof(ldst_inst));
4658 goto DISPATCH; 4659 goto DISPATCH;
@@ -4688,7 +4689,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
4688 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { 4689 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
4689 ldst_inst* inst_cream = (ldst_inst*)inst_base->component; 4690 ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
4690 inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); 4691 inst_cream->get_addr(cpu, inst_cream->inst, addr, 1);
4691 unsigned int value = Memory::Read16(addr); 4692
4693 unsigned int value = ReadMemory16(cpu, addr);
4692 if (BIT(value, 15)) { 4694 if (BIT(value, 15)) {
4693 value |= 0xffff0000; 4695 value |= 0xffff0000;
4694 } 4696 }
@@ -4709,7 +4711,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
4709 ldst_inst* inst_cream = (ldst_inst*)inst_base->component; 4711 ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
4710 inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); 4712 inst_cream->get_addr(cpu, inst_cream->inst, addr, 1);
4711 4713
4712 unsigned int value = Memory::Read32(addr); 4714 unsigned int value = ReadMemory32(cpu, addr);
4713 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; 4715 cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
4714 4716
4715 if (BITS(inst_cream->inst, 12, 15) == 15) { 4717 if (BITS(inst_cream->inst, 12, 15) == 15) {
@@ -6010,36 +6012,36 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
6010 if (BIT(inst_cream->inst, 22) == 1) { 6012 if (BIT(inst_cream->inst, 22) == 1) {
6011 for (int i = 0; i < 13; i++) { 6013 for (int i = 0; i < 13; i++) {
6012 if (BIT(inst_cream->inst, i)) { 6014 if (BIT(inst_cream->inst, i)) {
6013 Memory::Write32(addr, cpu->Reg[i]); 6015 WriteMemory32(cpu, addr, cpu->Reg[i]);
6014 addr += 4; 6016 addr += 4;
6015 } 6017 }
6016 } 6018 }
6017 if (BIT(inst_cream->inst, 13)) { 6019 if (BIT(inst_cream->inst, 13)) {
6018 if (cpu->Mode == USER32MODE) 6020 if (cpu->Mode == USER32MODE)
6019 Memory::Write32(addr, cpu->Reg[13]); 6021 WriteMemory32(cpu, addr, cpu->Reg[13]);
6020 else 6022 else
6021 Memory::Write32(addr, cpu->Reg_usr[0]); 6023 WriteMemory32(cpu, addr, cpu->Reg_usr[0]);
6022 6024
6023 addr += 4; 6025 addr += 4;
6024 } 6026 }
6025 if (BIT(inst_cream->inst, 14)) { 6027 if (BIT(inst_cream->inst, 14)) {
6026 if (cpu->Mode == USER32MODE) 6028 if (cpu->Mode == USER32MODE)
6027 Memory::Write32(addr, cpu->Reg[14]); 6029 WriteMemory32(cpu, addr, cpu->Reg[14]);
6028 else 6030 else
6029 Memory::Write32(addr, cpu->Reg_usr[1]); 6031 WriteMemory32(cpu, addr, cpu->Reg_usr[1]);
6030 6032
6031 addr += 4; 6033 addr += 4;
6032 } 6034 }
6033 if (BIT(inst_cream->inst, 15)) { 6035 if (BIT(inst_cream->inst, 15)) {
6034 Memory::Write32(addr, cpu->Reg_usr[1] + 8); 6036 WriteMemory32(cpu, addr, cpu->Reg_usr[1] + 8);
6035 } 6037 }
6036 } else { 6038 } else {
6037 for (int i = 0; i < 15; i++) { 6039 for (int i = 0; i < 15; i++) {
6038 if (BIT(inst_cream->inst, i)) { 6040 if (BIT(inst_cream->inst, i)) {
6039 if (i == Rn) 6041 if (i == Rn)
6040 Memory::Write32(addr, old_RN); 6042 WriteMemory32(cpu, addr, old_RN);
6041 else 6043 else
6042 Memory::Write32(addr, cpu->Reg[i]); 6044 WriteMemory32(cpu, addr, cpu->Reg[i]);
6043 6045
6044 addr += 4; 6046 addr += 4;
6045 } 6047 }
@@ -6047,7 +6049,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
6047 6049
6048 // Check PC reg 6050 // Check PC reg
6049 if (BIT(inst_cream->inst, 15)) 6051 if (BIT(inst_cream->inst, 15))
6050 Memory::Write32(addr, cpu->Reg_usr[1] + 8); 6052 WriteMemory32(cpu, addr, cpu->Reg_usr[1] + 8);
6051 } 6053 }
6052 } 6054 }
6053 cpu->Reg[15] += GET_INST_SIZE(cpu); 6055 cpu->Reg[15] += GET_INST_SIZE(cpu);
@@ -6080,7 +6082,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
6080 inst_cream->get_addr(cpu, inst_cream->inst, addr, 0); 6082 inst_cream->get_addr(cpu, inst_cream->inst, addr, 0);
6081 6083
6082 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; 6084 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)];
6083 Memory::Write32(addr, value); 6085 WriteMemory32(cpu, addr, value);
6084 } 6086 }
6085 cpu->Reg[15] += GET_INST_SIZE(cpu); 6087 cpu->Reg[15] += GET_INST_SIZE(cpu);
6086 INC_PC(sizeof(ldst_inst)); 6088 INC_PC(sizeof(ldst_inst));
@@ -6143,10 +6145,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
6143 ldst_inst* inst_cream = (ldst_inst*)inst_base->component; 6145 ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
6144 inst_cream->get_addr(cpu, inst_cream->inst, addr, 0); 6146 inst_cream->get_addr(cpu, inst_cream->inst, addr, 0);
6145 6147
6146 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; 6148 // The 3DS doesn't have the Large Physical Access Extension (LPAE)
6147 Memory::Write32(addr, value); 6149 // so STRD wouldn't store these as a single write.
6148 value = cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1]; 6150 WriteMemory32(cpu, addr + 0, cpu->Reg[BITS(inst_cream->inst, 12, 15)]);
6149 Memory::Write32(addr + 4, value); 6151 WriteMemory32(cpu, addr + 4, cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1]);
6150 } 6152 }
6151 cpu->Reg[15] += GET_INST_SIZE(cpu); 6153 cpu->Reg[15] += GET_INST_SIZE(cpu);
6152 INC_PC(sizeof(ldst_inst)); 6154 INC_PC(sizeof(ldst_inst));
@@ -6163,7 +6165,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
6163 remove_exclusive(cpu, write_addr); 6165 remove_exclusive(cpu, write_addr);
6164 cpu->exclusive_state = 0; 6166 cpu->exclusive_state = 0;
6165 6167
6166 Memory::Write32(write_addr, cpu->Reg[inst_cream->Rm]); 6168 WriteMemory32(cpu, write_addr, RM);
6167 RD = 0; 6169 RD = 0;
6168 } else { 6170 } else {
6169 // Failed to write due to mutex access 6171 // Failed to write due to mutex access
@@ -6207,8 +6209,16 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
6207 remove_exclusive(cpu, write_addr); 6209 remove_exclusive(cpu, write_addr);
6208 cpu->exclusive_state = 0; 6210 cpu->exclusive_state = 0;
6209 6211
6210 Memory::Write32(write_addr, cpu->Reg[inst_cream->Rm]); 6212 const u32 rt = cpu->Reg[inst_cream->Rm + 0];
6211 Memory::Write32(write_addr + 4, cpu->Reg[inst_cream->Rm + 1]); 6213 const u32 rt2 = cpu->Reg[inst_cream->Rm + 1];
6214 u64 value;
6215
6216 if (InBigEndianMode(cpu))
6217 value = (((u64)rt << 32) | rt2);
6218 else
6219 value = (((u64)rt2 << 32) | rt);
6220
6221 WriteMemory64(cpu, write_addr, value);
6212 RD = 0; 6222 RD = 0;
6213 } 6223 }
6214 else { 6224 else {
@@ -6231,7 +6241,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
6231 remove_exclusive(cpu, write_addr); 6241 remove_exclusive(cpu, write_addr);
6232 cpu->exclusive_state = 0; 6242 cpu->exclusive_state = 0;
6233 6243
6234 Memory::Write16(write_addr, cpu->Reg[inst_cream->Rm]); 6244 WriteMemory16(cpu, write_addr, RM);
6235 RD = 0; 6245 RD = 0;
6236 } else { 6246 } else {
6237 // Failed to write due to mutex access 6247 // Failed to write due to mutex access
@@ -6250,7 +6260,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
6250 inst_cream->get_addr(cpu, inst_cream->inst, addr, 0); 6260 inst_cream->get_addr(cpu, inst_cream->inst, addr, 0);
6251 6261
6252 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xffff; 6262 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xffff;
6253 Memory::Write16(addr, value); 6263 WriteMemory16(cpu, addr, value);
6254 } 6264 }
6255 cpu->Reg[15] += GET_INST_SIZE(cpu); 6265 cpu->Reg[15] += GET_INST_SIZE(cpu);
6256 INC_PC(sizeof(ldst_inst)); 6266 INC_PC(sizeof(ldst_inst));
@@ -6264,7 +6274,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
6264 inst_cream->get_addr(cpu, inst_cream->inst, addr, 0); 6274 inst_cream->get_addr(cpu, inst_cream->inst, addr, 0);
6265 6275
6266 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; 6276 unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)];
6267 Memory::Write32(addr, value); 6277 WriteMemory32(cpu, addr, value);
6268 } 6278 }
6269 cpu->Reg[15] += GET_INST_SIZE(cpu); 6279 cpu->Reg[15] += GET_INST_SIZE(cpu);
6270 INC_PC(sizeof(ldst_inst)); 6280 INC_PC(sizeof(ldst_inst));
@@ -6323,8 +6333,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
6323 swp_inst* inst_cream = (swp_inst*)inst_base->component; 6333 swp_inst* inst_cream = (swp_inst*)inst_base->component;
6324 6334
6325 addr = RN; 6335 addr = RN;
6326 unsigned int value = Memory::Read32(addr); 6336 unsigned int value = ReadMemory32(cpu, addr);
6327 Memory::Write32(addr, RM); 6337 WriteMemory32(cpu, addr, RM);
6328 6338
6329 RD = value; 6339 RD = value;
6330 } 6340 }
diff --git a/src/core/arm/interpreter/armsupp.cpp b/src/core/arm/interpreter/armsupp.cpp
index ed4f6c2a2..aca2bfbbd 100644
--- a/src/core/arm/interpreter/armsupp.cpp
+++ b/src/core/arm/interpreter/armsupp.cpp
@@ -201,3 +201,9 @@ u32 ARMul_UnsignedSatQ(s32 value, u8 shift, bool* saturation_occurred)
201 *saturation_occurred = false; 201 *saturation_occurred = false;
202 return (u32)value; 202 return (u32)value;
203} 203}
204
205// Whether or not the given CPU is in big endian mode (E bit is set)
206bool InBigEndianMode(ARMul_State* cpu)
207{
208 return (cpu->Cpsr & (1 << 9)) != 0;
209}
diff --git a/src/core/arm/skyeye_common/armdefs.h b/src/core/arm/skyeye_common/armdefs.h
index 16f3ac86c..c1a19fecc 100644
--- a/src/core/arm/skyeye_common/armdefs.h
+++ b/src/core/arm/skyeye_common/armdefs.h
@@ -18,7 +18,6 @@
18#pragma once 18#pragma once
19 19
20#include "common/common_types.h" 20#include "common/common_types.h"
21#include "core/arm/skyeye_common/armmmu.h"
22#include "core/arm/skyeye_common/arm_regformat.h" 21#include "core/arm/skyeye_common/arm_regformat.h"
23#include "core/arm/skyeye_common/skyeye_defs.h" 22#include "core/arm/skyeye_common/skyeye_defs.h"
24 23
@@ -356,3 +355,5 @@ extern u16 ARMul_UnsignedSaturatedSub16(u16, u16);
356extern u8 ARMul_UnsignedAbsoluteDifference(u8, u8); 355extern u8 ARMul_UnsignedAbsoluteDifference(u8, u8);
357extern u32 ARMul_SignedSatQ(s32, u8, bool*); 356extern u32 ARMul_SignedSatQ(s32, u8, bool*);
358extern u32 ARMul_UnsignedSatQ(s32, u8, bool*); 357extern u32 ARMul_UnsignedSatQ(s32, u8, bool*);
358
359extern bool InBigEndianMode(ARMul_State*);
diff --git a/src/core/arm/skyeye_common/armmmu.h b/src/core/arm/skyeye_common/armmmu.h
index 6e54142ee..0f9eadafa 100644
--- a/src/core/arm/skyeye_common/armmmu.h
+++ b/src/core/arm/skyeye_common/armmmu.h
@@ -20,6 +20,9 @@
20 20
21#pragma once 21#pragma once
22 22
23#include "core/mem_map.h"
24#include "core/arm/skyeye_common/armdefs.h"
25
23// Register numbers in the MMU 26// Register numbers in the MMU
24enum 27enum
25{ 28{
@@ -54,3 +57,55 @@ enum
54 XSCALE_CP15_AUX_CONTROL = 1, 57 XSCALE_CP15_AUX_CONTROL = 1,
55 XSCALE_CP15_COPRO_ACCESS = 15, 58 XSCALE_CP15_COPRO_ACCESS = 15,
56}; 59};
60
61// Reads data in big/little endian format based on the
62// state of the E (endian) bit in the emulated CPU's APSR.
63inline u16 ReadMemory16(ARMul_State* cpu, u32 address) {
64 u16 data = Memory::Read16(address);
65
66 if (InBigEndianMode(cpu))
67 data = Common::swap16(data);
68
69 return data;
70}
71
72inline u32 ReadMemory32(ARMul_State* cpu, u32 address) {
73 u32 data = Memory::Read32(address);
74
75 if (InBigEndianMode(cpu))
76 data = Common::swap32(data);
77
78 return data;
79}
80
81inline u64 ReadMemory64(ARMul_State* cpu, u32 address) {
82 u64 data = Memory::Read64(address);
83
84 if (InBigEndianMode(cpu))
85 data = Common::swap64(data);
86
87 return data;
88}
89
90// Writes data in big/little endian format based on the
91// state of the E (endian) bit in the emulated CPU's APSR.
92inline void WriteMemory16(ARMul_State* cpu, u32 address, u16 data) {
93 if (InBigEndianMode(cpu))
94 data = Common::swap16(data);
95
96 Memory::Write16(address, data);
97}
98
99inline void WriteMemory32(ARMul_State* cpu, u32 address, u32 data) {
100 if (InBigEndianMode(cpu))
101 data = Common::swap32(data);
102
103 Memory::Write32(address, data);
104}
105
106inline void WriteMemory64(ARMul_State* cpu, u32 address, u64 data) {
107 if (InBigEndianMode(cpu))
108 data = Common::swap64(data);
109
110 Memory::Write64(address, data);
111}
diff --git a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
index b9b96c388..368b5a25d 100644
--- a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
+++ b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
@@ -1388,12 +1388,20 @@ VSTR_INST:
1388 1388
1389 if (inst_cream->single) 1389 if (inst_cream->single)
1390 { 1390 {
1391 Memory::Write32(addr, cpu->ExtReg[inst_cream->d]); 1391 WriteMemory32(cpu, addr, cpu->ExtReg[inst_cream->d]);
1392 } 1392 }
1393 else 1393 else
1394 { 1394 {
1395 Memory::Write32(addr, cpu->ExtReg[inst_cream->d*2]); 1395 const u32 word1 = cpu->ExtReg[inst_cream->d*2+0];
1396 Memory::Write32(addr + 4, cpu->ExtReg[inst_cream->d*2+1]); 1396 const u32 word2 = cpu->ExtReg[inst_cream->d*2+1];
1397
1398 if (InBigEndianMode(cpu)) {
1399 WriteMemory32(cpu, addr + 0, word2);
1400 WriteMemory32(cpu, addr + 4, word1);
1401 } else {
1402 WriteMemory32(cpu, addr + 0, word1);
1403 WriteMemory32(cpu, addr + 4, word2);
1404 }
1397 } 1405 }
1398 } 1406 }
1399 cpu->Reg[15] += GET_INST_SIZE(cpu); 1407 cpu->Reg[15] += GET_INST_SIZE(cpu);
@@ -1447,17 +1455,27 @@ VPUSH_INST:
1447 { 1455 {
1448 if (inst_cream->single) 1456 if (inst_cream->single)
1449 { 1457 {
1450 Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]); 1458 WriteMemory32(cpu, addr, cpu->ExtReg[inst_cream->d+i]);
1451 addr += 4; 1459 addr += 4;
1452 } 1460 }
1453 else 1461 else
1454 { 1462 {
1455 Memory::Write32(addr, cpu->ExtReg[(inst_cream->d+i)*2]); 1463 const u32 word1 = cpu->ExtReg[(inst_cream->d+i)*2+0];
1456 Memory::Write32(addr + 4, cpu->ExtReg[(inst_cream->d+i)*2 + 1]); 1464 const u32 word2 = cpu->ExtReg[(inst_cream->d+i)*2+1];
1465
1466 if (InBigEndianMode(cpu)) {
1467 WriteMemory32(cpu, addr + 0, word2);
1468 WriteMemory32(cpu, addr + 4, word1);
1469 } else {
1470 WriteMemory32(cpu, addr + 0, word1);
1471 WriteMemory32(cpu, addr + 4, word2);
1472 }
1473
1457 addr += 8; 1474 addr += 8;
1458 } 1475 }
1459 } 1476 }
1460 cpu->Reg[R13] = cpu->Reg[R13] - inst_cream->imm32; 1477
1478 cpu->Reg[R13] -= inst_cream->imm32;
1461 } 1479 }
1462 cpu->Reg[15] += GET_INST_SIZE(cpu); 1480 cpu->Reg[15] += GET_INST_SIZE(cpu);
1463 INC_PC(sizeof(vpush_inst)); 1481 INC_PC(sizeof(vpush_inst));
@@ -1516,13 +1534,22 @@ VSTM_INST: /* encoding 1 */
1516 { 1534 {
1517 if (inst_cream->single) 1535 if (inst_cream->single)
1518 { 1536 {
1519 Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]); 1537 WriteMemory32(cpu, addr, cpu->ExtReg[inst_cream->d+i]);
1520 addr += 4; 1538 addr += 4;
1521 } 1539 }
1522 else 1540 else
1523 { 1541 {
1524 Memory::Write32(addr, cpu->ExtReg[(inst_cream->d+i)*2]); 1542 const u32 word1 = cpu->ExtReg[(inst_cream->d+i)*2+0];
1525 Memory::Write32(addr + 4, cpu->ExtReg[(inst_cream->d+i)*2 + 1]); 1543 const u32 word2 = cpu->ExtReg[(inst_cream->d+i)*2+1];
1544
1545 if (InBigEndianMode(cpu)) {
1546 WriteMemory32(cpu, addr + 0, word2);
1547 WriteMemory32(cpu, addr + 4, word1);
1548 } else {
1549 WriteMemory32(cpu, addr + 0, word1);
1550 WriteMemory32(cpu, addr + 4, word2);
1551 }
1552
1526 addr += 8; 1553 addr += 8;
1527 } 1554 }
1528 } 1555 }
@@ -1575,8 +1602,6 @@ VPOP_INST:
1575 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 1602 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
1576 CHECK_VFP_ENABLED; 1603 CHECK_VFP_ENABLED;
1577 1604
1578 unsigned int value1, value2;
1579
1580 vpop_inst *inst_cream = (vpop_inst *)inst_base->component; 1605 vpop_inst *inst_cream = (vpop_inst *)inst_base->component;
1581 1606
1582 addr = cpu->Reg[R13]; 1607 addr = cpu->Reg[R13];
@@ -1585,20 +1610,26 @@ VPOP_INST:
1585 { 1610 {
1586 if (inst_cream->single) 1611 if (inst_cream->single)
1587 { 1612 {
1588 value1 = Memory::Read32(addr); 1613 cpu->ExtReg[inst_cream->d+i] = ReadMemory32(cpu, addr);
1589 cpu->ExtReg[inst_cream->d+i] = value1;
1590 addr += 4; 1614 addr += 4;
1591 } 1615 }
1592 else 1616 else
1593 { 1617 {
1594 value1 = Memory::Read32(addr); 1618 const u32 word1 = ReadMemory32(cpu, addr + 0);
1595 value2 = Memory::Read32(addr + 4); 1619 const u32 word2 = ReadMemory32(cpu, addr + 4);
1596 cpu->ExtReg[(inst_cream->d+i)*2] = value1; 1620
1597 cpu->ExtReg[(inst_cream->d+i)*2 + 1] = value2; 1621 if (InBigEndianMode(cpu)) {
1622 cpu->ExtReg[(inst_cream->d+i)*2+0] = word2;
1623 cpu->ExtReg[(inst_cream->d+i)*2+1] = word1;
1624 } else {
1625 cpu->ExtReg[(inst_cream->d+i)*2+0] = word1;
1626 cpu->ExtReg[(inst_cream->d+i)*2+1] = word2;
1627 }
1628
1598 addr += 8; 1629 addr += 8;
1599 } 1630 }
1600 } 1631 }
1601 cpu->Reg[R13] = cpu->Reg[R13] + inst_cream->imm32; 1632 cpu->Reg[R13] += inst_cream->imm32;
1602 } 1633 }
1603 cpu->Reg[15] += GET_INST_SIZE(cpu); 1634 cpu->Reg[15] += GET_INST_SIZE(cpu);
1604 INC_PC(sizeof(vpop_inst)); 1635 INC_PC(sizeof(vpop_inst));
@@ -1653,16 +1684,20 @@ VLDR_INST:
1653 1684
1654 if (inst_cream->single) 1685 if (inst_cream->single)
1655 { 1686 {
1656 cpu->ExtReg[inst_cream->d] = Memory::Read32(addr); 1687 cpu->ExtReg[inst_cream->d] = ReadMemory32(cpu, addr);
1657 } 1688 }
1658 else 1689 else
1659 { 1690 {
1660 unsigned int word1, word2; 1691 const u32 word1 = ReadMemory32(cpu, addr + 0);
1661 word1 = Memory::Read32(addr); 1692 const u32 word2 = ReadMemory32(cpu, addr + 4);
1662 word2 = Memory::Read32(addr + 4); 1693
1663 1694 if (InBigEndianMode(cpu)) {
1664 cpu->ExtReg[inst_cream->d*2] = word1; 1695 cpu->ExtReg[inst_cream->d*2+0] = word2;
1665 cpu->ExtReg[inst_cream->d*2+1] = word2; 1696 cpu->ExtReg[inst_cream->d*2+1] = word1;
1697 } else {
1698 cpu->ExtReg[inst_cream->d*2+0] = word1;
1699 cpu->ExtReg[inst_cream->d*2+1] = word2;
1700 }
1666 } 1701 }
1667 } 1702 }
1668 cpu->Reg[15] += GET_INST_SIZE(cpu); 1703 cpu->Reg[15] += GET_INST_SIZE(cpu);
@@ -1722,13 +1757,22 @@ VLDM_INST:
1722 { 1757 {
1723 if (inst_cream->single) 1758 if (inst_cream->single)
1724 { 1759 {
1725 cpu->ExtReg[inst_cream->d+i] = Memory::Read32(addr); 1760 cpu->ExtReg[inst_cream->d+i] = ReadMemory32(cpu, addr);
1726 addr += 4; 1761 addr += 4;
1727 } 1762 }
1728 else 1763 else
1729 { 1764 {
1730 cpu->ExtReg[(inst_cream->d+i)*2] = Memory::Read32(addr); 1765 const u32 word1 = ReadMemory32(cpu, addr + 0);
1731 cpu->ExtReg[(inst_cream->d+i)*2 + 1] = Memory::Read32(addr + 4); 1766 const u32 word2 = ReadMemory32(cpu, addr + 4);
1767
1768 if (InBigEndianMode(cpu)) {
1769 cpu->ExtReg[(inst_cream->d+i)*2+0] = word2;
1770 cpu->ExtReg[(inst_cream->d+i)*2+1] = word1;
1771 } else {
1772 cpu->ExtReg[(inst_cream->d+i)*2+0] = word1;
1773 cpu->ExtReg[(inst_cream->d+i)*2+1] = word2;
1774 }
1775
1732 addr += 8; 1776 addr += 8;
1733 } 1777 }
1734 } 1778 }
diff --git a/src/core/mem_map.h b/src/core/mem_map.h
index 8f4f21fec..bce99dffa 100644
--- a/src/core/mem_map.h
+++ b/src/core/mem_map.h
@@ -147,6 +147,7 @@ inline void Write(VAddr addr, T data);
147u8 Read8(VAddr addr); 147u8 Read8(VAddr addr);
148u16 Read16(VAddr addr); 148u16 Read16(VAddr addr);
149u32 Read32(VAddr addr); 149u32 Read32(VAddr addr);
150u64 Read64(VAddr addr);
150 151
151u32 Read8_ZX(VAddr addr); 152u32 Read8_ZX(VAddr addr);
152u32 Read16_ZX(VAddr addr); 153u32 Read16_ZX(VAddr addr);
diff --git a/src/core/mem_map_funcs.cpp b/src/core/mem_map_funcs.cpp
index 48f61db4e..a161a8204 100644
--- a/src/core/mem_map_funcs.cpp
+++ b/src/core/mem_map_funcs.cpp
@@ -245,6 +245,12 @@ u32 Read32(const VAddr addr) {
245 return (u32)data; 245 return (u32)data;
246} 246}
247 247
248u64 Read64(const VAddr addr) {
249 u64_le data = 0;
250 Read<u64_le>(data, addr);
251 return (u64)data;
252}
253
248u32 Read8_ZX(const VAddr addr) { 254u32 Read8_ZX(const VAddr addr) {
249 return (u32)Read8(addr); 255 return (u32)Read8(addr);
250} 256}