diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_interpreter.cpp | 150 | ||||
| -rw-r--r-- | src/core/arm/interpreter/armsupp.cpp | 6 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/armdefs.h | 3 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/armmmu.h | 55 | ||||
| -rw-r--r-- | src/core/arm/skyeye_common/vfp/vfpinstr.cpp | 102 | ||||
| -rw-r--r-- | src/core/mem_map.h | 1 | ||||
| -rw-r--r-- | src/core/mem_map_funcs.cpp | 6 |
7 files changed, 240 insertions, 83 deletions
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp index d953adba9..cfa6de8fc 100644 --- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp +++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp | |||
| @@ -1075,6 +1075,10 @@ typedef struct _swp_inst { | |||
| 1075 | unsigned int Rm; | 1075 | unsigned int Rm; |
| 1076 | } swp_inst; | 1076 | } swp_inst; |
| 1077 | 1077 | ||
| 1078 | typedef struct setend_inst { | ||
| 1079 | unsigned int set_bigend; | ||
| 1080 | } setend_inst; | ||
| 1081 | |||
| 1078 | typedef struct _b_2_thumb { | 1082 | typedef struct _b_2_thumb { |
| 1079 | unsigned int imm; | 1083 | unsigned int imm; |
| 1080 | }b_2_thumb; | 1084 | }b_2_thumb; |
| @@ -2283,7 +2287,20 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(sel)(unsigned int inst, int index) | |||
| 2283 | return inst_base; | 2287 | return inst_base; |
| 2284 | } | 2288 | } |
| 2285 | 2289 | ||
| 2286 | static ARM_INST_PTR INTERPRETER_TRANSLATE(setend)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SETEND"); } | 2290 | static ARM_INST_PTR INTERPRETER_TRANSLATE(setend)(unsigned int inst, int index) |
| 2291 | { | ||
| 2292 | arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(setend_inst)); | ||
| 2293 | setend_inst* const inst_cream = (setend_inst*)inst_base->component; | ||
| 2294 | |||
| 2295 | inst_base->cond = AL; | ||
| 2296 | inst_base->idx = index; | ||
| 2297 | inst_base->br = NON_BRANCH; | ||
| 2298 | inst_base->load_r15 = 0; | ||
| 2299 | |||
| 2300 | inst_cream->set_bigend = BIT(inst, 9); | ||
| 2301 | |||
| 2302 | return inst_base; | ||
| 2303 | } | ||
| 2287 | 2304 | ||
| 2288 | static ARM_INST_PTR INTERPRETER_TRANSLATE(shadd8)(unsigned int inst, int index) | 2305 | static ARM_INST_PTR INTERPRETER_TRANSLATE(shadd8)(unsigned int inst, int index) |
| 2289 | { | 2306 | { |
| @@ -4345,30 +4362,30 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 4345 | if (BIT(inst, 22) && !BIT(inst, 15)) { | 4362 | if (BIT(inst, 22) && !BIT(inst, 15)) { |
| 4346 | for (int i = 0; i < 13; i++) { | 4363 | for (int i = 0; i < 13; i++) { |
| 4347 | if(BIT(inst, i)) { | 4364 | if(BIT(inst, i)) { |
| 4348 | cpu->Reg[i] = Memory::Read32(addr); | 4365 | cpu->Reg[i] = ReadMemory32(cpu, addr); |
| 4349 | addr += 4; | 4366 | addr += 4; |
| 4350 | } | 4367 | } |
| 4351 | } | 4368 | } |
| 4352 | if (BIT(inst, 13)) { | 4369 | if (BIT(inst, 13)) { |
| 4353 | if (cpu->Mode == USER32MODE) | 4370 | if (cpu->Mode == USER32MODE) |
| 4354 | cpu->Reg[13] = Memory::Read32(addr); | 4371 | cpu->Reg[13] = ReadMemory32(cpu, addr); |
| 4355 | else | 4372 | else |
| 4356 | cpu->Reg_usr[0] = Memory::Read32(addr); | 4373 | cpu->Reg_usr[0] = ReadMemory32(cpu, addr); |
| 4357 | 4374 | ||
| 4358 | addr += 4; | 4375 | addr += 4; |
| 4359 | } | 4376 | } |
| 4360 | if (BIT(inst, 14)) { | 4377 | if (BIT(inst, 14)) { |
| 4361 | if (cpu->Mode == USER32MODE) | 4378 | if (cpu->Mode == USER32MODE) |
| 4362 | cpu->Reg[14] = Memory::Read32(addr); | 4379 | cpu->Reg[14] = ReadMemory32(cpu, addr); |
| 4363 | else | 4380 | else |
| 4364 | cpu->Reg_usr[1] = Memory::Read32(addr); | 4381 | cpu->Reg_usr[1] = ReadMemory32(cpu, addr); |
| 4365 | 4382 | ||
| 4366 | addr += 4; | 4383 | addr += 4; |
| 4367 | } | 4384 | } |
| 4368 | } else if (!BIT(inst, 22)) { | 4385 | } else if (!BIT(inst, 22)) { |
| 4369 | for(int i = 0; i < 16; i++ ){ | 4386 | for(int i = 0; i < 16; i++ ){ |
| 4370 | if(BIT(inst, i)){ | 4387 | if(BIT(inst, i)){ |
| 4371 | unsigned int ret = Memory::Read32(addr); | 4388 | unsigned int ret = ReadMemory32(cpu, addr); |
| 4372 | 4389 | ||
| 4373 | // For armv5t, should enter thumb when bits[0] is non-zero. | 4390 | // For armv5t, should enter thumb when bits[0] is non-zero. |
| 4374 | if(i == 15){ | 4391 | if(i == 15){ |
| @@ -4383,7 +4400,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 4383 | } else if (BIT(inst, 22) && BIT(inst, 15)) { | 4400 | } else if (BIT(inst, 22) && BIT(inst, 15)) { |
| 4384 | for(int i = 0; i < 15; i++ ){ | 4401 | for(int i = 0; i < 15; i++ ){ |
| 4385 | if(BIT(inst, i)){ | 4402 | if(BIT(inst, i)){ |
| 4386 | cpu->Reg[i] = Memory::Read32(addr); | 4403 | cpu->Reg[i] = ReadMemory32(cpu, addr); |
| 4387 | addr += 4; | 4404 | addr += 4; |
| 4388 | } | 4405 | } |
| 4389 | } | 4406 | } |
| @@ -4394,7 +4411,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 4394 | LOAD_NZCVT; | 4411 | LOAD_NZCVT; |
| 4395 | } | 4412 | } |
| 4396 | 4413 | ||
| 4397 | cpu->Reg[15] = Memory::Read32(addr); | 4414 | cpu->Reg[15] = ReadMemory32(cpu, addr); |
| 4398 | } | 4415 | } |
| 4399 | 4416 | ||
| 4400 | if (BIT(inst, 15)) { | 4417 | if (BIT(inst, 15)) { |
| @@ -4428,20 +4445,18 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 4428 | LDR_INST: | 4445 | LDR_INST: |
| 4429 | { | 4446 | { |
| 4430 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 4447 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 4431 | //if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4448 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); |
| 4432 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); | ||
| 4433 | 4449 | ||
| 4434 | unsigned int value = Memory::Read32(addr); | 4450 | unsigned int value = ReadMemory32(cpu, addr); |
| 4435 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | 4451 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; |
| 4436 | 4452 | ||
| 4437 | if (BITS(inst_cream->inst, 12, 15) == 15) { | 4453 | if (BITS(inst_cream->inst, 12, 15) == 15) { |
| 4438 | // For armv5t, should enter thumb when bits[0] is non-zero. | 4454 | // For armv5t, should enter thumb when bits[0] is non-zero. |
| 4439 | cpu->TFlag = value & 0x1; | 4455 | cpu->TFlag = value & 0x1; |
| 4440 | cpu->Reg[15] &= 0xFFFFFFFE; | 4456 | cpu->Reg[15] &= 0xFFFFFFFE; |
| 4441 | INC_PC(sizeof(ldst_inst)); | 4457 | INC_PC(sizeof(ldst_inst)); |
| 4442 | goto DISPATCH; | 4458 | goto DISPATCH; |
| 4443 | } | 4459 | } |
| 4444 | //} | ||
| 4445 | 4460 | ||
| 4446 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4461 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4447 | INC_PC(sizeof(ldst_inst)); | 4462 | INC_PC(sizeof(ldst_inst)); |
| @@ -4454,7 +4469,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 4454 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 4469 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 4455 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); | 4470 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); |
| 4456 | 4471 | ||
| 4457 | unsigned int value = Memory::Read32(addr); | 4472 | unsigned int value = ReadMemory32(cpu, addr); |
| 4458 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | 4473 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; |
| 4459 | 4474 | ||
| 4460 | if (BITS(inst_cream->inst, 12, 15) == 15) { | 4475 | if (BITS(inst_cream->inst, 12, 15) == 15) { |
| @@ -4537,8 +4552,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 4537 | // 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) |
| 4538 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); | 4553 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); |
| 4539 | 4554 | ||
| 4540 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = Memory::Read32(addr); | 4555 | // The 3DS doesn't have LPAE (Large Physical Access Extension), so it |
| 4541 | 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); | ||
| 4542 | 4559 | ||
| 4543 | // No dispatch since this operation should not modify R15 | 4560 | // No dispatch since this operation should not modify R15 |
| 4544 | } | 4561 | } |
| @@ -4557,7 +4574,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 4557 | add_exclusive_addr(cpu, read_addr); | 4574 | add_exclusive_addr(cpu, read_addr); |
| 4558 | cpu->exclusive_state = 1; | 4575 | cpu->exclusive_state = 1; |
| 4559 | 4576 | ||
| 4560 | RD = Memory::Read32(read_addr); | 4577 | RD = ReadMemory32(cpu, read_addr); |
| 4561 | if (inst_cream->Rd == 15) { | 4578 | if (inst_cream->Rd == 15) { |
| 4562 | INC_PC(sizeof(generic_arm_inst)); | 4579 | INC_PC(sizeof(generic_arm_inst)); |
| 4563 | goto DISPATCH; | 4580 | goto DISPATCH; |
| @@ -4597,7 +4614,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 4597 | add_exclusive_addr(cpu, read_addr); | 4614 | add_exclusive_addr(cpu, read_addr); |
| 4598 | cpu->exclusive_state = 1; | 4615 | cpu->exclusive_state = 1; |
| 4599 | 4616 | ||
| 4600 | RD = Memory::Read16(read_addr); | 4617 | RD = ReadMemory16(cpu, read_addr); |
| 4601 | if (inst_cream->Rd == 15) { | 4618 | if (inst_cream->Rd == 15) { |
| 4602 | INC_PC(sizeof(generic_arm_inst)); | 4619 | INC_PC(sizeof(generic_arm_inst)); |
| 4603 | goto DISPATCH; | 4620 | goto DISPATCH; |
| @@ -4617,8 +4634,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 4617 | add_exclusive_addr(cpu, read_addr); | 4634 | add_exclusive_addr(cpu, read_addr); |
| 4618 | cpu->exclusive_state = 1; | 4635 | cpu->exclusive_state = 1; |
| 4619 | 4636 | ||
| 4620 | RD = Memory::Read32(read_addr); | 4637 | RD = ReadMemory32(cpu, read_addr); |
| 4621 | RD2 = Memory::Read32(read_addr + 4); | 4638 | RD2 = ReadMemory32(cpu, read_addr + 4); |
| 4622 | 4639 | ||
| 4623 | if (inst_cream->Rd == 15) { | 4640 | if (inst_cream->Rd == 15) { |
| 4624 | INC_PC(sizeof(generic_arm_inst)); | 4641 | INC_PC(sizeof(generic_arm_inst)); |
| @@ -4635,7 +4652,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 4635 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | 4652 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { |
| 4636 | ldst_inst* inst_cream = (ldst_inst*)inst_base->component; | 4653 | ldst_inst* inst_cream = (ldst_inst*)inst_base->component; |
| 4637 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); | 4654 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); |
| 4638 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = Memory::Read16(addr); | 4655 | |
| 4656 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = ReadMemory16(cpu, addr); | ||
| 4639 | if (BITS(inst_cream->inst, 12, 15) == 15) { | 4657 | if (BITS(inst_cream->inst, 12, 15) == 15) { |
| 4640 | INC_PC(sizeof(ldst_inst)); | 4658 | INC_PC(sizeof(ldst_inst)); |
| 4641 | goto DISPATCH; | 4659 | goto DISPATCH; |
| @@ -4671,7 +4689,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 4671 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | 4689 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { |
| 4672 | ldst_inst* inst_cream = (ldst_inst*)inst_base->component; | 4690 | ldst_inst* inst_cream = (ldst_inst*)inst_base->component; |
| 4673 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); | 4691 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); |
| 4674 | unsigned int value = Memory::Read16(addr); | 4692 | |
| 4693 | unsigned int value = ReadMemory16(cpu, addr); | ||
| 4675 | if (BIT(value, 15)) { | 4694 | if (BIT(value, 15)) { |
| 4676 | value |= 0xffff0000; | 4695 | value |= 0xffff0000; |
| 4677 | } | 4696 | } |
| @@ -4692,7 +4711,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 4692 | ldst_inst* inst_cream = (ldst_inst*)inst_base->component; | 4711 | ldst_inst* inst_cream = (ldst_inst*)inst_base->component; |
| 4693 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); | 4712 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 1); |
| 4694 | 4713 | ||
| 4695 | unsigned int value = Memory::Read32(addr); | 4714 | unsigned int value = ReadMemory32(cpu, addr); |
| 4696 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | 4715 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; |
| 4697 | 4716 | ||
| 4698 | if (BITS(inst_cream->inst, 12, 15) == 15) { | 4717 | if (BITS(inst_cream->inst, 12, 15) == 15) { |
| @@ -5521,6 +5540,23 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 5521 | } | 5540 | } |
| 5522 | 5541 | ||
| 5523 | SETEND_INST: | 5542 | SETEND_INST: |
| 5543 | { | ||
| 5544 | // SETEND is unconditional | ||
| 5545 | setend_inst* const inst_cream = (setend_inst*)inst_base->component; | ||
| 5546 | const bool big_endian = (inst_cream->set_bigend == 1); | ||
| 5547 | |||
| 5548 | if (big_endian) | ||
| 5549 | cpu->Cpsr |= (1 << 9); | ||
| 5550 | else | ||
| 5551 | cpu->Cpsr &= ~(1 << 9); | ||
| 5552 | |||
| 5553 | LOG_WARNING(Core_ARM11, "SETEND %s executed", big_endian ? "BE" : "LE"); | ||
| 5554 | |||
| 5555 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5556 | INC_PC(sizeof(setend_inst)); | ||
| 5557 | FETCH_INST; | ||
| 5558 | GOTO_NEXT_INST; | ||
| 5559 | } | ||
| 5524 | 5560 | ||
| 5525 | SHADD8_INST: | 5561 | SHADD8_INST: |
| 5526 | SHADD16_INST: | 5562 | SHADD16_INST: |
| @@ -5976,36 +6012,36 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 5976 | if (BIT(inst_cream->inst, 22) == 1) { | 6012 | if (BIT(inst_cream->inst, 22) == 1) { |
| 5977 | for (int i = 0; i < 13; i++) { | 6013 | for (int i = 0; i < 13; i++) { |
| 5978 | if (BIT(inst_cream->inst, i)) { | 6014 | if (BIT(inst_cream->inst, i)) { |
| 5979 | Memory::Write32(addr, cpu->Reg[i]); | 6015 | WriteMemory32(cpu, addr, cpu->Reg[i]); |
| 5980 | addr += 4; | 6016 | addr += 4; |
| 5981 | } | 6017 | } |
| 5982 | } | 6018 | } |
| 5983 | if (BIT(inst_cream->inst, 13)) { | 6019 | if (BIT(inst_cream->inst, 13)) { |
| 5984 | if (cpu->Mode == USER32MODE) | 6020 | if (cpu->Mode == USER32MODE) |
| 5985 | Memory::Write32(addr, cpu->Reg[13]); | 6021 | WriteMemory32(cpu, addr, cpu->Reg[13]); |
| 5986 | else | 6022 | else |
| 5987 | Memory::Write32(addr, cpu->Reg_usr[0]); | 6023 | WriteMemory32(cpu, addr, cpu->Reg_usr[0]); |
| 5988 | 6024 | ||
| 5989 | addr += 4; | 6025 | addr += 4; |
| 5990 | } | 6026 | } |
| 5991 | if (BIT(inst_cream->inst, 14)) { | 6027 | if (BIT(inst_cream->inst, 14)) { |
| 5992 | if (cpu->Mode == USER32MODE) | 6028 | if (cpu->Mode == USER32MODE) |
| 5993 | Memory::Write32(addr, cpu->Reg[14]); | 6029 | WriteMemory32(cpu, addr, cpu->Reg[14]); |
| 5994 | else | 6030 | else |
| 5995 | Memory::Write32(addr, cpu->Reg_usr[1]); | 6031 | WriteMemory32(cpu, addr, cpu->Reg_usr[1]); |
| 5996 | 6032 | ||
| 5997 | addr += 4; | 6033 | addr += 4; |
| 5998 | } | 6034 | } |
| 5999 | if (BIT(inst_cream->inst, 15)) { | 6035 | if (BIT(inst_cream->inst, 15)) { |
| 6000 | Memory::Write32(addr, cpu->Reg_usr[1] + 8); | 6036 | WriteMemory32(cpu, addr, cpu->Reg_usr[1] + 8); |
| 6001 | } | 6037 | } |
| 6002 | } else { | 6038 | } else { |
| 6003 | for (int i = 0; i < 15; i++) { | 6039 | for (int i = 0; i < 15; i++) { |
| 6004 | if (BIT(inst_cream->inst, i)) { | 6040 | if (BIT(inst_cream->inst, i)) { |
| 6005 | if (i == Rn) | 6041 | if (i == Rn) |
| 6006 | Memory::Write32(addr, old_RN); | 6042 | WriteMemory32(cpu, addr, old_RN); |
| 6007 | else | 6043 | else |
| 6008 | Memory::Write32(addr, cpu->Reg[i]); | 6044 | WriteMemory32(cpu, addr, cpu->Reg[i]); |
| 6009 | 6045 | ||
| 6010 | addr += 4; | 6046 | addr += 4; |
| 6011 | } | 6047 | } |
| @@ -6013,7 +6049,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 6013 | 6049 | ||
| 6014 | // Check PC reg | 6050 | // Check PC reg |
| 6015 | if (BIT(inst_cream->inst, 15)) | 6051 | if (BIT(inst_cream->inst, 15)) |
| 6016 | Memory::Write32(addr, cpu->Reg_usr[1] + 8); | 6052 | WriteMemory32(cpu, addr, cpu->Reg_usr[1] + 8); |
| 6017 | } | 6053 | } |
| 6018 | } | 6054 | } |
| 6019 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6055 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| @@ -6046,7 +6082,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 6046 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 0); | 6082 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 0); |
| 6047 | 6083 | ||
| 6048 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; | 6084 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; |
| 6049 | Memory::Write32(addr, value); | 6085 | WriteMemory32(cpu, addr, value); |
| 6050 | } | 6086 | } |
| 6051 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6087 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6052 | INC_PC(sizeof(ldst_inst)); | 6088 | INC_PC(sizeof(ldst_inst)); |
| @@ -6109,10 +6145,10 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 6109 | ldst_inst* inst_cream = (ldst_inst*)inst_base->component; | 6145 | ldst_inst* inst_cream = (ldst_inst*)inst_base->component; |
| 6110 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 0); | 6146 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 0); |
| 6111 | 6147 | ||
| 6112 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; | 6148 | // The 3DS doesn't have the Large Physical Access Extension (LPAE) |
| 6113 | Memory::Write32(addr, value); | 6149 | // so STRD wouldn't store these as a single write. |
| 6114 | value = cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1]; | 6150 | WriteMemory32(cpu, addr + 0, cpu->Reg[BITS(inst_cream->inst, 12, 15)]); |
| 6115 | Memory::Write32(addr + 4, value); | 6151 | WriteMemory32(cpu, addr + 4, cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1]); |
| 6116 | } | 6152 | } |
| 6117 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6153 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6118 | INC_PC(sizeof(ldst_inst)); | 6154 | INC_PC(sizeof(ldst_inst)); |
| @@ -6129,7 +6165,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 6129 | remove_exclusive(cpu, write_addr); | 6165 | remove_exclusive(cpu, write_addr); |
| 6130 | cpu->exclusive_state = 0; | 6166 | cpu->exclusive_state = 0; |
| 6131 | 6167 | ||
| 6132 | Memory::Write32(write_addr, cpu->Reg[inst_cream->Rm]); | 6168 | WriteMemory32(cpu, write_addr, RM); |
| 6133 | RD = 0; | 6169 | RD = 0; |
| 6134 | } else { | 6170 | } else { |
| 6135 | // Failed to write due to mutex access | 6171 | // Failed to write due to mutex access |
| @@ -6173,8 +6209,16 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 6173 | remove_exclusive(cpu, write_addr); | 6209 | remove_exclusive(cpu, write_addr); |
| 6174 | cpu->exclusive_state = 0; | 6210 | cpu->exclusive_state = 0; |
| 6175 | 6211 | ||
| 6176 | Memory::Write32(write_addr, cpu->Reg[inst_cream->Rm]); | 6212 | const u32 rt = cpu->Reg[inst_cream->Rm + 0]; |
| 6177 | 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); | ||
| 6178 | RD = 0; | 6222 | RD = 0; |
| 6179 | } | 6223 | } |
| 6180 | else { | 6224 | else { |
| @@ -6197,7 +6241,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 6197 | remove_exclusive(cpu, write_addr); | 6241 | remove_exclusive(cpu, write_addr); |
| 6198 | cpu->exclusive_state = 0; | 6242 | cpu->exclusive_state = 0; |
| 6199 | 6243 | ||
| 6200 | Memory::Write16(write_addr, cpu->Reg[inst_cream->Rm]); | 6244 | WriteMemory16(cpu, write_addr, RM); |
| 6201 | RD = 0; | 6245 | RD = 0; |
| 6202 | } else { | 6246 | } else { |
| 6203 | // Failed to write due to mutex access | 6247 | // Failed to write due to mutex access |
| @@ -6216,7 +6260,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 6216 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 0); | 6260 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 0); |
| 6217 | 6261 | ||
| 6218 | 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; |
| 6219 | Memory::Write16(addr, value); | 6263 | WriteMemory16(cpu, addr, value); |
| 6220 | } | 6264 | } |
| 6221 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6265 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6222 | INC_PC(sizeof(ldst_inst)); | 6266 | INC_PC(sizeof(ldst_inst)); |
| @@ -6230,7 +6274,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 6230 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 0); | 6274 | inst_cream->get_addr(cpu, inst_cream->inst, addr, 0); |
| 6231 | 6275 | ||
| 6232 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; | 6276 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; |
| 6233 | Memory::Write32(addr, value); | 6277 | WriteMemory32(cpu, addr, value); |
| 6234 | } | 6278 | } |
| 6235 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6279 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 6236 | INC_PC(sizeof(ldst_inst)); | 6280 | INC_PC(sizeof(ldst_inst)); |
| @@ -6289,8 +6333,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 6289 | swp_inst* inst_cream = (swp_inst*)inst_base->component; | 6333 | swp_inst* inst_cream = (swp_inst*)inst_base->component; |
| 6290 | 6334 | ||
| 6291 | addr = RN; | 6335 | addr = RN; |
| 6292 | unsigned int value = Memory::Read32(addr); | 6336 | unsigned int value = ReadMemory32(cpu, addr); |
| 6293 | Memory::Write32(addr, RM); | 6337 | WriteMemory32(cpu, addr, RM); |
| 6294 | 6338 | ||
| 6295 | RD = value; | 6339 | RD = value; |
| 6296 | } | 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) | ||
| 206 | bool 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); | |||
| 356 | extern u8 ARMul_UnsignedAbsoluteDifference(u8, u8); | 355 | extern u8 ARMul_UnsignedAbsoluteDifference(u8, u8); |
| 357 | extern u32 ARMul_SignedSatQ(s32, u8, bool*); | 356 | extern u32 ARMul_SignedSatQ(s32, u8, bool*); |
| 358 | extern u32 ARMul_UnsignedSatQ(s32, u8, bool*); | 357 | extern u32 ARMul_UnsignedSatQ(s32, u8, bool*); |
| 358 | |||
| 359 | extern 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 |
| 24 | enum | 27 | enum |
| 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. | ||
| 63 | inline 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 | |||
| 72 | inline 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 | |||
| 81 | inline 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. | ||
| 92 | inline 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 | |||
| 99 | inline 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 | |||
| 106 | inline 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); | |||
| 147 | u8 Read8(VAddr addr); | 147 | u8 Read8(VAddr addr); |
| 148 | u16 Read16(VAddr addr); | 148 | u16 Read16(VAddr addr); |
| 149 | u32 Read32(VAddr addr); | 149 | u32 Read32(VAddr addr); |
| 150 | u64 Read64(VAddr addr); | ||
| 150 | 151 | ||
| 151 | u32 Read8_ZX(VAddr addr); | 152 | u32 Read8_ZX(VAddr addr); |
| 152 | u32 Read16_ZX(VAddr addr); | 153 | u32 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 | ||
| 248 | u64 Read64(const VAddr addr) { | ||
| 249 | u64_le data = 0; | ||
| 250 | Read<u64_le>(data, addr); | ||
| 251 | return (u64)data; | ||
| 252 | } | ||
| 253 | |||
| 248 | u32 Read8_ZX(const VAddr addr) { | 254 | u32 Read8_ZX(const VAddr addr) { |
| 249 | return (u32)Read8(addr); | 255 | return (u32)Read8(addr); |
| 250 | } | 256 | } |