summaryrefslogtreecommitdiff
path: root/src/core/arm/dyncom
diff options
context:
space:
mode:
authorGravatar Lioncash2015-03-11 16:10:14 -0400
committerGravatar Lioncash2015-03-17 15:13:32 -0400
commit9fdb311d6e2d636c4599ddc3d4cb9adad6cec540 (patch)
tree358501f8f2e31c7c27ee17c62996ef01e21354c7 /src/core/arm/dyncom
parentdyncom: Implement SETEND (diff)
downloadyuzu-9fdb311d6e2d636c4599ddc3d4cb9adad6cec540.tar.gz
yuzu-9fdb311d6e2d636c4599ddc3d4cb9adad6cec540.tar.xz
yuzu-9fdb311d6e2d636c4599ddc3d4cb9adad6cec540.zip
dyncom: Make Load/Store instructions support big endian
Diffstat (limited to 'src/core/arm/dyncom')
-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 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 }