diff options
Diffstat (limited to 'src/core')
46 files changed, 1736 insertions, 1809 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 8267ee586..6cc60fd58 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -4,10 +4,9 @@ set(SRCS | |||
| 4 | arm/dyncom/arm_dyncom.cpp | 4 | arm/dyncom/arm_dyncom.cpp |
| 5 | arm/dyncom/arm_dyncom_dec.cpp | 5 | arm/dyncom/arm_dyncom_dec.cpp |
| 6 | arm/dyncom/arm_dyncom_interpreter.cpp | 6 | arm/dyncom/arm_dyncom_interpreter.cpp |
| 7 | arm/dyncom/arm_dyncom_run.cpp | ||
| 8 | arm/dyncom/arm_dyncom_thumb.cpp | 7 | arm/dyncom/arm_dyncom_thumb.cpp |
| 9 | arm/interpreter/arminit.cpp | 8 | arm/skyeye_common/armstate.cpp |
| 10 | arm/interpreter/armsupp.cpp | 9 | arm/skyeye_common/armsupp.cpp |
| 11 | arm/skyeye_common/vfp/vfp.cpp | 10 | arm/skyeye_common/vfp/vfp.cpp |
| 12 | arm/skyeye_common/vfp/vfpdouble.cpp | 11 | arm/skyeye_common/vfp/vfpdouble.cpp |
| 13 | arm/skyeye_common/vfp/vfpinstr.cpp | 12 | arm/skyeye_common/vfp/vfpinstr.cpp |
| @@ -132,8 +131,8 @@ set(HEADERS | |||
| 132 | arm/dyncom/arm_dyncom_run.h | 131 | arm/dyncom/arm_dyncom_run.h |
| 133 | arm/dyncom/arm_dyncom_thumb.h | 132 | arm/dyncom/arm_dyncom_thumb.h |
| 134 | arm/skyeye_common/arm_regformat.h | 133 | arm/skyeye_common/arm_regformat.h |
| 135 | arm/skyeye_common/armdefs.h | 134 | arm/skyeye_common/armstate.h |
| 136 | arm/skyeye_common/armmmu.h | 135 | arm/skyeye_common/armsupp.h |
| 137 | arm/skyeye_common/vfp/asm_vfp.h | 136 | arm/skyeye_common/vfp/asm_vfp.h |
| 138 | arm/skyeye_common/vfp/vfp.h | 137 | arm/skyeye_common/vfp/vfp.h |
| 139 | arm/skyeye_common/vfp/vfp_helper.h | 138 | arm/skyeye_common/vfp/vfp_helper.h |
diff --git a/src/core/arm/dyncom/arm_dyncom.cpp b/src/core/arm/dyncom/arm_dyncom.cpp index 529c4ac70..c665f706f 100644 --- a/src/core/arm/dyncom/arm_dyncom.cpp +++ b/src/core/arm/dyncom/arm_dyncom.cpp | |||
| @@ -6,7 +6,8 @@ | |||
| 6 | 6 | ||
| 7 | #include "common/make_unique.h" | 7 | #include "common/make_unique.h" |
| 8 | 8 | ||
| 9 | #include "core/arm/skyeye_common/armdefs.h" | 9 | #include "core/arm/skyeye_common/armstate.h" |
| 10 | #include "core/arm/skyeye_common/armsupp.h" | ||
| 10 | #include "core/arm/skyeye_common/vfp/vfp.h" | 11 | #include "core/arm/skyeye_common/vfp/vfp.h" |
| 11 | 12 | ||
| 12 | #include "core/arm/dyncom/arm_dyncom.h" | 13 | #include "core/arm/dyncom/arm_dyncom.h" |
| @@ -17,26 +18,7 @@ | |||
| 17 | #include "core/core_timing.h" | 18 | #include "core/core_timing.h" |
| 18 | 19 | ||
| 19 | ARM_DynCom::ARM_DynCom(PrivilegeMode initial_mode) { | 20 | ARM_DynCom::ARM_DynCom(PrivilegeMode initial_mode) { |
| 20 | state = Common::make_unique<ARMul_State>(); | 21 | state = Common::make_unique<ARMul_State>(initial_mode); |
| 21 | |||
| 22 | ARMul_NewState(state.get()); | ||
| 23 | ARMul_SelectProcessor(state.get(), ARM_v6_Prop | ARM_v5_Prop | ARM_v5e_Prop); | ||
| 24 | |||
| 25 | state->abort_model = ABORT_BASE_RESTORED; | ||
| 26 | |||
| 27 | state->bigendSig = LOW; | ||
| 28 | state->lateabtSig = LOW; | ||
| 29 | state->NirqSig = HIGH; | ||
| 30 | |||
| 31 | // Reset the core to initial state | ||
| 32 | ARMul_Reset(state.get()); | ||
| 33 | state->Emulate = RUN; | ||
| 34 | |||
| 35 | // Switch to the desired privilege mode. | ||
| 36 | switch_mode(state.get(), initial_mode); | ||
| 37 | |||
| 38 | state->Reg[13] = 0x10000000; // Set stack pointer to the top of the stack | ||
| 39 | state->Reg[15] = 0x00000000; | ||
| 40 | } | 22 | } |
| 41 | 23 | ||
| 42 | ARM_DynCom::~ARM_DynCom() { | 24 | ARM_DynCom::~ARM_DynCom() { |
| @@ -100,8 +82,8 @@ void ARM_DynCom::ResetContext(Core::ThreadContext& context, u32 stack_top, u32 e | |||
| 100 | } | 82 | } |
| 101 | 83 | ||
| 102 | void ARM_DynCom::SaveContext(Core::ThreadContext& ctx) { | 84 | void ARM_DynCom::SaveContext(Core::ThreadContext& ctx) { |
| 103 | memcpy(ctx.cpu_registers, state->Reg, sizeof(ctx.cpu_registers)); | 85 | memcpy(ctx.cpu_registers, state->Reg.data(), sizeof(ctx.cpu_registers)); |
| 104 | memcpy(ctx.fpu_registers, state->ExtReg, sizeof(ctx.fpu_registers)); | 86 | memcpy(ctx.fpu_registers, state->ExtReg.data(), sizeof(ctx.fpu_registers)); |
| 105 | 87 | ||
| 106 | ctx.sp = state->Reg[13]; | 88 | ctx.sp = state->Reg[13]; |
| 107 | ctx.lr = state->Reg[14]; | 89 | ctx.lr = state->Reg[14]; |
| @@ -113,8 +95,8 @@ void ARM_DynCom::SaveContext(Core::ThreadContext& ctx) { | |||
| 113 | } | 95 | } |
| 114 | 96 | ||
| 115 | void ARM_DynCom::LoadContext(const Core::ThreadContext& ctx) { | 97 | void ARM_DynCom::LoadContext(const Core::ThreadContext& ctx) { |
| 116 | memcpy(state->Reg, ctx.cpu_registers, sizeof(ctx.cpu_registers)); | 98 | memcpy(state->Reg.data(), ctx.cpu_registers, sizeof(ctx.cpu_registers)); |
| 117 | memcpy(state->ExtReg, ctx.fpu_registers, sizeof(ctx.fpu_registers)); | 99 | memcpy(state->ExtReg.data(), ctx.fpu_registers, sizeof(ctx.fpu_registers)); |
| 118 | 100 | ||
| 119 | state->Reg[13] = ctx.sp; | 101 | state->Reg[13] = ctx.sp; |
| 120 | state->Reg[14] = ctx.lr; | 102 | state->Reg[14] = ctx.lr; |
diff --git a/src/core/arm/dyncom/arm_dyncom.h b/src/core/arm/dyncom/arm_dyncom.h index cc9355722..87ab6908a 100644 --- a/src/core/arm/dyncom/arm_dyncom.h +++ b/src/core/arm/dyncom/arm_dyncom.h | |||
| @@ -9,8 +9,8 @@ | |||
| 9 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 10 | 10 | ||
| 11 | #include "core/arm/arm_interface.h" | 11 | #include "core/arm/arm_interface.h" |
| 12 | #include "core/arm/skyeye_common/armdefs.h" | ||
| 13 | #include "core/arm/skyeye_common/arm_regformat.h" | 12 | #include "core/arm/skyeye_common/arm_regformat.h" |
| 13 | #include "core/arm/skyeye_common/armstate.h" | ||
| 14 | 14 | ||
| 15 | namespace Core { | 15 | namespace Core { |
| 16 | struct ThreadContext; | 16 | struct ThreadContext; |
diff --git a/src/core/arm/dyncom/arm_dyncom_dec.cpp b/src/core/arm/dyncom/arm_dyncom_dec.cpp index 697be9556..ee4288314 100644 --- a/src/core/arm/dyncom/arm_dyncom_dec.cpp +++ b/src/core/arm/dyncom/arm_dyncom_dec.cpp | |||
| @@ -2,10 +2,10 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "core/arm/skyeye_common/armdefs.h" | ||
| 6 | #include "core/arm/dyncom/arm_dyncom_dec.h" | 5 | #include "core/arm/dyncom/arm_dyncom_dec.h" |
| 6 | #include "core/arm/skyeye_common/armsupp.h" | ||
| 7 | 7 | ||
| 8 | const ISEITEM arm_instruction[] = { | 8 | const InstructionSetEncodingItem arm_instruction[] = { |
| 9 | { "vmla", 4, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x0, 9, 11, 0x5, 4, 4, 0 }}, | 9 | { "vmla", 4, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x0, 9, 11, 0x5, 4, 4, 0 }}, |
| 10 | { "vmls", 7, ARMVFP2, { 28, 31, 0xF, 25, 27, 0x1, 23, 23, 1, 11, 11, 0, 8, 9, 0x2, 6, 6, 1, 4, 4, 0 }}, | 10 | { "vmls", 7, ARMVFP2, { 28, 31, 0xF, 25, 27, 0x1, 23, 23, 1, 11, 11, 0, 8, 9, 0x2, 6, 6, 1, 4, 4, 0 }}, |
| 11 | { "vnmla", 4, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x1, 9, 11, 0x5, 4, 4, 0 }}, | 11 | { "vnmla", 4, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x1, 9, 11, 0x5, 4, 4, 0 }}, |
| @@ -207,7 +207,7 @@ const ISEITEM arm_instruction[] = { | |||
| 207 | { "bbl", 1, 0, { 25, 27, 0x00000005 }}, | 207 | { "bbl", 1, 0, { 25, 27, 0x00000005 }}, |
| 208 | }; | 208 | }; |
| 209 | 209 | ||
| 210 | const ISEITEM arm_exclusion_code[] = { | 210 | const InstructionSetEncodingItem arm_exclusion_code[] = { |
| 211 | { "vmla", 0, ARMVFP2, { 0 }}, | 211 | { "vmla", 0, ARMVFP2, { 0 }}, |
| 212 | { "vmls", 0, ARMVFP2, { 0 }}, | 212 | { "vmls", 0, ARMVFP2, { 0 }}, |
| 213 | { "vnmla", 0, ARMVFP2, { 0 }}, | 213 | { "vnmla", 0, ARMVFP2, { 0 }}, |
| @@ -414,14 +414,13 @@ const ISEITEM arm_exclusion_code[] = { | |||
| 414 | { "invalid", 0, INVALID, { 0 }} | 414 | { "invalid", 0, INVALID, { 0 }} |
| 415 | }; | 415 | }; |
| 416 | 416 | ||
| 417 | int decode_arm_instr(uint32_t instr, int32_t *idx) { | 417 | ARMDecodeStatus DecodeARMInstruction(u32 instr, s32* idx) { |
| 418 | int n = 0; | 418 | int n = 0; |
| 419 | int base = 0; | 419 | int base = 0; |
| 420 | int ret = DECODE_FAILURE; | 420 | int instr_slots = sizeof(arm_instruction) / sizeof(InstructionSetEncodingItem); |
| 421 | int i = 0; | 421 | ARMDecodeStatus ret = ARMDecodeStatus::FAILURE; |
| 422 | int instr_slots = sizeof(arm_instruction) / sizeof(ISEITEM); | ||
| 423 | 422 | ||
| 424 | for (i = 0; i < instr_slots; i++) { | 423 | for (int i = 0; i < instr_slots; i++) { |
| 425 | n = arm_instruction[i].attribute_value; | 424 | n = arm_instruction[i].attribute_value; |
| 426 | base = 0; | 425 | base = 0; |
| 427 | 426 | ||
| @@ -438,11 +437,11 @@ int decode_arm_instr(uint32_t instr, int32_t *idx) { | |||
| 438 | n--; | 437 | n--; |
| 439 | } | 438 | } |
| 440 | 439 | ||
| 441 | // All conditions is satisfied. | 440 | // All conditions are satisfied. |
| 442 | if (n == 0) | 441 | if (n == 0) |
| 443 | ret = DECODE_SUCCESS; | 442 | ret = ARMDecodeStatus::SUCCESS; |
| 444 | 443 | ||
| 445 | if (ret == DECODE_SUCCESS) { | 444 | if (ret == ARMDecodeStatus::SUCCESS) { |
| 446 | n = arm_exclusion_code[i].attribute_value; | 445 | n = arm_exclusion_code[i].attribute_value; |
| 447 | if (n != 0) { | 446 | if (n != 0) { |
| 448 | base = 0; | 447 | base = 0; |
| @@ -454,13 +453,13 @@ int decode_arm_instr(uint32_t instr, int32_t *idx) { | |||
| 454 | n--; | 453 | n--; |
| 455 | } | 454 | } |
| 456 | 455 | ||
| 457 | // All conditions is satisfied. | 456 | // All conditions are satisfied. |
| 458 | if (n == 0) | 457 | if (n == 0) |
| 459 | ret = DECODE_FAILURE; | 458 | ret = ARMDecodeStatus::FAILURE; |
| 460 | } | 459 | } |
| 461 | } | 460 | } |
| 462 | 461 | ||
| 463 | if (ret == DECODE_SUCCESS) { | 462 | if (ret == ARMDecodeStatus::SUCCESS) { |
| 464 | *idx = i; | 463 | *idx = i; |
| 465 | return ret; | 464 | return ret; |
| 466 | } | 465 | } |
diff --git a/src/core/arm/dyncom/arm_dyncom_dec.h b/src/core/arm/dyncom/arm_dyncom_dec.h index 4b5f5ad7e..d7170e0fc 100644 --- a/src/core/arm/dyncom/arm_dyncom_dec.h +++ b/src/core/arm/dyncom/arm_dyncom_dec.h | |||
| @@ -4,22 +4,22 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | int decode_arm_instr(uint32_t instr, int32_t *idx); | 7 | #include "common/common_types.h" |
| 8 | 8 | ||
| 9 | enum DECODE_STATUS { | 9 | enum class ARMDecodeStatus { |
| 10 | DECODE_SUCCESS, | 10 | SUCCESS, |
| 11 | DECODE_FAILURE | 11 | FAILURE |
| 12 | }; | 12 | }; |
| 13 | 13 | ||
| 14 | struct instruction_set_encoding_item { | 14 | ARMDecodeStatus DecodeARMInstruction(u32 instr, s32* idx); |
| 15 | |||
| 16 | struct InstructionSetEncodingItem { | ||
| 15 | const char *name; | 17 | const char *name; |
| 16 | int attribute_value; | 18 | int attribute_value; |
| 17 | int version; | 19 | int version; |
| 18 | u32 content[21]; | 20 | u32 content[21]; |
| 19 | }; | 21 | }; |
| 20 | 22 | ||
| 21 | typedef struct instruction_set_encoding_item ISEITEM; | ||
| 22 | |||
| 23 | // ARM versions | 23 | // ARM versions |
| 24 | enum { | 24 | enum { |
| 25 | INVALID = 0, | 25 | INVALID = 0, |
| @@ -36,4 +36,4 @@ enum { | |||
| 36 | ARMV6K, | 36 | ARMV6K, |
| 37 | }; | 37 | }; |
| 38 | 38 | ||
| 39 | extern const ISEITEM arm_instruction[]; | 39 | extern const InstructionSetEncodingItem arm_instruction[]; |
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp index 785f39566..bb0cbb4dc 100644 --- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp +++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp | |||
| @@ -17,8 +17,8 @@ | |||
| 17 | #include "core/arm/dyncom/arm_dyncom_interpreter.h" | 17 | #include "core/arm/dyncom/arm_dyncom_interpreter.h" |
| 18 | #include "core/arm/dyncom/arm_dyncom_thumb.h" | 18 | #include "core/arm/dyncom/arm_dyncom_thumb.h" |
| 19 | #include "core/arm/dyncom/arm_dyncom_run.h" | 19 | #include "core/arm/dyncom/arm_dyncom_run.h" |
| 20 | #include "core/arm/skyeye_common/armdefs.h" | 20 | #include "core/arm/skyeye_common/armstate.h" |
| 21 | #include "core/arm/skyeye_common/armmmu.h" | 21 | #include "core/arm/skyeye_common/armsupp.h" |
| 22 | #include "core/arm/skyeye_common/vfp/vfp.h" | 22 | #include "core/arm/skyeye_common/vfp/vfp.h" |
| 23 | 23 | ||
| 24 | Common::Profiling::TimingCategory profile_execute("DynCom::Execute"); | 24 | Common::Profiling::TimingCategory profile_execute("DynCom::Execute"); |
| @@ -47,28 +47,6 @@ enum { | |||
| 47 | 47 | ||
| 48 | typedef unsigned int (*shtop_fp_t)(ARMul_State* cpu, unsigned int sht_oper); | 48 | typedef unsigned int (*shtop_fp_t)(ARMul_State* cpu, unsigned int sht_oper); |
| 49 | 49 | ||
| 50 | // Defines a reservation granule of 2 words, which protects the first 2 words starting at the tag. | ||
| 51 | // This is the smallest granule allowed by the v7 spec, and is coincidentally just large enough to | ||
| 52 | // support LDR/STREXD. | ||
| 53 | static const ARMword RESERVATION_GRANULE_MASK = 0xFFFFFFF8; | ||
| 54 | |||
| 55 | // Exclusive memory access | ||
| 56 | static int exclusive_detect(ARMul_State* state, ARMword addr) { | ||
| 57 | if(state->exclusive_tag == (addr & RESERVATION_GRANULE_MASK)) | ||
| 58 | return 0; | ||
| 59 | else | ||
| 60 | return -1; | ||
| 61 | } | ||
| 62 | |||
| 63 | static void add_exclusive_addr(ARMul_State* state, ARMword addr){ | ||
| 64 | state->exclusive_tag = addr & RESERVATION_GRANULE_MASK; | ||
| 65 | return; | ||
| 66 | } | ||
| 67 | |||
| 68 | static void remove_exclusive(ARMul_State* state, ARMword addr){ | ||
| 69 | state->exclusive_tag = 0xFFFFFFFF; | ||
| 70 | } | ||
| 71 | |||
| 72 | static int CondPassed(ARMul_State* cpu, unsigned int cond) { | 50 | static int CondPassed(ARMul_State* cpu, unsigned int cond) { |
| 73 | const u32 NFLAG = cpu->NFlag; | 51 | const u32 NFLAG = cpu->NFlag; |
| 74 | const u32 ZFLAG = cpu->ZFlag; | 52 | const u32 ZFLAG = cpu->ZFlag; |
| @@ -3490,21 +3468,15 @@ enum { | |||
| 3490 | FETCH_FAILURE | 3468 | FETCH_FAILURE |
| 3491 | }; | 3469 | }; |
| 3492 | 3470 | ||
| 3493 | static tdstate decode_thumb_instr(u32 inst, u32 addr, u32* arm_inst, u32* inst_size, ARM_INST_PTR* ptr_inst_base) { | 3471 | static ThumbDecodeStatus DecodeThumbInstruction(u32 inst, u32 addr, u32* arm_inst, u32* inst_size, ARM_INST_PTR* ptr_inst_base) { |
| 3494 | // Check if in Thumb mode | 3472 | // Check if in Thumb mode |
| 3495 | tdstate ret = thumb_translate (addr, inst, arm_inst, inst_size); | 3473 | ThumbDecodeStatus ret = TranslateThumbInstruction (addr, inst, arm_inst, inst_size); |
| 3496 | if(ret == t_branch){ | 3474 | if (ret == ThumbDecodeStatus::BRANCH) { |
| 3497 | // TODO: FIXME, endian should be judged | ||
| 3498 | u32 tinstr; | ||
| 3499 | if((addr & 0x3) != 0) | ||
| 3500 | tinstr = inst >> 16; | ||
| 3501 | else | ||
| 3502 | tinstr = inst & 0xFFFF; | ||
| 3503 | |||
| 3504 | int inst_index; | 3475 | int inst_index; |
| 3505 | int table_length = sizeof(arm_instruction_trans) / sizeof(transop_fp_t); | 3476 | int table_length = sizeof(arm_instruction_trans) / sizeof(transop_fp_t); |
| 3477 | u32 tinstr = GetThumbInstruction(inst, addr); | ||
| 3506 | 3478 | ||
| 3507 | switch((tinstr & 0xF800) >> 11){ | 3479 | switch ((tinstr & 0xF800) >> 11) { |
| 3508 | case 26: | 3480 | case 26: |
| 3509 | case 27: | 3481 | case 27: |
| 3510 | if (((tinstr & 0x0F00) != 0x0E00) && ((tinstr & 0x0F00) != 0x0F00)){ | 3482 | if (((tinstr & 0x0F00) != 0x0E00) && ((tinstr & 0x0F00) != 0x0F00)){ |
| @@ -3537,7 +3509,7 @@ static tdstate decode_thumb_instr(u32 inst, u32 addr, u32* arm_inst, u32* inst_s | |||
| 3537 | *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); | 3509 | *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); |
| 3538 | break; | 3510 | break; |
| 3539 | default: | 3511 | default: |
| 3540 | ret = t_undefined; | 3512 | ret = ThumbDecodeStatus::UNDEFINED; |
| 3541 | break; | 3513 | break; |
| 3542 | } | 3514 | } |
| 3543 | } | 3515 | } |
| @@ -3549,10 +3521,6 @@ enum { | |||
| 3549 | FETCH_EXCEPTION | 3521 | FETCH_EXCEPTION |
| 3550 | }; | 3522 | }; |
| 3551 | 3523 | ||
| 3552 | typedef struct instruction_set_encoding_item ISEITEM; | ||
| 3553 | |||
| 3554 | extern const ISEITEM arm_instruction[]; | ||
| 3555 | |||
| 3556 | static int InterpreterTranslate(ARMul_State* cpu, int& bb_start, u32 addr) { | 3524 | static int InterpreterTranslate(ARMul_State* cpu, int& bb_start, u32 addr) { |
| 3557 | Common::Profiling::ScopeTimer timer_decode(profile_decode); | 3525 | Common::Profiling::ScopeTimer timer_decode(profile_decode); |
| 3558 | 3526 | ||
| @@ -3574,20 +3542,19 @@ static int InterpreterTranslate(ARMul_State* cpu, int& bb_start, u32 addr) { | |||
| 3574 | inst = Memory::Read32(phys_addr & 0xFFFFFFFC); | 3542 | inst = Memory::Read32(phys_addr & 0xFFFFFFFC); |
| 3575 | 3543 | ||
| 3576 | size++; | 3544 | size++; |
| 3577 | // If we are in thumb instruction, we will translate one thumb to one corresponding arm instruction | 3545 | // If we are in Thumb mode, we'll translate one Thumb instruction to the corresponding ARM instruction |
| 3578 | if (cpu->TFlag) { | 3546 | if (cpu->TFlag) { |
| 3579 | uint32_t arm_inst; | 3547 | uint32_t arm_inst; |
| 3580 | tdstate state = decode_thumb_instr(inst, phys_addr, &arm_inst, &inst_size, &inst_base); | 3548 | ThumbDecodeStatus state = DecodeThumbInstruction(inst, phys_addr, &arm_inst, &inst_size, &inst_base); |
| 3581 | 3549 | ||
| 3582 | // We have translated the branch instruction of thumb in thumb decoder | 3550 | // We have translated the Thumb branch instruction in the Thumb decoder |
| 3583 | if(state == t_branch){ | 3551 | if (state == ThumbDecodeStatus::BRANCH) { |
| 3584 | goto translated; | 3552 | goto translated; |
| 3585 | } | 3553 | } |
| 3586 | inst = arm_inst; | 3554 | inst = arm_inst; |
| 3587 | } | 3555 | } |
| 3588 | 3556 | ||
| 3589 | ret = decode_arm_instr(inst, &idx); | 3557 | if (DecodeARMInstruction(inst, &idx) == ARMDecodeStatus::FAILURE) { |
| 3590 | if (ret == DECODE_FAILURE) { | ||
| 3591 | std::string disasm = ARM_Disasm::Disassemble(phys_addr, inst); | 3558 | std::string disasm = ARM_Disasm::Disassemble(phys_addr, inst); |
| 3592 | LOG_ERROR(Core_ARM11, "Decode failure.\tPC : [0x%x]\tInstruction : %s [%x]", phys_addr, disasm.c_str(), inst); | 3559 | LOG_ERROR(Core_ARM11, "Decode failure.\tPC : [0x%x]\tInstruction : %s [%x]", phys_addr, disasm.c_str(), inst); |
| 3593 | LOG_ERROR(Core_ARM11, "cpsr=0x%x, cpu->TFlag=%d, r15=0x%x", cpu->Cpsr, cpu->TFlag, cpu->Reg[15]); | 3560 | LOG_ERROR(Core_ARM11, "cpsr=0x%x, cpu->TFlag=%d, r15=0x%x", cpu->Cpsr, cpu->TFlag, cpu->Reg[15]); |
| @@ -3919,7 +3886,6 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 3919 | #endif | 3886 | #endif |
| 3920 | arm_inst* inst_base; | 3887 | arm_inst* inst_base; |
| 3921 | unsigned int addr; | 3888 | unsigned int addr; |
| 3922 | unsigned int phys_addr; | ||
| 3923 | unsigned int num_instrs = 0; | 3889 | unsigned int num_instrs = 0; |
| 3924 | 3890 | ||
| 3925 | int ptr; | 3891 | int ptr; |
| @@ -3938,8 +3904,6 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 3938 | else | 3904 | else |
| 3939 | cpu->Reg[15] &= 0xfffffffc; | 3905 | cpu->Reg[15] &= 0xfffffffc; |
| 3940 | 3906 | ||
| 3941 | phys_addr = cpu->Reg[15]; | ||
| 3942 | |||
| 3943 | // Find the cached instruction cream, otherwise translate it... | 3907 | // Find the cached instruction cream, otherwise translate it... |
| 3944 | auto itr = cpu->instruction_cache.find(cpu->Reg[15]); | 3908 | auto itr = cpu->instruction_cache.find(cpu->Reg[15]); |
| 3945 | if (itr != cpu->instruction_cache.end()) { | 3909 | if (itr != cpu->instruction_cache.end()) { |
| @@ -3957,14 +3921,18 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 3957 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | 3921 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { |
| 3958 | adc_inst* const inst_cream = (adc_inst*)inst_base->component; | 3922 | adc_inst* const inst_cream = (adc_inst*)inst_base->component; |
| 3959 | 3923 | ||
| 3924 | u32 rn_val = RN; | ||
| 3925 | if (inst_cream->Rn == 15) | ||
| 3926 | rn_val += 2 * cpu->GetInstructionSize(); | ||
| 3927 | |||
| 3960 | bool carry; | 3928 | bool carry; |
| 3961 | bool overflow; | 3929 | bool overflow; |
| 3962 | RD = AddWithCarry(RN, SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow); | 3930 | RD = AddWithCarry(rn_val, SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow); |
| 3963 | 3931 | ||
| 3964 | if (inst_cream->S && (inst_cream->Rd == 15)) { | 3932 | if (inst_cream->S && (inst_cream->Rd == 15)) { |
| 3965 | if (CurrentModeHasSPSR) { | 3933 | if (CurrentModeHasSPSR) { |
| 3966 | cpu->Cpsr = cpu->Spsr_copy; | 3934 | cpu->Cpsr = cpu->Spsr_copy; |
| 3967 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); | 3935 | cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F); |
| 3968 | LOAD_NZCVT; | 3936 | LOAD_NZCVT; |
| 3969 | } | 3937 | } |
| 3970 | } else if (inst_cream->S) { | 3938 | } else if (inst_cream->S) { |
| @@ -3978,7 +3946,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 3978 | goto DISPATCH; | 3946 | goto DISPATCH; |
| 3979 | } | 3947 | } |
| 3980 | } | 3948 | } |
| 3981 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 3949 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 3982 | INC_PC(sizeof(adc_inst)); | 3950 | INC_PC(sizeof(adc_inst)); |
| 3983 | FETCH_INST; | 3951 | FETCH_INST; |
| 3984 | GOTO_NEXT_INST; | 3952 | GOTO_NEXT_INST; |
| @@ -3990,7 +3958,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 3990 | 3958 | ||
| 3991 | u32 rn_val = RN; | 3959 | u32 rn_val = RN; |
| 3992 | if (inst_cream->Rn == 15) | 3960 | if (inst_cream->Rn == 15) |
| 3993 | rn_val += 2 * GET_INST_SIZE(cpu); | 3961 | rn_val += 2 * cpu->GetInstructionSize(); |
| 3994 | 3962 | ||
| 3995 | bool carry; | 3963 | bool carry; |
| 3996 | bool overflow; | 3964 | bool overflow; |
| @@ -3999,7 +3967,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 3999 | if (inst_cream->S && (inst_cream->Rd == 15)) { | 3967 | if (inst_cream->S && (inst_cream->Rd == 15)) { |
| 4000 | if (CurrentModeHasSPSR) { | 3968 | if (CurrentModeHasSPSR) { |
| 4001 | cpu->Cpsr = cpu->Spsr_copy; | 3969 | cpu->Cpsr = cpu->Spsr_copy; |
| 4002 | switch_mode(cpu, cpu->Cpsr & 0x1f); | 3970 | cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F); |
| 4003 | LOAD_NZCVT; | 3971 | LOAD_NZCVT; |
| 4004 | } | 3972 | } |
| 4005 | } else if (inst_cream->S) { | 3973 | } else if (inst_cream->S) { |
| @@ -4013,22 +3981,28 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4013 | goto DISPATCH; | 3981 | goto DISPATCH; |
| 4014 | } | 3982 | } |
| 4015 | } | 3983 | } |
| 4016 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 3984 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4017 | INC_PC(sizeof(add_inst)); | 3985 | INC_PC(sizeof(add_inst)); |
| 4018 | FETCH_INST; | 3986 | FETCH_INST; |
| 4019 | GOTO_NEXT_INST; | 3987 | GOTO_NEXT_INST; |
| 4020 | } | 3988 | } |
| 4021 | AND_INST: | 3989 | AND_INST: |
| 4022 | { | 3990 | { |
| 4023 | and_inst *inst_cream = (and_inst *)inst_base->component; | 3991 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { |
| 4024 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 3992 | and_inst* const inst_cream = (and_inst*)inst_base->component; |
| 3993 | |||
| 4025 | u32 lop = RN; | 3994 | u32 lop = RN; |
| 4026 | u32 rop = SHIFTER_OPERAND; | 3995 | u32 rop = SHIFTER_OPERAND; |
| 3996 | |||
| 3997 | if (inst_cream->Rn == 15) | ||
| 3998 | lop += 2 * cpu->GetInstructionSize(); | ||
| 3999 | |||
| 4027 | RD = lop & rop; | 4000 | RD = lop & rop; |
| 4001 | |||
| 4028 | if (inst_cream->S && (inst_cream->Rd == 15)) { | 4002 | if (inst_cream->S && (inst_cream->Rd == 15)) { |
| 4029 | if (CurrentModeHasSPSR) { | 4003 | if (CurrentModeHasSPSR) { |
| 4030 | cpu->Cpsr = cpu->Spsr_copy; | 4004 | cpu->Cpsr = cpu->Spsr_copy; |
| 4031 | switch_mode(cpu, cpu->Cpsr & 0x1f); | 4005 | cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F); |
| 4032 | LOAD_NZCVT; | 4006 | LOAD_NZCVT; |
| 4033 | } | 4007 | } |
| 4034 | } else if (inst_cream->S) { | 4008 | } else if (inst_cream->S) { |
| @@ -4041,7 +4015,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4041 | goto DISPATCH; | 4015 | goto DISPATCH; |
| 4042 | } | 4016 | } |
| 4043 | } | 4017 | } |
| 4044 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4018 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4045 | INC_PC(sizeof(and_inst)); | 4019 | INC_PC(sizeof(and_inst)); |
| 4046 | FETCH_INST; | 4020 | FETCH_INST; |
| 4047 | GOTO_NEXT_INST; | 4021 | GOTO_NEXT_INST; |
| @@ -4057,7 +4031,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4057 | INC_PC(sizeof(bbl_inst)); | 4031 | INC_PC(sizeof(bbl_inst)); |
| 4058 | goto DISPATCH; | 4032 | goto DISPATCH; |
| 4059 | } | 4033 | } |
| 4060 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4034 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4061 | INC_PC(sizeof(bbl_inst)); | 4035 | INC_PC(sizeof(bbl_inst)); |
| 4062 | goto DISPATCH; | 4036 | goto DISPATCH; |
| 4063 | } | 4037 | } |
| @@ -4067,14 +4041,14 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4067 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4041 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4068 | u32 lop = RN; | 4042 | u32 lop = RN; |
| 4069 | if (inst_cream->Rn == 15) { | 4043 | if (inst_cream->Rn == 15) { |
| 4070 | lop += 2 * GET_INST_SIZE(cpu); | 4044 | lop += 2 * cpu->GetInstructionSize(); |
| 4071 | } | 4045 | } |
| 4072 | u32 rop = SHIFTER_OPERAND; | 4046 | u32 rop = SHIFTER_OPERAND; |
| 4073 | RD = lop & (~rop); | 4047 | RD = lop & (~rop); |
| 4074 | if ((inst_cream->S) && (inst_cream->Rd == 15)) { | 4048 | if ((inst_cream->S) && (inst_cream->Rd == 15)) { |
| 4075 | if (CurrentModeHasSPSR) { | 4049 | if (CurrentModeHasSPSR) { |
| 4076 | cpu->Cpsr = cpu->Spsr_copy; | 4050 | cpu->Cpsr = cpu->Spsr_copy; |
| 4077 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); | 4051 | cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F); |
| 4078 | LOAD_NZCVT; | 4052 | LOAD_NZCVT; |
| 4079 | } | 4053 | } |
| 4080 | } else if (inst_cream->S) { | 4054 | } else if (inst_cream->S) { |
| @@ -4087,7 +4061,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4087 | goto DISPATCH; | 4061 | goto DISPATCH; |
| 4088 | } | 4062 | } |
| 4089 | } | 4063 | } |
| 4090 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4064 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4091 | INC_PC(sizeof(bic_inst)); | 4065 | INC_PC(sizeof(bic_inst)); |
| 4092 | FETCH_INST; | 4066 | FETCH_INST; |
| 4093 | GOTO_NEXT_INST; | 4067 | GOTO_NEXT_INST; |
| @@ -4098,7 +4072,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4098 | bkpt_inst* const inst_cream = (bkpt_inst*)inst_base->component; | 4072 | bkpt_inst* const inst_cream = (bkpt_inst*)inst_base->component; |
| 4099 | LOG_DEBUG(Core_ARM11, "Breakpoint instruction hit. Immediate: 0x%08X", inst_cream->imm); | 4073 | LOG_DEBUG(Core_ARM11, "Breakpoint instruction hit. Immediate: 0x%08X", inst_cream->imm); |
| 4100 | } | 4074 | } |
| 4101 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4075 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4102 | INC_PC(sizeof(bkpt_inst)); | 4076 | INC_PC(sizeof(bkpt_inst)); |
| 4103 | FETCH_INST; | 4077 | FETCH_INST; |
| 4104 | GOTO_NEXT_INST; | 4078 | GOTO_NEXT_INST; |
| @@ -4109,13 +4083,13 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4109 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4083 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4110 | unsigned int inst = inst_cream->inst; | 4084 | unsigned int inst = inst_cream->inst; |
| 4111 | if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) { | 4085 | if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) { |
| 4112 | cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu)); | 4086 | cpu->Reg[14] = (cpu->Reg[15] + cpu->GetInstructionSize()); |
| 4113 | if(cpu->TFlag) | 4087 | if(cpu->TFlag) |
| 4114 | cpu->Reg[14] |= 0x1; | 4088 | cpu->Reg[14] |= 0x1; |
| 4115 | cpu->Reg[15] = cpu->Reg[inst_cream->val.Rm] & 0xfffffffe; | 4089 | cpu->Reg[15] = cpu->Reg[inst_cream->val.Rm] & 0xfffffffe; |
| 4116 | cpu->TFlag = cpu->Reg[inst_cream->val.Rm] & 0x1; | 4090 | cpu->TFlag = cpu->Reg[inst_cream->val.Rm] & 0x1; |
| 4117 | } else { | 4091 | } else { |
| 4118 | cpu->Reg[14] = (cpu->Reg[15] + GET_INST_SIZE(cpu)); | 4092 | cpu->Reg[14] = (cpu->Reg[15] + cpu->GetInstructionSize()); |
| 4119 | cpu->TFlag = 0x1; | 4093 | cpu->TFlag = 0x1; |
| 4120 | int signed_int = inst_cream->val.signed_immed_24; | 4094 | int signed_int = inst_cream->val.signed_immed_24; |
| 4121 | signed_int = (signed_int & 0x800000) ? (0x3F000000 | signed_int) : signed_int; | 4095 | signed_int = (signed_int & 0x800000) ? (0x3F000000 | signed_int) : signed_int; |
| @@ -4125,7 +4099,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4125 | INC_PC(sizeof(blx_inst)); | 4099 | INC_PC(sizeof(blx_inst)); |
| 4126 | goto DISPATCH; | 4100 | goto DISPATCH; |
| 4127 | } | 4101 | } |
| 4128 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4102 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4129 | INC_PC(sizeof(blx_inst)); | 4103 | INC_PC(sizeof(blx_inst)); |
| 4130 | goto DISPATCH; | 4104 | goto DISPATCH; |
| 4131 | } | 4105 | } |
| @@ -4147,7 +4121,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4147 | u32 address = RM; | 4121 | u32 address = RM; |
| 4148 | 4122 | ||
| 4149 | if (inst_cream->Rm == 15) | 4123 | if (inst_cream->Rm == 15) |
| 4150 | address += 2 * GET_INST_SIZE(cpu); | 4124 | address += 2 * cpu->GetInstructionSize(); |
| 4151 | 4125 | ||
| 4152 | cpu->TFlag = address & 1; | 4126 | cpu->TFlag = address & 1; |
| 4153 | cpu->Reg[15] = address & 0xfffffffe; | 4127 | cpu->Reg[15] = address & 0xfffffffe; |
| @@ -4155,7 +4129,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4155 | goto DISPATCH; | 4129 | goto DISPATCH; |
| 4156 | } | 4130 | } |
| 4157 | 4131 | ||
| 4158 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4132 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4159 | INC_PC(sizeof(bx_inst)); | 4133 | INC_PC(sizeof(bx_inst)); |
| 4160 | goto DISPATCH; | 4134 | goto DISPATCH; |
| 4161 | } | 4135 | } |
| @@ -4167,7 +4141,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4167 | cpu->NumInstrsToExecute = 0; | 4141 | cpu->NumInstrsToExecute = 0; |
| 4168 | return num_instrs; | 4142 | return num_instrs; |
| 4169 | } | 4143 | } |
| 4170 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4144 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4171 | INC_PC(sizeof(cdp_inst)); | 4145 | INC_PC(sizeof(cdp_inst)); |
| 4172 | FETCH_INST; | 4146 | FETCH_INST; |
| 4173 | GOTO_NEXT_INST; | 4147 | GOTO_NEXT_INST; |
| @@ -4175,10 +4149,8 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4175 | 4149 | ||
| 4176 | CLREX_INST: | 4150 | CLREX_INST: |
| 4177 | { | 4151 | { |
| 4178 | remove_exclusive(cpu, 0); | 4152 | cpu->UnsetExclusiveMemoryAddress(); |
| 4179 | cpu->exclusive_state = 0; | 4153 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4180 | |||
| 4181 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 4182 | INC_PC(sizeof(clrex_inst)); | 4154 | INC_PC(sizeof(clrex_inst)); |
| 4183 | FETCH_INST; | 4155 | FETCH_INST; |
| 4184 | GOTO_NEXT_INST; | 4156 | GOTO_NEXT_INST; |
| @@ -4189,7 +4161,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4189 | clz_inst* inst_cream = (clz_inst*)inst_base->component; | 4161 | clz_inst* inst_cream = (clz_inst*)inst_base->component; |
| 4190 | RD = clz(RM); | 4162 | RD = clz(RM); |
| 4191 | } | 4163 | } |
| 4192 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4164 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4193 | INC_PC(sizeof(clz_inst)); | 4165 | INC_PC(sizeof(clz_inst)); |
| 4194 | FETCH_INST; | 4166 | FETCH_INST; |
| 4195 | GOTO_NEXT_INST; | 4167 | GOTO_NEXT_INST; |
| @@ -4199,16 +4171,20 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4199 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | 4171 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { |
| 4200 | cmn_inst* const inst_cream = (cmn_inst*)inst_base->component; | 4172 | cmn_inst* const inst_cream = (cmn_inst*)inst_base->component; |
| 4201 | 4173 | ||
| 4174 | u32 rn_val = RN; | ||
| 4175 | if (inst_cream->Rn == 15) | ||
| 4176 | rn_val += 2 * cpu->GetInstructionSize(); | ||
| 4177 | |||
| 4202 | bool carry; | 4178 | bool carry; |
| 4203 | bool overflow; | 4179 | bool overflow; |
| 4204 | u32 result = AddWithCarry(RN, SHIFTER_OPERAND, 0, &carry, &overflow); | 4180 | u32 result = AddWithCarry(rn_val, SHIFTER_OPERAND, 0, &carry, &overflow); |
| 4205 | 4181 | ||
| 4206 | UPDATE_NFLAG(result); | 4182 | UPDATE_NFLAG(result); |
| 4207 | UPDATE_ZFLAG(result); | 4183 | UPDATE_ZFLAG(result); |
| 4208 | cpu->CFlag = carry; | 4184 | cpu->CFlag = carry; |
| 4209 | cpu->VFlag = overflow; | 4185 | cpu->VFlag = overflow; |
| 4210 | } | 4186 | } |
| 4211 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4187 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4212 | INC_PC(sizeof(cmn_inst)); | 4188 | INC_PC(sizeof(cmn_inst)); |
| 4213 | FETCH_INST; | 4189 | FETCH_INST; |
| 4214 | GOTO_NEXT_INST; | 4190 | GOTO_NEXT_INST; |
| @@ -4220,7 +4196,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4220 | 4196 | ||
| 4221 | u32 rn_val = RN; | 4197 | u32 rn_val = RN; |
| 4222 | if (inst_cream->Rn == 15) | 4198 | if (inst_cream->Rn == 15) |
| 4223 | rn_val += 2 * GET_INST_SIZE(cpu); | 4199 | rn_val += 2 * cpu->GetInstructionSize(); |
| 4224 | 4200 | ||
| 4225 | bool carry; | 4201 | bool carry; |
| 4226 | bool overflow; | 4202 | bool overflow; |
| @@ -4231,7 +4207,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4231 | cpu->CFlag = carry; | 4207 | cpu->CFlag = carry; |
| 4232 | cpu->VFlag = overflow; | 4208 | cpu->VFlag = overflow; |
| 4233 | } | 4209 | } |
| 4234 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4210 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4235 | INC_PC(sizeof(cmp_inst)); | 4211 | INC_PC(sizeof(cmp_inst)); |
| 4236 | FETCH_INST; | 4212 | FETCH_INST; |
| 4237 | GOTO_NEXT_INST; | 4213 | GOTO_NEXT_INST; |
| @@ -4241,7 +4217,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4241 | cps_inst *inst_cream = (cps_inst *)inst_base->component; | 4217 | cps_inst *inst_cream = (cps_inst *)inst_base->component; |
| 4242 | uint32_t aif_val = 0; | 4218 | uint32_t aif_val = 0; |
| 4243 | uint32_t aif_mask = 0; | 4219 | uint32_t aif_mask = 0; |
| 4244 | if (InAPrivilegedMode(cpu)) { | 4220 | if (cpu->InAPrivilegedMode()) { |
| 4245 | if (inst_cream->imod1) { | 4221 | if (inst_cream->imod1) { |
| 4246 | if (inst_cream->A) { | 4222 | if (inst_cream->A) { |
| 4247 | aif_val |= (inst_cream->imod0 << 8); | 4223 | aif_val |= (inst_cream->imod0 << 8); |
| @@ -4260,10 +4236,10 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4260 | } | 4236 | } |
| 4261 | if (inst_cream->mmod) { | 4237 | if (inst_cream->mmod) { |
| 4262 | cpu->Cpsr = (cpu->Cpsr & 0xffffffe0) | inst_cream->mode; | 4238 | cpu->Cpsr = (cpu->Cpsr & 0xffffffe0) | inst_cream->mode; |
| 4263 | switch_mode(cpu, inst_cream->mode); | 4239 | cpu->ChangePrivilegeMode(inst_cream->mode); |
| 4264 | } | 4240 | } |
| 4265 | } | 4241 | } |
| 4266 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4242 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4267 | INC_PC(sizeof(cps_inst)); | 4243 | INC_PC(sizeof(cps_inst)); |
| 4268 | FETCH_INST; | 4244 | FETCH_INST; |
| 4269 | GOTO_NEXT_INST; | 4245 | GOTO_NEXT_INST; |
| @@ -4279,7 +4255,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4279 | goto DISPATCH; | 4255 | goto DISPATCH; |
| 4280 | } | 4256 | } |
| 4281 | } | 4257 | } |
| 4282 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4258 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4283 | INC_PC(sizeof(mov_inst)); | 4259 | INC_PC(sizeof(mov_inst)); |
| 4284 | FETCH_INST; | 4260 | FETCH_INST; |
| 4285 | GOTO_NEXT_INST; | 4261 | GOTO_NEXT_INST; |
| @@ -4291,14 +4267,14 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4291 | 4267 | ||
| 4292 | u32 lop = RN; | 4268 | u32 lop = RN; |
| 4293 | if (inst_cream->Rn == 15) { | 4269 | if (inst_cream->Rn == 15) { |
| 4294 | lop += 2 * GET_INST_SIZE(cpu); | 4270 | lop += 2 * cpu->GetInstructionSize(); |
| 4295 | } | 4271 | } |
| 4296 | u32 rop = SHIFTER_OPERAND; | 4272 | u32 rop = SHIFTER_OPERAND; |
| 4297 | RD = lop ^ rop; | 4273 | RD = lop ^ rop; |
| 4298 | if (inst_cream->S && (inst_cream->Rd == 15)) { | 4274 | if (inst_cream->S && (inst_cream->Rd == 15)) { |
| 4299 | if (CurrentModeHasSPSR) { | 4275 | if (CurrentModeHasSPSR) { |
| 4300 | cpu->Cpsr = cpu->Spsr_copy; | 4276 | cpu->Cpsr = cpu->Spsr_copy; |
| 4301 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); | 4277 | cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F); |
| 4302 | LOAD_NZCVT; | 4278 | LOAD_NZCVT; |
| 4303 | } | 4279 | } |
| 4304 | } else if (inst_cream->S) { | 4280 | } else if (inst_cream->S) { |
| @@ -4311,7 +4287,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4311 | goto DISPATCH; | 4287 | goto DISPATCH; |
| 4312 | } | 4288 | } |
| 4313 | } | 4289 | } |
| 4314 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4290 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4315 | INC_PC(sizeof(eor_inst)); | 4291 | INC_PC(sizeof(eor_inst)); |
| 4316 | FETCH_INST; | 4292 | FETCH_INST; |
| 4317 | GOTO_NEXT_INST; | 4293 | GOTO_NEXT_INST; |
| @@ -4320,7 +4296,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4320 | { | 4296 | { |
| 4321 | // Instruction not implemented | 4297 | // Instruction not implemented |
| 4322 | //LOG_CRITICAL(Core_ARM11, "unimplemented instruction"); | 4298 | //LOG_CRITICAL(Core_ARM11, "unimplemented instruction"); |
| 4323 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4299 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4324 | INC_PC(sizeof(ldc_inst)); | 4300 | INC_PC(sizeof(ldc_inst)); |
| 4325 | FETCH_INST; | 4301 | FETCH_INST; |
| 4326 | GOTO_NEXT_INST; | 4302 | GOTO_NEXT_INST; |
| @@ -4335,30 +4311,30 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4335 | if (BIT(inst, 22) && !BIT(inst, 15)) { | 4311 | if (BIT(inst, 22) && !BIT(inst, 15)) { |
| 4336 | for (int i = 0; i < 13; i++) { | 4312 | for (int i = 0; i < 13; i++) { |
| 4337 | if(BIT(inst, i)) { | 4313 | if(BIT(inst, i)) { |
| 4338 | cpu->Reg[i] = ReadMemory32(cpu, addr); | 4314 | cpu->Reg[i] = cpu->ReadMemory32(addr); |
| 4339 | addr += 4; | 4315 | addr += 4; |
| 4340 | } | 4316 | } |
| 4341 | } | 4317 | } |
| 4342 | if (BIT(inst, 13)) { | 4318 | if (BIT(inst, 13)) { |
| 4343 | if (cpu->Mode == USER32MODE) | 4319 | if (cpu->Mode == USER32MODE) |
| 4344 | cpu->Reg[13] = ReadMemory32(cpu, addr); | 4320 | cpu->Reg[13] = cpu->ReadMemory32(addr); |
| 4345 | else | 4321 | else |
| 4346 | cpu->Reg_usr[0] = ReadMemory32(cpu, addr); | 4322 | cpu->Reg_usr[0] = cpu->ReadMemory32(addr); |
| 4347 | 4323 | ||
| 4348 | addr += 4; | 4324 | addr += 4; |
| 4349 | } | 4325 | } |
| 4350 | if (BIT(inst, 14)) { | 4326 | if (BIT(inst, 14)) { |
| 4351 | if (cpu->Mode == USER32MODE) | 4327 | if (cpu->Mode == USER32MODE) |
| 4352 | cpu->Reg[14] = ReadMemory32(cpu, addr); | 4328 | cpu->Reg[14] = cpu->ReadMemory32(addr); |
| 4353 | else | 4329 | else |
| 4354 | cpu->Reg_usr[1] = ReadMemory32(cpu, addr); | 4330 | cpu->Reg_usr[1] = cpu->ReadMemory32(addr); |
| 4355 | 4331 | ||
| 4356 | addr += 4; | 4332 | addr += 4; |
| 4357 | } | 4333 | } |
| 4358 | } else if (!BIT(inst, 22)) { | 4334 | } else if (!BIT(inst, 22)) { |
| 4359 | for(int i = 0; i < 16; i++ ){ | 4335 | for(int i = 0; i < 16; i++ ){ |
| 4360 | if(BIT(inst, i)){ | 4336 | if(BIT(inst, i)){ |
| 4361 | unsigned int ret = ReadMemory32(cpu, addr); | 4337 | unsigned int ret = cpu->ReadMemory32(addr); |
| 4362 | 4338 | ||
| 4363 | // For armv5t, should enter thumb when bits[0] is non-zero. | 4339 | // For armv5t, should enter thumb when bits[0] is non-zero. |
| 4364 | if(i == 15){ | 4340 | if(i == 15){ |
| @@ -4373,18 +4349,18 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4373 | } else if (BIT(inst, 22) && BIT(inst, 15)) { | 4349 | } else if (BIT(inst, 22) && BIT(inst, 15)) { |
| 4374 | for(int i = 0; i < 15; i++ ){ | 4350 | for(int i = 0; i < 15; i++ ){ |
| 4375 | if(BIT(inst, i)){ | 4351 | if(BIT(inst, i)){ |
| 4376 | cpu->Reg[i] = ReadMemory32(cpu, addr); | 4352 | cpu->Reg[i] = cpu->ReadMemory32(addr); |
| 4377 | addr += 4; | 4353 | addr += 4; |
| 4378 | } | 4354 | } |
| 4379 | } | 4355 | } |
| 4380 | 4356 | ||
| 4381 | if (CurrentModeHasSPSR) { | 4357 | if (CurrentModeHasSPSR) { |
| 4382 | cpu->Cpsr = cpu->Spsr_copy; | 4358 | cpu->Cpsr = cpu->Spsr_copy; |
| 4383 | switch_mode(cpu, cpu->Cpsr & 0x1f); | 4359 | cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F); |
| 4384 | LOAD_NZCVT; | 4360 | LOAD_NZCVT; |
| 4385 | } | 4361 | } |
| 4386 | 4362 | ||
| 4387 | cpu->Reg[15] = ReadMemory32(cpu, addr); | 4363 | cpu->Reg[15] = cpu->ReadMemory32(addr); |
| 4388 | } | 4364 | } |
| 4389 | 4365 | ||
| 4390 | if (BIT(inst, 15)) { | 4366 | if (BIT(inst, 15)) { |
| @@ -4392,7 +4368,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4392 | goto DISPATCH; | 4368 | goto DISPATCH; |
| 4393 | } | 4369 | } |
| 4394 | } | 4370 | } |
| 4395 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4371 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4396 | INC_PC(sizeof(ldst_inst)); | 4372 | INC_PC(sizeof(ldst_inst)); |
| 4397 | FETCH_INST; | 4373 | FETCH_INST; |
| 4398 | GOTO_NEXT_INST; | 4374 | GOTO_NEXT_INST; |
| @@ -4410,7 +4386,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4410 | } | 4386 | } |
| 4411 | RD = operand2; | 4387 | RD = operand2; |
| 4412 | } | 4388 | } |
| 4413 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4389 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4414 | INC_PC(sizeof(sxth_inst)); | 4390 | INC_PC(sizeof(sxth_inst)); |
| 4415 | FETCH_INST; | 4391 | FETCH_INST; |
| 4416 | GOTO_NEXT_INST; | 4392 | GOTO_NEXT_INST; |
| @@ -4420,7 +4396,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4420 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 4396 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 4421 | inst_cream->get_addr(cpu, inst_cream->inst, addr); | 4397 | inst_cream->get_addr(cpu, inst_cream->inst, addr); |
| 4422 | 4398 | ||
| 4423 | unsigned int value = ReadMemory32(cpu, addr); | 4399 | unsigned int value = cpu->ReadMemory32(addr); |
| 4424 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | 4400 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; |
| 4425 | 4401 | ||
| 4426 | if (BITS(inst_cream->inst, 12, 15) == 15) { | 4402 | if (BITS(inst_cream->inst, 12, 15) == 15) { |
| @@ -4431,7 +4407,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4431 | goto DISPATCH; | 4407 | goto DISPATCH; |
| 4432 | } | 4408 | } |
| 4433 | 4409 | ||
| 4434 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4410 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4435 | INC_PC(sizeof(ldst_inst)); | 4411 | INC_PC(sizeof(ldst_inst)); |
| 4436 | FETCH_INST; | 4412 | FETCH_INST; |
| 4437 | GOTO_NEXT_INST; | 4413 | GOTO_NEXT_INST; |
| @@ -4442,7 +4418,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4442 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 4418 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; |
| 4443 | inst_cream->get_addr(cpu, inst_cream->inst, addr); | 4419 | inst_cream->get_addr(cpu, inst_cream->inst, addr); |
| 4444 | 4420 | ||
| 4445 | unsigned int value = ReadMemory32(cpu, addr); | 4421 | unsigned int value = cpu->ReadMemory32(addr); |
| 4446 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | 4422 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; |
| 4447 | 4423 | ||
| 4448 | if (BITS(inst_cream->inst, 12, 15) == 15) { | 4424 | if (BITS(inst_cream->inst, 12, 15) == 15) { |
| @@ -4453,7 +4429,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4453 | goto DISPATCH; | 4429 | goto DISPATCH; |
| 4454 | } | 4430 | } |
| 4455 | } | 4431 | } |
| 4456 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4432 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4457 | INC_PC(sizeof(ldst_inst)); | 4433 | INC_PC(sizeof(ldst_inst)); |
| 4458 | FETCH_INST; | 4434 | FETCH_INST; |
| 4459 | GOTO_NEXT_INST; | 4435 | GOTO_NEXT_INST; |
| @@ -4464,7 +4440,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4464 | uxth_inst* inst_cream = (uxth_inst*)inst_base->component; | 4440 | uxth_inst* inst_cream = (uxth_inst*)inst_base->component; |
| 4465 | RD = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff; | 4441 | RD = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff; |
| 4466 | } | 4442 | } |
| 4467 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4443 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4468 | INC_PC(sizeof(uxth_inst)); | 4444 | INC_PC(sizeof(uxth_inst)); |
| 4469 | FETCH_INST; | 4445 | FETCH_INST; |
| 4470 | GOTO_NEXT_INST; | 4446 | GOTO_NEXT_INST; |
| @@ -4477,7 +4453,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4477 | 4453 | ||
| 4478 | RD = RN + operand2; | 4454 | RD = RN + operand2; |
| 4479 | } | 4455 | } |
| 4480 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4456 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4481 | INC_PC(sizeof(uxtah_inst)); | 4457 | INC_PC(sizeof(uxtah_inst)); |
| 4482 | FETCH_INST; | 4458 | FETCH_INST; |
| 4483 | GOTO_NEXT_INST; | 4459 | GOTO_NEXT_INST; |
| @@ -4495,7 +4471,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4495 | goto DISPATCH; | 4471 | goto DISPATCH; |
| 4496 | } | 4472 | } |
| 4497 | } | 4473 | } |
| 4498 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4474 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4499 | INC_PC(sizeof(ldst_inst)); | 4475 | INC_PC(sizeof(ldst_inst)); |
| 4500 | FETCH_INST; | 4476 | FETCH_INST; |
| 4501 | GOTO_NEXT_INST; | 4477 | GOTO_NEXT_INST; |
| @@ -4513,7 +4489,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4513 | goto DISPATCH; | 4489 | goto DISPATCH; |
| 4514 | } | 4490 | } |
| 4515 | } | 4491 | } |
| 4516 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4492 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4517 | INC_PC(sizeof(ldst_inst)); | 4493 | INC_PC(sizeof(ldst_inst)); |
| 4518 | FETCH_INST; | 4494 | FETCH_INST; |
| 4519 | GOTO_NEXT_INST; | 4495 | GOTO_NEXT_INST; |
| @@ -4527,8 +4503,8 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4527 | 4503 | ||
| 4528 | // The 3DS doesn't have LPAE (Large Physical Access Extension), so it | 4504 | // The 3DS doesn't have LPAE (Large Physical Access Extension), so it |
| 4529 | // wouldn't do this as a single read. | 4505 | // wouldn't do this as a single read. |
| 4530 | cpu->Reg[BITS(inst_cream->inst, 12, 15) + 0] = ReadMemory32(cpu, addr); | 4506 | cpu->Reg[BITS(inst_cream->inst, 12, 15) + 0] = cpu->ReadMemory32(addr); |
| 4531 | cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = ReadMemory32(cpu, addr + 4); | 4507 | cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = cpu->ReadMemory32(addr + 4); |
| 4532 | 4508 | ||
| 4533 | // No dispatch since this operation should not modify R15 | 4509 | // No dispatch since this operation should not modify R15 |
| 4534 | } | 4510 | } |
| @@ -4544,16 +4520,15 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4544 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; | 4520 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; |
| 4545 | unsigned int read_addr = RN; | 4521 | unsigned int read_addr = RN; |
| 4546 | 4522 | ||
| 4547 | add_exclusive_addr(cpu, read_addr); | 4523 | cpu->SetExclusiveMemoryAddress(read_addr); |
| 4548 | cpu->exclusive_state = 1; | ||
| 4549 | 4524 | ||
| 4550 | RD = ReadMemory32(cpu, read_addr); | 4525 | RD = cpu->ReadMemory32(read_addr); |
| 4551 | if (inst_cream->Rd == 15) { | 4526 | if (inst_cream->Rd == 15) { |
| 4552 | INC_PC(sizeof(generic_arm_inst)); | 4527 | INC_PC(sizeof(generic_arm_inst)); |
| 4553 | goto DISPATCH; | 4528 | goto DISPATCH; |
| 4554 | } | 4529 | } |
| 4555 | } | 4530 | } |
| 4556 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4531 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4557 | INC_PC(sizeof(generic_arm_inst)); | 4532 | INC_PC(sizeof(generic_arm_inst)); |
| 4558 | FETCH_INST; | 4533 | FETCH_INST; |
| 4559 | GOTO_NEXT_INST; | 4534 | GOTO_NEXT_INST; |
| @@ -4564,8 +4539,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4564 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; | 4539 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; |
| 4565 | unsigned int read_addr = RN; | 4540 | unsigned int read_addr = RN; |
| 4566 | 4541 | ||
| 4567 | add_exclusive_addr(cpu, read_addr); | 4542 | cpu->SetExclusiveMemoryAddress(read_addr); |
| 4568 | cpu->exclusive_state = 1; | ||
| 4569 | 4543 | ||
| 4570 | RD = Memory::Read8(read_addr); | 4544 | RD = Memory::Read8(read_addr); |
| 4571 | if (inst_cream->Rd == 15) { | 4545 | if (inst_cream->Rd == 15) { |
| @@ -4573,7 +4547,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4573 | goto DISPATCH; | 4547 | goto DISPATCH; |
| 4574 | } | 4548 | } |
| 4575 | } | 4549 | } |
| 4576 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4550 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4577 | INC_PC(sizeof(generic_arm_inst)); | 4551 | INC_PC(sizeof(generic_arm_inst)); |
| 4578 | FETCH_INST; | 4552 | FETCH_INST; |
| 4579 | GOTO_NEXT_INST; | 4553 | GOTO_NEXT_INST; |
| @@ -4584,16 +4558,15 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4584 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; | 4558 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; |
| 4585 | unsigned int read_addr = RN; | 4559 | unsigned int read_addr = RN; |
| 4586 | 4560 | ||
| 4587 | add_exclusive_addr(cpu, read_addr); | 4561 | cpu->SetExclusiveMemoryAddress(read_addr); |
| 4588 | cpu->exclusive_state = 1; | ||
| 4589 | 4562 | ||
| 4590 | RD = ReadMemory16(cpu, read_addr); | 4563 | RD = cpu->ReadMemory16(read_addr); |
| 4591 | if (inst_cream->Rd == 15) { | 4564 | if (inst_cream->Rd == 15) { |
| 4592 | INC_PC(sizeof(generic_arm_inst)); | 4565 | INC_PC(sizeof(generic_arm_inst)); |
| 4593 | goto DISPATCH; | 4566 | goto DISPATCH; |
| 4594 | } | 4567 | } |
| 4595 | } | 4568 | } |
| 4596 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4569 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4597 | INC_PC(sizeof(generic_arm_inst)); | 4570 | INC_PC(sizeof(generic_arm_inst)); |
| 4598 | FETCH_INST; | 4571 | FETCH_INST; |
| 4599 | GOTO_NEXT_INST; | 4572 | GOTO_NEXT_INST; |
| @@ -4604,18 +4577,17 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4604 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; | 4577 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; |
| 4605 | unsigned int read_addr = RN; | 4578 | unsigned int read_addr = RN; |
| 4606 | 4579 | ||
| 4607 | add_exclusive_addr(cpu, read_addr); | 4580 | cpu->SetExclusiveMemoryAddress(read_addr); |
| 4608 | cpu->exclusive_state = 1; | ||
| 4609 | 4581 | ||
| 4610 | RD = ReadMemory32(cpu, read_addr); | 4582 | RD = cpu->ReadMemory32(read_addr); |
| 4611 | RD2 = ReadMemory32(cpu, read_addr + 4); | 4583 | RD2 = cpu->ReadMemory32(read_addr + 4); |
| 4612 | 4584 | ||
| 4613 | if (inst_cream->Rd == 15) { | 4585 | if (inst_cream->Rd == 15) { |
| 4614 | INC_PC(sizeof(generic_arm_inst)); | 4586 | INC_PC(sizeof(generic_arm_inst)); |
| 4615 | goto DISPATCH; | 4587 | goto DISPATCH; |
| 4616 | } | 4588 | } |
| 4617 | } | 4589 | } |
| 4618 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4590 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4619 | INC_PC(sizeof(generic_arm_inst)); | 4591 | INC_PC(sizeof(generic_arm_inst)); |
| 4620 | FETCH_INST; | 4592 | FETCH_INST; |
| 4621 | GOTO_NEXT_INST; | 4593 | GOTO_NEXT_INST; |
| @@ -4626,13 +4598,13 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4626 | ldst_inst* inst_cream = (ldst_inst*)inst_base->component; | 4598 | ldst_inst* inst_cream = (ldst_inst*)inst_base->component; |
| 4627 | inst_cream->get_addr(cpu, inst_cream->inst, addr); | 4599 | inst_cream->get_addr(cpu, inst_cream->inst, addr); |
| 4628 | 4600 | ||
| 4629 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = ReadMemory16(cpu, addr); | 4601 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = cpu->ReadMemory16(addr); |
| 4630 | if (BITS(inst_cream->inst, 12, 15) == 15) { | 4602 | if (BITS(inst_cream->inst, 12, 15) == 15) { |
| 4631 | INC_PC(sizeof(ldst_inst)); | 4603 | INC_PC(sizeof(ldst_inst)); |
| 4632 | goto DISPATCH; | 4604 | goto DISPATCH; |
| 4633 | } | 4605 | } |
| 4634 | } | 4606 | } |
| 4635 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4607 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4636 | INC_PC(sizeof(ldst_inst)); | 4608 | INC_PC(sizeof(ldst_inst)); |
| 4637 | FETCH_INST; | 4609 | FETCH_INST; |
| 4638 | GOTO_NEXT_INST; | 4610 | GOTO_NEXT_INST; |
| @@ -4652,7 +4624,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4652 | goto DISPATCH; | 4624 | goto DISPATCH; |
| 4653 | } | 4625 | } |
| 4654 | } | 4626 | } |
| 4655 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4627 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4656 | INC_PC(sizeof(ldst_inst)); | 4628 | INC_PC(sizeof(ldst_inst)); |
| 4657 | FETCH_INST; | 4629 | FETCH_INST; |
| 4658 | GOTO_NEXT_INST; | 4630 | GOTO_NEXT_INST; |
| @@ -4663,7 +4635,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4663 | ldst_inst* inst_cream = (ldst_inst*)inst_base->component; | 4635 | ldst_inst* inst_cream = (ldst_inst*)inst_base->component; |
| 4664 | inst_cream->get_addr(cpu, inst_cream->inst, addr); | 4636 | inst_cream->get_addr(cpu, inst_cream->inst, addr); |
| 4665 | 4637 | ||
| 4666 | unsigned int value = ReadMemory16(cpu, addr); | 4638 | unsigned int value = cpu->ReadMemory16(addr); |
| 4667 | if (BIT(value, 15)) { | 4639 | if (BIT(value, 15)) { |
| 4668 | value |= 0xffff0000; | 4640 | value |= 0xffff0000; |
| 4669 | } | 4641 | } |
| @@ -4673,7 +4645,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4673 | goto DISPATCH; | 4645 | goto DISPATCH; |
| 4674 | } | 4646 | } |
| 4675 | } | 4647 | } |
| 4676 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4648 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4677 | INC_PC(sizeof(ldst_inst)); | 4649 | INC_PC(sizeof(ldst_inst)); |
| 4678 | FETCH_INST; | 4650 | FETCH_INST; |
| 4679 | GOTO_NEXT_INST; | 4651 | GOTO_NEXT_INST; |
| @@ -4684,7 +4656,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4684 | ldst_inst* inst_cream = (ldst_inst*)inst_base->component; | 4656 | ldst_inst* inst_cream = (ldst_inst*)inst_base->component; |
| 4685 | inst_cream->get_addr(cpu, inst_cream->inst, addr); | 4657 | inst_cream->get_addr(cpu, inst_cream->inst, addr); |
| 4686 | 4658 | ||
| 4687 | unsigned int value = ReadMemory32(cpu, addr); | 4659 | unsigned int value = cpu->ReadMemory32(addr); |
| 4688 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | 4660 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; |
| 4689 | 4661 | ||
| 4690 | if (BITS(inst_cream->inst, 12, 15) == 15) { | 4662 | if (BITS(inst_cream->inst, 12, 15) == 15) { |
| @@ -4692,7 +4664,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4692 | goto DISPATCH; | 4664 | goto DISPATCH; |
| 4693 | } | 4665 | } |
| 4694 | } | 4666 | } |
| 4695 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4667 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4696 | INC_PC(sizeof(ldst_inst)); | 4668 | INC_PC(sizeof(ldst_inst)); |
| 4697 | FETCH_INST; | 4669 | FETCH_INST; |
| 4698 | GOTO_NEXT_INST; | 4670 | GOTO_NEXT_INST; |
| @@ -4707,10 +4679,10 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4707 | DEBUG_MSG; | 4679 | DEBUG_MSG; |
| 4708 | } else { | 4680 | } else { |
| 4709 | if (inst_cream->cp_num == 15) | 4681 | if (inst_cream->cp_num == 15) |
| 4710 | WriteCP15Register(cpu, RD, CRn, OPCODE_1, CRm, OPCODE_2); | 4682 | cpu->WriteCP15Register(RD, CRn, OPCODE_1, CRm, OPCODE_2); |
| 4711 | } | 4683 | } |
| 4712 | } | 4684 | } |
| 4713 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4685 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4714 | INC_PC(sizeof(mcr_inst)); | 4686 | INC_PC(sizeof(mcr_inst)); |
| 4715 | FETCH_INST; | 4687 | FETCH_INST; |
| 4716 | GOTO_NEXT_INST; | 4688 | GOTO_NEXT_INST; |
| @@ -4727,7 +4699,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4727 | inst_cream->cp_num, inst_cream->crm, inst_cream->opcode_1, inst_cream->rt, inst_cream->rt2); | 4699 | inst_cream->cp_num, inst_cream->crm, inst_cream->opcode_1, inst_cream->rt, inst_cream->rt2); |
| 4728 | } | 4700 | } |
| 4729 | 4701 | ||
| 4730 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4702 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4731 | INC_PC(sizeof(mcrr_inst)); | 4703 | INC_PC(sizeof(mcrr_inst)); |
| 4732 | FETCH_INST; | 4704 | FETCH_INST; |
| 4733 | GOTO_NEXT_INST; | 4705 | GOTO_NEXT_INST; |
| @@ -4752,7 +4724,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4752 | goto DISPATCH; | 4724 | goto DISPATCH; |
| 4753 | } | 4725 | } |
| 4754 | } | 4726 | } |
| 4755 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4727 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4756 | INC_PC(sizeof(mla_inst)); | 4728 | INC_PC(sizeof(mla_inst)); |
| 4757 | FETCH_INST; | 4729 | FETCH_INST; |
| 4758 | GOTO_NEXT_INST; | 4730 | GOTO_NEXT_INST; |
| @@ -4766,7 +4738,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4766 | if (inst_cream->S && (inst_cream->Rd == 15)) { | 4738 | if (inst_cream->S && (inst_cream->Rd == 15)) { |
| 4767 | if (CurrentModeHasSPSR) { | 4739 | if (CurrentModeHasSPSR) { |
| 4768 | cpu->Cpsr = cpu->Spsr_copy; | 4740 | cpu->Cpsr = cpu->Spsr_copy; |
| 4769 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); | 4741 | cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F); |
| 4770 | LOAD_NZCVT; | 4742 | LOAD_NZCVT; |
| 4771 | } | 4743 | } |
| 4772 | } else if (inst_cream->S) { | 4744 | } else if (inst_cream->S) { |
| @@ -4779,7 +4751,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4779 | goto DISPATCH; | 4751 | goto DISPATCH; |
| 4780 | } | 4752 | } |
| 4781 | } | 4753 | } |
| 4782 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4754 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4783 | INC_PC(sizeof(mov_inst)); | 4755 | INC_PC(sizeof(mov_inst)); |
| 4784 | FETCH_INST; | 4756 | FETCH_INST; |
| 4785 | GOTO_NEXT_INST; | 4757 | GOTO_NEXT_INST; |
| @@ -4800,10 +4772,10 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4800 | goto END; | 4772 | goto END; |
| 4801 | } else { | 4773 | } else { |
| 4802 | if (inst_cream->cp_num == 15) | 4774 | if (inst_cream->cp_num == 15) |
| 4803 | RD = ReadCP15Register(cpu, CRn, OPCODE_1, CRm, OPCODE_2); | 4775 | RD = cpu->ReadCP15Register(CRn, OPCODE_1, CRm, OPCODE_2); |
| 4804 | } | 4776 | } |
| 4805 | } | 4777 | } |
| 4806 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4778 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4807 | INC_PC(sizeof(mrc_inst)); | 4779 | INC_PC(sizeof(mrc_inst)); |
| 4808 | FETCH_INST; | 4780 | FETCH_INST; |
| 4809 | GOTO_NEXT_INST; | 4781 | GOTO_NEXT_INST; |
| @@ -4820,7 +4792,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4820 | inst_cream->cp_num, inst_cream->crm, inst_cream->opcode_1, inst_cream->rt, inst_cream->rt2); | 4792 | inst_cream->cp_num, inst_cream->crm, inst_cream->opcode_1, inst_cream->rt, inst_cream->rt2); |
| 4821 | } | 4793 | } |
| 4822 | 4794 | ||
| 4823 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4795 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4824 | INC_PC(sizeof(mcrr_inst)); | 4796 | INC_PC(sizeof(mcrr_inst)); |
| 4825 | FETCH_INST; | 4797 | FETCH_INST; |
| 4826 | GOTO_NEXT_INST; | 4798 | GOTO_NEXT_INST; |
| @@ -4838,7 +4810,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4838 | RD = cpu->Cpsr; | 4810 | RD = cpu->Cpsr; |
| 4839 | } | 4811 | } |
| 4840 | } | 4812 | } |
| 4841 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4813 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4842 | INC_PC(sizeof(mrs_inst)); | 4814 | INC_PC(sizeof(mrs_inst)); |
| 4843 | FETCH_INST; | 4815 | FETCH_INST; |
| 4844 | GOTO_NEXT_INST; | 4816 | GOTO_NEXT_INST; |
| @@ -4861,7 +4833,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4861 | | (BIT(inst, 18) ? 0xff0000 : 0) | (BIT(inst, 19) ? 0xff000000 : 0); | 4833 | | (BIT(inst, 18) ? 0xff0000 : 0) | (BIT(inst, 19) ? 0xff000000 : 0); |
| 4862 | uint32_t mask = 0; | 4834 | uint32_t mask = 0; |
| 4863 | if (!inst_cream->R) { | 4835 | if (!inst_cream->R) { |
| 4864 | if (InAPrivilegedMode(cpu)) { | 4836 | if (cpu->InAPrivilegedMode()) { |
| 4865 | if ((operand & StateMask) != 0) { | 4837 | if ((operand & StateMask) != 0) { |
| 4866 | /// UNPREDICTABLE | 4838 | /// UNPREDICTABLE |
| 4867 | DEBUG_MSG; | 4839 | DEBUG_MSG; |
| @@ -4873,7 +4845,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4873 | SAVE_NZCVT; | 4845 | SAVE_NZCVT; |
| 4874 | 4846 | ||
| 4875 | cpu->Cpsr = (cpu->Cpsr & ~mask) | (operand & mask); | 4847 | cpu->Cpsr = (cpu->Cpsr & ~mask) | (operand & mask); |
| 4876 | switch_mode(cpu, cpu->Cpsr & 0x1f); | 4848 | cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F); |
| 4877 | LOAD_NZCVT; | 4849 | LOAD_NZCVT; |
| 4878 | } else { | 4850 | } else { |
| 4879 | if (CurrentModeHasSPSR) { | 4851 | if (CurrentModeHasSPSR) { |
| @@ -4882,7 +4854,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4882 | } | 4854 | } |
| 4883 | } | 4855 | } |
| 4884 | } | 4856 | } |
| 4885 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4857 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4886 | INC_PC(sizeof(msr_inst)); | 4858 | INC_PC(sizeof(msr_inst)); |
| 4887 | FETCH_INST; | 4859 | FETCH_INST; |
| 4888 | GOTO_NEXT_INST; | 4860 | GOTO_NEXT_INST; |
| @@ -4904,7 +4876,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4904 | goto DISPATCH; | 4876 | goto DISPATCH; |
| 4905 | } | 4877 | } |
| 4906 | } | 4878 | } |
| 4907 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4879 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4908 | INC_PC(sizeof(mul_inst)); | 4880 | INC_PC(sizeof(mul_inst)); |
| 4909 | FETCH_INST; | 4881 | FETCH_INST; |
| 4910 | GOTO_NEXT_INST; | 4882 | GOTO_NEXT_INST; |
| @@ -4919,7 +4891,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4919 | if (inst_cream->S && (inst_cream->Rd == 15)) { | 4891 | if (inst_cream->S && (inst_cream->Rd == 15)) { |
| 4920 | if (CurrentModeHasSPSR) { | 4892 | if (CurrentModeHasSPSR) { |
| 4921 | cpu->Cpsr = cpu->Spsr_copy; | 4893 | cpu->Cpsr = cpu->Spsr_copy; |
| 4922 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); | 4894 | cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F); |
| 4923 | LOAD_NZCVT; | 4895 | LOAD_NZCVT; |
| 4924 | } | 4896 | } |
| 4925 | } else if (inst_cream->S) { | 4897 | } else if (inst_cream->S) { |
| @@ -4932,7 +4904,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4932 | goto DISPATCH; | 4904 | goto DISPATCH; |
| 4933 | } | 4905 | } |
| 4934 | } | 4906 | } |
| 4935 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4907 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4936 | INC_PC(sizeof(mvn_inst)); | 4908 | INC_PC(sizeof(mvn_inst)); |
| 4937 | FETCH_INST; | 4909 | FETCH_INST; |
| 4938 | GOTO_NEXT_INST; | 4910 | GOTO_NEXT_INST; |
| @@ -4944,12 +4916,16 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4944 | 4916 | ||
| 4945 | u32 lop = RN; | 4917 | u32 lop = RN; |
| 4946 | u32 rop = SHIFTER_OPERAND; | 4918 | u32 rop = SHIFTER_OPERAND; |
| 4919 | |||
| 4920 | if (inst_cream->Rn == 15) | ||
| 4921 | lop += 2 * cpu->GetInstructionSize(); | ||
| 4922 | |||
| 4947 | RD = lop | rop; | 4923 | RD = lop | rop; |
| 4948 | 4924 | ||
| 4949 | if (inst_cream->S && (inst_cream->Rd == 15)) { | 4925 | if (inst_cream->S && (inst_cream->Rd == 15)) { |
| 4950 | if (CurrentModeHasSPSR) { | 4926 | if (CurrentModeHasSPSR) { |
| 4951 | cpu->Cpsr = cpu->Spsr_copy; | 4927 | cpu->Cpsr = cpu->Spsr_copy; |
| 4952 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); | 4928 | cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F); |
| 4953 | LOAD_NZCVT; | 4929 | LOAD_NZCVT; |
| 4954 | } | 4930 | } |
| 4955 | } else if (inst_cream->S) { | 4931 | } else if (inst_cream->S) { |
| @@ -4962,7 +4938,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4962 | goto DISPATCH; | 4938 | goto DISPATCH; |
| 4963 | } | 4939 | } |
| 4964 | } | 4940 | } |
| 4965 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4941 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4966 | INC_PC(sizeof(orr_inst)); | 4942 | INC_PC(sizeof(orr_inst)); |
| 4967 | FETCH_INST; | 4943 | FETCH_INST; |
| 4968 | GOTO_NEXT_INST; | 4944 | GOTO_NEXT_INST; |
| @@ -4970,7 +4946,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4970 | 4946 | ||
| 4971 | NOP_INST: | 4947 | NOP_INST: |
| 4972 | { | 4948 | { |
| 4973 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4949 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4974 | INC_PC_STUB; | 4950 | INC_PC_STUB; |
| 4975 | FETCH_INST; | 4951 | FETCH_INST; |
| 4976 | GOTO_NEXT_INST; | 4952 | GOTO_NEXT_INST; |
| @@ -4982,7 +4958,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4982 | pkh_inst *inst_cream = (pkh_inst *)inst_base->component; | 4958 | pkh_inst *inst_cream = (pkh_inst *)inst_base->component; |
| 4983 | RD = (RN & 0xFFFF) | ((RM << inst_cream->imm) & 0xFFFF0000); | 4959 | RD = (RN & 0xFFFF) | ((RM << inst_cream->imm) & 0xFFFF0000); |
| 4984 | } | 4960 | } |
| 4985 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4961 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4986 | INC_PC(sizeof(pkh_inst)); | 4962 | INC_PC(sizeof(pkh_inst)); |
| 4987 | FETCH_INST; | 4963 | FETCH_INST; |
| 4988 | GOTO_NEXT_INST; | 4964 | GOTO_NEXT_INST; |
| @@ -4995,7 +4971,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 4995 | int shift_imm = inst_cream->imm ? inst_cream->imm : 31; | 4971 | int shift_imm = inst_cream->imm ? inst_cream->imm : 31; |
| 4996 | RD = ((static_cast<s32>(RM) >> shift_imm) & 0xFFFF) | (RN & 0xFFFF0000); | 4972 | RD = ((static_cast<s32>(RM) >> shift_imm) & 0xFFFF) | (RN & 0xFFFF0000); |
| 4997 | } | 4973 | } |
| 4998 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4974 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 4999 | INC_PC(sizeof(pkh_inst)); | 4975 | INC_PC(sizeof(pkh_inst)); |
| 5000 | FETCH_INST; | 4976 | FETCH_INST; |
| 5001 | GOTO_NEXT_INST; | 4977 | GOTO_NEXT_INST; |
| @@ -5005,7 +4981,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5005 | { | 4981 | { |
| 5006 | // Not implemented. PLD is a hint instruction, so it's optional. | 4982 | // Not implemented. PLD is a hint instruction, so it's optional. |
| 5007 | 4983 | ||
| 5008 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4984 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 5009 | INC_PC(sizeof(pld_inst)); | 4985 | INC_PC(sizeof(pld_inst)); |
| 5010 | FETCH_INST; | 4986 | FETCH_INST; |
| 5011 | GOTO_NEXT_INST; | 4987 | GOTO_NEXT_INST; |
| @@ -5078,7 +5054,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5078 | RD = result; | 5054 | RD = result; |
| 5079 | } | 5055 | } |
| 5080 | 5056 | ||
| 5081 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5057 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 5082 | INC_PC(sizeof(generic_arm_inst)); | 5058 | INC_PC(sizeof(generic_arm_inst)); |
| 5083 | FETCH_INST; | 5059 | FETCH_INST; |
| 5084 | GOTO_NEXT_INST; | 5060 | GOTO_NEXT_INST; |
| @@ -5140,7 +5116,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5140 | RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16); | 5116 | RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16); |
| 5141 | } | 5117 | } |
| 5142 | 5118 | ||
| 5143 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5119 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 5144 | INC_PC(sizeof(generic_arm_inst)); | 5120 | INC_PC(sizeof(generic_arm_inst)); |
| 5145 | FETCH_INST; | 5121 | FETCH_INST; |
| 5146 | GOTO_NEXT_INST; | 5122 | GOTO_NEXT_INST; |
| @@ -5173,7 +5149,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5173 | } | 5149 | } |
| 5174 | } | 5150 | } |
| 5175 | 5151 | ||
| 5176 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5152 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 5177 | INC_PC(sizeof(rev_inst)); | 5153 | INC_PC(sizeof(rev_inst)); |
| 5178 | FETCH_INST; | 5154 | FETCH_INST; |
| 5179 | GOTO_NEXT_INST; | 5155 | GOTO_NEXT_INST; |
| @@ -5187,8 +5163,8 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5187 | u32 address = 0; | 5163 | u32 address = 0; |
| 5188 | inst_cream->get_addr(cpu, inst_cream->inst, address); | 5164 | inst_cream->get_addr(cpu, inst_cream->inst, address); |
| 5189 | 5165 | ||
| 5190 | cpu->Cpsr = ReadMemory32(cpu, address); | 5166 | cpu->Cpsr = cpu->ReadMemory32(address); |
| 5191 | cpu->Reg[15] = ReadMemory32(cpu, address + 4); | 5167 | cpu->Reg[15] = cpu->ReadMemory32(address + 4); |
| 5192 | 5168 | ||
| 5193 | INC_PC(sizeof(ldst_inst)); | 5169 | INC_PC(sizeof(ldst_inst)); |
| 5194 | goto DISPATCH; | 5170 | goto DISPATCH; |
| @@ -5201,7 +5177,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5201 | 5177 | ||
| 5202 | u32 rn_val = RN; | 5178 | u32 rn_val = RN; |
| 5203 | if (inst_cream->Rn == 15) | 5179 | if (inst_cream->Rn == 15) |
| 5204 | rn_val += 2 * GET_INST_SIZE(cpu); | 5180 | rn_val += 2 * cpu->GetInstructionSize(); |
| 5205 | 5181 | ||
| 5206 | bool carry; | 5182 | bool carry; |
| 5207 | bool overflow; | 5183 | bool overflow; |
| @@ -5210,7 +5186,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5210 | if (inst_cream->S && (inst_cream->Rd == 15)) { | 5186 | if (inst_cream->S && (inst_cream->Rd == 15)) { |
| 5211 | if (CurrentModeHasSPSR) { | 5187 | if (CurrentModeHasSPSR) { |
| 5212 | cpu->Cpsr = cpu->Spsr_copy; | 5188 | cpu->Cpsr = cpu->Spsr_copy; |
| 5213 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); | 5189 | cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F); |
| 5214 | LOAD_NZCVT; | 5190 | LOAD_NZCVT; |
| 5215 | } | 5191 | } |
| 5216 | } else if (inst_cream->S) { | 5192 | } else if (inst_cream->S) { |
| @@ -5224,7 +5200,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5224 | goto DISPATCH; | 5200 | goto DISPATCH; |
| 5225 | } | 5201 | } |
| 5226 | } | 5202 | } |
| 5227 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5203 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 5228 | INC_PC(sizeof(rsb_inst)); | 5204 | INC_PC(sizeof(rsb_inst)); |
| 5229 | FETCH_INST; | 5205 | FETCH_INST; |
| 5230 | GOTO_NEXT_INST; | 5206 | GOTO_NEXT_INST; |
| @@ -5234,14 +5210,18 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5234 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | 5210 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { |
| 5235 | rsc_inst* const inst_cream = (rsc_inst*)inst_base->component; | 5211 | rsc_inst* const inst_cream = (rsc_inst*)inst_base->component; |
| 5236 | 5212 | ||
| 5213 | u32 rn_val = RN; | ||
| 5214 | if (inst_cream->Rn == 15) | ||
| 5215 | rn_val += 2 * cpu->GetInstructionSize(); | ||
| 5216 | |||
| 5237 | bool carry; | 5217 | bool carry; |
| 5238 | bool overflow; | 5218 | bool overflow; |
| 5239 | RD = AddWithCarry(~RN, SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow); | 5219 | RD = AddWithCarry(~rn_val, SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow); |
| 5240 | 5220 | ||
| 5241 | if (inst_cream->S && (inst_cream->Rd == 15)) { | 5221 | if (inst_cream->S && (inst_cream->Rd == 15)) { |
| 5242 | if (CurrentModeHasSPSR) { | 5222 | if (CurrentModeHasSPSR) { |
| 5243 | cpu->Cpsr = cpu->Spsr_copy; | 5223 | cpu->Cpsr = cpu->Spsr_copy; |
| 5244 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); | 5224 | cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F); |
| 5245 | LOAD_NZCVT; | 5225 | LOAD_NZCVT; |
| 5246 | } | 5226 | } |
| 5247 | } else if (inst_cream->S) { | 5227 | } else if (inst_cream->S) { |
| @@ -5255,7 +5235,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5255 | goto DISPATCH; | 5235 | goto DISPATCH; |
| 5256 | } | 5236 | } |
| 5257 | } | 5237 | } |
| 5258 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5238 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 5259 | INC_PC(sizeof(rsc_inst)); | 5239 | INC_PC(sizeof(rsc_inst)); |
| 5260 | FETCH_INST; | 5240 | FETCH_INST; |
| 5261 | GOTO_NEXT_INST; | 5241 | GOTO_NEXT_INST; |
| @@ -5363,7 +5343,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5363 | } | 5343 | } |
| 5364 | } | 5344 | } |
| 5365 | 5345 | ||
| 5366 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5346 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 5367 | INC_PC(sizeof(generic_arm_inst)); | 5347 | INC_PC(sizeof(generic_arm_inst)); |
| 5368 | FETCH_INST; | 5348 | FETCH_INST; |
| 5369 | GOTO_NEXT_INST; | 5349 | GOTO_NEXT_INST; |
| @@ -5374,14 +5354,18 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5374 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { | 5354 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { |
| 5375 | sbc_inst* const inst_cream = (sbc_inst*)inst_base->component; | 5355 | sbc_inst* const inst_cream = (sbc_inst*)inst_base->component; |
| 5376 | 5356 | ||
| 5357 | u32 rn_val = RN; | ||
| 5358 | if (inst_cream->Rn == 15) | ||
| 5359 | rn_val += 2 * cpu->GetInstructionSize(); | ||
| 5360 | |||
| 5377 | bool carry; | 5361 | bool carry; |
| 5378 | bool overflow; | 5362 | bool overflow; |
| 5379 | RD = AddWithCarry(RN, ~SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow); | 5363 | RD = AddWithCarry(rn_val, ~SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow); |
| 5380 | 5364 | ||
| 5381 | if (inst_cream->S && (inst_cream->Rd == 15)) { | 5365 | if (inst_cream->S && (inst_cream->Rd == 15)) { |
| 5382 | if (CurrentModeHasSPSR) { | 5366 | if (CurrentModeHasSPSR) { |
| 5383 | cpu->Cpsr = cpu->Spsr_copy; | 5367 | cpu->Cpsr = cpu->Spsr_copy; |
| 5384 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); | 5368 | cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F); |
| 5385 | LOAD_NZCVT; | 5369 | LOAD_NZCVT; |
| 5386 | } | 5370 | } |
| 5387 | } else if (inst_cream->S) { | 5371 | } else if (inst_cream->S) { |
| @@ -5395,7 +5379,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5395 | goto DISPATCH; | 5379 | goto DISPATCH; |
| 5396 | } | 5380 | } |
| 5397 | } | 5381 | } |
| 5398 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5382 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 5399 | INC_PC(sizeof(sbc_inst)); | 5383 | INC_PC(sizeof(sbc_inst)); |
| 5400 | FETCH_INST; | 5384 | FETCH_INST; |
| 5401 | GOTO_NEXT_INST; | 5385 | GOTO_NEXT_INST; |
| @@ -5434,7 +5418,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5434 | RD = result; | 5418 | RD = result; |
| 5435 | } | 5419 | } |
| 5436 | 5420 | ||
| 5437 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5421 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 5438 | INC_PC(sizeof(generic_arm_inst)); | 5422 | INC_PC(sizeof(generic_arm_inst)); |
| 5439 | FETCH_INST; | 5423 | FETCH_INST; |
| 5440 | GOTO_NEXT_INST; | 5424 | GOTO_NEXT_INST; |
| @@ -5453,7 +5437,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5453 | 5437 | ||
| 5454 | LOG_WARNING(Core_ARM11, "SETEND %s executed", big_endian ? "BE" : "LE"); | 5438 | LOG_WARNING(Core_ARM11, "SETEND %s executed", big_endian ? "BE" : "LE"); |
| 5455 | 5439 | ||
| 5456 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5440 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 5457 | INC_PC(sizeof(setend_inst)); | 5441 | INC_PC(sizeof(setend_inst)); |
| 5458 | FETCH_INST; | 5442 | FETCH_INST; |
| 5459 | GOTO_NEXT_INST; | 5443 | GOTO_NEXT_INST; |
| @@ -5466,7 +5450,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5466 | LOG_TRACE(Core_ARM11, "SEV executed."); | 5450 | LOG_TRACE(Core_ARM11, "SEV executed."); |
| 5467 | } | 5451 | } |
| 5468 | 5452 | ||
| 5469 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5453 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 5470 | INC_PC_STUB; | 5454 | INC_PC_STUB; |
| 5471 | FETCH_INST; | 5455 | FETCH_INST; |
| 5472 | GOTO_NEXT_INST; | 5456 | GOTO_NEXT_INST; |
| @@ -5538,7 +5522,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5538 | } | 5522 | } |
| 5539 | } | 5523 | } |
| 5540 | 5524 | ||
| 5541 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5525 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 5542 | INC_PC(sizeof(generic_arm_inst)); | 5526 | INC_PC(sizeof(generic_arm_inst)); |
| 5543 | FETCH_INST; | 5527 | FETCH_INST; |
| 5544 | GOTO_NEXT_INST; | 5528 | GOTO_NEXT_INST; |
| @@ -5563,7 +5547,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5563 | if (AddOverflow(operand1 * operand2, RN, RD)) | 5547 | if (AddOverflow(operand1 * operand2, RN, RD)) |
| 5564 | cpu->Cpsr |= (1 << 27); | 5548 | cpu->Cpsr |= (1 << 27); |
| 5565 | } | 5549 | } |
| 5566 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5550 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 5567 | INC_PC(sizeof(smla_inst)); | 5551 | INC_PC(sizeof(smla_inst)); |
| 5568 | FETCH_INST; | 5552 | FETCH_INST; |
| 5569 | GOTO_NEXT_INST; | 5553 | GOTO_NEXT_INST; |
| @@ -5619,7 +5603,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5619 | } | 5603 | } |
| 5620 | } | 5604 | } |
| 5621 | 5605 | ||
| 5622 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5606 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 5623 | INC_PC(sizeof(smlad_inst)); | 5607 | INC_PC(sizeof(smlad_inst)); |
| 5624 | FETCH_INST; | 5608 | FETCH_INST; |
| 5625 | GOTO_NEXT_INST; | 5609 | GOTO_NEXT_INST; |
| @@ -5648,7 +5632,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5648 | cpu->ZFlag = (RDHI == 0 && RDLO == 0); | 5632 | cpu->ZFlag = (RDHI == 0 && RDLO == 0); |
| 5649 | } | 5633 | } |
| 5650 | } | 5634 | } |
| 5651 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5635 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 5652 | INC_PC(sizeof(umlal_inst)); | 5636 | INC_PC(sizeof(umlal_inst)); |
| 5653 | FETCH_INST; | 5637 | FETCH_INST; |
| 5654 | GOTO_NEXT_INST; | 5638 | GOTO_NEXT_INST; |
| @@ -5678,7 +5662,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5678 | RDHI = ((dest >> 32) & 0xFFFFFFFF); | 5662 | RDHI = ((dest >> 32) & 0xFFFFFFFF); |
| 5679 | } | 5663 | } |
| 5680 | 5664 | ||
| 5681 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5665 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 5682 | INC_PC(sizeof(smlalxy_inst)); | 5666 | INC_PC(sizeof(smlalxy_inst)); |
| 5683 | FETCH_INST; | 5667 | FETCH_INST; |
| 5684 | GOTO_NEXT_INST; | 5668 | GOTO_NEXT_INST; |
| @@ -5703,7 +5687,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5703 | cpu->Cpsr |= (1 << 27); | 5687 | cpu->Cpsr |= (1 << 27); |
| 5704 | } | 5688 | } |
| 5705 | 5689 | ||
| 5706 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5690 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 5707 | INC_PC(sizeof(smlad_inst)); | 5691 | INC_PC(sizeof(smlad_inst)); |
| 5708 | FETCH_INST; | 5692 | FETCH_INST; |
| 5709 | GOTO_NEXT_INST; | 5693 | GOTO_NEXT_INST; |
| @@ -5741,7 +5725,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5741 | RDHI = ((result >> 32) & 0xFFFFFFFF); | 5725 | RDHI = ((result >> 32) & 0xFFFFFFFF); |
| 5742 | } | 5726 | } |
| 5743 | 5727 | ||
| 5744 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5728 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 5745 | INC_PC(sizeof(smlald_inst)); | 5729 | INC_PC(sizeof(smlald_inst)); |
| 5746 | FETCH_INST; | 5730 | FETCH_INST; |
| 5747 | GOTO_NEXT_INST; | 5731 | GOTO_NEXT_INST; |
| @@ -5777,7 +5761,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5777 | RD = ((result >> 32) & 0xFFFFFFFF); | 5761 | RD = ((result >> 32) & 0xFFFFFFFF); |
| 5778 | } | 5762 | } |
| 5779 | 5763 | ||
| 5780 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5764 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 5781 | INC_PC(sizeof(smlad_inst)); | 5765 | INC_PC(sizeof(smlad_inst)); |
| 5782 | FETCH_INST; | 5766 | FETCH_INST; |
| 5783 | GOTO_NEXT_INST; | 5767 | GOTO_NEXT_INST; |
| @@ -5799,7 +5783,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5799 | operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31); | 5783 | operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31); |
| 5800 | RD = operand1 * operand2; | 5784 | RD = operand1 * operand2; |
| 5801 | } | 5785 | } |
| 5802 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5786 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 5803 | INC_PC(sizeof(smul_inst)); | 5787 | INC_PC(sizeof(smul_inst)); |
| 5804 | FETCH_INST; | 5788 | FETCH_INST; |
| 5805 | GOTO_NEXT_INST; | 5789 | GOTO_NEXT_INST; |
| @@ -5825,7 +5809,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5825 | cpu->ZFlag = (RDHI == 0 && RDLO == 0); | 5809 | cpu->ZFlag = (RDHI == 0 && RDLO == 0); |
| 5826 | } | 5810 | } |
| 5827 | } | 5811 | } |
| 5828 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5812 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 5829 | INC_PC(sizeof(umull_inst)); | 5813 | INC_PC(sizeof(umull_inst)); |
| 5830 | FETCH_INST; | 5814 | FETCH_INST; |
| 5831 | GOTO_NEXT_INST; | 5815 | GOTO_NEXT_INST; |
| @@ -5841,7 +5825,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5841 | s64 result = (s64)rm * (s64)(s32)RN; | 5825 | s64 result = (s64)rm * (s64)(s32)RN; |
| 5842 | RD = BITS(result, 16, 47); | 5826 | RD = BITS(result, 16, 47); |
| 5843 | } | 5827 | } |
| 5844 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5828 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 5845 | INC_PC(sizeof(smlad_inst)); | 5829 | INC_PC(sizeof(smlad_inst)); |
| 5846 | FETCH_INST; | 5830 | FETCH_INST; |
| 5847 | GOTO_NEXT_INST; | 5831 | GOTO_NEXT_INST; |
| @@ -5855,10 +5839,10 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5855 | u32 address = 0; | 5839 | u32 address = 0; |
| 5856 | inst_cream->get_addr(cpu, inst_cream->inst, address); | 5840 | inst_cream->get_addr(cpu, inst_cream->inst, address); |
| 5857 | 5841 | ||
| 5858 | WriteMemory32(cpu, address + 0, cpu->Reg[14]); | 5842 | cpu->WriteMemory32(address + 0, cpu->Reg[14]); |
| 5859 | WriteMemory32(cpu, address + 4, cpu->Spsr_copy); | 5843 | cpu->WriteMemory32(address + 4, cpu->Spsr_copy); |
| 5860 | 5844 | ||
| 5861 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5845 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 5862 | INC_PC(sizeof(ldst_inst)); | 5846 | INC_PC(sizeof(ldst_inst)); |
| 5863 | FETCH_INST; | 5847 | FETCH_INST; |
| 5864 | GOTO_NEXT_INST; | 5848 | GOTO_NEXT_INST; |
| @@ -5891,7 +5875,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5891 | RD = rn_val; | 5875 | RD = rn_val; |
| 5892 | } | 5876 | } |
| 5893 | 5877 | ||
| 5894 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5878 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 5895 | INC_PC(sizeof(ssat_inst)); | 5879 | INC_PC(sizeof(ssat_inst)); |
| 5896 | FETCH_INST; | 5880 | FETCH_INST; |
| 5897 | GOTO_NEXT_INST; | 5881 | GOTO_NEXT_INST; |
| @@ -5913,7 +5897,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5913 | cpu->Cpsr |= (1 << 27); | 5897 | cpu->Cpsr |= (1 << 27); |
| 5914 | } | 5898 | } |
| 5915 | 5899 | ||
| 5916 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5900 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 5917 | INC_PC(sizeof(ssat_inst)); | 5901 | INC_PC(sizeof(ssat_inst)); |
| 5918 | FETCH_INST; | 5902 | FETCH_INST; |
| 5919 | GOTO_NEXT_INST; | 5903 | GOTO_NEXT_INST; |
| @@ -5923,7 +5907,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5923 | { | 5907 | { |
| 5924 | // Instruction not implemented | 5908 | // Instruction not implemented |
| 5925 | //LOG_CRITICAL(Core_ARM11, "unimplemented instruction"); | 5909 | //LOG_CRITICAL(Core_ARM11, "unimplemented instruction"); |
| 5926 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5910 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 5927 | INC_PC(sizeof(stc_inst)); | 5911 | INC_PC(sizeof(stc_inst)); |
| 5928 | FETCH_INST; | 5912 | FETCH_INST; |
| 5929 | GOTO_NEXT_INST; | 5913 | GOTO_NEXT_INST; |
| @@ -5941,36 +5925,36 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5941 | if (BIT(inst_cream->inst, 22) == 1) { | 5925 | if (BIT(inst_cream->inst, 22) == 1) { |
| 5942 | for (int i = 0; i < 13; i++) { | 5926 | for (int i = 0; i < 13; i++) { |
| 5943 | if (BIT(inst_cream->inst, i)) { | 5927 | if (BIT(inst_cream->inst, i)) { |
| 5944 | WriteMemory32(cpu, addr, cpu->Reg[i]); | 5928 | cpu->WriteMemory32(addr, cpu->Reg[i]); |
| 5945 | addr += 4; | 5929 | addr += 4; |
| 5946 | } | 5930 | } |
| 5947 | } | 5931 | } |
| 5948 | if (BIT(inst_cream->inst, 13)) { | 5932 | if (BIT(inst_cream->inst, 13)) { |
| 5949 | if (cpu->Mode == USER32MODE) | 5933 | if (cpu->Mode == USER32MODE) |
| 5950 | WriteMemory32(cpu, addr, cpu->Reg[13]); | 5934 | cpu->WriteMemory32(addr, cpu->Reg[13]); |
| 5951 | else | 5935 | else |
| 5952 | WriteMemory32(cpu, addr, cpu->Reg_usr[0]); | 5936 | cpu->WriteMemory32(addr, cpu->Reg_usr[0]); |
| 5953 | 5937 | ||
| 5954 | addr += 4; | 5938 | addr += 4; |
| 5955 | } | 5939 | } |
| 5956 | if (BIT(inst_cream->inst, 14)) { | 5940 | if (BIT(inst_cream->inst, 14)) { |
| 5957 | if (cpu->Mode == USER32MODE) | 5941 | if (cpu->Mode == USER32MODE) |
| 5958 | WriteMemory32(cpu, addr, cpu->Reg[14]); | 5942 | cpu->WriteMemory32(addr, cpu->Reg[14]); |
| 5959 | else | 5943 | else |
| 5960 | WriteMemory32(cpu, addr, cpu->Reg_usr[1]); | 5944 | cpu->WriteMemory32(addr, cpu->Reg_usr[1]); |
| 5961 | 5945 | ||
| 5962 | addr += 4; | 5946 | addr += 4; |
| 5963 | } | 5947 | } |
| 5964 | if (BIT(inst_cream->inst, 15)) { | 5948 | if (BIT(inst_cream->inst, 15)) { |
| 5965 | WriteMemory32(cpu, addr, cpu->Reg_usr[1] + 8); | 5949 | cpu->WriteMemory32(addr, cpu->Reg_usr[1] + 8); |
| 5966 | } | 5950 | } |
| 5967 | } else { | 5951 | } else { |
| 5968 | for (int i = 0; i < 15; i++) { | 5952 | for (int i = 0; i < 15; i++) { |
| 5969 | if (BIT(inst_cream->inst, i)) { | 5953 | if (BIT(inst_cream->inst, i)) { |
| 5970 | if (i == Rn) | 5954 | if (i == Rn) |
| 5971 | WriteMemory32(cpu, addr, old_RN); | 5955 | cpu->WriteMemory32(addr, old_RN); |
| 5972 | else | 5956 | else |
| 5973 | WriteMemory32(cpu, addr, cpu->Reg[i]); | 5957 | cpu->WriteMemory32(addr, cpu->Reg[i]); |
| 5974 | 5958 | ||
| 5975 | addr += 4; | 5959 | addr += 4; |
| 5976 | } | 5960 | } |
| @@ -5978,10 +5962,10 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5978 | 5962 | ||
| 5979 | // Check PC reg | 5963 | // Check PC reg |
| 5980 | if (BIT(inst_cream->inst, 15)) | 5964 | if (BIT(inst_cream->inst, 15)) |
| 5981 | WriteMemory32(cpu, addr, cpu->Reg_usr[1] + 8); | 5965 | cpu->WriteMemory32(addr, cpu->Reg_usr[1] + 8); |
| 5982 | } | 5966 | } |
| 5983 | } | 5967 | } |
| 5984 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5968 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 5985 | INC_PC(sizeof(ldst_inst)); | 5969 | INC_PC(sizeof(ldst_inst)); |
| 5986 | FETCH_INST; | 5970 | FETCH_INST; |
| 5987 | GOTO_NEXT_INST; | 5971 | GOTO_NEXT_INST; |
| @@ -5999,7 +5983,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 5999 | } | 5983 | } |
| 6000 | RD = operand2; | 5984 | RD = operand2; |
| 6001 | } | 5985 | } |
| 6002 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5986 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 6003 | INC_PC(sizeof(sxtb_inst)); | 5987 | INC_PC(sizeof(sxtb_inst)); |
| 6004 | FETCH_INST; | 5988 | FETCH_INST; |
| 6005 | GOTO_NEXT_INST; | 5989 | GOTO_NEXT_INST; |
| @@ -6011,9 +5995,9 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6011 | inst_cream->get_addr(cpu, inst_cream->inst, addr); | 5995 | inst_cream->get_addr(cpu, inst_cream->inst, addr); |
| 6012 | 5996 | ||
| 6013 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; | 5997 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; |
| 6014 | WriteMemory32(cpu, addr, value); | 5998 | cpu->WriteMemory32(addr, value); |
| 6015 | } | 5999 | } |
| 6016 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6000 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 6017 | INC_PC(sizeof(ldst_inst)); | 6001 | INC_PC(sizeof(ldst_inst)); |
| 6018 | FETCH_INST; | 6002 | FETCH_INST; |
| 6019 | GOTO_NEXT_INST; | 6003 | GOTO_NEXT_INST; |
| @@ -6024,7 +6008,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6024 | uxtb_inst* inst_cream = (uxtb_inst*)inst_base->component; | 6008 | uxtb_inst* inst_cream = (uxtb_inst*)inst_base->component; |
| 6025 | RD = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff; | 6009 | RD = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff; |
| 6026 | } | 6010 | } |
| 6027 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6011 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 6028 | INC_PC(sizeof(uxtb_inst)); | 6012 | INC_PC(sizeof(uxtb_inst)); |
| 6029 | FETCH_INST; | 6013 | FETCH_INST; |
| 6030 | GOTO_NEXT_INST; | 6014 | GOTO_NEXT_INST; |
| @@ -6037,7 +6021,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6037 | unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff; | 6021 | unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff; |
| 6038 | RD = RN + operand2; | 6022 | RD = RN + operand2; |
| 6039 | } | 6023 | } |
| 6040 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6024 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 6041 | INC_PC(sizeof(uxtab_inst)); | 6025 | INC_PC(sizeof(uxtab_inst)); |
| 6042 | FETCH_INST; | 6026 | FETCH_INST; |
| 6043 | GOTO_NEXT_INST; | 6027 | GOTO_NEXT_INST; |
| @@ -6050,7 +6034,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6050 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff; | 6034 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff; |
| 6051 | Memory::Write8(addr, value); | 6035 | Memory::Write8(addr, value); |
| 6052 | } | 6036 | } |
| 6053 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6037 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 6054 | INC_PC(sizeof(ldst_inst)); | 6038 | INC_PC(sizeof(ldst_inst)); |
| 6055 | FETCH_INST; | 6039 | FETCH_INST; |
| 6056 | GOTO_NEXT_INST; | 6040 | GOTO_NEXT_INST; |
| @@ -6063,7 +6047,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6063 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff; | 6047 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff; |
| 6064 | Memory::Write8(addr, value); | 6048 | Memory::Write8(addr, value); |
| 6065 | } | 6049 | } |
| 6066 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6050 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 6067 | INC_PC(sizeof(ldst_inst)); | 6051 | INC_PC(sizeof(ldst_inst)); |
| 6068 | FETCH_INST; | 6052 | FETCH_INST; |
| 6069 | GOTO_NEXT_INST; | 6053 | GOTO_NEXT_INST; |
| @@ -6076,10 +6060,10 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6076 | 6060 | ||
| 6077 | // The 3DS doesn't have the Large Physical Access Extension (LPAE) | 6061 | // The 3DS doesn't have the Large Physical Access Extension (LPAE) |
| 6078 | // so STRD wouldn't store these as a single write. | 6062 | // so STRD wouldn't store these as a single write. |
| 6079 | WriteMemory32(cpu, addr + 0, cpu->Reg[BITS(inst_cream->inst, 12, 15)]); | 6063 | cpu->WriteMemory32(addr + 0, cpu->Reg[BITS(inst_cream->inst, 12, 15)]); |
| 6080 | WriteMemory32(cpu, addr + 4, cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1]); | 6064 | cpu->WriteMemory32(addr + 4, cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1]); |
| 6081 | } | 6065 | } |
| 6082 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6066 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 6083 | INC_PC(sizeof(ldst_inst)); | 6067 | INC_PC(sizeof(ldst_inst)); |
| 6084 | FETCH_INST; | 6068 | FETCH_INST; |
| 6085 | GOTO_NEXT_INST; | 6069 | GOTO_NEXT_INST; |
| @@ -6090,18 +6074,16 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6090 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; | 6074 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; |
| 6091 | unsigned int write_addr = cpu->Reg[inst_cream->Rn]; | 6075 | unsigned int write_addr = cpu->Reg[inst_cream->Rn]; |
| 6092 | 6076 | ||
| 6093 | if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) { | 6077 | if (cpu->IsExclusiveMemoryAccess(write_addr)) { |
| 6094 | remove_exclusive(cpu, write_addr); | 6078 | cpu->UnsetExclusiveMemoryAddress(); |
| 6095 | cpu->exclusive_state = 0; | 6079 | cpu->WriteMemory32(write_addr, RM); |
| 6096 | |||
| 6097 | WriteMemory32(cpu, write_addr, RM); | ||
| 6098 | RD = 0; | 6080 | RD = 0; |
| 6099 | } else { | 6081 | } else { |
| 6100 | // Failed to write due to mutex access | 6082 | // Failed to write due to mutex access |
| 6101 | RD = 1; | 6083 | RD = 1; |
| 6102 | } | 6084 | } |
| 6103 | } | 6085 | } |
| 6104 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6086 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 6105 | INC_PC(sizeof(generic_arm_inst)); | 6087 | INC_PC(sizeof(generic_arm_inst)); |
| 6106 | FETCH_INST; | 6088 | FETCH_INST; |
| 6107 | GOTO_NEXT_INST; | 6089 | GOTO_NEXT_INST; |
| @@ -6112,10 +6094,8 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6112 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; | 6094 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; |
| 6113 | unsigned int write_addr = cpu->Reg[inst_cream->Rn]; | 6095 | unsigned int write_addr = cpu->Reg[inst_cream->Rn]; |
| 6114 | 6096 | ||
| 6115 | if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) { | 6097 | if (cpu->IsExclusiveMemoryAccess(write_addr)) { |
| 6116 | remove_exclusive(cpu, write_addr); | 6098 | cpu->UnsetExclusiveMemoryAddress(); |
| 6117 | cpu->exclusive_state = 0; | ||
| 6118 | |||
| 6119 | Memory::Write8(write_addr, cpu->Reg[inst_cream->Rm]); | 6099 | Memory::Write8(write_addr, cpu->Reg[inst_cream->Rm]); |
| 6120 | RD = 0; | 6100 | RD = 0; |
| 6121 | } else { | 6101 | } else { |
| @@ -6123,7 +6103,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6123 | RD = 1; | 6103 | RD = 1; |
| 6124 | } | 6104 | } |
| 6125 | } | 6105 | } |
| 6126 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6106 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 6127 | INC_PC(sizeof(generic_arm_inst)); | 6107 | INC_PC(sizeof(generic_arm_inst)); |
| 6128 | FETCH_INST; | 6108 | FETCH_INST; |
| 6129 | GOTO_NEXT_INST; | 6109 | GOTO_NEXT_INST; |
| @@ -6134,20 +6114,19 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6134 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; | 6114 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; |
| 6135 | unsigned int write_addr = cpu->Reg[inst_cream->Rn]; | 6115 | unsigned int write_addr = cpu->Reg[inst_cream->Rn]; |
| 6136 | 6116 | ||
| 6137 | if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) { | 6117 | if (cpu->IsExclusiveMemoryAccess(write_addr)) { |
| 6138 | remove_exclusive(cpu, write_addr); | 6118 | cpu->UnsetExclusiveMemoryAddress(); |
| 6139 | cpu->exclusive_state = 0; | ||
| 6140 | 6119 | ||
| 6141 | const u32 rt = cpu->Reg[inst_cream->Rm + 0]; | 6120 | const u32 rt = cpu->Reg[inst_cream->Rm + 0]; |
| 6142 | const u32 rt2 = cpu->Reg[inst_cream->Rm + 1]; | 6121 | const u32 rt2 = cpu->Reg[inst_cream->Rm + 1]; |
| 6143 | u64 value; | 6122 | u64 value; |
| 6144 | 6123 | ||
| 6145 | if (InBigEndianMode(cpu)) | 6124 | if (cpu->InBigEndianMode()) |
| 6146 | value = (((u64)rt << 32) | rt2); | 6125 | value = (((u64)rt << 32) | rt2); |
| 6147 | else | 6126 | else |
| 6148 | value = (((u64)rt2 << 32) | rt); | 6127 | value = (((u64)rt2 << 32) | rt); |
| 6149 | 6128 | ||
| 6150 | WriteMemory64(cpu, write_addr, value); | 6129 | cpu->WriteMemory64(write_addr, value); |
| 6151 | RD = 0; | 6130 | RD = 0; |
| 6152 | } | 6131 | } |
| 6153 | else { | 6132 | else { |
| @@ -6155,7 +6134,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6155 | RD = 1; | 6134 | RD = 1; |
| 6156 | } | 6135 | } |
| 6157 | } | 6136 | } |
| 6158 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6137 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 6159 | INC_PC(sizeof(generic_arm_inst)); | 6138 | INC_PC(sizeof(generic_arm_inst)); |
| 6160 | FETCH_INST; | 6139 | FETCH_INST; |
| 6161 | GOTO_NEXT_INST; | 6140 | GOTO_NEXT_INST; |
| @@ -6166,18 +6145,16 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6166 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; | 6145 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; |
| 6167 | unsigned int write_addr = cpu->Reg[inst_cream->Rn]; | 6146 | unsigned int write_addr = cpu->Reg[inst_cream->Rn]; |
| 6168 | 6147 | ||
| 6169 | if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) { | 6148 | if (cpu->IsExclusiveMemoryAccess(write_addr)) { |
| 6170 | remove_exclusive(cpu, write_addr); | 6149 | cpu->UnsetExclusiveMemoryAddress(); |
| 6171 | cpu->exclusive_state = 0; | 6150 | cpu->WriteMemory16(write_addr, RM); |
| 6172 | |||
| 6173 | WriteMemory16(cpu, write_addr, RM); | ||
| 6174 | RD = 0; | 6151 | RD = 0; |
| 6175 | } else { | 6152 | } else { |
| 6176 | // Failed to write due to mutex access | 6153 | // Failed to write due to mutex access |
| 6177 | RD = 1; | 6154 | RD = 1; |
| 6178 | } | 6155 | } |
| 6179 | } | 6156 | } |
| 6180 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6157 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 6181 | INC_PC(sizeof(generic_arm_inst)); | 6158 | INC_PC(sizeof(generic_arm_inst)); |
| 6182 | FETCH_INST; | 6159 | FETCH_INST; |
| 6183 | GOTO_NEXT_INST; | 6160 | GOTO_NEXT_INST; |
| @@ -6189,9 +6166,9 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6189 | inst_cream->get_addr(cpu, inst_cream->inst, addr); | 6166 | inst_cream->get_addr(cpu, inst_cream->inst, addr); |
| 6190 | 6167 | ||
| 6191 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xffff; | 6168 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xffff; |
| 6192 | WriteMemory16(cpu, addr, value); | 6169 | cpu->WriteMemory16(addr, value); |
| 6193 | } | 6170 | } |
| 6194 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6171 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 6195 | INC_PC(sizeof(ldst_inst)); | 6172 | INC_PC(sizeof(ldst_inst)); |
| 6196 | FETCH_INST; | 6173 | FETCH_INST; |
| 6197 | GOTO_NEXT_INST; | 6174 | GOTO_NEXT_INST; |
| @@ -6203,9 +6180,9 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6203 | inst_cream->get_addr(cpu, inst_cream->inst, addr); | 6180 | inst_cream->get_addr(cpu, inst_cream->inst, addr); |
| 6204 | 6181 | ||
| 6205 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; | 6182 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)]; |
| 6206 | WriteMemory32(cpu, addr, value); | 6183 | cpu->WriteMemory32(addr, value); |
| 6207 | } | 6184 | } |
| 6208 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6185 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 6209 | INC_PC(sizeof(ldst_inst)); | 6186 | INC_PC(sizeof(ldst_inst)); |
| 6210 | FETCH_INST; | 6187 | FETCH_INST; |
| 6211 | GOTO_NEXT_INST; | 6188 | GOTO_NEXT_INST; |
| @@ -6217,7 +6194,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6217 | 6194 | ||
| 6218 | u32 rn_val = RN; | 6195 | u32 rn_val = RN; |
| 6219 | if (inst_cream->Rn == 15) | 6196 | if (inst_cream->Rn == 15) |
| 6220 | rn_val += 8; | 6197 | rn_val += 2 * cpu->GetInstructionSize(); |
| 6221 | 6198 | ||
| 6222 | bool carry; | 6199 | bool carry; |
| 6223 | bool overflow; | 6200 | bool overflow; |
| @@ -6226,7 +6203,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6226 | if (inst_cream->S && (inst_cream->Rd == 15)) { | 6203 | if (inst_cream->S && (inst_cream->Rd == 15)) { |
| 6227 | if (CurrentModeHasSPSR) { | 6204 | if (CurrentModeHasSPSR) { |
| 6228 | cpu->Cpsr = cpu->Spsr_copy; | 6205 | cpu->Cpsr = cpu->Spsr_copy; |
| 6229 | switch_mode(cpu, cpu->Spsr_copy & 0x1f); | 6206 | cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F); |
| 6230 | LOAD_NZCVT; | 6207 | LOAD_NZCVT; |
| 6231 | } | 6208 | } |
| 6232 | } else if (inst_cream->S) { | 6209 | } else if (inst_cream->S) { |
| @@ -6240,7 +6217,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6240 | goto DISPATCH; | 6217 | goto DISPATCH; |
| 6241 | } | 6218 | } |
| 6242 | } | 6219 | } |
| 6243 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6220 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 6244 | INC_PC(sizeof(sub_inst)); | 6221 | INC_PC(sizeof(sub_inst)); |
| 6245 | FETCH_INST; | 6222 | FETCH_INST; |
| 6246 | GOTO_NEXT_INST; | 6223 | GOTO_NEXT_INST; |
| @@ -6252,7 +6229,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6252 | SVC::CallSVC(inst_cream->num & 0xFFFF); | 6229 | SVC::CallSVC(inst_cream->num & 0xFFFF); |
| 6253 | } | 6230 | } |
| 6254 | 6231 | ||
| 6255 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6232 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 6256 | INC_PC(sizeof(swi_inst)); | 6233 | INC_PC(sizeof(swi_inst)); |
| 6257 | FETCH_INST; | 6234 | FETCH_INST; |
| 6258 | GOTO_NEXT_INST; | 6235 | GOTO_NEXT_INST; |
| @@ -6263,12 +6240,12 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6263 | swp_inst* inst_cream = (swp_inst*)inst_base->component; | 6240 | swp_inst* inst_cream = (swp_inst*)inst_base->component; |
| 6264 | 6241 | ||
| 6265 | addr = RN; | 6242 | addr = RN; |
| 6266 | unsigned int value = ReadMemory32(cpu, addr); | 6243 | unsigned int value = cpu->ReadMemory32(addr); |
| 6267 | WriteMemory32(cpu, addr, RM); | 6244 | cpu->WriteMemory32(addr, RM); |
| 6268 | 6245 | ||
| 6269 | RD = value; | 6246 | RD = value; |
| 6270 | } | 6247 | } |
| 6271 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6248 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 6272 | INC_PC(sizeof(swp_inst)); | 6249 | INC_PC(sizeof(swp_inst)); |
| 6273 | FETCH_INST; | 6250 | FETCH_INST; |
| 6274 | GOTO_NEXT_INST; | 6251 | GOTO_NEXT_INST; |
| @@ -6282,7 +6259,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6282 | Memory::Write8(addr, (RM & 0xFF)); | 6259 | Memory::Write8(addr, (RM & 0xFF)); |
| 6283 | RD = value; | 6260 | RD = value; |
| 6284 | } | 6261 | } |
| 6285 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6262 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 6286 | INC_PC(sizeof(swp_inst)); | 6263 | INC_PC(sizeof(swp_inst)); |
| 6287 | FETCH_INST; | 6264 | FETCH_INST; |
| 6288 | GOTO_NEXT_INST; | 6265 | GOTO_NEXT_INST; |
| @@ -6298,7 +6275,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6298 | operand2 = (0x80 & operand2)? (0xFFFFFF00 | operand2):operand2; | 6275 | operand2 = (0x80 & operand2)? (0xFFFFFF00 | operand2):operand2; |
| 6299 | RD = RN + operand2; | 6276 | RD = RN + operand2; |
| 6300 | } | 6277 | } |
| 6301 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6278 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 6302 | INC_PC(sizeof(uxtab_inst)); | 6279 | INC_PC(sizeof(uxtab_inst)); |
| 6303 | FETCH_INST; | 6280 | FETCH_INST; |
| 6304 | GOTO_NEXT_INST; | 6281 | GOTO_NEXT_INST; |
| @@ -6331,7 +6308,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6331 | } | 6308 | } |
| 6332 | } | 6309 | } |
| 6333 | 6310 | ||
| 6334 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6311 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 6335 | INC_PC(sizeof(sxtab_inst)); | 6312 | INC_PC(sizeof(sxtab_inst)); |
| 6336 | FETCH_INST; | 6313 | FETCH_INST; |
| 6337 | GOTO_NEXT_INST; | 6314 | GOTO_NEXT_INST; |
| @@ -6347,7 +6324,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6347 | operand2 = (0x8000 & operand2) ? (0xFFFF0000 | operand2) : operand2; | 6324 | operand2 = (0x8000 & operand2) ? (0xFFFF0000 | operand2) : operand2; |
| 6348 | RD = RN + operand2; | 6325 | RD = RN + operand2; |
| 6349 | } | 6326 | } |
| 6350 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6327 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 6351 | INC_PC(sizeof(sxtah_inst)); | 6328 | INC_PC(sizeof(sxtah_inst)); |
| 6352 | FETCH_INST; | 6329 | FETCH_INST; |
| 6353 | GOTO_NEXT_INST; | 6330 | GOTO_NEXT_INST; |
| @@ -6362,7 +6339,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6362 | u32 rop = SHIFTER_OPERAND; | 6339 | u32 rop = SHIFTER_OPERAND; |
| 6363 | 6340 | ||
| 6364 | if (inst_cream->Rn == 15) | 6341 | if (inst_cream->Rn == 15) |
| 6365 | lop += GET_INST_SIZE(cpu) * 2; | 6342 | lop += cpu->GetInstructionSize() * 2; |
| 6366 | 6343 | ||
| 6367 | u32 result = lop ^ rop; | 6344 | u32 result = lop ^ rop; |
| 6368 | 6345 | ||
| @@ -6370,7 +6347,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6370 | UPDATE_ZFLAG(result); | 6347 | UPDATE_ZFLAG(result); |
| 6371 | UPDATE_CFLAG_WITH_SC; | 6348 | UPDATE_CFLAG_WITH_SC; |
| 6372 | } | 6349 | } |
| 6373 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6350 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 6374 | INC_PC(sizeof(teq_inst)); | 6351 | INC_PC(sizeof(teq_inst)); |
| 6375 | FETCH_INST; | 6352 | FETCH_INST; |
| 6376 | GOTO_NEXT_INST; | 6353 | GOTO_NEXT_INST; |
| @@ -6384,7 +6361,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6384 | u32 rop = SHIFTER_OPERAND; | 6361 | u32 rop = SHIFTER_OPERAND; |
| 6385 | 6362 | ||
| 6386 | if (inst_cream->Rn == 15) | 6363 | if (inst_cream->Rn == 15) |
| 6387 | lop += GET_INST_SIZE(cpu) * 2; | 6364 | lop += cpu->GetInstructionSize() * 2; |
| 6388 | 6365 | ||
| 6389 | u32 result = lop & rop; | 6366 | u32 result = lop & rop; |
| 6390 | 6367 | ||
| @@ -6392,7 +6369,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6392 | UPDATE_ZFLAG(result); | 6369 | UPDATE_ZFLAG(result); |
| 6393 | UPDATE_CFLAG_WITH_SC; | 6370 | UPDATE_CFLAG_WITH_SC; |
| 6394 | } | 6371 | } |
| 6395 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6372 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 6396 | INC_PC(sizeof(tst_inst)); | 6373 | INC_PC(sizeof(tst_inst)); |
| 6397 | FETCH_INST; | 6374 | FETCH_INST; |
| 6398 | GOTO_NEXT_INST; | 6375 | GOTO_NEXT_INST; |
| @@ -6563,7 +6540,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6563 | RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16); | 6540 | RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16); |
| 6564 | } | 6541 | } |
| 6565 | 6542 | ||
| 6566 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6543 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 6567 | INC_PC(sizeof(generic_arm_inst)); | 6544 | INC_PC(sizeof(generic_arm_inst)); |
| 6568 | FETCH_INST; | 6545 | FETCH_INST; |
| 6569 | GOTO_NEXT_INST; | 6546 | GOTO_NEXT_INST; |
| @@ -6643,7 +6620,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6643 | } | 6620 | } |
| 6644 | } | 6621 | } |
| 6645 | 6622 | ||
| 6646 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6623 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 6647 | INC_PC(sizeof(generic_arm_inst)); | 6624 | INC_PC(sizeof(generic_arm_inst)); |
| 6648 | FETCH_INST; | 6625 | FETCH_INST; |
| 6649 | GOTO_NEXT_INST; | 6626 | GOTO_NEXT_INST; |
| @@ -6662,7 +6639,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6662 | RDLO = (result & 0xFFFFFFFF); | 6639 | RDLO = (result & 0xFFFFFFFF); |
| 6663 | RDHI = ((result >> 32) & 0xFFFFFFFF); | 6640 | RDHI = ((result >> 32) & 0xFFFFFFFF); |
| 6664 | } | 6641 | } |
| 6665 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6642 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 6666 | INC_PC(sizeof(umaal_inst)); | 6643 | INC_PC(sizeof(umaal_inst)); |
| 6667 | FETCH_INST; | 6644 | FETCH_INST; |
| 6668 | GOTO_NEXT_INST; | 6645 | GOTO_NEXT_INST; |
| @@ -6685,7 +6662,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6685 | cpu->ZFlag = (RDHI == 0 && RDLO == 0); | 6662 | cpu->ZFlag = (RDHI == 0 && RDLO == 0); |
| 6686 | } | 6663 | } |
| 6687 | } | 6664 | } |
| 6688 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6665 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 6689 | INC_PC(sizeof(umlal_inst)); | 6666 | INC_PC(sizeof(umlal_inst)); |
| 6690 | FETCH_INST; | 6667 | FETCH_INST; |
| 6691 | GOTO_NEXT_INST; | 6668 | GOTO_NEXT_INST; |
| @@ -6705,7 +6682,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6705 | cpu->ZFlag = (RDHI == 0 && RDLO == 0); | 6682 | cpu->ZFlag = (RDHI == 0 && RDLO == 0); |
| 6706 | } | 6683 | } |
| 6707 | } | 6684 | } |
| 6708 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6685 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 6709 | INC_PC(sizeof(umull_inst)); | 6686 | INC_PC(sizeof(umull_inst)); |
| 6710 | FETCH_INST; | 6687 | FETCH_INST; |
| 6711 | GOTO_NEXT_INST; | 6688 | GOTO_NEXT_INST; |
| @@ -6733,7 +6710,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6733 | { | 6710 | { |
| 6734 | bl_1_thumb* inst_cream = (bl_1_thumb*)inst_base->component; | 6711 | bl_1_thumb* inst_cream = (bl_1_thumb*)inst_base->component; |
| 6735 | cpu->Reg[14] = cpu->Reg[15] + 4 + inst_cream->imm; | 6712 | cpu->Reg[14] = cpu->Reg[15] + 4 + inst_cream->imm; |
| 6736 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6713 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 6737 | INC_PC(sizeof(bl_1_thumb)); | 6714 | INC_PC(sizeof(bl_1_thumb)); |
| 6738 | FETCH_INST; | 6715 | FETCH_INST; |
| 6739 | GOTO_NEXT_INST; | 6716 | GOTO_NEXT_INST; |
| @@ -6814,7 +6791,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6814 | RD = ((lo_val & 0xFFFF) | hi_val << 16); | 6791 | RD = ((lo_val & 0xFFFF) | hi_val << 16); |
| 6815 | } | 6792 | } |
| 6816 | 6793 | ||
| 6817 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6794 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 6818 | INC_PC(sizeof(generic_arm_inst)); | 6795 | INC_PC(sizeof(generic_arm_inst)); |
| 6819 | FETCH_INST; | 6796 | FETCH_INST; |
| 6820 | GOTO_NEXT_INST; | 6797 | GOTO_NEXT_INST; |
| @@ -6844,7 +6821,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6844 | RD = finalDif; | 6821 | RD = finalDif; |
| 6845 | } | 6822 | } |
| 6846 | 6823 | ||
| 6847 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6824 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 6848 | INC_PC(sizeof(generic_arm_inst)); | 6825 | INC_PC(sizeof(generic_arm_inst)); |
| 6849 | FETCH_INST; | 6826 | FETCH_INST; |
| 6850 | GOTO_NEXT_INST; | 6827 | GOTO_NEXT_INST; |
| @@ -6877,7 +6854,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6877 | RD = rn_val; | 6854 | RD = rn_val; |
| 6878 | } | 6855 | } |
| 6879 | 6856 | ||
| 6880 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6857 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 6881 | INC_PC(sizeof(ssat_inst)); | 6858 | INC_PC(sizeof(ssat_inst)); |
| 6882 | FETCH_INST; | 6859 | FETCH_INST; |
| 6883 | GOTO_NEXT_INST; | 6860 | GOTO_NEXT_INST; |
| @@ -6899,7 +6876,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6899 | cpu->Cpsr |= (1 << 27); | 6876 | cpu->Cpsr |= (1 << 27); |
| 6900 | } | 6877 | } |
| 6901 | 6878 | ||
| 6902 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6879 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 6903 | INC_PC(sizeof(ssat_inst)); | 6880 | INC_PC(sizeof(ssat_inst)); |
| 6904 | FETCH_INST; | 6881 | FETCH_INST; |
| 6905 | GOTO_NEXT_INST; | 6882 | GOTO_NEXT_INST; |
| @@ -6930,7 +6907,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6930 | } | 6907 | } |
| 6931 | } | 6908 | } |
| 6932 | 6909 | ||
| 6933 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6910 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 6934 | INC_PC(sizeof(uxtab_inst)); | 6911 | INC_PC(sizeof(uxtab_inst)); |
| 6935 | FETCH_INST; | 6912 | FETCH_INST; |
| 6936 | GOTO_NEXT_INST; | 6913 | GOTO_NEXT_INST; |
| @@ -6943,7 +6920,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6943 | LOG_TRACE(Core_ARM11, "WFE executed."); | 6920 | LOG_TRACE(Core_ARM11, "WFE executed."); |
| 6944 | } | 6921 | } |
| 6945 | 6922 | ||
| 6946 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6923 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 6947 | INC_PC_STUB; | 6924 | INC_PC_STUB; |
| 6948 | FETCH_INST; | 6925 | FETCH_INST; |
| 6949 | GOTO_NEXT_INST; | 6926 | GOTO_NEXT_INST; |
| @@ -6956,7 +6933,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6956 | LOG_TRACE(Core_ARM11, "WFI executed."); | 6933 | LOG_TRACE(Core_ARM11, "WFI executed."); |
| 6957 | } | 6934 | } |
| 6958 | 6935 | ||
| 6959 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6936 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 6960 | INC_PC_STUB; | 6937 | INC_PC_STUB; |
| 6961 | FETCH_INST; | 6938 | FETCH_INST; |
| 6962 | GOTO_NEXT_INST; | 6939 | GOTO_NEXT_INST; |
| @@ -6969,7 +6946,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { | |||
| 6969 | LOG_TRACE(Core_ARM11, "YIELD executed."); | 6946 | LOG_TRACE(Core_ARM11, "YIELD executed."); |
| 6970 | } | 6947 | } |
| 6971 | 6948 | ||
| 6972 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 6949 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 6973 | INC_PC_STUB; | 6950 | INC_PC_STUB; |
| 6974 | FETCH_INST; | 6951 | FETCH_INST; |
| 6975 | GOTO_NEXT_INST; | 6952 | GOTO_NEXT_INST; |
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.h b/src/core/arm/dyncom/arm_dyncom_interpreter.h index 1c324d29c..7a46dcc94 100644 --- a/src/core/arm/dyncom/arm_dyncom_interpreter.h +++ b/src/core/arm/dyncom/arm_dyncom_interpreter.h | |||
| @@ -4,6 +4,6 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include "core/arm/skyeye_common/armdefs.h" | 7 | struct ARMul_State; |
| 8 | 8 | ||
| 9 | unsigned InterpreterMainLoop(ARMul_State* state); | 9 | unsigned InterpreterMainLoop(ARMul_State* state); |
diff --git a/src/core/arm/dyncom/arm_dyncom_run.cpp b/src/core/arm/dyncom/arm_dyncom_run.cpp deleted file mode 100644 index 5a9a6a788..000000000 --- a/src/core/arm/dyncom/arm_dyncom_run.cpp +++ /dev/null | |||
| @@ -1,93 +0,0 @@ | |||
| 1 | // Copyright 2012 Michael Kang, 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "core/arm/dyncom/arm_dyncom_run.h" | ||
| 6 | #include "core/arm/skyeye_common/armdefs.h" | ||
| 7 | |||
| 8 | void switch_mode(ARMul_State* core, uint32_t mode) { | ||
| 9 | if (core->Mode == mode) | ||
| 10 | return; | ||
| 11 | |||
| 12 | if (mode != USERBANK) { | ||
| 13 | switch (core->Mode) { | ||
| 14 | case SYSTEM32MODE: // Shares registers with user mode | ||
| 15 | case USER32MODE: | ||
| 16 | core->Reg_usr[0] = core->Reg[13]; | ||
| 17 | core->Reg_usr[1] = core->Reg[14]; | ||
| 18 | break; | ||
| 19 | case IRQ32MODE: | ||
| 20 | core->Reg_irq[0] = core->Reg[13]; | ||
| 21 | core->Reg_irq[1] = core->Reg[14]; | ||
| 22 | core->Spsr[IRQBANK] = core->Spsr_copy; | ||
| 23 | break; | ||
| 24 | case SVC32MODE: | ||
| 25 | core->Reg_svc[0] = core->Reg[13]; | ||
| 26 | core->Reg_svc[1] = core->Reg[14]; | ||
| 27 | core->Spsr[SVCBANK] = core->Spsr_copy; | ||
| 28 | break; | ||
| 29 | case ABORT32MODE: | ||
| 30 | core->Reg_abort[0] = core->Reg[13]; | ||
| 31 | core->Reg_abort[1] = core->Reg[14]; | ||
| 32 | core->Spsr[ABORTBANK] = core->Spsr_copy; | ||
| 33 | break; | ||
| 34 | case UNDEF32MODE: | ||
| 35 | core->Reg_undef[0] = core->Reg[13]; | ||
| 36 | core->Reg_undef[1] = core->Reg[14]; | ||
| 37 | core->Spsr[UNDEFBANK] = core->Spsr_copy; | ||
| 38 | break; | ||
| 39 | case FIQ32MODE: | ||
| 40 | core->Reg_firq[0] = core->Reg[13]; | ||
| 41 | core->Reg_firq[1] = core->Reg[14]; | ||
| 42 | core->Spsr[FIQBANK] = core->Spsr_copy; | ||
| 43 | break; | ||
| 44 | } | ||
| 45 | |||
| 46 | switch (mode) { | ||
| 47 | case USER32MODE: | ||
| 48 | core->Reg[13] = core->Reg_usr[0]; | ||
| 49 | core->Reg[14] = core->Reg_usr[1]; | ||
| 50 | core->Bank = USERBANK; | ||
| 51 | break; | ||
| 52 | case IRQ32MODE: | ||
| 53 | core->Reg[13] = core->Reg_irq[0]; | ||
| 54 | core->Reg[14] = core->Reg_irq[1]; | ||
| 55 | core->Spsr_copy = core->Spsr[IRQBANK]; | ||
| 56 | core->Bank = IRQBANK; | ||
| 57 | break; | ||
| 58 | case SVC32MODE: | ||
| 59 | core->Reg[13] = core->Reg_svc[0]; | ||
| 60 | core->Reg[14] = core->Reg_svc[1]; | ||
| 61 | core->Spsr_copy = core->Spsr[SVCBANK]; | ||
| 62 | core->Bank = SVCBANK; | ||
| 63 | break; | ||
| 64 | case ABORT32MODE: | ||
| 65 | core->Reg[13] = core->Reg_abort[0]; | ||
| 66 | core->Reg[14] = core->Reg_abort[1]; | ||
| 67 | core->Spsr_copy = core->Spsr[ABORTBANK]; | ||
| 68 | core->Bank = ABORTBANK; | ||
| 69 | break; | ||
| 70 | case UNDEF32MODE: | ||
| 71 | core->Reg[13] = core->Reg_undef[0]; | ||
| 72 | core->Reg[14] = core->Reg_undef[1]; | ||
| 73 | core->Spsr_copy = core->Spsr[UNDEFBANK]; | ||
| 74 | core->Bank = UNDEFBANK; | ||
| 75 | break; | ||
| 76 | case FIQ32MODE: | ||
| 77 | core->Reg[13] = core->Reg_firq[0]; | ||
| 78 | core->Reg[14] = core->Reg_firq[1]; | ||
| 79 | core->Spsr_copy = core->Spsr[FIQBANK]; | ||
| 80 | core->Bank = FIQBANK; | ||
| 81 | break; | ||
| 82 | case SYSTEM32MODE: // Shares registers with user mode. | ||
| 83 | core->Reg[13] = core->Reg_usr[0]; | ||
| 84 | core->Reg[14] = core->Reg_usr[1]; | ||
| 85 | core->Bank = SYSTEMBANK; | ||
| 86 | break; | ||
| 87 | } | ||
| 88 | |||
| 89 | // Set the mode bits in the APSR | ||
| 90 | core->Cpsr = (core->Cpsr & ~core->Mode) | mode; | ||
| 91 | core->Mode = mode; | ||
| 92 | } | ||
| 93 | } | ||
diff --git a/src/core/arm/dyncom/arm_dyncom_run.h b/src/core/arm/dyncom/arm_dyncom_run.h index 85774c565..13bef17fc 100644 --- a/src/core/arm/dyncom/arm_dyncom_run.h +++ b/src/core/arm/dyncom/arm_dyncom_run.h | |||
| @@ -18,40 +18,31 @@ | |||
| 18 | 18 | ||
| 19 | #pragma once | 19 | #pragma once |
| 20 | 20 | ||
| 21 | #include "core/arm/skyeye_common/armdefs.h" | 21 | #include "core/arm/skyeye_common/armstate.h" |
| 22 | |||
| 23 | void switch_mode(ARMul_State* core, uint32_t mode); | ||
| 24 | |||
| 25 | // Note that for the 3DS, a Thumb instruction will only ever be | ||
| 26 | // two bytes in size. Thus we don't need to worry about ThumbEE | ||
| 27 | // or Thumb-2 where instructions can be 4 bytes in length. | ||
| 28 | static inline u32 GET_INST_SIZE(ARMul_State* core) { | ||
| 29 | return core->TFlag? 2 : 4; | ||
| 30 | } | ||
| 31 | 22 | ||
| 32 | /** | 23 | /** |
| 33 | * Checks if the PC is being read, and if so, word-aligns it. | 24 | * Checks if the PC is being read, and if so, word-aligns it. |
| 34 | * Used with address calculations. | 25 | * Used with address calculations. |
| 35 | * | 26 | * |
| 36 | * @param core The ARM CPU state instance. | 27 | * @param cpu The ARM CPU state instance. |
| 37 | * @param Rn The register being read. | 28 | * @param Rn The register being read. |
| 38 | * | 29 | * |
| 39 | * @return If the PC is being read, then the word-aligned PC value is returned. | 30 | * @return If the PC is being read, then the word-aligned PC value is returned. |
| 40 | * If the PC is not being read, then the value stored in the register is returned. | 31 | * If the PC is not being read, then the value stored in the register is returned. |
| 41 | */ | 32 | */ |
| 42 | static inline u32 CHECK_READ_REG15_WA(ARMul_State* core, int Rn) { | 33 | static inline u32 CHECK_READ_REG15_WA(ARMul_State* cpu, int Rn) { |
| 43 | return (Rn == 15) ? ((core->Reg[15] & ~0x3) + GET_INST_SIZE(core) * 2) : core->Reg[Rn]; | 34 | return (Rn == 15) ? ((cpu->Reg[15] & ~0x3) + cpu->GetInstructionSize() * 2) : cpu->Reg[Rn]; |
| 44 | } | 35 | } |
| 45 | 36 | ||
| 46 | /** | 37 | /** |
| 47 | * Reads the PC. Used for data processing operations that use the PC. | 38 | * Reads the PC. Used for data processing operations that use the PC. |
| 48 | * | 39 | * |
| 49 | * @param core The ARM CPU state instance. | 40 | * @param cpu The ARM CPU state instance. |
| 50 | * @param Rn The register being read. | 41 | * @param Rn The register being read. |
| 51 | * | 42 | * |
| 52 | * @return If the PC is being read, then the incremented PC value is returned. | 43 | * @return If the PC is being read, then the incremented PC value is returned. |
| 53 | * If the PC is not being read, then the values stored in the register is returned. | 44 | * If the PC is not being read, then the values stored in the register is returned. |
| 54 | */ | 45 | */ |
| 55 | static inline u32 CHECK_READ_REG15(ARMul_State* core, int Rn) { | 46 | static inline u32 CHECK_READ_REG15(ARMul_State* cpu, int Rn) { |
| 56 | return (Rn == 15) ? ((core->Reg[15] & ~0x1) + GET_INST_SIZE(core) * 2) : core->Reg[Rn]; | 47 | return (Rn == 15) ? ((cpu->Reg[15] & ~0x1) + cpu->GetInstructionSize() * 2) : cpu->Reg[Rn]; |
| 57 | } | 48 | } |
diff --git a/src/core/arm/dyncom/arm_dyncom_thumb.cpp b/src/core/arm/dyncom/arm_dyncom_thumb.cpp index f10a5b70f..29272fd5d 100644 --- a/src/core/arm/dyncom/arm_dyncom_thumb.cpp +++ b/src/core/arm/dyncom/arm_dyncom_thumb.cpp | |||
| @@ -6,20 +6,15 @@ | |||
| 6 | // ARM instruction, and using the existing ARM simulator. | 6 | // ARM instruction, and using the existing ARM simulator. |
| 7 | 7 | ||
| 8 | #include "core/arm/dyncom/arm_dyncom_thumb.h" | 8 | #include "core/arm/dyncom/arm_dyncom_thumb.h" |
| 9 | #include "core/arm/skyeye_common/armsupp.h" | ||
| 9 | 10 | ||
| 10 | // Decode a 16bit Thumb instruction. The instruction is in the low 16-bits of the tinstr field, | 11 | // Decode a 16bit Thumb instruction. The instruction is in the low 16-bits of the tinstr field, |
| 11 | // with the following Thumb instruction held in the high 16-bits. Passing in two Thumb instructions | 12 | // with the following Thumb instruction held in the high 16-bits. Passing in two Thumb instructions |
| 12 | // allows easier simulation of the special dual BL instruction. | 13 | // allows easier simulation of the special dual BL instruction. |
| 13 | 14 | ||
| 14 | tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) { | 15 | ThumbDecodeStatus TranslateThumbInstruction(u32 addr, u32 instr, u32* ainstr, u32* inst_size) { |
| 15 | tdstate valid = t_uninitialized; | 16 | ThumbDecodeStatus valid = ThumbDecodeStatus::UNINITIALIZED; |
| 16 | ARMword tinstr = instr; | 17 | u32 tinstr = GetThumbInstruction(instr, addr); |
| 17 | |||
| 18 | // The endian should be judge here | ||
| 19 | if((addr & 0x3) != 0) | ||
| 20 | tinstr = instr >> 16; | ||
| 21 | else | ||
| 22 | tinstr &= 0xFFFF; | ||
| 23 | 18 | ||
| 24 | *ainstr = 0xDEADC0DE; // Debugging to catch non updates | 19 | *ainstr = 0xDEADC0DE; // Debugging to catch non updates |
| 25 | 20 | ||
| @@ -36,7 +31,7 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) { | |||
| 36 | 31 | ||
| 37 | case 3: // ADD/SUB | 32 | case 3: // ADD/SUB |
| 38 | { | 33 | { |
| 39 | static const ARMword subset[4] = { | 34 | static const u32 subset[4] = { |
| 40 | 0xE0900000, // ADDS Rd,Rs,Rn | 35 | 0xE0900000, // ADDS Rd,Rs,Rn |
| 41 | 0xE0500000, // SUBS Rd,Rs,Rn | 36 | 0xE0500000, // SUBS Rd,Rs,Rn |
| 42 | 0xE2900000, // ADDS Rd,Rs,#imm3 | 37 | 0xE2900000, // ADDS Rd,Rs,#imm3 |
| @@ -55,7 +50,7 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) { | |||
| 55 | case 6: // ADD | 50 | case 6: // ADD |
| 56 | case 7: // SUB | 51 | case 7: // SUB |
| 57 | { | 52 | { |
| 58 | static const ARMword subset[4] = { | 53 | static const u32 subset[4] = { |
| 59 | 0xE3B00000, // MOVS Rd,#imm8 | 54 | 0xE3B00000, // MOVS Rd,#imm8 |
| 60 | 0xE3500000, // CMP Rd,#imm8 | 55 | 0xE3500000, // CMP Rd,#imm8 |
| 61 | 0xE2900000, // ADDS Rd,Rd,#imm8 | 56 | 0xE2900000, // ADDS Rd,Rd,#imm8 |
| @@ -84,7 +79,7 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) { | |||
| 84 | }; | 79 | }; |
| 85 | 80 | ||
| 86 | static const struct { | 81 | static const struct { |
| 87 | ARMword opcode; | 82 | u32 opcode; |
| 88 | otype type; | 83 | otype type; |
| 89 | } subset[16] = { | 84 | } subset[16] = { |
| 90 | { 0xE0100000, t_norm }, // ANDS Rd,Rd,Rs | 85 | { 0xE0100000, t_norm }, // ANDS Rd,Rd,Rs |
| @@ -129,8 +124,8 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) { | |||
| 129 | break; | 124 | break; |
| 130 | } | 125 | } |
| 131 | } else { | 126 | } else { |
| 132 | ARMword Rd = ((tinstr & 0x0007) >> 0); | 127 | u32 Rd = ((tinstr & 0x0007) >> 0); |
| 133 | ARMword Rs = ((tinstr & 0x0078) >> 3); | 128 | u32 Rs = ((tinstr & 0x0078) >> 3); |
| 134 | 129 | ||
| 135 | if (tinstr & (1 << 7)) | 130 | if (tinstr & (1 << 7)) |
| 136 | Rd += 8; | 131 | Rd += 8; |
| @@ -184,7 +179,7 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) { | |||
| 184 | case 10: | 179 | case 10: |
| 185 | case 11: | 180 | case 11: |
| 186 | { | 181 | { |
| 187 | static const ARMword subset[8] = { | 182 | static const u32 subset[8] = { |
| 188 | 0xE7800000, // STR Rd,[Rb,Ro] | 183 | 0xE7800000, // STR Rd,[Rb,Ro] |
| 189 | 0xE18000B0, // STRH Rd,[Rb,Ro] | 184 | 0xE18000B0, // STRH Rd,[Rb,Ro] |
| 190 | 0xE7C00000, // STRB Rd,[Rb,Ro] | 185 | 0xE7C00000, // STRB Rd,[Rb,Ro] |
| @@ -207,7 +202,7 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) { | |||
| 207 | case 14: // STRB Rd,[Rb,#imm5] | 202 | case 14: // STRB Rd,[Rb,#imm5] |
| 208 | case 15: // LDRB Rd,[Rb,#imm5] | 203 | case 15: // LDRB Rd,[Rb,#imm5] |
| 209 | { | 204 | { |
| 210 | static const ARMword subset[4] = { | 205 | static const u32 subset[4] = { |
| 211 | 0xE5800000, // STR Rd,[Rb,#imm5] | 206 | 0xE5800000, // STR Rd,[Rb,#imm5] |
| 212 | 0xE5900000, // LDR Rd,[Rb,#imm5] | 207 | 0xE5900000, // LDR Rd,[Rb,#imm5] |
| 213 | 0xE5C00000, // STRB Rd,[Rb,#imm5] | 208 | 0xE5C00000, // STRB Rd,[Rb,#imm5] |
| @@ -274,7 +269,7 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) { | |||
| 274 | | BITS(tinstr, 0, 3) // imm4 field; | 269 | | BITS(tinstr, 0, 3) // imm4 field; |
| 275 | | (BITS(tinstr, 4, 7) << 8); // beginning 4 bits of imm12 | 270 | | (BITS(tinstr, 4, 7) << 8); // beginning 4 bits of imm12 |
| 276 | } else if ((tinstr & 0x0F00) == 0x0200) { | 271 | } else if ((tinstr & 0x0F00) == 0x0200) { |
| 277 | static const ARMword subset[4] = { | 272 | static const u32 subset[4] = { |
| 278 | 0xE6BF0070, // SXTH | 273 | 0xE6BF0070, // SXTH |
| 279 | 0xE6AF0070, // SXTB | 274 | 0xE6AF0070, // SXTB |
| 280 | 0xE6FF0070, // UXTH | 275 | 0xE6FF0070, // UXTH |
| @@ -298,7 +293,7 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) { | |||
| 298 | | (BIT(tinstr, 4) << 18); // enable bit | 293 | | (BIT(tinstr, 4) << 18); // enable bit |
| 299 | } | 294 | } |
| 300 | } else if ((tinstr & 0x0F00) == 0x0a00) { | 295 | } else if ((tinstr & 0x0F00) == 0x0a00) { |
| 301 | static const ARMword subset[3] = { | 296 | static const u32 subset[3] = { |
| 302 | 0xE6BF0F30, // REV | 297 | 0xE6BF0F30, // REV |
| 303 | 0xE6BF0FB0, // REV16 | 298 | 0xE6BF0FB0, // REV16 |
| 304 | 0xE6FF0FB0, // REVSH | 299 | 0xE6FF0FB0, // REVSH |
| @@ -308,7 +303,7 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) { | |||
| 308 | | (BITS(tinstr, 0, 2) << 12) // Rd | 303 | | (BITS(tinstr, 0, 2) << 12) // Rd |
| 309 | | BITS(tinstr, 3, 5); // Rm | 304 | | BITS(tinstr, 3, 5); // Rm |
| 310 | } else { | 305 | } else { |
| 311 | static const ARMword subset[4] = { | 306 | static const u32 subset[4] = { |
| 312 | 0xE92D0000, // STMDB sp!,{rlist} | 307 | 0xE92D0000, // STMDB sp!,{rlist} |
| 313 | 0xE92D4000, // STMDB sp!,{rlist,lr} | 308 | 0xE92D4000, // STMDB sp!,{rlist,lr} |
| 314 | 0xE8BD0000, // LDMIA sp!,{rlist} | 309 | 0xE8BD0000, // LDMIA sp!,{rlist} |
| @@ -356,21 +351,21 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) { | |||
| 356 | else | 351 | else |
| 357 | *ainstr |= (tinstr & 0x00FF); | 352 | *ainstr |= (tinstr & 0x00FF); |
| 358 | } else if ((tinstr & 0x0F00) != 0x0E00) | 353 | } else if ((tinstr & 0x0F00) != 0x0E00) |
| 359 | valid = t_branch; | 354 | valid = ThumbDecodeStatus::BRANCH; |
| 360 | else // UNDEFINED : cc=1110(AL) uses different format | 355 | else // UNDEFINED : cc=1110(AL) uses different format |
| 361 | valid = t_undefined; | 356 | valid = ThumbDecodeStatus::UNDEFINED; |
| 362 | 357 | ||
| 363 | break; | 358 | break; |
| 364 | 359 | ||
| 365 | case 28: // B | 360 | case 28: // B |
| 366 | valid = t_branch; | 361 | valid = ThumbDecodeStatus::BRANCH; |
| 367 | break; | 362 | break; |
| 368 | 363 | ||
| 369 | case 29: | 364 | case 29: |
| 370 | if(tinstr & 0x1) | 365 | if (tinstr & 0x1) |
| 371 | valid = t_undefined; | 366 | valid = ThumbDecodeStatus::UNDEFINED; |
| 372 | else | 367 | else |
| 373 | valid = t_branch; | 368 | valid = ThumbDecodeStatus::BRANCH; |
| 374 | break; | 369 | break; |
| 375 | 370 | ||
| 376 | case 30: // BL instruction 1 | 371 | case 30: // BL instruction 1 |
| @@ -379,7 +374,7 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) { | |||
| 379 | // simulation simple (from the user perspective) we check if the following instruction is | 374 | // simulation simple (from the user perspective) we check if the following instruction is |
| 380 | // the second half of this BL, and if it is we simulate it immediately | 375 | // the second half of this BL, and if it is we simulate it immediately |
| 381 | 376 | ||
| 382 | valid = t_branch; | 377 | valid = ThumbDecodeStatus::BRANCH; |
| 383 | break; | 378 | break; |
| 384 | 379 | ||
| 385 | case 31: // BL instruction 2 | 380 | case 31: // BL instruction 2 |
| @@ -388,7 +383,7 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) { | |||
| 388 | // ever be matched with the fmt19 "BL instruction 1" instruction. However, we do allow the | 383 | // ever be matched with the fmt19 "BL instruction 1" instruction. However, we do allow the |
| 389 | // simulation of it on its own, with undefined results if r14 is not suitably initialised. | 384 | // simulation of it on its own, with undefined results if r14 is not suitably initialised. |
| 390 | 385 | ||
| 391 | valid = t_branch; | 386 | valid = ThumbDecodeStatus::BRANCH; |
| 392 | break; | 387 | break; |
| 393 | } | 388 | } |
| 394 | 389 | ||
diff --git a/src/core/arm/dyncom/arm_dyncom_thumb.h b/src/core/arm/dyncom/arm_dyncom_thumb.h index 8394ff156..447974363 100644 --- a/src/core/arm/dyncom/arm_dyncom_thumb.h +++ b/src/core/arm/dyncom/arm_dyncom_thumb.h | |||
| @@ -26,22 +26,24 @@ | |||
| 26 | 26 | ||
| 27 | #pragma once | 27 | #pragma once |
| 28 | 28 | ||
| 29 | #include "core/arm/skyeye_common/armdefs.h" | 29 | #include "common/common_types.h" |
| 30 | 30 | ||
| 31 | enum tdstate { | 31 | enum class ThumbDecodeStatus { |
| 32 | t_undefined, // Undefined Thumb instruction | 32 | UNDEFINED, // Undefined Thumb instruction |
| 33 | t_decoded, // Instruction decoded to ARM equivalent | 33 | DECODED, // Instruction decoded to ARM equivalent |
| 34 | t_branch, // Thumb branch (already processed) | 34 | BRANCH, // Thumb branch (already processed) |
| 35 | t_uninitialized, | 35 | UNINITIALIZED, |
| 36 | }; | 36 | }; |
| 37 | 37 | ||
| 38 | tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size); | 38 | // Translates a Thumb mode instruction into its ARM equivalent. |
| 39 | ThumbDecodeStatus TranslateThumbInstruction(u32 addr, u32 instr, u32* ainstr, u32* inst_size); | ||
| 39 | 40 | ||
| 40 | static inline u32 get_thumb_instr(u32 instr, u32 pc) { | 41 | static inline u32 GetThumbInstruction(u32 instr, u32 address) { |
| 41 | u32 tinstr; | 42 | // Normally you would need to handle instruction endianness, |
| 42 | if ((pc & 0x3) != 0) | 43 | // however, it is fixed to little-endian on the MPCore, so |
| 43 | tinstr = instr >> 16; | 44 | // there's no need to check for this beforehand. |
| 44 | else | 45 | if ((address & 0x3) != 0) |
| 45 | tinstr = instr & 0xFFFF; | 46 | return instr >> 16; |
| 46 | return tinstr; | 47 | |
| 48 | return instr & 0xFFFF; | ||
| 47 | } | 49 | } |
diff --git a/src/core/arm/interpreter/arminit.cpp b/src/core/arm/interpreter/arminit.cpp deleted file mode 100644 index 4f7a48fab..000000000 --- a/src/core/arm/interpreter/arminit.cpp +++ /dev/null | |||
| @@ -1,128 +0,0 @@ | |||
| 1 | /* arminit.c -- ARMulator initialization: ARM6 Instruction Emulator. | ||
| 2 | Copyright (C) 1994 Advanced RISC Machines Ltd. | ||
| 3 | |||
| 4 | This program is free software; you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation; either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program; if not, write to the Free Software | ||
| 16 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | ||
| 17 | |||
| 18 | #include <cstring> | ||
| 19 | #include "core/arm/skyeye_common/armdefs.h" | ||
| 20 | #include "core/arm/skyeye_common/vfp/vfp.h" | ||
| 21 | |||
| 22 | /***************************************************************************\ | ||
| 23 | * Returns a new instantiation of the ARMulator's state * | ||
| 24 | \***************************************************************************/ | ||
| 25 | ARMul_State* ARMul_NewState(ARMul_State* state) | ||
| 26 | { | ||
| 27 | state->Emulate = RUN; | ||
| 28 | state->Mode = USER32MODE; | ||
| 29 | |||
| 30 | state->lateabtSig = HIGH; | ||
| 31 | state->bigendSig = LOW; | ||
| 32 | |||
| 33 | return state; | ||
| 34 | } | ||
| 35 | |||
| 36 | /***************************************************************************\ | ||
| 37 | * Call this routine to set ARMulator to model a certain processor * | ||
| 38 | \***************************************************************************/ | ||
| 39 | |||
| 40 | void ARMul_SelectProcessor(ARMul_State* state, unsigned properties) | ||
| 41 | { | ||
| 42 | state->is_v4 = (properties & (ARM_v4_Prop | ARM_v5_Prop)) != 0; | ||
| 43 | state->is_v5 = (properties & ARM_v5_Prop) != 0; | ||
| 44 | state->is_v5e = (properties & ARM_v5e_Prop) != 0; | ||
| 45 | state->is_v6 = (properties & ARM_v6_Prop) != 0; | ||
| 46 | state->is_v7 = (properties & ARM_v7_Prop) != 0; | ||
| 47 | } | ||
| 48 | |||
| 49 | // Resets certain MPCore CP15 values to their ARM-defined reset values. | ||
| 50 | static void ResetMPCoreCP15Registers(ARMul_State* cpu) | ||
| 51 | { | ||
| 52 | // c0 | ||
| 53 | cpu->CP15[CP15_MAIN_ID] = 0x410FB024; | ||
| 54 | cpu->CP15[CP15_TLB_TYPE] = 0x00000800; | ||
| 55 | cpu->CP15[CP15_PROCESSOR_FEATURE_0] = 0x00000111; | ||
| 56 | cpu->CP15[CP15_PROCESSOR_FEATURE_1] = 0x00000001; | ||
| 57 | cpu->CP15[CP15_DEBUG_FEATURE_0] = 0x00000002; | ||
| 58 | cpu->CP15[CP15_MEMORY_MODEL_FEATURE_0] = 0x01100103; | ||
| 59 | cpu->CP15[CP15_MEMORY_MODEL_FEATURE_1] = 0x10020302; | ||
| 60 | cpu->CP15[CP15_MEMORY_MODEL_FEATURE_2] = 0x01222000; | ||
| 61 | cpu->CP15[CP15_MEMORY_MODEL_FEATURE_3] = 0x00000000; | ||
| 62 | cpu->CP15[CP15_ISA_FEATURE_0] = 0x00100011; | ||
| 63 | cpu->CP15[CP15_ISA_FEATURE_1] = 0x12002111; | ||
| 64 | cpu->CP15[CP15_ISA_FEATURE_2] = 0x11221011; | ||
| 65 | cpu->CP15[CP15_ISA_FEATURE_3] = 0x01102131; | ||
| 66 | cpu->CP15[CP15_ISA_FEATURE_4] = 0x00000141; | ||
| 67 | |||
| 68 | // c1 | ||
| 69 | cpu->CP15[CP15_CONTROL] = 0x00054078; | ||
| 70 | cpu->CP15[CP15_AUXILIARY_CONTROL] = 0x0000000F; | ||
| 71 | cpu->CP15[CP15_COPROCESSOR_ACCESS_CONTROL] = 0x00000000; | ||
| 72 | |||
| 73 | // c2 | ||
| 74 | cpu->CP15[CP15_TRANSLATION_BASE_TABLE_0] = 0x00000000; | ||
| 75 | cpu->CP15[CP15_TRANSLATION_BASE_TABLE_1] = 0x00000000; | ||
| 76 | cpu->CP15[CP15_TRANSLATION_BASE_CONTROL] = 0x00000000; | ||
| 77 | |||
| 78 | // c3 | ||
| 79 | cpu->CP15[CP15_DOMAIN_ACCESS_CONTROL] = 0x00000000; | ||
| 80 | |||
| 81 | // c7 | ||
| 82 | cpu->CP15[CP15_PHYS_ADDRESS] = 0x00000000; | ||
| 83 | |||
| 84 | // c9 | ||
| 85 | cpu->CP15[CP15_DATA_CACHE_LOCKDOWN] = 0xFFFFFFF0; | ||
| 86 | |||
| 87 | // c10 | ||
| 88 | cpu->CP15[CP15_TLB_LOCKDOWN] = 0x00000000; | ||
| 89 | cpu->CP15[CP15_PRIMARY_REGION_REMAP] = 0x00098AA4; | ||
| 90 | cpu->CP15[CP15_NORMAL_REGION_REMAP] = 0x44E048E0; | ||
| 91 | |||
| 92 | // c13 | ||
| 93 | cpu->CP15[CP15_PID] = 0x00000000; | ||
| 94 | cpu->CP15[CP15_CONTEXT_ID] = 0x00000000; | ||
| 95 | cpu->CP15[CP15_THREAD_UPRW] = 0x00000000; | ||
| 96 | cpu->CP15[CP15_THREAD_URO] = 0x00000000; | ||
| 97 | cpu->CP15[CP15_THREAD_PRW] = 0x00000000; | ||
| 98 | |||
| 99 | // c15 | ||
| 100 | cpu->CP15[CP15_PERFORMANCE_MONITOR_CONTROL] = 0x00000000; | ||
| 101 | cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_VIRT_ADDRESS] = 0x00000000; | ||
| 102 | cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_PHYS_ADDRESS] = 0x00000000; | ||
| 103 | cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_ATTRIBUTE] = 0x00000000; | ||
| 104 | cpu->CP15[CP15_TLB_DEBUG_CONTROL] = 0x00000000; | ||
| 105 | } | ||
| 106 | |||
| 107 | /***************************************************************************\ | ||
| 108 | * Call this routine to set up the initial machine state (or perform a RESET * | ||
| 109 | \***************************************************************************/ | ||
| 110 | void ARMul_Reset(ARMul_State* state) | ||
| 111 | { | ||
| 112 | VFPInit(state); | ||
| 113 | |||
| 114 | state->Reg[15] = 0; | ||
| 115 | state->Cpsr = INTBITS | SVC32MODE; | ||
| 116 | state->Mode = SVC32MODE; | ||
| 117 | state->Bank = SVCBANK; | ||
| 118 | |||
| 119 | ResetMPCoreCP15Registers(state); | ||
| 120 | |||
| 121 | state->NresetSig = HIGH; | ||
| 122 | state->NfiqSig = HIGH; | ||
| 123 | state->NirqSig = HIGH; | ||
| 124 | state->NtransSig = (state->Mode & 3) ? HIGH : LOW; | ||
| 125 | state->abortSig = LOW; | ||
| 126 | |||
| 127 | state->NumInstrs = 0; | ||
| 128 | } | ||
diff --git a/src/core/arm/interpreter/armsupp.cpp b/src/core/arm/interpreter/armsupp.cpp deleted file mode 100644 index 83f7f3e2c..000000000 --- a/src/core/arm/interpreter/armsupp.cpp +++ /dev/null | |||
| @@ -1,637 +0,0 @@ | |||
| 1 | /* armsupp.c -- ARMulator support code: ARM6 Instruction Emulator. | ||
| 2 | Copyright (C) 1994 Advanced RISC Machines Ltd. | ||
| 3 | |||
| 4 | This program is free software; you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation; either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program; if not, write to the Free Software | ||
| 16 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | ||
| 17 | |||
| 18 | #include "common/logging/log.h" | ||
| 19 | |||
| 20 | #include "core/mem_map.h" | ||
| 21 | #include "core/arm/skyeye_common/armdefs.h" | ||
| 22 | #include "core/arm/skyeye_common/arm_regformat.h" | ||
| 23 | |||
| 24 | // Unsigned sum of absolute difference | ||
| 25 | u8 ARMul_UnsignedAbsoluteDifference(u8 left, u8 right) | ||
| 26 | { | ||
| 27 | if (left > right) | ||
| 28 | return left - right; | ||
| 29 | |||
| 30 | return right - left; | ||
| 31 | } | ||
| 32 | |||
| 33 | // Add with carry, indicates if a carry-out or signed overflow occurred. | ||
| 34 | u32 AddWithCarry(u32 left, u32 right, u32 carry_in, bool* carry_out_occurred, bool* overflow_occurred) | ||
| 35 | { | ||
| 36 | u64 unsigned_sum = (u64)left + (u64)right + (u64)carry_in; | ||
| 37 | s64 signed_sum = (s64)(s32)left + (s64)(s32)right + (s64)carry_in; | ||
| 38 | u64 result = (unsigned_sum & 0xFFFFFFFF); | ||
| 39 | |||
| 40 | if (carry_out_occurred) | ||
| 41 | *carry_out_occurred = (result != unsigned_sum); | ||
| 42 | |||
| 43 | if (overflow_occurred) | ||
| 44 | *overflow_occurred = ((s64)(s32)result != signed_sum); | ||
| 45 | |||
| 46 | return (u32)result; | ||
| 47 | } | ||
| 48 | |||
| 49 | // Compute whether an addition of A and B, giving RESULT, overflowed. | ||
| 50 | bool AddOverflow(ARMword a, ARMword b, ARMword result) | ||
| 51 | { | ||
| 52 | return ((NEG(a) && NEG(b) && POS(result)) || | ||
| 53 | (POS(a) && POS(b) && NEG(result))); | ||
| 54 | } | ||
| 55 | |||
| 56 | // Compute whether a subtraction of A and B, giving RESULT, overflowed. | ||
| 57 | bool SubOverflow(ARMword a, ARMword b, ARMword result) | ||
| 58 | { | ||
| 59 | return ((NEG(a) && POS(b) && POS(result)) || | ||
| 60 | (POS(a) && NEG(b) && NEG(result))); | ||
| 61 | } | ||
| 62 | |||
| 63 | // Returns true if the Q flag should be set as a result of overflow. | ||
| 64 | bool ARMul_AddOverflowQ(ARMword a, ARMword b) | ||
| 65 | { | ||
| 66 | u32 result = a + b; | ||
| 67 | if (((result ^ a) & (u32)0x80000000) && ((a ^ b) & (u32)0x80000000) == 0) | ||
| 68 | return true; | ||
| 69 | |||
| 70 | return false; | ||
| 71 | } | ||
| 72 | |||
| 73 | // 8-bit signed saturated addition | ||
| 74 | u8 ARMul_SignedSaturatedAdd8(u8 left, u8 right) | ||
| 75 | { | ||
| 76 | u8 result = left + right; | ||
| 77 | |||
| 78 | if (((result ^ left) & 0x80) && ((left ^ right) & 0x80) == 0) { | ||
| 79 | if (left & 0x80) | ||
| 80 | result = 0x80; | ||
| 81 | else | ||
| 82 | result = 0x7F; | ||
| 83 | } | ||
| 84 | |||
| 85 | return result; | ||
| 86 | } | ||
| 87 | |||
| 88 | // 8-bit signed saturated subtraction | ||
| 89 | u8 ARMul_SignedSaturatedSub8(u8 left, u8 right) | ||
| 90 | { | ||
| 91 | u8 result = left - right; | ||
| 92 | |||
| 93 | if (((result ^ left) & 0x80) && ((left ^ right) & 0x80) != 0) { | ||
| 94 | if (left & 0x80) | ||
| 95 | result = 0x80; | ||
| 96 | else | ||
| 97 | result = 0x7F; | ||
| 98 | } | ||
| 99 | |||
| 100 | return result; | ||
| 101 | } | ||
| 102 | |||
| 103 | // 16-bit signed saturated addition | ||
| 104 | u16 ARMul_SignedSaturatedAdd16(u16 left, u16 right) | ||
| 105 | { | ||
| 106 | u16 result = left + right; | ||
| 107 | |||
| 108 | if (((result ^ left) & 0x8000) && ((left ^ right) & 0x8000) == 0) { | ||
| 109 | if (left & 0x8000) | ||
| 110 | result = 0x8000; | ||
| 111 | else | ||
| 112 | result = 0x7FFF; | ||
| 113 | } | ||
| 114 | |||
| 115 | return result; | ||
| 116 | } | ||
| 117 | |||
| 118 | // 16-bit signed saturated subtraction | ||
| 119 | u16 ARMul_SignedSaturatedSub16(u16 left, u16 right) | ||
| 120 | { | ||
| 121 | u16 result = left - right; | ||
| 122 | |||
| 123 | if (((result ^ left) & 0x8000) && ((left ^ right) & 0x8000) != 0) { | ||
| 124 | if (left & 0x8000) | ||
| 125 | result = 0x8000; | ||
| 126 | else | ||
| 127 | result = 0x7FFF; | ||
| 128 | } | ||
| 129 | |||
| 130 | return result; | ||
| 131 | } | ||
| 132 | |||
| 133 | // 8-bit unsigned saturated addition | ||
| 134 | u8 ARMul_UnsignedSaturatedAdd8(u8 left, u8 right) | ||
| 135 | { | ||
| 136 | u8 result = left + right; | ||
| 137 | |||
| 138 | if (result < left) | ||
| 139 | result = 0xFF; | ||
| 140 | |||
| 141 | return result; | ||
| 142 | } | ||
| 143 | |||
| 144 | // 16-bit unsigned saturated addition | ||
| 145 | u16 ARMul_UnsignedSaturatedAdd16(u16 left, u16 right) | ||
| 146 | { | ||
| 147 | u16 result = left + right; | ||
| 148 | |||
| 149 | if (result < left) | ||
| 150 | result = 0xFFFF; | ||
| 151 | |||
| 152 | return result; | ||
| 153 | } | ||
| 154 | |||
| 155 | // 8-bit unsigned saturated subtraction | ||
| 156 | u8 ARMul_UnsignedSaturatedSub8(u8 left, u8 right) | ||
| 157 | { | ||
| 158 | if (left <= right) | ||
| 159 | return 0; | ||
| 160 | |||
| 161 | return left - right; | ||
| 162 | } | ||
| 163 | |||
| 164 | // 16-bit unsigned saturated subtraction | ||
| 165 | u16 ARMul_UnsignedSaturatedSub16(u16 left, u16 right) | ||
| 166 | { | ||
| 167 | if (left <= right) | ||
| 168 | return 0; | ||
| 169 | |||
| 170 | return left - right; | ||
| 171 | } | ||
| 172 | |||
| 173 | // Signed saturation. | ||
| 174 | u32 ARMul_SignedSatQ(s32 value, u8 shift, bool* saturation_occurred) | ||
| 175 | { | ||
| 176 | const u32 max = (1 << shift) - 1; | ||
| 177 | const s32 top = (value >> shift); | ||
| 178 | |||
| 179 | if (top > 0) { | ||
| 180 | *saturation_occurred = true; | ||
| 181 | return max; | ||
| 182 | } | ||
| 183 | else if (top < -1) { | ||
| 184 | *saturation_occurred = true; | ||
| 185 | return ~max; | ||
| 186 | } | ||
| 187 | |||
| 188 | *saturation_occurred = false; | ||
| 189 | return (u32)value; | ||
| 190 | } | ||
| 191 | |||
| 192 | // Unsigned saturation | ||
| 193 | u32 ARMul_UnsignedSatQ(s32 value, u8 shift, bool* saturation_occurred) | ||
| 194 | { | ||
| 195 | const u32 max = (1 << shift) - 1; | ||
| 196 | |||
| 197 | if (value < 0) { | ||
| 198 | *saturation_occurred = true; | ||
| 199 | return 0; | ||
| 200 | } else if ((u32)value > max) { | ||
| 201 | *saturation_occurred = true; | ||
| 202 | return max; | ||
| 203 | } | ||
| 204 | |||
| 205 | *saturation_occurred = false; | ||
| 206 | return (u32)value; | ||
| 207 | } | ||
| 208 | |||
| 209 | // Whether or not the given CPU is in big endian mode (E bit is set) | ||
| 210 | bool InBigEndianMode(ARMul_State* cpu) | ||
| 211 | { | ||
| 212 | return (cpu->Cpsr & (1 << 9)) != 0; | ||
| 213 | } | ||
| 214 | |||
| 215 | // Whether or not the given CPU is in a mode other than user mode. | ||
| 216 | bool InAPrivilegedMode(ARMul_State* cpu) | ||
| 217 | { | ||
| 218 | return (cpu->Mode != USER32MODE); | ||
| 219 | } | ||
| 220 | |||
| 221 | // Reads from the CP15 registers. Used with implementation of the MRC instruction. | ||
| 222 | // Note that since the 3DS does not have the hypervisor extensions, these registers | ||
| 223 | // are not implemented. | ||
| 224 | u32 ReadCP15Register(ARMul_State* cpu, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2) | ||
| 225 | { | ||
| 226 | // Unprivileged registers | ||
| 227 | if (crn == 13 && opcode_1 == 0 && crm == 0) | ||
| 228 | { | ||
| 229 | if (opcode_2 == 2) | ||
| 230 | return cpu->CP15[CP15_THREAD_UPRW]; | ||
| 231 | |||
| 232 | if (opcode_2 == 3) | ||
| 233 | return cpu->CP15[CP15_THREAD_URO]; | ||
| 234 | } | ||
| 235 | |||
| 236 | if (InAPrivilegedMode(cpu)) | ||
| 237 | { | ||
| 238 | if (crn == 0 && opcode_1 == 0) | ||
| 239 | { | ||
| 240 | if (crm == 0) | ||
| 241 | { | ||
| 242 | if (opcode_2 == 0) | ||
| 243 | return cpu->CP15[CP15_MAIN_ID]; | ||
| 244 | |||
| 245 | if (opcode_2 == 1) | ||
| 246 | return cpu->CP15[CP15_CACHE_TYPE]; | ||
| 247 | |||
| 248 | if (opcode_2 == 3) | ||
| 249 | return cpu->CP15[CP15_TLB_TYPE]; | ||
| 250 | |||
| 251 | if (opcode_2 == 5) | ||
| 252 | return cpu->CP15[CP15_CPU_ID]; | ||
| 253 | } | ||
| 254 | else if (crm == 1) | ||
| 255 | { | ||
| 256 | if (opcode_2 == 0) | ||
| 257 | return cpu->CP15[CP15_PROCESSOR_FEATURE_0]; | ||
| 258 | |||
| 259 | if (opcode_2 == 1) | ||
| 260 | return cpu->CP15[CP15_PROCESSOR_FEATURE_1]; | ||
| 261 | |||
| 262 | if (opcode_2 == 2) | ||
| 263 | return cpu->CP15[CP15_DEBUG_FEATURE_0]; | ||
| 264 | |||
| 265 | if (opcode_2 == 4) | ||
| 266 | return cpu->CP15[CP15_MEMORY_MODEL_FEATURE_0]; | ||
| 267 | |||
| 268 | if (opcode_2 == 5) | ||
| 269 | return cpu->CP15[CP15_MEMORY_MODEL_FEATURE_1]; | ||
| 270 | |||
| 271 | if (opcode_2 == 6) | ||
| 272 | return cpu->CP15[CP15_MEMORY_MODEL_FEATURE_2]; | ||
| 273 | |||
| 274 | if (opcode_2 == 7) | ||
| 275 | return cpu->CP15[CP15_MEMORY_MODEL_FEATURE_3]; | ||
| 276 | } | ||
| 277 | else if (crm == 2) | ||
| 278 | { | ||
| 279 | if (opcode_2 == 0) | ||
| 280 | return cpu->CP15[CP15_ISA_FEATURE_0]; | ||
| 281 | |||
| 282 | if (opcode_2 == 1) | ||
| 283 | return cpu->CP15[CP15_ISA_FEATURE_1]; | ||
| 284 | |||
| 285 | if (opcode_2 == 2) | ||
| 286 | return cpu->CP15[CP15_ISA_FEATURE_2]; | ||
| 287 | |||
| 288 | if (opcode_2 == 3) | ||
| 289 | return cpu->CP15[CP15_ISA_FEATURE_3]; | ||
| 290 | |||
| 291 | if (opcode_2 == 4) | ||
| 292 | return cpu->CP15[CP15_ISA_FEATURE_4]; | ||
| 293 | } | ||
| 294 | } | ||
| 295 | |||
| 296 | if (crn == 1 && opcode_1 == 0 && crm == 0) | ||
| 297 | { | ||
| 298 | if (opcode_2 == 0) | ||
| 299 | return cpu->CP15[CP15_CONTROL]; | ||
| 300 | |||
| 301 | if (opcode_2 == 1) | ||
| 302 | return cpu->CP15[CP15_AUXILIARY_CONTROL]; | ||
| 303 | |||
| 304 | if (opcode_2 == 2) | ||
| 305 | return cpu->CP15[CP15_COPROCESSOR_ACCESS_CONTROL]; | ||
| 306 | } | ||
| 307 | |||
| 308 | if (crn == 2 && opcode_1 == 0 && crm == 0) | ||
| 309 | { | ||
| 310 | if (opcode_2 == 0) | ||
| 311 | return cpu->CP15[CP15_TRANSLATION_BASE_TABLE_0]; | ||
| 312 | |||
| 313 | if (opcode_2 == 1) | ||
| 314 | return cpu->CP15[CP15_TRANSLATION_BASE_TABLE_1]; | ||
| 315 | |||
| 316 | if (opcode_2 == 2) | ||
| 317 | return cpu->CP15[CP15_TRANSLATION_BASE_CONTROL]; | ||
| 318 | } | ||
| 319 | |||
| 320 | if (crn == 3 && opcode_1 == 0 && crm == 0 && opcode_2 == 0) | ||
| 321 | return cpu->CP15[CP15_DOMAIN_ACCESS_CONTROL]; | ||
| 322 | |||
| 323 | if (crn == 5 && opcode_1 == 0 && crm == 0) | ||
| 324 | { | ||
| 325 | if (opcode_2 == 0) | ||
| 326 | return cpu->CP15[CP15_FAULT_STATUS]; | ||
| 327 | |||
| 328 | if (opcode_2 == 1) | ||
| 329 | return cpu->CP15[CP15_INSTR_FAULT_STATUS]; | ||
| 330 | } | ||
| 331 | |||
| 332 | if (crn == 6 && opcode_1 == 0 && crm == 0) | ||
| 333 | { | ||
| 334 | if (opcode_2 == 0) | ||
| 335 | return cpu->CP15[CP15_FAULT_ADDRESS]; | ||
| 336 | |||
| 337 | if (opcode_2 == 1) | ||
| 338 | return cpu->CP15[CP15_WFAR]; | ||
| 339 | } | ||
| 340 | |||
| 341 | if (crn == 7 && opcode_1 == 0 && crm == 4 && opcode_2 == 0) | ||
| 342 | return cpu->CP15[CP15_PHYS_ADDRESS]; | ||
| 343 | |||
| 344 | if (crn == 9 && opcode_1 == 0 && crm == 0 && opcode_2 == 0) | ||
| 345 | return cpu->CP15[CP15_DATA_CACHE_LOCKDOWN]; | ||
| 346 | |||
| 347 | if (crn == 10 && opcode_1 == 0) | ||
| 348 | { | ||
| 349 | if (crm == 0 && opcode_2 == 0) | ||
| 350 | return cpu->CP15[CP15_TLB_LOCKDOWN]; | ||
| 351 | |||
| 352 | if (crm == 2) | ||
| 353 | { | ||
| 354 | if (opcode_2 == 0) | ||
| 355 | return cpu->CP15[CP15_PRIMARY_REGION_REMAP]; | ||
| 356 | |||
| 357 | if (opcode_2 == 1) | ||
| 358 | return cpu->CP15[CP15_NORMAL_REGION_REMAP]; | ||
| 359 | } | ||
| 360 | } | ||
| 361 | |||
| 362 | if (crn == 13 && crm == 0) | ||
| 363 | { | ||
| 364 | if (opcode_2 == 0) | ||
| 365 | return cpu->CP15[CP15_PID]; | ||
| 366 | |||
| 367 | if (opcode_2 == 1) | ||
| 368 | return cpu->CP15[CP15_CONTEXT_ID]; | ||
| 369 | |||
| 370 | if (opcode_2 == 4) | ||
| 371 | return cpu->CP15[CP15_THREAD_PRW]; | ||
| 372 | } | ||
| 373 | |||
| 374 | if (crn == 15) | ||
| 375 | { | ||
| 376 | if (opcode_1 == 0 && crm == 12) | ||
| 377 | { | ||
| 378 | if (opcode_2 == 0) | ||
| 379 | return cpu->CP15[CP15_PERFORMANCE_MONITOR_CONTROL]; | ||
| 380 | |||
| 381 | if (opcode_2 == 1) | ||
| 382 | return cpu->CP15[CP15_CYCLE_COUNTER]; | ||
| 383 | |||
| 384 | if (opcode_2 == 2) | ||
| 385 | return cpu->CP15[CP15_COUNT_0]; | ||
| 386 | |||
| 387 | if (opcode_2 == 3) | ||
| 388 | return cpu->CP15[CP15_COUNT_1]; | ||
| 389 | } | ||
| 390 | |||
| 391 | if (opcode_1 == 5 && opcode_2 == 2) | ||
| 392 | { | ||
| 393 | if (crm == 5) | ||
| 394 | return cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_VIRT_ADDRESS]; | ||
| 395 | |||
| 396 | if (crm == 6) | ||
| 397 | return cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_PHYS_ADDRESS]; | ||
| 398 | |||
| 399 | if (crm == 7) | ||
| 400 | return cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_ATTRIBUTE]; | ||
| 401 | } | ||
| 402 | |||
| 403 | if (opcode_1 == 7 && crm == 1 && opcode_2 == 0) | ||
| 404 | return cpu->CP15[CP15_TLB_DEBUG_CONTROL]; | ||
| 405 | } | ||
| 406 | } | ||
| 407 | |||
| 408 | LOG_ERROR(Core_ARM11, "MRC CRn=%u, CRm=%u, OP1=%u OP2=%u is not implemented. Returning zero.", crn, crm, opcode_1, opcode_2); | ||
| 409 | return 0; | ||
| 410 | } | ||
| 411 | |||
| 412 | // Write to the CP15 registers. Used with implementation of the MCR instruction. | ||
| 413 | // Note that since the 3DS does not have the hypervisor extensions, these registers | ||
| 414 | // are not implemented. | ||
| 415 | void WriteCP15Register(ARMul_State* cpu, u32 value, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2) | ||
| 416 | { | ||
| 417 | if (InAPrivilegedMode(cpu)) | ||
| 418 | { | ||
| 419 | if (crn == 1 && opcode_1 == 0 && crm == 0) | ||
| 420 | { | ||
| 421 | if (opcode_2 == 0) | ||
| 422 | cpu->CP15[CP15_CONTROL] = value; | ||
| 423 | else if (opcode_2 == 1) | ||
| 424 | cpu->CP15[CP15_AUXILIARY_CONTROL] = value; | ||
| 425 | else if (opcode_2 == 2) | ||
| 426 | cpu->CP15[CP15_COPROCESSOR_ACCESS_CONTROL] = value; | ||
| 427 | } | ||
| 428 | else if (crn == 2 && opcode_1 == 0 && crm == 0) | ||
| 429 | { | ||
| 430 | if (opcode_2 == 0) | ||
| 431 | cpu->CP15[CP15_TRANSLATION_BASE_TABLE_0] = value; | ||
| 432 | else if (opcode_2 == 1) | ||
| 433 | cpu->CP15[CP15_TRANSLATION_BASE_TABLE_1] = value; | ||
| 434 | else if (opcode_2 == 2) | ||
| 435 | cpu->CP15[CP15_TRANSLATION_BASE_CONTROL] = value; | ||
| 436 | } | ||
| 437 | else if (crn == 3 && opcode_1 == 0 && crm == 0 && opcode_2 == 0) | ||
| 438 | { | ||
| 439 | cpu->CP15[CP15_DOMAIN_ACCESS_CONTROL] = value; | ||
| 440 | } | ||
| 441 | else if (crn == 5 && opcode_1 == 0 && crm == 0) | ||
| 442 | { | ||
| 443 | if (opcode_2 == 0) | ||
| 444 | cpu->CP15[CP15_FAULT_STATUS] = value; | ||
| 445 | else if (opcode_2 == 1) | ||
| 446 | cpu->CP15[CP15_INSTR_FAULT_STATUS] = value; | ||
| 447 | } | ||
| 448 | else if (crn == 6 && opcode_1 == 0 && crm == 0) | ||
| 449 | { | ||
| 450 | if (opcode_2 == 0) | ||
| 451 | cpu->CP15[CP15_FAULT_ADDRESS] = value; | ||
| 452 | else if (opcode_2 == 1) | ||
| 453 | cpu->CP15[CP15_WFAR] = value; | ||
| 454 | } | ||
| 455 | else if (crn == 7 && opcode_1 == 0) | ||
| 456 | { | ||
| 457 | if (crm == 0 && opcode_2 == 4) | ||
| 458 | { | ||
| 459 | cpu->CP15[CP15_WAIT_FOR_INTERRUPT] = value; | ||
| 460 | } | ||
| 461 | else if (crm == 4 && opcode_2 == 0) | ||
| 462 | { | ||
| 463 | // NOTE: Not entirely accurate. This should do permission checks. | ||
| 464 | cpu->CP15[CP15_PHYS_ADDRESS] = Memory::VirtualToPhysicalAddress(value); | ||
| 465 | } | ||
| 466 | else if (crm == 5) | ||
| 467 | { | ||
| 468 | if (opcode_2 == 0) | ||
| 469 | cpu->CP15[CP15_INVALIDATE_INSTR_CACHE] = value; | ||
| 470 | else if (opcode_2 == 1) | ||
| 471 | cpu->CP15[CP15_INVALIDATE_INSTR_CACHE_USING_MVA] = value; | ||
| 472 | else if (opcode_2 == 2) | ||
| 473 | cpu->CP15[CP15_INVALIDATE_INSTR_CACHE_USING_INDEX] = value; | ||
| 474 | else if (opcode_2 == 6) | ||
| 475 | cpu->CP15[CP15_FLUSH_BRANCH_TARGET_CACHE] = value; | ||
| 476 | else if (opcode_2 == 7) | ||
| 477 | cpu->CP15[CP15_FLUSH_BRANCH_TARGET_CACHE_ENTRY] = value; | ||
| 478 | } | ||
| 479 | else if (crm == 6) | ||
| 480 | { | ||
| 481 | if (opcode_2 == 0) | ||
| 482 | cpu->CP15[CP15_INVALIDATE_DATA_CACHE] = value; | ||
| 483 | else if (opcode_2 == 1) | ||
| 484 | cpu->CP15[CP15_INVALIDATE_DATA_CACHE_LINE_USING_MVA] = value; | ||
| 485 | else if (opcode_2 == 2) | ||
| 486 | cpu->CP15[CP15_INVALIDATE_DATA_CACHE_LINE_USING_INDEX] = value; | ||
| 487 | } | ||
| 488 | else if (crm == 7 && opcode_2 == 0) | ||
| 489 | { | ||
| 490 | cpu->CP15[CP15_INVALIDATE_DATA_AND_INSTR_CACHE] = value; | ||
| 491 | } | ||
| 492 | else if (crm == 10) | ||
| 493 | { | ||
| 494 | if (opcode_2 == 0) | ||
| 495 | cpu->CP15[CP15_CLEAN_DATA_CACHE] = value; | ||
| 496 | else if (opcode_2 == 1) | ||
| 497 | cpu->CP15[CP15_CLEAN_DATA_CACHE_LINE_USING_MVA] = value; | ||
| 498 | else if (opcode_2 == 2) | ||
| 499 | cpu->CP15[CP15_CLEAN_DATA_CACHE_LINE_USING_INDEX] = value; | ||
| 500 | } | ||
| 501 | else if (crm == 14) | ||
| 502 | { | ||
| 503 | if (opcode_2 == 0) | ||
| 504 | cpu->CP15[CP15_CLEAN_AND_INVALIDATE_DATA_CACHE] = value; | ||
| 505 | else if (opcode_2 == 1) | ||
| 506 | cpu->CP15[CP15_CLEAN_AND_INVALIDATE_DATA_CACHE_LINE_USING_MVA] = value; | ||
| 507 | else if (opcode_2 == 2) | ||
| 508 | cpu->CP15[CP15_CLEAN_AND_INVALIDATE_DATA_CACHE_LINE_USING_INDEX] = value; | ||
| 509 | } | ||
| 510 | } | ||
| 511 | else if (crn == 8 && opcode_1 == 0) | ||
| 512 | { | ||
| 513 | LOG_WARNING(Core_ARM11, "TLB operations not fully implemented."); | ||
| 514 | |||
| 515 | if (crm == 5) | ||
| 516 | { | ||
| 517 | if (opcode_2 == 0) | ||
| 518 | cpu->CP15[CP15_INVALIDATE_ITLB] = value; | ||
| 519 | else if (opcode_2 == 1) | ||
| 520 | cpu->CP15[CP15_INVALIDATE_ITLB_SINGLE_ENTRY] = value; | ||
| 521 | else if (opcode_2 == 2) | ||
| 522 | cpu->CP15[CP15_INVALIDATE_ITLB_ENTRY_ON_ASID_MATCH] = value; | ||
| 523 | else if (opcode_2 == 3) | ||
| 524 | cpu->CP15[CP15_INVALIDATE_ITLB_ENTRY_ON_MVA] = value; | ||
| 525 | } | ||
| 526 | else if (crm == 6) | ||
| 527 | { | ||
| 528 | if (opcode_2 == 0) | ||
| 529 | cpu->CP15[CP15_INVALIDATE_DTLB] = value; | ||
| 530 | else if (opcode_2 == 1) | ||
| 531 | cpu->CP15[CP15_INVALIDATE_DTLB_SINGLE_ENTRY] = value; | ||
| 532 | else if (opcode_2 == 2) | ||
| 533 | cpu->CP15[CP15_INVALIDATE_DTLB_ENTRY_ON_ASID_MATCH] = value; | ||
| 534 | else if (opcode_2 == 3) | ||
| 535 | cpu->CP15[CP15_INVALIDATE_DTLB_ENTRY_ON_MVA] = value; | ||
| 536 | } | ||
| 537 | else if (crm == 7) | ||
| 538 | { | ||
| 539 | if (opcode_2 == 0) | ||
| 540 | cpu->CP15[CP15_INVALIDATE_UTLB] = value; | ||
| 541 | else if (opcode_2 == 1) | ||
| 542 | cpu->CP15[CP15_INVALIDATE_UTLB_SINGLE_ENTRY] = value; | ||
| 543 | else if (opcode_2 == 2) | ||
| 544 | cpu->CP15[CP15_INVALIDATE_UTLB_ENTRY_ON_ASID_MATCH] = value; | ||
| 545 | else if (opcode_2 == 3) | ||
| 546 | cpu->CP15[CP15_INVALIDATE_UTLB_ENTRY_ON_MVA] = value; | ||
| 547 | } | ||
| 548 | } | ||
| 549 | else if (crn == 9 && opcode_1 == 0 && crm == 0 && opcode_2 == 0) | ||
| 550 | { | ||
| 551 | cpu->CP15[CP15_DATA_CACHE_LOCKDOWN] = value; | ||
| 552 | } | ||
| 553 | else if (crn == 10 && opcode_1 == 0) | ||
| 554 | { | ||
| 555 | if (crm == 0 && opcode_2 == 0) | ||
| 556 | { | ||
| 557 | cpu->CP15[CP15_TLB_LOCKDOWN] = value; | ||
| 558 | } | ||
| 559 | else if (crm == 2) | ||
| 560 | { | ||
| 561 | if (opcode_2 == 0) | ||
| 562 | cpu->CP15[CP15_PRIMARY_REGION_REMAP] = value; | ||
| 563 | else if (opcode_2 == 1) | ||
| 564 | cpu->CP15[CP15_NORMAL_REGION_REMAP] = value; | ||
| 565 | } | ||
| 566 | } | ||
| 567 | else if (crn == 13 && opcode_1 == 0 && crm == 0) | ||
| 568 | { | ||
| 569 | if (opcode_2 == 0) | ||
| 570 | cpu->CP15[CP15_PID] = value; | ||
| 571 | else if (opcode_2 == 1) | ||
| 572 | cpu->CP15[CP15_CONTEXT_ID] = value; | ||
| 573 | else if (opcode_2 == 3) | ||
| 574 | cpu->CP15[CP15_THREAD_URO] = value; | ||
| 575 | else if (opcode_2 == 4) | ||
| 576 | cpu->CP15[CP15_THREAD_PRW] = value; | ||
| 577 | } | ||
| 578 | else if (crn == 15) | ||
| 579 | { | ||
| 580 | if (opcode_1 == 0 && crm == 12) | ||
| 581 | { | ||
| 582 | if (opcode_2 == 0) | ||
| 583 | cpu->CP15[CP15_PERFORMANCE_MONITOR_CONTROL] = value; | ||
| 584 | else if (opcode_2 == 1) | ||
| 585 | cpu->CP15[CP15_CYCLE_COUNTER] = value; | ||
| 586 | else if (opcode_2 == 2) | ||
| 587 | cpu->CP15[CP15_COUNT_0] = value; | ||
| 588 | else if (opcode_2 == 3) | ||
| 589 | cpu->CP15[CP15_COUNT_1] = value; | ||
| 590 | } | ||
| 591 | else if (opcode_1 == 5) | ||
| 592 | { | ||
| 593 | if (crm == 4) | ||
| 594 | { | ||
| 595 | if (opcode_2 == 2) | ||
| 596 | cpu->CP15[CP15_READ_MAIN_TLB_LOCKDOWN_ENTRY] = value; | ||
| 597 | else if (opcode_2 == 4) | ||
| 598 | cpu->CP15[CP15_WRITE_MAIN_TLB_LOCKDOWN_ENTRY] = value; | ||
| 599 | } | ||
| 600 | else if (crm == 5 && opcode_2 == 2) | ||
| 601 | { | ||
| 602 | cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_VIRT_ADDRESS] = value; | ||
| 603 | } | ||
| 604 | else if (crm == 6 && opcode_2 == 2) | ||
| 605 | { | ||
| 606 | cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_PHYS_ADDRESS] = value; | ||
| 607 | } | ||
| 608 | else if (crm == 7 && opcode_2 == 2) | ||
| 609 | { | ||
| 610 | cpu->CP15[CP15_MAIN_TLB_LOCKDOWN_ATTRIBUTE] = value; | ||
| 611 | } | ||
| 612 | } | ||
| 613 | else if (opcode_1 == 7 && crm == 1 && opcode_2 == 0) | ||
| 614 | { | ||
| 615 | cpu->CP15[CP15_TLB_DEBUG_CONTROL] = value; | ||
| 616 | } | ||
| 617 | } | ||
| 618 | } | ||
| 619 | |||
| 620 | // Unprivileged registers | ||
| 621 | if (crn == 7 && opcode_1 == 0 && crm == 5 && opcode_2 == 4) | ||
| 622 | { | ||
| 623 | cpu->CP15[CP15_FLUSH_PREFETCH_BUFFER] = value; | ||
| 624 | } | ||
| 625 | else if (crn == 7 && opcode_1 == 0 && crm == 10) | ||
| 626 | { | ||
| 627 | if (opcode_2 == 4) | ||
| 628 | cpu->CP15[CP15_DATA_SYNC_BARRIER] = value; | ||
| 629 | else if (opcode_2 == 5) | ||
| 630 | cpu->CP15[CP15_DATA_MEMORY_BARRIER] = value; | ||
| 631 | |||
| 632 | } | ||
| 633 | else if (crn == 13 && opcode_1 == 0 && crm == 0 && opcode_2 == 2) | ||
| 634 | { | ||
| 635 | cpu->CP15[CP15_THREAD_UPRW] = value; | ||
| 636 | } | ||
| 637 | } | ||
diff --git a/src/core/arm/skyeye_common/armdefs.h b/src/core/arm/skyeye_common/armdefs.h deleted file mode 100644 index d2c901100..000000000 --- a/src/core/arm/skyeye_common/armdefs.h +++ /dev/null | |||
| @@ -1,318 +0,0 @@ | |||
| 1 | /* armdefs.h -- ARMulator common definitions: ARM6 Instruction Emulator. | ||
| 2 | Copyright (C) 1994 Advanced RISC Machines Ltd. | ||
| 3 | |||
| 4 | This program is free software; you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation; either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program; if not, write to the Free Software | ||
| 16 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | ||
| 17 | |||
| 18 | #pragma once | ||
| 19 | |||
| 20 | #include <unordered_map> | ||
| 21 | |||
| 22 | #include "common/common_types.h" | ||
| 23 | #include "core/arm/skyeye_common/arm_regformat.h" | ||
| 24 | |||
| 25 | #define BITS(s, a, b) ((s << ((sizeof(s) * 8 - 1) - b)) >> (sizeof(s) * 8 - b + a - 1)) | ||
| 26 | #define BIT(s, n) ((s >> (n)) & 1) | ||
| 27 | |||
| 28 | // Signal levels | ||
| 29 | enum { | ||
| 30 | LOW = 0, | ||
| 31 | HIGH = 1, | ||
| 32 | LOWHIGH = 1, | ||
| 33 | HIGHLOW = 2 | ||
| 34 | }; | ||
| 35 | |||
| 36 | // Cache types | ||
| 37 | enum { | ||
| 38 | NONCACHE = 0, | ||
| 39 | DATACACHE = 1, | ||
| 40 | INSTCACHE = 2, | ||
| 41 | }; | ||
| 42 | |||
| 43 | // Abort models | ||
| 44 | enum { | ||
| 45 | ABORT_BASE_RESTORED = 0, | ||
| 46 | ABORT_EARLY = 1, | ||
| 47 | ABORT_BASE_UPDATED = 2 | ||
| 48 | }; | ||
| 49 | |||
| 50 | #define POS(i) ( (~(i)) >> 31 ) | ||
| 51 | #define NEG(i) ( (i) >> 31 ) | ||
| 52 | |||
| 53 | typedef u64 ARMdword; // must be 64 bits wide | ||
| 54 | typedef u32 ARMword; // must be 32 bits wide | ||
| 55 | typedef u16 ARMhword; // must be 16 bits wide | ||
| 56 | typedef u8 ARMbyte; // must be 8 bits wide | ||
| 57 | |||
| 58 | #define VFP_REG_NUM 64 | ||
| 59 | struct ARMul_State | ||
| 60 | { | ||
| 61 | ARMword Emulate; // To start and stop emulation | ||
| 62 | |||
| 63 | // Order of the following register should not be modified | ||
| 64 | ARMword Reg[16]; // The current register file | ||
| 65 | ARMword Cpsr; // The current PSR | ||
| 66 | ARMword Spsr_copy; | ||
| 67 | ARMword phys_pc; | ||
| 68 | ARMword Reg_usr[2]; | ||
| 69 | ARMword Reg_svc[2]; // R13_SVC R14_SVC | ||
| 70 | ARMword Reg_abort[2]; // R13_ABORT R14_ABORT | ||
| 71 | ARMword Reg_undef[2]; // R13 UNDEF R14 UNDEF | ||
| 72 | ARMword Reg_irq[2]; // R13_IRQ R14_IRQ | ||
| 73 | ARMword Reg_firq[7]; // R8---R14 FIRQ | ||
| 74 | ARMword Spsr[7]; // The exception psr's | ||
| 75 | ARMword Mode; // The current mode | ||
| 76 | ARMword Bank; // The current register bank | ||
| 77 | ARMword exclusive_tag; // The address for which the local monitor is in exclusive access mode | ||
| 78 | ARMword exclusive_state; | ||
| 79 | ARMword exclusive_result; | ||
| 80 | ARMword CP15[CP15_REGISTER_COUNT]; | ||
| 81 | |||
| 82 | // FPSID, FPSCR, and FPEXC | ||
| 83 | ARMword VFP[VFP_SYSTEM_REGISTER_COUNT]; | ||
| 84 | // VFPv2 and VFPv3-D16 has 16 doubleword registers (D0-D16 or S0-S31). | ||
| 85 | // VFPv3-D32/ASIMD may have up to 32 doubleword registers (D0-D31), | ||
| 86 | // and only 32 singleword registers are accessible (S0-S31). | ||
| 87 | ARMword ExtReg[VFP_REG_NUM]; | ||
| 88 | /* ---- End of the ordered registers ---- */ | ||
| 89 | |||
| 90 | ARMword NFlag, ZFlag, CFlag, VFlag, IFFlags; // Dummy flags for speed | ||
| 91 | unsigned int shifter_carry_out; | ||
| 92 | |||
| 93 | // Add armv6 flags dyf:2010-08-09 | ||
| 94 | ARMword GEFlag, EFlag, AFlag, QFlag; | ||
| 95 | |||
| 96 | ARMword TFlag; // Thumb state | ||
| 97 | |||
| 98 | unsigned long long NumInstrs; // The number of instructions executed | ||
| 99 | unsigned NumInstrsToExecute; | ||
| 100 | |||
| 101 | unsigned NresetSig; // Reset the processor | ||
| 102 | unsigned NfiqSig; | ||
| 103 | unsigned NirqSig; | ||
| 104 | |||
| 105 | unsigned abortSig; | ||
| 106 | unsigned NtransSig; | ||
| 107 | unsigned bigendSig; | ||
| 108 | unsigned syscallSig; | ||
| 109 | |||
| 110 | /* 2004-05-09 chy | ||
| 111 | ---------------------------------------------------------- | ||
| 112 | read ARM Architecture Reference Manual | ||
| 113 | 2.6.5 Data Abort | ||
| 114 | There are three Abort Model in ARM arch. | ||
| 115 | |||
| 116 | Early Abort Model: used in some ARMv3 and earlier implementations. In this | ||
| 117 | model, base register wirteback occurred for LDC,LDM,STC,STM instructions, and | ||
| 118 | the base register was unchanged for all other instructions. (oldest) | ||
| 119 | |||
| 120 | Base Restored Abort Model: If a Data Abort occurs in an instruction which | ||
| 121 | specifies base register writeback, the value in the base register is | ||
| 122 | unchanged. (strongarm, xscale) | ||
| 123 | |||
| 124 | Base Updated Abort Model: If a Data Abort occurs in an instruction which | ||
| 125 | specifies base register writeback, the base register writeback still occurs. | ||
| 126 | (arm720T) | ||
| 127 | |||
| 128 | read PART B | ||
| 129 | chap2 The System Control Coprocessor CP15 | ||
| 130 | 2.4 Register1:control register | ||
| 131 | L(bit 6): in some ARMv3 and earlier implementations, the abort model of the | ||
| 132 | processor could be configured: | ||
| 133 | 0=early Abort Model Selected(now obsolete) | ||
| 134 | 1=Late Abort Model selceted(same as Base Updated Abort Model) | ||
| 135 | |||
| 136 | on later processors, this bit reads as 1 and ignores writes. | ||
| 137 | ------------------------------------------------------------- | ||
| 138 | So, if lateabtSig=1, then it means Late Abort Model(Base Updated Abort Model) | ||
| 139 | if lateabtSig=0, then it means Base Restored Abort Model | ||
| 140 | */ | ||
| 141 | unsigned lateabtSig; | ||
| 142 | |||
| 143 | // For differentiating ARM core emulaiton. | ||
| 144 | bool is_v4; // Are we emulating a v4 architecture (or higher)? | ||
| 145 | bool is_v5; // Are we emulating a v5 architecture? | ||
| 146 | bool is_v5e; // Are we emulating a v5e architecture? | ||
| 147 | bool is_v6; // Are we emulating a v6 architecture? | ||
| 148 | bool is_v7; // Are we emulating a v7 architecture? | ||
| 149 | |||
| 150 | // ARM_ARM A2-18 | ||
| 151 | // 0 Base Restored Abort Model, 1 the Early Abort Model, 2 Base Updated Abort Model | ||
| 152 | int abort_model; | ||
| 153 | |||
| 154 | // TODO(bunnei): Move this cache to a better place - it should be per codeset (likely per | ||
| 155 | // process for our purposes), not per ARMul_State (which tracks CPU core state). | ||
| 156 | std::unordered_map<u32, int> instruction_cache; | ||
| 157 | }; | ||
| 158 | |||
| 159 | /***************************************************************************\ | ||
| 160 | * Types of ARM we know about * | ||
| 161 | \***************************************************************************/ | ||
| 162 | |||
| 163 | enum { | ||
| 164 | ARM_v4_Prop = 0x01, | ||
| 165 | ARM_v5_Prop = 0x02, | ||
| 166 | ARM_v5e_Prop = 0x04, | ||
| 167 | ARM_v6_Prop = 0x08, | ||
| 168 | ARM_v7_Prop = 0x10, | ||
| 169 | }; | ||
| 170 | |||
| 171 | /***************************************************************************\ | ||
| 172 | * The hardware vector addresses * | ||
| 173 | \***************************************************************************/ | ||
| 174 | |||
| 175 | enum { | ||
| 176 | ARMResetV = 0, | ||
| 177 | ARMUndefinedInstrV = 4, | ||
| 178 | ARMSWIV = 8, | ||
| 179 | ARMPrefetchAbortV = 12, | ||
| 180 | ARMDataAbortV = 16, | ||
| 181 | ARMAddrExceptnV = 20, | ||
| 182 | ARMIRQV = 24, | ||
| 183 | ARMFIQV = 28, | ||
| 184 | ARMErrorV = 32, // This is an offset, not an address! | ||
| 185 | |||
| 186 | ARMul_ResetV = ARMResetV, | ||
| 187 | ARMul_UndefinedInstrV = ARMUndefinedInstrV, | ||
| 188 | ARMul_SWIV = ARMSWIV, | ||
| 189 | ARMul_PrefetchAbortV = ARMPrefetchAbortV, | ||
| 190 | ARMul_DataAbortV = ARMDataAbortV, | ||
| 191 | ARMul_AddrExceptnV = ARMAddrExceptnV, | ||
| 192 | ARMul_IRQV = ARMIRQV, | ||
| 193 | ARMul_FIQV = ARMFIQV | ||
| 194 | }; | ||
| 195 | |||
| 196 | /***************************************************************************\ | ||
| 197 | * Mode and Bank Constants * | ||
| 198 | \***************************************************************************/ | ||
| 199 | |||
| 200 | enum PrivilegeMode { | ||
| 201 | USER32MODE = 16, | ||
| 202 | FIQ32MODE = 17, | ||
| 203 | IRQ32MODE = 18, | ||
| 204 | SVC32MODE = 19, | ||
| 205 | ABORT32MODE = 23, | ||
| 206 | UNDEF32MODE = 27, | ||
| 207 | SYSTEM32MODE = 31 | ||
| 208 | }; | ||
| 209 | |||
| 210 | enum { | ||
| 211 | USERBANK = 0, | ||
| 212 | FIQBANK = 1, | ||
| 213 | IRQBANK = 2, | ||
| 214 | SVCBANK = 3, | ||
| 215 | ABORTBANK = 4, | ||
| 216 | UNDEFBANK = 5, | ||
| 217 | DUMMYBANK = 6, | ||
| 218 | SYSTEMBANK = 7 | ||
| 219 | }; | ||
| 220 | |||
| 221 | /***************************************************************************\ | ||
| 222 | * Definitons of things in the emulator * | ||
| 223 | \***************************************************************************/ | ||
| 224 | extern void ARMul_Reset(ARMul_State* state); | ||
| 225 | extern ARMul_State* ARMul_NewState(ARMul_State* state); | ||
| 226 | |||
| 227 | /***************************************************************************\ | ||
| 228 | * Definitons of things in the co-processor interface * | ||
| 229 | \***************************************************************************/ | ||
| 230 | |||
| 231 | enum { | ||
| 232 | ARMul_FIRST = 0, | ||
| 233 | ARMul_TRANSFER = 1, | ||
| 234 | ARMul_BUSY = 2, | ||
| 235 | ARMul_DATA = 3, | ||
| 236 | ARMul_INTERRUPT = 4, | ||
| 237 | ARMul_DONE = 0, | ||
| 238 | ARMul_CANT = 1, | ||
| 239 | ARMul_INC = 3 | ||
| 240 | }; | ||
| 241 | |||
| 242 | /***************************************************************************\ | ||
| 243 | * Definitons of things in the host environment * | ||
| 244 | \***************************************************************************/ | ||
| 245 | |||
| 246 | enum ConditionCode { | ||
| 247 | EQ = 0, | ||
| 248 | NE = 1, | ||
| 249 | CS = 2, | ||
| 250 | CC = 3, | ||
| 251 | MI = 4, | ||
| 252 | PL = 5, | ||
| 253 | VS = 6, | ||
| 254 | VC = 7, | ||
| 255 | HI = 8, | ||
| 256 | LS = 9, | ||
| 257 | GE = 10, | ||
| 258 | LT = 11, | ||
| 259 | GT = 12, | ||
| 260 | LE = 13, | ||
| 261 | AL = 14, | ||
| 262 | NV = 15, | ||
| 263 | }; | ||
| 264 | |||
| 265 | // Flags for use with the APSR. | ||
| 266 | enum : u32 { | ||
| 267 | NBIT = (1U << 31U), | ||
| 268 | ZBIT = (1 << 30), | ||
| 269 | CBIT = (1 << 29), | ||
| 270 | VBIT = (1 << 28), | ||
| 271 | QBIT = (1 << 27), | ||
| 272 | JBIT = (1 << 24), | ||
| 273 | EBIT = (1 << 9), | ||
| 274 | ABIT = (1 << 8), | ||
| 275 | IBIT = (1 << 7), | ||
| 276 | FBIT = (1 << 6), | ||
| 277 | TBIT = (1 << 5), | ||
| 278 | |||
| 279 | // Masks for groups of bits in the APSR. | ||
| 280 | MODEBITS = 0x1F, | ||
| 281 | INTBITS = 0x1C0, | ||
| 282 | }; | ||
| 283 | |||
| 284 | // Values for Emulate. | ||
| 285 | enum { | ||
| 286 | STOP = 0, // Stop | ||
| 287 | CHANGEMODE = 1, // Change mode | ||
| 288 | ONCE = 2, // Execute just one iteration | ||
| 289 | RUN = 3 // Continuous execution | ||
| 290 | }; | ||
| 291 | |||
| 292 | |||
| 293 | extern bool AddOverflow(ARMword, ARMword, ARMword); | ||
| 294 | extern bool SubOverflow(ARMword, ARMword, ARMword); | ||
| 295 | |||
| 296 | extern void ARMul_SelectProcessor(ARMul_State*, unsigned); | ||
| 297 | |||
| 298 | extern u32 AddWithCarry(u32, u32, u32, bool*, bool*); | ||
| 299 | extern bool ARMul_AddOverflowQ(ARMword, ARMword); | ||
| 300 | |||
| 301 | extern u8 ARMul_SignedSaturatedAdd8(u8, u8); | ||
| 302 | extern u8 ARMul_SignedSaturatedSub8(u8, u8); | ||
| 303 | extern u16 ARMul_SignedSaturatedAdd16(u16, u16); | ||
| 304 | extern u16 ARMul_SignedSaturatedSub16(u16, u16); | ||
| 305 | |||
| 306 | extern u8 ARMul_UnsignedSaturatedAdd8(u8, u8); | ||
| 307 | extern u16 ARMul_UnsignedSaturatedAdd16(u16, u16); | ||
| 308 | extern u8 ARMul_UnsignedSaturatedSub8(u8, u8); | ||
| 309 | extern u16 ARMul_UnsignedSaturatedSub16(u16, u16); | ||
| 310 | extern u8 ARMul_UnsignedAbsoluteDifference(u8, u8); | ||
| 311 | extern u32 ARMul_SignedSatQ(s32, u8, bool*); | ||
| 312 | extern u32 ARMul_UnsignedSatQ(s32, u8, bool*); | ||
| 313 | |||
| 314 | extern bool InBigEndianMode(ARMul_State*); | ||
| 315 | extern bool InAPrivilegedMode(ARMul_State*); | ||
| 316 | |||
| 317 | extern u32 ReadCP15Register(ARMul_State* cpu, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2); | ||
| 318 | extern void WriteCP15Register(ARMul_State* cpu, u32 value, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2); | ||
diff --git a/src/core/arm/skyeye_common/armmmu.h b/src/core/arm/skyeye_common/armmmu.h deleted file mode 100644 index c67d7209b..000000000 --- a/src/core/arm/skyeye_common/armmmu.h +++ /dev/null | |||
| @@ -1,103 +0,0 @@ | |||
| 1 | /* | ||
| 2 | armmmu.c - Memory Management Unit emulation. | ||
| 3 | ARMulator extensions for the ARM7100 family. | ||
| 4 | Copyright (C) 1999 Ben Williamson | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 19 | */ | ||
| 20 | |||
| 21 | #pragma once | ||
| 22 | |||
| 23 | #include "common/swap.h" | ||
| 24 | |||
| 25 | #include "core/memory.h" | ||
| 26 | #include "core/arm/skyeye_common/armdefs.h" | ||
| 27 | |||
| 28 | // Register numbers in the MMU | ||
| 29 | enum | ||
| 30 | { | ||
| 31 | MMU_ID = 0, | ||
| 32 | MMU_CONTROL = 1, | ||
| 33 | MMU_TRANSLATION_TABLE_BASE = 2, | ||
| 34 | MMU_DOMAIN_ACCESS_CONTROL = 3, | ||
| 35 | MMU_FAULT_STATUS = 5, | ||
| 36 | MMU_FAULT_ADDRESS = 6, | ||
| 37 | MMU_CACHE_OPS = 7, | ||
| 38 | MMU_TLB_OPS = 8, | ||
| 39 | MMU_CACHE_LOCKDOWN = 9, | ||
| 40 | MMU_TLB_LOCKDOWN = 10, | ||
| 41 | MMU_PID = 13, | ||
| 42 | |||
| 43 | // MMU_V4 | ||
| 44 | MMU_V4_CACHE_OPS = 7, | ||
| 45 | MMU_V4_TLB_OPS = 8, | ||
| 46 | |||
| 47 | // MMU_V3 | ||
| 48 | MMU_V3_FLUSH_TLB = 5, | ||
| 49 | MMU_V3_FLUSH_TLB_ENTRY = 6, | ||
| 50 | MMU_V3_FLUSH_CACHE = 7, | ||
| 51 | }; | ||
| 52 | |||
| 53 | // Reads data in big/little endian format based on the | ||
| 54 | // state of the E (endian) bit in the emulated CPU's APSR. | ||
| 55 | inline u16 ReadMemory16(ARMul_State* cpu, u32 address) { | ||
| 56 | u16 data = Memory::Read16(address); | ||
| 57 | |||
| 58 | if (InBigEndianMode(cpu)) | ||
| 59 | data = Common::swap16(data); | ||
| 60 | |||
| 61 | return data; | ||
| 62 | } | ||
| 63 | |||
| 64 | inline u32 ReadMemory32(ARMul_State* cpu, u32 address) { | ||
| 65 | u32 data = Memory::Read32(address); | ||
| 66 | |||
| 67 | if (InBigEndianMode(cpu)) | ||
| 68 | data = Common::swap32(data); | ||
| 69 | |||
| 70 | return data; | ||
| 71 | } | ||
| 72 | |||
| 73 | inline u64 ReadMemory64(ARMul_State* cpu, u32 address) { | ||
| 74 | u64 data = Memory::Read64(address); | ||
| 75 | |||
| 76 | if (InBigEndianMode(cpu)) | ||
| 77 | data = Common::swap64(data); | ||
| 78 | |||
| 79 | return data; | ||
| 80 | } | ||
| 81 | |||
| 82 | // Writes data in big/little endian format based on the | ||
| 83 | // state of the E (endian) bit in the emulated CPU's APSR. | ||
| 84 | inline void WriteMemory16(ARMul_State* cpu, u32 address, u16 data) { | ||
| 85 | if (InBigEndianMode(cpu)) | ||
| 86 | data = Common::swap16(data); | ||
| 87 | |||
| 88 | Memory::Write16(address, data); | ||
| 89 | } | ||
| 90 | |||
| 91 | inline void WriteMemory32(ARMul_State* cpu, u32 address, u32 data) { | ||
| 92 | if (InBigEndianMode(cpu)) | ||
| 93 | data = Common::swap32(data); | ||
| 94 | |||
| 95 | Memory::Write32(address, data); | ||
| 96 | } | ||
| 97 | |||
| 98 | inline void WriteMemory64(ARMul_State* cpu, u32 address, u64 data) { | ||
| 99 | if (InBigEndianMode(cpu)) | ||
| 100 | data = Common::swap64(data); | ||
| 101 | |||
| 102 | Memory::Write64(address, data); | ||
| 103 | } | ||
diff --git a/src/core/arm/skyeye_common/armstate.cpp b/src/core/arm/skyeye_common/armstate.cpp new file mode 100644 index 000000000..ccb2eb0eb --- /dev/null +++ b/src/core/arm/skyeye_common/armstate.cpp | |||
| @@ -0,0 +1,657 @@ | |||
| 1 | // Copyright 2015 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "common/swap.h" | ||
| 6 | #include "common/logging/log.h" | ||
| 7 | #include "core/mem_map.h" | ||
| 8 | #include "core/memory.h" | ||
| 9 | #include "core/arm/skyeye_common/armstate.h" | ||
| 10 | #include "core/arm/skyeye_common/vfp/vfp.h" | ||
| 11 | |||
| 12 | ARMul_State::ARMul_State(PrivilegeMode initial_mode) | ||
| 13 | { | ||
| 14 | Reset(); | ||
| 15 | ChangePrivilegeMode(initial_mode); | ||
| 16 | } | ||
| 17 | |||
| 18 | void ARMul_State::ChangePrivilegeMode(u32 new_mode) | ||
| 19 | { | ||
| 20 | if (Mode == new_mode) | ||
| 21 | return; | ||
| 22 | |||
| 23 | if (new_mode != USERBANK) { | ||
| 24 | switch (Mode) { | ||
| 25 | case SYSTEM32MODE: // Shares registers with user mode | ||
| 26 | case USER32MODE: | ||
| 27 | Reg_usr[0] = Reg[13]; | ||
| 28 | Reg_usr[1] = Reg[14]; | ||
| 29 | break; | ||
| 30 | case IRQ32MODE: | ||
| 31 | Reg_irq[0] = Reg[13]; | ||
| 32 | Reg_irq[1] = Reg[14]; | ||
| 33 | Spsr[IRQBANK] = Spsr_copy; | ||
| 34 | break; | ||
| 35 | case SVC32MODE: | ||
| 36 | Reg_svc[0] = Reg[13]; | ||
| 37 | Reg_svc[1] = Reg[14]; | ||
| 38 | Spsr[SVCBANK] = Spsr_copy; | ||
| 39 | break; | ||
| 40 | case ABORT32MODE: | ||
| 41 | Reg_abort[0] = Reg[13]; | ||
| 42 | Reg_abort[1] = Reg[14]; | ||
| 43 | Spsr[ABORTBANK] = Spsr_copy; | ||
| 44 | break; | ||
| 45 | case UNDEF32MODE: | ||
| 46 | Reg_undef[0] = Reg[13]; | ||
| 47 | Reg_undef[1] = Reg[14]; | ||
| 48 | Spsr[UNDEFBANK] = Spsr_copy; | ||
| 49 | break; | ||
| 50 | case FIQ32MODE: | ||
| 51 | Reg_firq[0] = Reg[13]; | ||
| 52 | Reg_firq[1] = Reg[14]; | ||
| 53 | Spsr[FIQBANK] = Spsr_copy; | ||
| 54 | break; | ||
| 55 | } | ||
| 56 | |||
| 57 | switch (new_mode) { | ||
| 58 | case USER32MODE: | ||
| 59 | Reg[13] = Reg_usr[0]; | ||
| 60 | Reg[14] = Reg_usr[1]; | ||
| 61 | Bank = USERBANK; | ||
| 62 | break; | ||
| 63 | case IRQ32MODE: | ||
| 64 | Reg[13] = Reg_irq[0]; | ||
| 65 | Reg[14] = Reg_irq[1]; | ||
| 66 | Spsr_copy = Spsr[IRQBANK]; | ||
| 67 | Bank = IRQBANK; | ||
| 68 | break; | ||
| 69 | case SVC32MODE: | ||
| 70 | Reg[13] = Reg_svc[0]; | ||
| 71 | Reg[14] = Reg_svc[1]; | ||
| 72 | Spsr_copy = Spsr[SVCBANK]; | ||
| 73 | Bank = SVCBANK; | ||
| 74 | break; | ||
| 75 | case ABORT32MODE: | ||
| 76 | Reg[13] = Reg_abort[0]; | ||
| 77 | Reg[14] = Reg_abort[1]; | ||
| 78 | Spsr_copy = Spsr[ABORTBANK]; | ||
| 79 | Bank = ABORTBANK; | ||
| 80 | break; | ||
| 81 | case UNDEF32MODE: | ||
| 82 | Reg[13] = Reg_undef[0]; | ||
| 83 | Reg[14] = Reg_undef[1]; | ||
| 84 | Spsr_copy = Spsr[UNDEFBANK]; | ||
| 85 | Bank = UNDEFBANK; | ||
| 86 | break; | ||
| 87 | case FIQ32MODE: | ||
| 88 | Reg[13] = Reg_firq[0]; | ||
| 89 | Reg[14] = Reg_firq[1]; | ||
| 90 | Spsr_copy = Spsr[FIQBANK]; | ||
| 91 | Bank = FIQBANK; | ||
| 92 | break; | ||
| 93 | case SYSTEM32MODE: // Shares registers with user mode. | ||
| 94 | Reg[13] = Reg_usr[0]; | ||
| 95 | Reg[14] = Reg_usr[1]; | ||
| 96 | Bank = SYSTEMBANK; | ||
| 97 | break; | ||
| 98 | } | ||
| 99 | |||
| 100 | // Set the mode bits in the APSR | ||
| 101 | Cpsr = (Cpsr & ~Mode) | new_mode; | ||
| 102 | Mode = new_mode; | ||
| 103 | } | ||
| 104 | } | ||
| 105 | |||
| 106 | // Performs a reset | ||
| 107 | void ARMul_State::Reset() | ||
| 108 | { | ||
| 109 | VFPInit(this); | ||
| 110 | |||
| 111 | // Set stack pointer to the top of the stack | ||
| 112 | Reg[13] = 0x10000000; | ||
| 113 | Reg[15] = 0; | ||
| 114 | |||
| 115 | Cpsr = INTBITS | SVC32MODE; | ||
| 116 | Mode = SVC32MODE; | ||
| 117 | Bank = SVCBANK; | ||
| 118 | |||
| 119 | ResetMPCoreCP15Registers(); | ||
| 120 | |||
| 121 | NresetSig = HIGH; | ||
| 122 | NfiqSig = HIGH; | ||
| 123 | NirqSig = HIGH; | ||
| 124 | NtransSig = (Mode & 3) ? HIGH : LOW; | ||
| 125 | abortSig = LOW; | ||
| 126 | |||
| 127 | NumInstrs = 0; | ||
| 128 | Emulate = RUN; | ||
| 129 | } | ||
| 130 | |||
| 131 | // Resets certain MPCore CP15 values to their ARM-defined reset values. | ||
| 132 | void ARMul_State::ResetMPCoreCP15Registers() | ||
| 133 | { | ||
| 134 | // c0 | ||
| 135 | CP15[CP15_MAIN_ID] = 0x410FB024; | ||
| 136 | CP15[CP15_TLB_TYPE] = 0x00000800; | ||
| 137 | CP15[CP15_PROCESSOR_FEATURE_0] = 0x00000111; | ||
| 138 | CP15[CP15_PROCESSOR_FEATURE_1] = 0x00000001; | ||
| 139 | CP15[CP15_DEBUG_FEATURE_0] = 0x00000002; | ||
| 140 | CP15[CP15_MEMORY_MODEL_FEATURE_0] = 0x01100103; | ||
| 141 | CP15[CP15_MEMORY_MODEL_FEATURE_1] = 0x10020302; | ||
| 142 | CP15[CP15_MEMORY_MODEL_FEATURE_2] = 0x01222000; | ||
| 143 | CP15[CP15_MEMORY_MODEL_FEATURE_3] = 0x00000000; | ||
| 144 | CP15[CP15_ISA_FEATURE_0] = 0x00100011; | ||
| 145 | CP15[CP15_ISA_FEATURE_1] = 0x12002111; | ||
| 146 | CP15[CP15_ISA_FEATURE_2] = 0x11221011; | ||
| 147 | CP15[CP15_ISA_FEATURE_3] = 0x01102131; | ||
| 148 | CP15[CP15_ISA_FEATURE_4] = 0x00000141; | ||
| 149 | |||
| 150 | // c1 | ||
| 151 | CP15[CP15_CONTROL] = 0x00054078; | ||
| 152 | CP15[CP15_AUXILIARY_CONTROL] = 0x0000000F; | ||
| 153 | CP15[CP15_COPROCESSOR_ACCESS_CONTROL] = 0x00000000; | ||
| 154 | |||
| 155 | // c2 | ||
| 156 | CP15[CP15_TRANSLATION_BASE_TABLE_0] = 0x00000000; | ||
| 157 | CP15[CP15_TRANSLATION_BASE_TABLE_1] = 0x00000000; | ||
| 158 | CP15[CP15_TRANSLATION_BASE_CONTROL] = 0x00000000; | ||
| 159 | |||
| 160 | // c3 | ||
| 161 | CP15[CP15_DOMAIN_ACCESS_CONTROL] = 0x00000000; | ||
| 162 | |||
| 163 | // c7 | ||
| 164 | CP15[CP15_PHYS_ADDRESS] = 0x00000000; | ||
| 165 | |||
| 166 | // c9 | ||
| 167 | CP15[CP15_DATA_CACHE_LOCKDOWN] = 0xFFFFFFF0; | ||
| 168 | |||
| 169 | // c10 | ||
| 170 | CP15[CP15_TLB_LOCKDOWN] = 0x00000000; | ||
| 171 | CP15[CP15_PRIMARY_REGION_REMAP] = 0x00098AA4; | ||
| 172 | CP15[CP15_NORMAL_REGION_REMAP] = 0x44E048E0; | ||
| 173 | |||
| 174 | // c13 | ||
| 175 | CP15[CP15_PID] = 0x00000000; | ||
| 176 | CP15[CP15_CONTEXT_ID] = 0x00000000; | ||
| 177 | CP15[CP15_THREAD_UPRW] = 0x00000000; | ||
| 178 | CP15[CP15_THREAD_URO] = 0x00000000; | ||
| 179 | CP15[CP15_THREAD_PRW] = 0x00000000; | ||
| 180 | |||
| 181 | // c15 | ||
| 182 | CP15[CP15_PERFORMANCE_MONITOR_CONTROL] = 0x00000000; | ||
| 183 | CP15[CP15_MAIN_TLB_LOCKDOWN_VIRT_ADDRESS] = 0x00000000; | ||
| 184 | CP15[CP15_MAIN_TLB_LOCKDOWN_PHYS_ADDRESS] = 0x00000000; | ||
| 185 | CP15[CP15_MAIN_TLB_LOCKDOWN_ATTRIBUTE] = 0x00000000; | ||
| 186 | CP15[CP15_TLB_DEBUG_CONTROL] = 0x00000000; | ||
| 187 | } | ||
| 188 | |||
| 189 | u16 ARMul_State::ReadMemory16(u32 address) const | ||
| 190 | { | ||
| 191 | u16 data = Memory::Read16(address); | ||
| 192 | |||
| 193 | if (InBigEndianMode()) | ||
| 194 | data = Common::swap16(data); | ||
| 195 | |||
| 196 | return data; | ||
| 197 | } | ||
| 198 | |||
| 199 | u32 ARMul_State::ReadMemory32(u32 address) const | ||
| 200 | { | ||
| 201 | u32 data = Memory::Read32(address); | ||
| 202 | |||
| 203 | if (InBigEndianMode()) | ||
| 204 | data = Common::swap32(data); | ||
| 205 | |||
| 206 | return data; | ||
| 207 | } | ||
| 208 | |||
| 209 | u64 ARMul_State::ReadMemory64(u32 address) const | ||
| 210 | { | ||
| 211 | u64 data = Memory::Read64(address); | ||
| 212 | |||
| 213 | if (InBigEndianMode()) | ||
| 214 | data = Common::swap64(data); | ||
| 215 | |||
| 216 | return data; | ||
| 217 | } | ||
| 218 | |||
| 219 | void ARMul_State::WriteMemory16(u32 address, u16 data) | ||
| 220 | { | ||
| 221 | if (InBigEndianMode()) | ||
| 222 | data = Common::swap16(data); | ||
| 223 | |||
| 224 | Memory::Write16(address, data); | ||
| 225 | } | ||
| 226 | |||
| 227 | void ARMul_State::WriteMemory32(u32 address, u32 data) | ||
| 228 | { | ||
| 229 | if (InBigEndianMode()) | ||
| 230 | data = Common::swap32(data); | ||
| 231 | |||
| 232 | Memory::Write32(address, data); | ||
| 233 | } | ||
| 234 | |||
| 235 | void ARMul_State::WriteMemory64(u32 address, u64 data) | ||
| 236 | { | ||
| 237 | if (InBigEndianMode()) | ||
| 238 | data = Common::swap64(data); | ||
| 239 | |||
| 240 | Memory::Write64(address, data); | ||
| 241 | } | ||
| 242 | |||
| 243 | |||
| 244 | // Reads from the CP15 registers. Used with implementation of the MRC instruction. | ||
| 245 | // Note that since the 3DS does not have the hypervisor extensions, these registers | ||
| 246 | // are not implemented. | ||
| 247 | u32 ARMul_State::ReadCP15Register(u32 crn, u32 opcode_1, u32 crm, u32 opcode_2) const | ||
| 248 | { | ||
| 249 | // Unprivileged registers | ||
| 250 | if (crn == 13 && opcode_1 == 0 && crm == 0) | ||
| 251 | { | ||
| 252 | if (opcode_2 == 2) | ||
| 253 | return CP15[CP15_THREAD_UPRW]; | ||
| 254 | |||
| 255 | if (opcode_2 == 3) | ||
| 256 | return CP15[CP15_THREAD_URO]; | ||
| 257 | } | ||
| 258 | |||
| 259 | if (InAPrivilegedMode()) | ||
| 260 | { | ||
| 261 | if (crn == 0 && opcode_1 == 0) | ||
| 262 | { | ||
| 263 | if (crm == 0) | ||
| 264 | { | ||
| 265 | if (opcode_2 == 0) | ||
| 266 | return CP15[CP15_MAIN_ID]; | ||
| 267 | |||
| 268 | if (opcode_2 == 1) | ||
| 269 | return CP15[CP15_CACHE_TYPE]; | ||
| 270 | |||
| 271 | if (opcode_2 == 3) | ||
| 272 | return CP15[CP15_TLB_TYPE]; | ||
| 273 | |||
| 274 | if (opcode_2 == 5) | ||
| 275 | return CP15[CP15_CPU_ID]; | ||
| 276 | } | ||
| 277 | else if (crm == 1) | ||
| 278 | { | ||
| 279 | if (opcode_2 == 0) | ||
| 280 | return CP15[CP15_PROCESSOR_FEATURE_0]; | ||
| 281 | |||
| 282 | if (opcode_2 == 1) | ||
| 283 | return CP15[CP15_PROCESSOR_FEATURE_1]; | ||
| 284 | |||
| 285 | if (opcode_2 == 2) | ||
| 286 | return CP15[CP15_DEBUG_FEATURE_0]; | ||
| 287 | |||
| 288 | if (opcode_2 == 4) | ||
| 289 | return CP15[CP15_MEMORY_MODEL_FEATURE_0]; | ||
| 290 | |||
| 291 | if (opcode_2 == 5) | ||
| 292 | return CP15[CP15_MEMORY_MODEL_FEATURE_1]; | ||
| 293 | |||
| 294 | if (opcode_2 == 6) | ||
| 295 | return CP15[CP15_MEMORY_MODEL_FEATURE_2]; | ||
| 296 | |||
| 297 | if (opcode_2 == 7) | ||
| 298 | return CP15[CP15_MEMORY_MODEL_FEATURE_3]; | ||
| 299 | } | ||
| 300 | else if (crm == 2) | ||
| 301 | { | ||
| 302 | if (opcode_2 == 0) | ||
| 303 | return CP15[CP15_ISA_FEATURE_0]; | ||
| 304 | |||
| 305 | if (opcode_2 == 1) | ||
| 306 | return CP15[CP15_ISA_FEATURE_1]; | ||
| 307 | |||
| 308 | if (opcode_2 == 2) | ||
| 309 | return CP15[CP15_ISA_FEATURE_2]; | ||
| 310 | |||
| 311 | if (opcode_2 == 3) | ||
| 312 | return CP15[CP15_ISA_FEATURE_3]; | ||
| 313 | |||
| 314 | if (opcode_2 == 4) | ||
| 315 | return CP15[CP15_ISA_FEATURE_4]; | ||
| 316 | } | ||
| 317 | } | ||
| 318 | |||
| 319 | if (crn == 1 && opcode_1 == 0 && crm == 0) | ||
| 320 | { | ||
| 321 | if (opcode_2 == 0) | ||
| 322 | return CP15[CP15_CONTROL]; | ||
| 323 | |||
| 324 | if (opcode_2 == 1) | ||
| 325 | return CP15[CP15_AUXILIARY_CONTROL]; | ||
| 326 | |||
| 327 | if (opcode_2 == 2) | ||
| 328 | return CP15[CP15_COPROCESSOR_ACCESS_CONTROL]; | ||
| 329 | } | ||
| 330 | |||
| 331 | if (crn == 2 && opcode_1 == 0 && crm == 0) | ||
| 332 | { | ||
| 333 | if (opcode_2 == 0) | ||
| 334 | return CP15[CP15_TRANSLATION_BASE_TABLE_0]; | ||
| 335 | |||
| 336 | if (opcode_2 == 1) | ||
| 337 | return CP15[CP15_TRANSLATION_BASE_TABLE_1]; | ||
| 338 | |||
| 339 | if (opcode_2 == 2) | ||
| 340 | return CP15[CP15_TRANSLATION_BASE_CONTROL]; | ||
| 341 | } | ||
| 342 | |||
| 343 | if (crn == 3 && opcode_1 == 0 && crm == 0 && opcode_2 == 0) | ||
| 344 | return CP15[CP15_DOMAIN_ACCESS_CONTROL]; | ||
| 345 | |||
| 346 | if (crn == 5 && opcode_1 == 0 && crm == 0) | ||
| 347 | { | ||
| 348 | if (opcode_2 == 0) | ||
| 349 | return CP15[CP15_FAULT_STATUS]; | ||
| 350 | |||
| 351 | if (opcode_2 == 1) | ||
| 352 | return CP15[CP15_INSTR_FAULT_STATUS]; | ||
| 353 | } | ||
| 354 | |||
| 355 | if (crn == 6 && opcode_1 == 0 && crm == 0) | ||
| 356 | { | ||
| 357 | if (opcode_2 == 0) | ||
| 358 | return CP15[CP15_FAULT_ADDRESS]; | ||
| 359 | |||
| 360 | if (opcode_2 == 1) | ||
| 361 | return CP15[CP15_WFAR]; | ||
| 362 | } | ||
| 363 | |||
| 364 | if (crn == 7 && opcode_1 == 0 && crm == 4 && opcode_2 == 0) | ||
| 365 | return CP15[CP15_PHYS_ADDRESS]; | ||
| 366 | |||
| 367 | if (crn == 9 && opcode_1 == 0 && crm == 0 && opcode_2 == 0) | ||
| 368 | return CP15[CP15_DATA_CACHE_LOCKDOWN]; | ||
| 369 | |||
| 370 | if (crn == 10 && opcode_1 == 0) | ||
| 371 | { | ||
| 372 | if (crm == 0 && opcode_2 == 0) | ||
| 373 | return CP15[CP15_TLB_LOCKDOWN]; | ||
| 374 | |||
| 375 | if (crm == 2) | ||
| 376 | { | ||
| 377 | if (opcode_2 == 0) | ||
| 378 | return CP15[CP15_PRIMARY_REGION_REMAP]; | ||
| 379 | |||
| 380 | if (opcode_2 == 1) | ||
| 381 | return CP15[CP15_NORMAL_REGION_REMAP]; | ||
| 382 | } | ||
| 383 | } | ||
| 384 | |||
| 385 | if (crn == 13 && crm == 0) | ||
| 386 | { | ||
| 387 | if (opcode_2 == 0) | ||
| 388 | return CP15[CP15_PID]; | ||
| 389 | |||
| 390 | if (opcode_2 == 1) | ||
| 391 | return CP15[CP15_CONTEXT_ID]; | ||
| 392 | |||
| 393 | if (opcode_2 == 4) | ||
| 394 | return CP15[CP15_THREAD_PRW]; | ||
| 395 | } | ||
| 396 | |||
| 397 | if (crn == 15) | ||
| 398 | { | ||
| 399 | if (opcode_1 == 0 && crm == 12) | ||
| 400 | { | ||
| 401 | if (opcode_2 == 0) | ||
| 402 | return CP15[CP15_PERFORMANCE_MONITOR_CONTROL]; | ||
| 403 | |||
| 404 | if (opcode_2 == 1) | ||
| 405 | return CP15[CP15_CYCLE_COUNTER]; | ||
| 406 | |||
| 407 | if (opcode_2 == 2) | ||
| 408 | return CP15[CP15_COUNT_0]; | ||
| 409 | |||
| 410 | if (opcode_2 == 3) | ||
| 411 | return CP15[CP15_COUNT_1]; | ||
| 412 | } | ||
| 413 | |||
| 414 | if (opcode_1 == 5 && opcode_2 == 2) | ||
| 415 | { | ||
| 416 | if (crm == 5) | ||
| 417 | return CP15[CP15_MAIN_TLB_LOCKDOWN_VIRT_ADDRESS]; | ||
| 418 | |||
| 419 | if (crm == 6) | ||
| 420 | return CP15[CP15_MAIN_TLB_LOCKDOWN_PHYS_ADDRESS]; | ||
| 421 | |||
| 422 | if (crm == 7) | ||
| 423 | return CP15[CP15_MAIN_TLB_LOCKDOWN_ATTRIBUTE]; | ||
| 424 | } | ||
| 425 | |||
| 426 | if (opcode_1 == 7 && crm == 1 && opcode_2 == 0) | ||
| 427 | return CP15[CP15_TLB_DEBUG_CONTROL]; | ||
| 428 | } | ||
| 429 | } | ||
| 430 | |||
| 431 | LOG_ERROR(Core_ARM11, "MRC CRn=%u, CRm=%u, OP1=%u OP2=%u is not implemented. Returning zero.", crn, crm, opcode_1, opcode_2); | ||
| 432 | return 0; | ||
| 433 | } | ||
| 434 | |||
| 435 | // Write to the CP15 registers. Used with implementation of the MCR instruction. | ||
| 436 | // Note that since the 3DS does not have the hypervisor extensions, these registers | ||
| 437 | // are not implemented. | ||
| 438 | void ARMul_State::WriteCP15Register(u32 value, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2) | ||
| 439 | { | ||
| 440 | if (InAPrivilegedMode()) | ||
| 441 | { | ||
| 442 | if (crn == 1 && opcode_1 == 0 && crm == 0) | ||
| 443 | { | ||
| 444 | if (opcode_2 == 0) | ||
| 445 | CP15[CP15_CONTROL] = value; | ||
| 446 | else if (opcode_2 == 1) | ||
| 447 | CP15[CP15_AUXILIARY_CONTROL] = value; | ||
| 448 | else if (opcode_2 == 2) | ||
| 449 | CP15[CP15_COPROCESSOR_ACCESS_CONTROL] = value; | ||
| 450 | } | ||
| 451 | else if (crn == 2 && opcode_1 == 0 && crm == 0) | ||
| 452 | { | ||
| 453 | if (opcode_2 == 0) | ||
| 454 | CP15[CP15_TRANSLATION_BASE_TABLE_0] = value; | ||
| 455 | else if (opcode_2 == 1) | ||
| 456 | CP15[CP15_TRANSLATION_BASE_TABLE_1] = value; | ||
| 457 | else if (opcode_2 == 2) | ||
| 458 | CP15[CP15_TRANSLATION_BASE_CONTROL] = value; | ||
| 459 | } | ||
| 460 | else if (crn == 3 && opcode_1 == 0 && crm == 0 && opcode_2 == 0) | ||
| 461 | { | ||
| 462 | CP15[CP15_DOMAIN_ACCESS_CONTROL] = value; | ||
| 463 | } | ||
| 464 | else if (crn == 5 && opcode_1 == 0 && crm == 0) | ||
| 465 | { | ||
| 466 | if (opcode_2 == 0) | ||
| 467 | CP15[CP15_FAULT_STATUS] = value; | ||
| 468 | else if (opcode_2 == 1) | ||
| 469 | CP15[CP15_INSTR_FAULT_STATUS] = value; | ||
| 470 | } | ||
| 471 | else if (crn == 6 && opcode_1 == 0 && crm == 0) | ||
| 472 | { | ||
| 473 | if (opcode_2 == 0) | ||
| 474 | CP15[CP15_FAULT_ADDRESS] = value; | ||
| 475 | else if (opcode_2 == 1) | ||
| 476 | CP15[CP15_WFAR] = value; | ||
| 477 | } | ||
| 478 | else if (crn == 7 && opcode_1 == 0) | ||
| 479 | { | ||
| 480 | if (crm == 0 && opcode_2 == 4) | ||
| 481 | { | ||
| 482 | CP15[CP15_WAIT_FOR_INTERRUPT] = value; | ||
| 483 | } | ||
| 484 | else if (crm == 4 && opcode_2 == 0) | ||
| 485 | { | ||
| 486 | // NOTE: Not entirely accurate. This should do permission checks. | ||
| 487 | CP15[CP15_PHYS_ADDRESS] = Memory::VirtualToPhysicalAddress(value); | ||
| 488 | } | ||
| 489 | else if (crm == 5) | ||
| 490 | { | ||
| 491 | if (opcode_2 == 0) | ||
| 492 | CP15[CP15_INVALIDATE_INSTR_CACHE] = value; | ||
| 493 | else if (opcode_2 == 1) | ||
| 494 | CP15[CP15_INVALIDATE_INSTR_CACHE_USING_MVA] = value; | ||
| 495 | else if (opcode_2 == 2) | ||
| 496 | CP15[CP15_INVALIDATE_INSTR_CACHE_USING_INDEX] = value; | ||
| 497 | else if (opcode_2 == 6) | ||
| 498 | CP15[CP15_FLUSH_BRANCH_TARGET_CACHE] = value; | ||
| 499 | else if (opcode_2 == 7) | ||
| 500 | CP15[CP15_FLUSH_BRANCH_TARGET_CACHE_ENTRY] = value; | ||
| 501 | } | ||
| 502 | else if (crm == 6) | ||
| 503 | { | ||
| 504 | if (opcode_2 == 0) | ||
| 505 | CP15[CP15_INVALIDATE_DATA_CACHE] = value; | ||
| 506 | else if (opcode_2 == 1) | ||
| 507 | CP15[CP15_INVALIDATE_DATA_CACHE_LINE_USING_MVA] = value; | ||
| 508 | else if (opcode_2 == 2) | ||
| 509 | CP15[CP15_INVALIDATE_DATA_CACHE_LINE_USING_INDEX] = value; | ||
| 510 | } | ||
| 511 | else if (crm == 7 && opcode_2 == 0) | ||
| 512 | { | ||
| 513 | CP15[CP15_INVALIDATE_DATA_AND_INSTR_CACHE] = value; | ||
| 514 | } | ||
| 515 | else if (crm == 10) | ||
| 516 | { | ||
| 517 | if (opcode_2 == 0) | ||
| 518 | CP15[CP15_CLEAN_DATA_CACHE] = value; | ||
| 519 | else if (opcode_2 == 1) | ||
| 520 | CP15[CP15_CLEAN_DATA_CACHE_LINE_USING_MVA] = value; | ||
| 521 | else if (opcode_2 == 2) | ||
| 522 | CP15[CP15_CLEAN_DATA_CACHE_LINE_USING_INDEX] = value; | ||
| 523 | } | ||
| 524 | else if (crm == 14) | ||
| 525 | { | ||
| 526 | if (opcode_2 == 0) | ||
| 527 | CP15[CP15_CLEAN_AND_INVALIDATE_DATA_CACHE] = value; | ||
| 528 | else if (opcode_2 == 1) | ||
| 529 | CP15[CP15_CLEAN_AND_INVALIDATE_DATA_CACHE_LINE_USING_MVA] = value; | ||
| 530 | else if (opcode_2 == 2) | ||
| 531 | CP15[CP15_CLEAN_AND_INVALIDATE_DATA_CACHE_LINE_USING_INDEX] = value; | ||
| 532 | } | ||
| 533 | } | ||
| 534 | else if (crn == 8 && opcode_1 == 0) | ||
| 535 | { | ||
| 536 | if (crm == 5) | ||
| 537 | { | ||
| 538 | if (opcode_2 == 0) | ||
| 539 | CP15[CP15_INVALIDATE_ITLB] = value; | ||
| 540 | else if (opcode_2 == 1) | ||
| 541 | CP15[CP15_INVALIDATE_ITLB_SINGLE_ENTRY] = value; | ||
| 542 | else if (opcode_2 == 2) | ||
| 543 | CP15[CP15_INVALIDATE_ITLB_ENTRY_ON_ASID_MATCH] = value; | ||
| 544 | else if (opcode_2 == 3) | ||
| 545 | CP15[CP15_INVALIDATE_ITLB_ENTRY_ON_MVA] = value; | ||
| 546 | } | ||
| 547 | else if (crm == 6) | ||
| 548 | { | ||
| 549 | if (opcode_2 == 0) | ||
| 550 | CP15[CP15_INVALIDATE_DTLB] = value; | ||
| 551 | else if (opcode_2 == 1) | ||
| 552 | CP15[CP15_INVALIDATE_DTLB_SINGLE_ENTRY] = value; | ||
| 553 | else if (opcode_2 == 2) | ||
| 554 | CP15[CP15_INVALIDATE_DTLB_ENTRY_ON_ASID_MATCH] = value; | ||
| 555 | else if (opcode_2 == 3) | ||
| 556 | CP15[CP15_INVALIDATE_DTLB_ENTRY_ON_MVA] = value; | ||
| 557 | } | ||
| 558 | else if (crm == 7) | ||
| 559 | { | ||
| 560 | if (opcode_2 == 0) | ||
| 561 | CP15[CP15_INVALIDATE_UTLB] = value; | ||
| 562 | else if (opcode_2 == 1) | ||
| 563 | CP15[CP15_INVALIDATE_UTLB_SINGLE_ENTRY] = value; | ||
| 564 | else if (opcode_2 == 2) | ||
| 565 | CP15[CP15_INVALIDATE_UTLB_ENTRY_ON_ASID_MATCH] = value; | ||
| 566 | else if (opcode_2 == 3) | ||
| 567 | CP15[CP15_INVALIDATE_UTLB_ENTRY_ON_MVA] = value; | ||
| 568 | } | ||
| 569 | } | ||
| 570 | else if (crn == 9 && opcode_1 == 0 && crm == 0 && opcode_2 == 0) | ||
| 571 | { | ||
| 572 | CP15[CP15_DATA_CACHE_LOCKDOWN] = value; | ||
| 573 | } | ||
| 574 | else if (crn == 10 && opcode_1 == 0) | ||
| 575 | { | ||
| 576 | if (crm == 0 && opcode_2 == 0) | ||
| 577 | { | ||
| 578 | CP15[CP15_TLB_LOCKDOWN] = value; | ||
| 579 | } | ||
| 580 | else if (crm == 2) | ||
| 581 | { | ||
| 582 | if (opcode_2 == 0) | ||
| 583 | CP15[CP15_PRIMARY_REGION_REMAP] = value; | ||
| 584 | else if (opcode_2 == 1) | ||
| 585 | CP15[CP15_NORMAL_REGION_REMAP] = value; | ||
| 586 | } | ||
| 587 | } | ||
| 588 | else if (crn == 13 && opcode_1 == 0 && crm == 0) | ||
| 589 | { | ||
| 590 | if (opcode_2 == 0) | ||
| 591 | CP15[CP15_PID] = value; | ||
| 592 | else if (opcode_2 == 1) | ||
| 593 | CP15[CP15_CONTEXT_ID] = value; | ||
| 594 | else if (opcode_2 == 3) | ||
| 595 | CP15[CP15_THREAD_URO] = value; | ||
| 596 | else if (opcode_2 == 4) | ||
| 597 | CP15[CP15_THREAD_PRW] = value; | ||
| 598 | } | ||
| 599 | else if (crn == 15) | ||
| 600 | { | ||
| 601 | if (opcode_1 == 0 && crm == 12) | ||
| 602 | { | ||
| 603 | if (opcode_2 == 0) | ||
| 604 | CP15[CP15_PERFORMANCE_MONITOR_CONTROL] = value; | ||
| 605 | else if (opcode_2 == 1) | ||
| 606 | CP15[CP15_CYCLE_COUNTER] = value; | ||
| 607 | else if (opcode_2 == 2) | ||
| 608 | CP15[CP15_COUNT_0] = value; | ||
| 609 | else if (opcode_2 == 3) | ||
| 610 | CP15[CP15_COUNT_1] = value; | ||
| 611 | } | ||
| 612 | else if (opcode_1 == 5) | ||
| 613 | { | ||
| 614 | if (crm == 4) | ||
| 615 | { | ||
| 616 | if (opcode_2 == 2) | ||
| 617 | CP15[CP15_READ_MAIN_TLB_LOCKDOWN_ENTRY] = value; | ||
| 618 | else if (opcode_2 == 4) | ||
| 619 | CP15[CP15_WRITE_MAIN_TLB_LOCKDOWN_ENTRY] = value; | ||
| 620 | } | ||
| 621 | else if (crm == 5 && opcode_2 == 2) | ||
| 622 | { | ||
| 623 | CP15[CP15_MAIN_TLB_LOCKDOWN_VIRT_ADDRESS] = value; | ||
| 624 | } | ||
| 625 | else if (crm == 6 && opcode_2 == 2) | ||
| 626 | { | ||
| 627 | CP15[CP15_MAIN_TLB_LOCKDOWN_PHYS_ADDRESS] = value; | ||
| 628 | } | ||
| 629 | else if (crm == 7 && opcode_2 == 2) | ||
| 630 | { | ||
| 631 | CP15[CP15_MAIN_TLB_LOCKDOWN_ATTRIBUTE] = value; | ||
| 632 | } | ||
| 633 | } | ||
| 634 | else if (opcode_1 == 7 && crm == 1 && opcode_2 == 0) | ||
| 635 | { | ||
| 636 | CP15[CP15_TLB_DEBUG_CONTROL] = value; | ||
| 637 | } | ||
| 638 | } | ||
| 639 | } | ||
| 640 | |||
| 641 | // Unprivileged registers | ||
| 642 | if (crn == 7 && opcode_1 == 0 && crm == 5 && opcode_2 == 4) | ||
| 643 | { | ||
| 644 | CP15[CP15_FLUSH_PREFETCH_BUFFER] = value; | ||
| 645 | } | ||
| 646 | else if (crn == 7 && opcode_1 == 0 && crm == 10) | ||
| 647 | { | ||
| 648 | if (opcode_2 == 4) | ||
| 649 | CP15[CP15_DATA_SYNC_BARRIER] = value; | ||
| 650 | else if (opcode_2 == 5) | ||
| 651 | CP15[CP15_DATA_MEMORY_BARRIER] = value; | ||
| 652 | } | ||
| 653 | else if (crn == 13 && opcode_1 == 0 && crm == 0 && opcode_2 == 2) | ||
| 654 | { | ||
| 655 | CP15[CP15_THREAD_UPRW] = value; | ||
| 656 | } | ||
| 657 | } | ||
diff --git a/src/core/arm/skyeye_common/armstate.h b/src/core/arm/skyeye_common/armstate.h new file mode 100644 index 000000000..b364e2621 --- /dev/null +++ b/src/core/arm/skyeye_common/armstate.h | |||
| @@ -0,0 +1,252 @@ | |||
| 1 | /* armdefs.h -- ARMulator common definitions: ARM6 Instruction Emulator. | ||
| 2 | Copyright (C) 1994 Advanced RISC Machines Ltd. | ||
| 3 | |||
| 4 | This program is free software; you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation; either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program; if not, write to the Free Software | ||
| 16 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | ||
| 17 | |||
| 18 | #pragma once | ||
| 19 | |||
| 20 | #include <array> | ||
| 21 | #include <unordered_map> | ||
| 22 | |||
| 23 | #include "common/common_types.h" | ||
| 24 | #include "core/arm/skyeye_common/arm_regformat.h" | ||
| 25 | |||
| 26 | // Signal levels | ||
| 27 | enum { | ||
| 28 | LOW = 0, | ||
| 29 | HIGH = 1, | ||
| 30 | LOWHIGH = 1, | ||
| 31 | HIGHLOW = 2 | ||
| 32 | }; | ||
| 33 | |||
| 34 | // Cache types | ||
| 35 | enum { | ||
| 36 | NONCACHE = 0, | ||
| 37 | DATACACHE = 1, | ||
| 38 | INSTCACHE = 2, | ||
| 39 | }; | ||
| 40 | |||
| 41 | // ARM privilege modes | ||
| 42 | enum PrivilegeMode { | ||
| 43 | USER32MODE = 16, | ||
| 44 | FIQ32MODE = 17, | ||
| 45 | IRQ32MODE = 18, | ||
| 46 | SVC32MODE = 19, | ||
| 47 | ABORT32MODE = 23, | ||
| 48 | UNDEF32MODE = 27, | ||
| 49 | SYSTEM32MODE = 31 | ||
| 50 | }; | ||
| 51 | |||
| 52 | // ARM privilege mode register banks | ||
| 53 | enum { | ||
| 54 | USERBANK = 0, | ||
| 55 | FIQBANK = 1, | ||
| 56 | IRQBANK = 2, | ||
| 57 | SVCBANK = 3, | ||
| 58 | ABORTBANK = 4, | ||
| 59 | UNDEFBANK = 5, | ||
| 60 | DUMMYBANK = 6, | ||
| 61 | SYSTEMBANK = 7 | ||
| 62 | }; | ||
| 63 | |||
| 64 | // Hardware vector addresses | ||
| 65 | enum { | ||
| 66 | ARMResetV = 0, | ||
| 67 | ARMUndefinedInstrV = 4, | ||
| 68 | ARMSWIV = 8, | ||
| 69 | ARMPrefetchAbortV = 12, | ||
| 70 | ARMDataAbortV = 16, | ||
| 71 | ARMAddrExceptnV = 20, | ||
| 72 | ARMIRQV = 24, | ||
| 73 | ARMFIQV = 28, | ||
| 74 | ARMErrorV = 32, // This is an offset, not an address! | ||
| 75 | |||
| 76 | ARMul_ResetV = ARMResetV, | ||
| 77 | ARMul_UndefinedInstrV = ARMUndefinedInstrV, | ||
| 78 | ARMul_SWIV = ARMSWIV, | ||
| 79 | ARMul_PrefetchAbortV = ARMPrefetchAbortV, | ||
| 80 | ARMul_DataAbortV = ARMDataAbortV, | ||
| 81 | ARMul_AddrExceptnV = ARMAddrExceptnV, | ||
| 82 | ARMul_IRQV = ARMIRQV, | ||
| 83 | ARMul_FIQV = ARMFIQV | ||
| 84 | }; | ||
| 85 | |||
| 86 | // Coprocessor status values | ||
| 87 | enum { | ||
| 88 | ARMul_FIRST = 0, | ||
| 89 | ARMul_TRANSFER = 1, | ||
| 90 | ARMul_BUSY = 2, | ||
| 91 | ARMul_DATA = 3, | ||
| 92 | ARMul_INTERRUPT = 4, | ||
| 93 | ARMul_DONE = 0, | ||
| 94 | ARMul_CANT = 1, | ||
| 95 | ARMul_INC = 3 | ||
| 96 | }; | ||
| 97 | |||
| 98 | // Instruction condition codes | ||
| 99 | enum ConditionCode { | ||
| 100 | EQ = 0, | ||
| 101 | NE = 1, | ||
| 102 | CS = 2, | ||
| 103 | CC = 3, | ||
| 104 | MI = 4, | ||
| 105 | PL = 5, | ||
| 106 | VS = 6, | ||
| 107 | VC = 7, | ||
| 108 | HI = 8, | ||
| 109 | LS = 9, | ||
| 110 | GE = 10, | ||
| 111 | LT = 11, | ||
| 112 | GT = 12, | ||
| 113 | LE = 13, | ||
| 114 | AL = 14, | ||
| 115 | NV = 15, | ||
| 116 | }; | ||
| 117 | |||
| 118 | // Flags for use with the APSR. | ||
| 119 | enum : u32 { | ||
| 120 | NBIT = (1U << 31U), | ||
| 121 | ZBIT = (1 << 30), | ||
| 122 | CBIT = (1 << 29), | ||
| 123 | VBIT = (1 << 28), | ||
| 124 | QBIT = (1 << 27), | ||
| 125 | JBIT = (1 << 24), | ||
| 126 | EBIT = (1 << 9), | ||
| 127 | ABIT = (1 << 8), | ||
| 128 | IBIT = (1 << 7), | ||
| 129 | FBIT = (1 << 6), | ||
| 130 | TBIT = (1 << 5), | ||
| 131 | |||
| 132 | // Masks for groups of bits in the APSR. | ||
| 133 | MODEBITS = 0x1F, | ||
| 134 | INTBITS = 0x1C0, | ||
| 135 | }; | ||
| 136 | |||
| 137 | // Values for Emulate. | ||
| 138 | enum { | ||
| 139 | STOP = 0, // Stop | ||
| 140 | CHANGEMODE = 1, // Change mode | ||
| 141 | ONCE = 2, // Execute just one iteration | ||
| 142 | RUN = 3 // Continuous execution | ||
| 143 | }; | ||
| 144 | |||
| 145 | |||
| 146 | struct ARMul_State final | ||
| 147 | { | ||
| 148 | public: | ||
| 149 | explicit ARMul_State(PrivilegeMode initial_mode); | ||
| 150 | |||
| 151 | void ChangePrivilegeMode(u32 new_mode); | ||
| 152 | void Reset(); | ||
| 153 | |||
| 154 | // Reads/writes data in big/little endian format based on the | ||
| 155 | // state of the E (endian) bit in the APSR. | ||
| 156 | u16 ReadMemory16(u32 address) const; | ||
| 157 | u32 ReadMemory32(u32 address) const; | ||
| 158 | u64 ReadMemory64(u32 address) const; | ||
| 159 | void WriteMemory16(u32 address, u16 data); | ||
| 160 | void WriteMemory32(u32 address, u32 data); | ||
| 161 | void WriteMemory64(u32 address, u64 data); | ||
| 162 | |||
| 163 | u32 ReadCP15Register(u32 crn, u32 opcode_1, u32 crm, u32 opcode_2) const; | ||
| 164 | void WriteCP15Register(u32 value, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2); | ||
| 165 | |||
| 166 | // Exclusive memory access functions | ||
| 167 | bool IsExclusiveMemoryAccess(u32 address) const { | ||
| 168 | return exclusive_state && exclusive_tag == (address & RESERVATION_GRANULE_MASK); | ||
| 169 | } | ||
| 170 | void SetExclusiveMemoryAddress(u32 address) { | ||
| 171 | exclusive_tag = address & RESERVATION_GRANULE_MASK; | ||
| 172 | exclusive_state = true; | ||
| 173 | } | ||
| 174 | void UnsetExclusiveMemoryAddress() { | ||
| 175 | exclusive_tag = 0xFFFFFFFF; | ||
| 176 | exclusive_state = false; | ||
| 177 | } | ||
| 178 | |||
| 179 | // Whether or not the given CPU is in big endian mode (E bit is set) | ||
| 180 | bool InBigEndianMode() const { | ||
| 181 | return (Cpsr & (1 << 9)) != 0; | ||
| 182 | } | ||
| 183 | // Whether or not the given CPU is in a mode other than user mode. | ||
| 184 | bool InAPrivilegedMode() const { | ||
| 185 | return (Mode != USER32MODE); | ||
| 186 | } | ||
| 187 | // Note that for the 3DS, a Thumb instruction will only ever be | ||
| 188 | // two bytes in size. Thus we don't need to worry about ThumbEE | ||
| 189 | // or Thumb-2 where instructions can be 4 bytes in length. | ||
| 190 | u32 GetInstructionSize() const { | ||
| 191 | return TFlag ? 2 : 4; | ||
| 192 | } | ||
| 193 | |||
| 194 | std::array<u32, 16> Reg; // The current register file | ||
| 195 | std::array<u32, 2> Reg_usr; | ||
| 196 | std::array<u32, 2> Reg_svc; // R13_SVC R14_SVC | ||
| 197 | std::array<u32, 2> Reg_abort; // R13_ABORT R14_ABORT | ||
| 198 | std::array<u32, 2> Reg_undef; // R13 UNDEF R14 UNDEF | ||
| 199 | std::array<u32, 2> Reg_irq; // R13_IRQ R14_IRQ | ||
| 200 | std::array<u32, 7> Reg_firq; // R8---R14 FIRQ | ||
| 201 | std::array<u32, 7> Spsr; // The exception psr's | ||
| 202 | std::array<u32, CP15_REGISTER_COUNT> CP15; | ||
| 203 | |||
| 204 | // FPSID, FPSCR, and FPEXC | ||
| 205 | std::array<u32, VFP_SYSTEM_REGISTER_COUNT> VFP; | ||
| 206 | |||
| 207 | // VFPv2 and VFPv3-D16 has 16 doubleword registers (D0-D16 or S0-S31). | ||
| 208 | // VFPv3-D32/ASIMD may have up to 32 doubleword registers (D0-D31), | ||
| 209 | // and only 32 singleword registers are accessible (S0-S31). | ||
| 210 | std::array<u32, 64> ExtReg; | ||
| 211 | |||
| 212 | u32 Emulate; // To start and stop emulation | ||
| 213 | u32 Cpsr; // The current PSR | ||
| 214 | u32 Spsr_copy; | ||
| 215 | u32 phys_pc; | ||
| 216 | |||
| 217 | u32 Mode; // The current mode | ||
| 218 | u32 Bank; // The current register bank | ||
| 219 | |||
| 220 | u32 NFlag, ZFlag, CFlag, VFlag, IFFlags; // Dummy flags for speed | ||
| 221 | unsigned int shifter_carry_out; | ||
| 222 | |||
| 223 | u32 TFlag; // Thumb state | ||
| 224 | |||
| 225 | unsigned long long NumInstrs; // The number of instructions executed | ||
| 226 | unsigned NumInstrsToExecute; | ||
| 227 | |||
| 228 | unsigned NresetSig; // Reset the processor | ||
| 229 | unsigned NfiqSig; | ||
| 230 | unsigned NirqSig; | ||
| 231 | |||
| 232 | unsigned abortSig; | ||
| 233 | unsigned NtransSig; | ||
| 234 | unsigned bigendSig; | ||
| 235 | unsigned syscallSig; | ||
| 236 | |||
| 237 | // TODO(bunnei): Move this cache to a better place - it should be per codeset (likely per | ||
| 238 | // process for our purposes), not per ARMul_State (which tracks CPU core state). | ||
| 239 | std::unordered_map<u32, int> instruction_cache; | ||
| 240 | |||
| 241 | private: | ||
| 242 | void ResetMPCoreCP15Registers(); | ||
| 243 | |||
| 244 | // Defines a reservation granule of 2 words, which protects the first 2 words starting at the tag. | ||
| 245 | // This is the smallest granule allowed by the v7 spec, and is coincidentally just large enough to | ||
| 246 | // support LDR/STREXD. | ||
| 247 | static const u32 RESERVATION_GRANULE_MASK = 0xFFFFFFF8; | ||
| 248 | |||
| 249 | u32 exclusive_tag; // The address for which the local monitor is in exclusive access mode | ||
| 250 | u32 exclusive_result; | ||
| 251 | bool exclusive_state; | ||
| 252 | }; | ||
diff --git a/src/core/arm/skyeye_common/armsupp.cpp b/src/core/arm/skyeye_common/armsupp.cpp new file mode 100644 index 000000000..d31fb9449 --- /dev/null +++ b/src/core/arm/skyeye_common/armsupp.cpp | |||
| @@ -0,0 +1,208 @@ | |||
| 1 | /* armsupp.c -- ARMulator support code: ARM6 Instruction Emulator. | ||
| 2 | Copyright (C) 1994 Advanced RISC Machines Ltd. | ||
| 3 | |||
| 4 | This program is free software; you can redistribute it and/or modify | ||
| 5 | it under the terms of the GNU General Public License as published by | ||
| 6 | the Free Software Foundation; either version 2 of the License, or | ||
| 7 | (at your option) any later version. | ||
| 8 | |||
| 9 | This program is distributed in the hope that it will be useful, | ||
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | GNU General Public License for more details. | ||
| 13 | |||
| 14 | You should have received a copy of the GNU General Public License | ||
| 15 | along with this program; if not, write to the Free Software | ||
| 16 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | ||
| 17 | |||
| 18 | #include "common/logging/log.h" | ||
| 19 | |||
| 20 | #include "core/mem_map.h" | ||
| 21 | #include "core/arm/skyeye_common/arm_regformat.h" | ||
| 22 | #include "core/arm/skyeye_common/armstate.h" | ||
| 23 | #include "core/arm/skyeye_common/armsupp.h" | ||
| 24 | |||
| 25 | // Unsigned sum of absolute difference | ||
| 26 | u8 ARMul_UnsignedAbsoluteDifference(u8 left, u8 right) | ||
| 27 | { | ||
| 28 | if (left > right) | ||
| 29 | return left - right; | ||
| 30 | |||
| 31 | return right - left; | ||
| 32 | } | ||
| 33 | |||
| 34 | // Add with carry, indicates if a carry-out or signed overflow occurred. | ||
| 35 | u32 AddWithCarry(u32 left, u32 right, u32 carry_in, bool* carry_out_occurred, bool* overflow_occurred) | ||
| 36 | { | ||
| 37 | u64 unsigned_sum = (u64)left + (u64)right + (u64)carry_in; | ||
| 38 | s64 signed_sum = (s64)(s32)left + (s64)(s32)right + (s64)carry_in; | ||
| 39 | u64 result = (unsigned_sum & 0xFFFFFFFF); | ||
| 40 | |||
| 41 | if (carry_out_occurred) | ||
| 42 | *carry_out_occurred = (result != unsigned_sum); | ||
| 43 | |||
| 44 | if (overflow_occurred) | ||
| 45 | *overflow_occurred = ((s64)(s32)result != signed_sum); | ||
| 46 | |||
| 47 | return (u32)result; | ||
| 48 | } | ||
| 49 | |||
| 50 | // Compute whether an addition of A and B, giving RESULT, overflowed. | ||
| 51 | bool AddOverflow(u32 a, u32 b, u32 result) | ||
| 52 | { | ||
| 53 | return ((NEG(a) && NEG(b) && POS(result)) || | ||
| 54 | (POS(a) && POS(b) && NEG(result))); | ||
| 55 | } | ||
| 56 | |||
| 57 | // Compute whether a subtraction of A and B, giving RESULT, overflowed. | ||
| 58 | bool SubOverflow(u32 a, u32 b, u32 result) | ||
| 59 | { | ||
| 60 | return ((NEG(a) && POS(b) && POS(result)) || | ||
| 61 | (POS(a) && NEG(b) && NEG(result))); | ||
| 62 | } | ||
| 63 | |||
| 64 | // Returns true if the Q flag should be set as a result of overflow. | ||
| 65 | bool ARMul_AddOverflowQ(u32 a, u32 b) | ||
| 66 | { | ||
| 67 | u32 result = a + b; | ||
| 68 | if (((result ^ a) & (u32)0x80000000) && ((a ^ b) & (u32)0x80000000) == 0) | ||
| 69 | return true; | ||
| 70 | |||
| 71 | return false; | ||
| 72 | } | ||
| 73 | |||
| 74 | // 8-bit signed saturated addition | ||
| 75 | u8 ARMul_SignedSaturatedAdd8(u8 left, u8 right) | ||
| 76 | { | ||
| 77 | u8 result = left + right; | ||
| 78 | |||
| 79 | if (((result ^ left) & 0x80) && ((left ^ right) & 0x80) == 0) { | ||
| 80 | if (left & 0x80) | ||
| 81 | result = 0x80; | ||
| 82 | else | ||
| 83 | result = 0x7F; | ||
| 84 | } | ||
| 85 | |||
| 86 | return result; | ||
| 87 | } | ||
| 88 | |||
| 89 | // 8-bit signed saturated subtraction | ||
| 90 | u8 ARMul_SignedSaturatedSub8(u8 left, u8 right) | ||
| 91 | { | ||
| 92 | u8 result = left - right; | ||
| 93 | |||
| 94 | if (((result ^ left) & 0x80) && ((left ^ right) & 0x80) != 0) { | ||
| 95 | if (left & 0x80) | ||
| 96 | result = 0x80; | ||
| 97 | else | ||
| 98 | result = 0x7F; | ||
| 99 | } | ||
| 100 | |||
| 101 | return result; | ||
| 102 | } | ||
| 103 | |||
| 104 | // 16-bit signed saturated addition | ||
| 105 | u16 ARMul_SignedSaturatedAdd16(u16 left, u16 right) | ||
| 106 | { | ||
| 107 | u16 result = left + right; | ||
| 108 | |||
| 109 | if (((result ^ left) & 0x8000) && ((left ^ right) & 0x8000) == 0) { | ||
| 110 | if (left & 0x8000) | ||
| 111 | result = 0x8000; | ||
| 112 | else | ||
| 113 | result = 0x7FFF; | ||
| 114 | } | ||
| 115 | |||
| 116 | return result; | ||
| 117 | } | ||
| 118 | |||
| 119 | // 16-bit signed saturated subtraction | ||
| 120 | u16 ARMul_SignedSaturatedSub16(u16 left, u16 right) | ||
| 121 | { | ||
| 122 | u16 result = left - right; | ||
| 123 | |||
| 124 | if (((result ^ left) & 0x8000) && ((left ^ right) & 0x8000) != 0) { | ||
| 125 | if (left & 0x8000) | ||
| 126 | result = 0x8000; | ||
| 127 | else | ||
| 128 | result = 0x7FFF; | ||
| 129 | } | ||
| 130 | |||
| 131 | return result; | ||
| 132 | } | ||
| 133 | |||
| 134 | // 8-bit unsigned saturated addition | ||
| 135 | u8 ARMul_UnsignedSaturatedAdd8(u8 left, u8 right) | ||
| 136 | { | ||
| 137 | u8 result = left + right; | ||
| 138 | |||
| 139 | if (result < left) | ||
| 140 | result = 0xFF; | ||
| 141 | |||
| 142 | return result; | ||
| 143 | } | ||
| 144 | |||
| 145 | // 16-bit unsigned saturated addition | ||
| 146 | u16 ARMul_UnsignedSaturatedAdd16(u16 left, u16 right) | ||
| 147 | { | ||
| 148 | u16 result = left + right; | ||
| 149 | |||
| 150 | if (result < left) | ||
| 151 | result = 0xFFFF; | ||
| 152 | |||
| 153 | return result; | ||
| 154 | } | ||
| 155 | |||
| 156 | // 8-bit unsigned saturated subtraction | ||
| 157 | u8 ARMul_UnsignedSaturatedSub8(u8 left, u8 right) | ||
| 158 | { | ||
| 159 | if (left <= right) | ||
| 160 | return 0; | ||
| 161 | |||
| 162 | return left - right; | ||
| 163 | } | ||
| 164 | |||
| 165 | // 16-bit unsigned saturated subtraction | ||
| 166 | u16 ARMul_UnsignedSaturatedSub16(u16 left, u16 right) | ||
| 167 | { | ||
| 168 | if (left <= right) | ||
| 169 | return 0; | ||
| 170 | |||
| 171 | return left - right; | ||
| 172 | } | ||
| 173 | |||
| 174 | // Signed saturation. | ||
| 175 | u32 ARMul_SignedSatQ(s32 value, u8 shift, bool* saturation_occurred) | ||
| 176 | { | ||
| 177 | const u32 max = (1 << shift) - 1; | ||
| 178 | const s32 top = (value >> shift); | ||
| 179 | |||
| 180 | if (top > 0) { | ||
| 181 | *saturation_occurred = true; | ||
| 182 | return max; | ||
| 183 | } | ||
| 184 | else if (top < -1) { | ||
| 185 | *saturation_occurred = true; | ||
| 186 | return ~max; | ||
| 187 | } | ||
| 188 | |||
| 189 | *saturation_occurred = false; | ||
| 190 | return (u32)value; | ||
| 191 | } | ||
| 192 | |||
| 193 | // Unsigned saturation | ||
| 194 | u32 ARMul_UnsignedSatQ(s32 value, u8 shift, bool* saturation_occurred) | ||
| 195 | { | ||
| 196 | const u32 max = (1 << shift) - 1; | ||
| 197 | |||
| 198 | if (value < 0) { | ||
| 199 | *saturation_occurred = true; | ||
| 200 | return 0; | ||
| 201 | } else if ((u32)value > max) { | ||
| 202 | *saturation_occurred = true; | ||
| 203 | return max; | ||
| 204 | } | ||
| 205 | |||
| 206 | *saturation_occurred = false; | ||
| 207 | return (u32)value; | ||
| 208 | } | ||
diff --git a/src/core/arm/skyeye_common/armsupp.h b/src/core/arm/skyeye_common/armsupp.h new file mode 100644 index 000000000..391309fa8 --- /dev/null +++ b/src/core/arm/skyeye_common/armsupp.h | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "common/common_types.h" | ||
| 8 | |||
| 9 | #define BITS(s, a, b) ((s << ((sizeof(s) * 8 - 1) - b)) >> (sizeof(s) * 8 - b + a - 1)) | ||
| 10 | #define BIT(s, n) ((s >> (n)) & 1) | ||
| 11 | |||
| 12 | #define POS(i) ( (~(i)) >> 31 ) | ||
| 13 | #define NEG(i) ( (i) >> 31 ) | ||
| 14 | |||
| 15 | bool AddOverflow(u32, u32, u32); | ||
| 16 | bool SubOverflow(u32, u32, u32); | ||
| 17 | |||
| 18 | u32 AddWithCarry(u32, u32, u32, bool*, bool*); | ||
| 19 | bool ARMul_AddOverflowQ(u32, u32); | ||
| 20 | |||
| 21 | u8 ARMul_SignedSaturatedAdd8(u8, u8); | ||
| 22 | u8 ARMul_SignedSaturatedSub8(u8, u8); | ||
| 23 | u16 ARMul_SignedSaturatedAdd16(u16, u16); | ||
| 24 | u16 ARMul_SignedSaturatedSub16(u16, u16); | ||
| 25 | |||
| 26 | u8 ARMul_UnsignedSaturatedAdd8(u8, u8); | ||
| 27 | u16 ARMul_UnsignedSaturatedAdd16(u16, u16); | ||
| 28 | u8 ARMul_UnsignedSaturatedSub8(u8, u8); | ||
| 29 | u16 ARMul_UnsignedSaturatedSub16(u16, u16); | ||
| 30 | u8 ARMul_UnsignedAbsoluteDifference(u8, u8); | ||
| 31 | u32 ARMul_SignedSatQ(s32, u8, bool*); | ||
| 32 | u32 ARMul_UnsignedSatQ(s32, u8, bool*); | ||
diff --git a/src/core/arm/skyeye_common/vfp/vfp.cpp b/src/core/arm/skyeye_common/vfp/vfp.cpp index 1ffc1f9af..26f303de4 100644 --- a/src/core/arm/skyeye_common/vfp/vfp.cpp +++ b/src/core/arm/skyeye_common/vfp/vfp.cpp | |||
| @@ -23,7 +23,7 @@ | |||
| 23 | #include "common/common_funcs.h" | 23 | #include "common/common_funcs.h" |
| 24 | #include "common/logging/log.h" | 24 | #include "common/logging/log.h" |
| 25 | 25 | ||
| 26 | #include "core/arm/skyeye_common/armdefs.h" | 26 | #include "core/arm/skyeye_common/armstate.h" |
| 27 | #include "core/arm/skyeye_common/vfp/asm_vfp.h" | 27 | #include "core/arm/skyeye_common/vfp/asm_vfp.h" |
| 28 | #include "core/arm/skyeye_common/vfp/vfp.h" | 28 | #include "core/arm/skyeye_common/vfp/vfp.h" |
| 29 | 29 | ||
| @@ -43,7 +43,7 @@ void VFPInit(ARMul_State* state) | |||
| 43 | state->VFP[VFP_MVFR1] = 0; | 43 | state->VFP[VFP_MVFR1] = 0; |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | void VMOVBRS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword n, ARMword* value) | 46 | void VMOVBRS(ARMul_State* state, u32 to_arm, u32 t, u32 n, u32* value) |
| 47 | { | 47 | { |
| 48 | if (to_arm) | 48 | if (to_arm) |
| 49 | { | 49 | { |
| @@ -55,7 +55,7 @@ void VMOVBRS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword n, ARMword* | |||
| 55 | } | 55 | } |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | void VMOVBRRD(ARMul_State* state, ARMword to_arm, ARMword t, ARMword t2, ARMword n, ARMword* value1, ARMword* value2) | 58 | void VMOVBRRD(ARMul_State* state, u32 to_arm, u32 t, u32 t2, u32 n, u32* value1, u32* value2) |
| 59 | { | 59 | { |
| 60 | if (to_arm) | 60 | if (to_arm) |
| 61 | { | 61 | { |
| @@ -68,7 +68,7 @@ void VMOVBRRD(ARMul_State* state, ARMword to_arm, ARMword t, ARMword t2, ARMword | |||
| 68 | state->ExtReg[n*2] = *value1; | 68 | state->ExtReg[n*2] = *value1; |
| 69 | } | 69 | } |
| 70 | } | 70 | } |
| 71 | void VMOVBRRSS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword t2, ARMword n, ARMword* value1, ARMword* value2) | 71 | void VMOVBRRSS(ARMul_State* state, u32 to_arm, u32 t, u32 t2, u32 n, u32* value1, u32* value2) |
| 72 | { | 72 | { |
| 73 | if (to_arm) | 73 | if (to_arm) |
| 74 | { | 74 | { |
| @@ -82,7 +82,7 @@ void VMOVBRRSS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword t2, ARMwor | |||
| 82 | } | 82 | } |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | void VMOVI(ARMul_State* state, ARMword single, ARMword d, ARMword imm) | 85 | void VMOVI(ARMul_State* state, u32 single, u32 d, u32 imm) |
| 86 | { | 86 | { |
| 87 | if (single) | 87 | if (single) |
| 88 | { | 88 | { |
| @@ -95,7 +95,7 @@ void VMOVI(ARMul_State* state, ARMword single, ARMword d, ARMword imm) | |||
| 95 | state->ExtReg[d*2] = 0; | 95 | state->ExtReg[d*2] = 0; |
| 96 | } | 96 | } |
| 97 | } | 97 | } |
| 98 | void VMOVR(ARMul_State* state, ARMword single, ARMword d, ARMword m) | 98 | void VMOVR(ARMul_State* state, u32 single, u32 d, u32 m) |
| 99 | { | 99 | { |
| 100 | if (single) | 100 | if (single) |
| 101 | { | 101 | { |
diff --git a/src/core/arm/skyeye_common/vfp/vfp.h b/src/core/arm/skyeye_common/vfp/vfp.h index 80ca93ccd..88908da9f 100644 --- a/src/core/arm/skyeye_common/vfp/vfp.h +++ b/src/core/arm/skyeye_common/vfp/vfp.h | |||
| @@ -36,8 +36,8 @@ void vfp_raise_exceptions(ARMul_State* state, u32 exceptions, u32 inst, u32 fpsc | |||
| 36 | u32 vfp_single_cpdo(ARMul_State* state, u32 inst, u32 fpscr); | 36 | u32 vfp_single_cpdo(ARMul_State* state, u32 inst, u32 fpscr); |
| 37 | u32 vfp_double_cpdo(ARMul_State* state, u32 inst, u32 fpscr); | 37 | u32 vfp_double_cpdo(ARMul_State* state, u32 inst, u32 fpscr); |
| 38 | 38 | ||
| 39 | void VMOVBRS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword n, ARMword* value); | 39 | void VMOVBRS(ARMul_State* state, u32 to_arm, u32 t, u32 n, u32* value); |
| 40 | void VMOVBRRD(ARMul_State* state, ARMword to_arm, ARMword t, ARMword t2, ARMword n, ARMword* value1, ARMword* value2); | 40 | void VMOVBRRD(ARMul_State* state, u32 to_arm, u32 t, u32 t2, u32 n, u32* value1, u32* value2); |
| 41 | void VMOVBRRSS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword t2, ARMword n, ARMword* value1, ARMword* value2); | 41 | void VMOVBRRSS(ARMul_State* state, u32 to_arm, u32 t, u32 t2, u32 n, u32* value1, u32* value2); |
| 42 | void VMOVI(ARMul_State* state, ARMword single, ARMword d, ARMword imm); | 42 | void VMOVI(ARMul_State* state, u32 single, u32 d, u32 imm); |
| 43 | void VMOVR(ARMul_State* state, ARMword single, ARMword d, ARMword imm); | 43 | void VMOVR(ARMul_State* state, u32 single, u32 d, u32 imm); |
diff --git a/src/core/arm/skyeye_common/vfp/vfp_helper.h b/src/core/arm/skyeye_common/vfp/vfp_helper.h index 2007d6dc4..91a8d4d57 100644 --- a/src/core/arm/skyeye_common/vfp/vfp_helper.h +++ b/src/core/arm/skyeye_common/vfp/vfp_helper.h | |||
| @@ -34,7 +34,7 @@ | |||
| 34 | 34 | ||
| 35 | #include <cstdio> | 35 | #include <cstdio> |
| 36 | #include "common/common_types.h" | 36 | #include "common/common_types.h" |
| 37 | #include "core/arm/skyeye_common/armdefs.h" | 37 | #include "core/arm/skyeye_common/armstate.h" |
| 38 | #include "core/arm/skyeye_common/vfp/asm_vfp.h" | 38 | #include "core/arm/skyeye_common/vfp/asm_vfp.h" |
| 39 | 39 | ||
| 40 | #define do_div(n, base) {n/=base;} | 40 | #define do_div(n, base) {n/=base;} |
| @@ -415,7 +415,7 @@ struct op { | |||
| 415 | u32 flags; | 415 | u32 flags; |
| 416 | }; | 416 | }; |
| 417 | 417 | ||
| 418 | static inline u32 fls(ARMword x) | 418 | static inline u32 fls(u32 x) |
| 419 | { | 419 | { |
| 420 | int r = 32; | 420 | int r = 32; |
| 421 | 421 | ||
diff --git a/src/core/arm/skyeye_common/vfp/vfpdouble.cpp b/src/core/arm/skyeye_common/vfp/vfpdouble.cpp index f91049585..1d844a66e 100644 --- a/src/core/arm/skyeye_common/vfp/vfpdouble.cpp +++ b/src/core/arm/skyeye_common/vfp/vfpdouble.cpp | |||
| @@ -70,9 +70,9 @@ static void vfp_double_dump(const char *str, struct vfp_double *d) | |||
| 70 | 70 | ||
| 71 | static void vfp_double_normalise_denormal(struct vfp_double *vd) | 71 | static void vfp_double_normalise_denormal(struct vfp_double *vd) |
| 72 | { | 72 | { |
| 73 | int bits = 31 - fls((ARMword)(vd->significand >> 32)); | 73 | int bits = 31 - fls((u32)(vd->significand >> 32)); |
| 74 | if (bits == 31) | 74 | if (bits == 31) |
| 75 | bits = 63 - fls((ARMword)vd->significand); | 75 | bits = 63 - fls((u32)vd->significand); |
| 76 | 76 | ||
| 77 | vfp_double_dump("normalise_denormal: in", vd); | 77 | vfp_double_dump("normalise_denormal: in", vd); |
| 78 | 78 | ||
| @@ -109,9 +109,9 @@ u32 vfp_double_normaliseround(ARMul_State* state, int dd, struct vfp_double *vd, | |||
| 109 | exponent = vd->exponent; | 109 | exponent = vd->exponent; |
| 110 | significand = vd->significand; | 110 | significand = vd->significand; |
| 111 | 111 | ||
| 112 | shift = 32 - fls((ARMword)(significand >> 32)); | 112 | shift = 32 - fls((u32)(significand >> 32)); |
| 113 | if (shift == 32) | 113 | if (shift == 32) |
| 114 | shift = 64 - fls((ARMword)significand); | 114 | shift = 64 - fls((u32)significand); |
| 115 | if (shift) { | 115 | if (shift) { |
| 116 | exponent -= shift; | 116 | exponent -= shift; |
| 117 | significand <<= shift; | 117 | significand <<= shift; |
| @@ -566,7 +566,7 @@ static u32 vfp_double_ftoui(ARMul_State* state, int sd, int unused, int dm, u32 | |||
| 566 | /* | 566 | /* |
| 567 | * 2^0 <= m < 2^32-2^8 | 567 | * 2^0 <= m < 2^32-2^8 |
| 568 | */ | 568 | */ |
| 569 | d = (ARMword)((vdm.significand << 1) >> shift); | 569 | d = (u32)((vdm.significand << 1) >> shift); |
| 570 | rem = vdm.significand << (65 - shift); | 570 | rem = vdm.significand << (65 - shift); |
| 571 | 571 | ||
| 572 | if (rmode == FPSCR_ROUND_NEAREST) { | 572 | if (rmode == FPSCR_ROUND_NEAREST) { |
| @@ -647,7 +647,7 @@ static u32 vfp_double_ftosi(ARMul_State* state, int sd, int unused, int dm, u32 | |||
| 647 | int shift = 1023 + 63 - vdm.exponent; /* 58 */ | 647 | int shift = 1023 + 63 - vdm.exponent; /* 58 */ |
| 648 | u64 rem, incr = 0; | 648 | u64 rem, incr = 0; |
| 649 | 649 | ||
| 650 | d = (ARMword)((vdm.significand << 1) >> shift); | 650 | d = (u32)((vdm.significand << 1) >> shift); |
| 651 | rem = vdm.significand << (65 - shift); | 651 | rem = vdm.significand << (65 - shift); |
| 652 | 652 | ||
| 653 | if (rmode == FPSCR_ROUND_NEAREST) { | 653 | if (rmode == FPSCR_ROUND_NEAREST) { |
diff --git a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp index 8efcbab1c..9b99fc5bc 100644 --- a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp +++ b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp | |||
| @@ -51,7 +51,7 @@ VMLA_INST: | |||
| 51 | 51 | ||
| 52 | CHECK_VFP_CDP_RET; | 52 | CHECK_VFP_CDP_RET; |
| 53 | } | 53 | } |
| 54 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 54 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 55 | INC_PC(sizeof(vmla_inst)); | 55 | INC_PC(sizeof(vmla_inst)); |
| 56 | FETCH_INST; | 56 | FETCH_INST; |
| 57 | GOTO_NEXT_INST; | 57 | GOTO_NEXT_INST; |
| @@ -100,7 +100,7 @@ VMLS_INST: | |||
| 100 | 100 | ||
| 101 | CHECK_VFP_CDP_RET; | 101 | CHECK_VFP_CDP_RET; |
| 102 | } | 102 | } |
| 103 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 103 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 104 | INC_PC(sizeof(vmls_inst)); | 104 | INC_PC(sizeof(vmls_inst)); |
| 105 | FETCH_INST; | 105 | FETCH_INST; |
| 106 | GOTO_NEXT_INST; | 106 | GOTO_NEXT_INST; |
| @@ -149,7 +149,7 @@ VNMLA_INST: | |||
| 149 | 149 | ||
| 150 | CHECK_VFP_CDP_RET; | 150 | CHECK_VFP_CDP_RET; |
| 151 | } | 151 | } |
| 152 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 152 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 153 | INC_PC(sizeof(vnmla_inst)); | 153 | INC_PC(sizeof(vnmla_inst)); |
| 154 | FETCH_INST; | 154 | FETCH_INST; |
| 155 | GOTO_NEXT_INST; | 155 | GOTO_NEXT_INST; |
| @@ -199,7 +199,7 @@ VNMLS_INST: | |||
| 199 | 199 | ||
| 200 | CHECK_VFP_CDP_RET; | 200 | CHECK_VFP_CDP_RET; |
| 201 | } | 201 | } |
| 202 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 202 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 203 | INC_PC(sizeof(vnmls_inst)); | 203 | INC_PC(sizeof(vnmls_inst)); |
| 204 | FETCH_INST; | 204 | FETCH_INST; |
| 205 | GOTO_NEXT_INST; | 205 | GOTO_NEXT_INST; |
| @@ -248,7 +248,7 @@ VNMUL_INST: | |||
| 248 | 248 | ||
| 249 | CHECK_VFP_CDP_RET; | 249 | CHECK_VFP_CDP_RET; |
| 250 | } | 250 | } |
| 251 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 251 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 252 | INC_PC(sizeof(vnmul_inst)); | 252 | INC_PC(sizeof(vnmul_inst)); |
| 253 | FETCH_INST; | 253 | FETCH_INST; |
| 254 | GOTO_NEXT_INST; | 254 | GOTO_NEXT_INST; |
| @@ -297,7 +297,7 @@ VMUL_INST: | |||
| 297 | 297 | ||
| 298 | CHECK_VFP_CDP_RET; | 298 | CHECK_VFP_CDP_RET; |
| 299 | } | 299 | } |
| 300 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 300 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 301 | INC_PC(sizeof(vmul_inst)); | 301 | INC_PC(sizeof(vmul_inst)); |
| 302 | FETCH_INST; | 302 | FETCH_INST; |
| 303 | GOTO_NEXT_INST; | 303 | GOTO_NEXT_INST; |
| @@ -346,7 +346,7 @@ VADD_INST: | |||
| 346 | 346 | ||
| 347 | CHECK_VFP_CDP_RET; | 347 | CHECK_VFP_CDP_RET; |
| 348 | } | 348 | } |
| 349 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 349 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 350 | INC_PC(sizeof(vadd_inst)); | 350 | INC_PC(sizeof(vadd_inst)); |
| 351 | FETCH_INST; | 351 | FETCH_INST; |
| 352 | GOTO_NEXT_INST; | 352 | GOTO_NEXT_INST; |
| @@ -395,7 +395,7 @@ VSUB_INST: | |||
| 395 | 395 | ||
| 396 | CHECK_VFP_CDP_RET; | 396 | CHECK_VFP_CDP_RET; |
| 397 | } | 397 | } |
| 398 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 398 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 399 | INC_PC(sizeof(vsub_inst)); | 399 | INC_PC(sizeof(vsub_inst)); |
| 400 | FETCH_INST; | 400 | FETCH_INST; |
| 401 | GOTO_NEXT_INST; | 401 | GOTO_NEXT_INST; |
| @@ -444,7 +444,7 @@ VDIV_INST: | |||
| 444 | 444 | ||
| 445 | CHECK_VFP_CDP_RET; | 445 | CHECK_VFP_CDP_RET; |
| 446 | } | 446 | } |
| 447 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 447 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 448 | INC_PC(sizeof(vdiv_inst)); | 448 | INC_PC(sizeof(vdiv_inst)); |
| 449 | FETCH_INST; | 449 | FETCH_INST; |
| 450 | GOTO_NEXT_INST; | 450 | GOTO_NEXT_INST; |
| @@ -492,7 +492,7 @@ VMOVI_INST: | |||
| 492 | 492 | ||
| 493 | VMOVI(cpu, inst_cream->single, inst_cream->d, inst_cream->imm); | 493 | VMOVI(cpu, inst_cream->single, inst_cream->d, inst_cream->imm); |
| 494 | } | 494 | } |
| 495 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 495 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 496 | INC_PC(sizeof(vmovi_inst)); | 496 | INC_PC(sizeof(vmovi_inst)); |
| 497 | FETCH_INST; | 497 | FETCH_INST; |
| 498 | GOTO_NEXT_INST; | 498 | GOTO_NEXT_INST; |
| @@ -536,7 +536,7 @@ VMOVR_INST: | |||
| 536 | 536 | ||
| 537 | VMOVR(cpu, inst_cream->single, inst_cream->d, inst_cream->m); | 537 | VMOVR(cpu, inst_cream->single, inst_cream->d, inst_cream->m); |
| 538 | } | 538 | } |
| 539 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 539 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 540 | INC_PC(sizeof(vmovr_inst)); | 540 | INC_PC(sizeof(vmovr_inst)); |
| 541 | FETCH_INST; | 541 | FETCH_INST; |
| 542 | GOTO_NEXT_INST; | 542 | GOTO_NEXT_INST; |
| @@ -585,7 +585,7 @@ VABS_INST: | |||
| 585 | 585 | ||
| 586 | CHECK_VFP_CDP_RET; | 586 | CHECK_VFP_CDP_RET; |
| 587 | } | 587 | } |
| 588 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 588 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 589 | INC_PC(sizeof(vabs_inst)); | 589 | INC_PC(sizeof(vabs_inst)); |
| 590 | FETCH_INST; | 590 | FETCH_INST; |
| 591 | GOTO_NEXT_INST; | 591 | GOTO_NEXT_INST; |
| @@ -635,7 +635,7 @@ VNEG_INST: | |||
| 635 | 635 | ||
| 636 | CHECK_VFP_CDP_RET; | 636 | CHECK_VFP_CDP_RET; |
| 637 | } | 637 | } |
| 638 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 638 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 639 | INC_PC(sizeof(vneg_inst)); | 639 | INC_PC(sizeof(vneg_inst)); |
| 640 | FETCH_INST; | 640 | FETCH_INST; |
| 641 | GOTO_NEXT_INST; | 641 | GOTO_NEXT_INST; |
| @@ -684,7 +684,7 @@ VSQRT_INST: | |||
| 684 | 684 | ||
| 685 | CHECK_VFP_CDP_RET; | 685 | CHECK_VFP_CDP_RET; |
| 686 | } | 686 | } |
| 687 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 687 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 688 | INC_PC(sizeof(vsqrt_inst)); | 688 | INC_PC(sizeof(vsqrt_inst)); |
| 689 | FETCH_INST; | 689 | FETCH_INST; |
| 690 | GOTO_NEXT_INST; | 690 | GOTO_NEXT_INST; |
| @@ -733,7 +733,7 @@ VCMP_INST: | |||
| 733 | 733 | ||
| 734 | CHECK_VFP_CDP_RET; | 734 | CHECK_VFP_CDP_RET; |
| 735 | } | 735 | } |
| 736 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 736 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 737 | INC_PC(sizeof(vcmp_inst)); | 737 | INC_PC(sizeof(vcmp_inst)); |
| 738 | FETCH_INST; | 738 | FETCH_INST; |
| 739 | GOTO_NEXT_INST; | 739 | GOTO_NEXT_INST; |
| @@ -782,7 +782,7 @@ VCMP2_INST: | |||
| 782 | 782 | ||
| 783 | CHECK_VFP_CDP_RET; | 783 | CHECK_VFP_CDP_RET; |
| 784 | } | 784 | } |
| 785 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 785 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 786 | INC_PC(sizeof(vcmp2_inst)); | 786 | INC_PC(sizeof(vcmp2_inst)); |
| 787 | FETCH_INST; | 787 | FETCH_INST; |
| 788 | GOTO_NEXT_INST; | 788 | GOTO_NEXT_INST; |
| @@ -831,7 +831,7 @@ VCVTBDS_INST: | |||
| 831 | 831 | ||
| 832 | CHECK_VFP_CDP_RET; | 832 | CHECK_VFP_CDP_RET; |
| 833 | } | 833 | } |
| 834 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 834 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 835 | INC_PC(sizeof(vcvtbds_inst)); | 835 | INC_PC(sizeof(vcvtbds_inst)); |
| 836 | FETCH_INST; | 836 | FETCH_INST; |
| 837 | GOTO_NEXT_INST; | 837 | GOTO_NEXT_INST; |
| @@ -882,7 +882,7 @@ VCVTBFF_INST: | |||
| 882 | 882 | ||
| 883 | CHECK_VFP_CDP_RET; | 883 | CHECK_VFP_CDP_RET; |
| 884 | } | 884 | } |
| 885 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 885 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 886 | INC_PC(sizeof(vcvtbff_inst)); | 886 | INC_PC(sizeof(vcvtbff_inst)); |
| 887 | FETCH_INST; | 887 | FETCH_INST; |
| 888 | GOTO_NEXT_INST; | 888 | GOTO_NEXT_INST; |
| @@ -931,7 +931,7 @@ VCVTBFI_INST: | |||
| 931 | 931 | ||
| 932 | CHECK_VFP_CDP_RET; | 932 | CHECK_VFP_CDP_RET; |
| 933 | } | 933 | } |
| 934 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 934 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 935 | INC_PC(sizeof(vcvtbfi_inst)); | 935 | INC_PC(sizeof(vcvtbfi_inst)); |
| 936 | FETCH_INST; | 936 | FETCH_INST; |
| 937 | GOTO_NEXT_INST; | 937 | GOTO_NEXT_INST; |
| @@ -981,7 +981,7 @@ VMOVBRS_INST: | |||
| 981 | 981 | ||
| 982 | VMOVBRS(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->n, &(cpu->Reg[inst_cream->t])); | 982 | VMOVBRS(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->n, &(cpu->Reg[inst_cream->t])); |
| 983 | } | 983 | } |
| 984 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 984 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 985 | INC_PC(sizeof(vmovbrs_inst)); | 985 | INC_PC(sizeof(vmovbrs_inst)); |
| 986 | FETCH_INST; | 986 | FETCH_INST; |
| 987 | GOTO_NEXT_INST; | 987 | GOTO_NEXT_INST; |
| @@ -1032,7 +1032,7 @@ VMSR_INST: | |||
| 1032 | { | 1032 | { |
| 1033 | cpu->VFP[VFP_FPSCR] = cpu->Reg[rt]; | 1033 | cpu->VFP[VFP_FPSCR] = cpu->Reg[rt]; |
| 1034 | } | 1034 | } |
| 1035 | else if (InAPrivilegedMode(cpu)) | 1035 | else if (cpu->InAPrivilegedMode()) |
| 1036 | { | 1036 | { |
| 1037 | if (reg == 8) | 1037 | if (reg == 8) |
| 1038 | cpu->VFP[VFP_FPEXC] = cpu->Reg[rt]; | 1038 | cpu->VFP[VFP_FPEXC] = cpu->Reg[rt]; |
| @@ -1042,7 +1042,7 @@ VMSR_INST: | |||
| 1042 | cpu->VFP[VFP_FPINST2] = cpu->Reg[rt]; | 1042 | cpu->VFP[VFP_FPINST2] = cpu->Reg[rt]; |
| 1043 | } | 1043 | } |
| 1044 | } | 1044 | } |
| 1045 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 1045 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 1046 | INC_PC(sizeof(vmsr_inst)); | 1046 | INC_PC(sizeof(vmsr_inst)); |
| 1047 | FETCH_INST; | 1047 | FETCH_INST; |
| 1048 | GOTO_NEXT_INST; | 1048 | GOTO_NEXT_INST; |
| @@ -1090,7 +1090,7 @@ VMOVBRC_INST: | |||
| 1090 | 1090 | ||
| 1091 | cpu->ExtReg[(2 * inst_cream->d) + inst_cream->index] = cpu->Reg[inst_cream->t]; | 1091 | cpu->ExtReg[(2 * inst_cream->d) + inst_cream->index] = cpu->Reg[inst_cream->t]; |
| 1092 | } | 1092 | } |
| 1093 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 1093 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 1094 | INC_PC(sizeof(vmovbrc_inst)); | 1094 | INC_PC(sizeof(vmovbrc_inst)); |
| 1095 | FETCH_INST; | 1095 | FETCH_INST; |
| 1096 | GOTO_NEXT_INST; | 1096 | GOTO_NEXT_INST; |
| @@ -1163,7 +1163,7 @@ VMRS_INST: | |||
| 1163 | { | 1163 | { |
| 1164 | cpu->Reg[rt] = cpu->VFP[VFP_MVFR0]; | 1164 | cpu->Reg[rt] = cpu->VFP[VFP_MVFR0]; |
| 1165 | } | 1165 | } |
| 1166 | else if (InAPrivilegedMode(cpu)) | 1166 | else if (cpu->InAPrivilegedMode()) |
| 1167 | { | 1167 | { |
| 1168 | if (reg == 8) | 1168 | if (reg == 8) |
| 1169 | cpu->Reg[rt] = cpu->VFP[VFP_FPEXC]; | 1169 | cpu->Reg[rt] = cpu->VFP[VFP_FPEXC]; |
| @@ -1173,7 +1173,7 @@ VMRS_INST: | |||
| 1173 | cpu->Reg[rt] = cpu->VFP[VFP_FPINST2]; | 1173 | cpu->Reg[rt] = cpu->VFP[VFP_FPINST2]; |
| 1174 | } | 1174 | } |
| 1175 | } | 1175 | } |
| 1176 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 1176 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 1177 | INC_PC(sizeof(vmrs_inst)); | 1177 | INC_PC(sizeof(vmrs_inst)); |
| 1178 | FETCH_INST; | 1178 | FETCH_INST; |
| 1179 | GOTO_NEXT_INST; | 1179 | GOTO_NEXT_INST; |
| @@ -1221,7 +1221,7 @@ VMOVBCR_INST: | |||
| 1221 | 1221 | ||
| 1222 | cpu->Reg[inst_cream->t] = cpu->ExtReg[(2 * inst_cream->d) + inst_cream->index]; | 1222 | cpu->Reg[inst_cream->t] = cpu->ExtReg[(2 * inst_cream->d) + inst_cream->index]; |
| 1223 | } | 1223 | } |
| 1224 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 1224 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 1225 | INC_PC(sizeof(vmovbcr_inst)); | 1225 | INC_PC(sizeof(vmovbcr_inst)); |
| 1226 | FETCH_INST; | 1226 | FETCH_INST; |
| 1227 | GOTO_NEXT_INST; | 1227 | GOTO_NEXT_INST; |
| @@ -1274,7 +1274,7 @@ VMOVBRRSS_INST: | |||
| 1274 | VMOVBRRSS(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->t2, inst_cream->m, | 1274 | VMOVBRRSS(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->t2, inst_cream->m, |
| 1275 | &cpu->Reg[inst_cream->t], &cpu->Reg[inst_cream->t2]); | 1275 | &cpu->Reg[inst_cream->t], &cpu->Reg[inst_cream->t2]); |
| 1276 | } | 1276 | } |
| 1277 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 1277 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 1278 | INC_PC(sizeof(vmovbrrss_inst)); | 1278 | INC_PC(sizeof(vmovbrrss_inst)); |
| 1279 | FETCH_INST; | 1279 | FETCH_INST; |
| 1280 | GOTO_NEXT_INST; | 1280 | GOTO_NEXT_INST; |
| @@ -1322,7 +1322,7 @@ VMOVBRRD_INST: | |||
| 1322 | VMOVBRRD(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->t2, inst_cream->m, | 1322 | VMOVBRRD(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->t2, inst_cream->m, |
| 1323 | &(cpu->Reg[inst_cream->t]), &(cpu->Reg[inst_cream->t2])); | 1323 | &(cpu->Reg[inst_cream->t]), &(cpu->Reg[inst_cream->t2])); |
| 1324 | } | 1324 | } |
| 1325 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 1325 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 1326 | INC_PC(sizeof(vmovbrrd_inst)); | 1326 | INC_PC(sizeof(vmovbrrd_inst)); |
| 1327 | FETCH_INST; | 1327 | FETCH_INST; |
| 1328 | GOTO_NEXT_INST; | 1328 | GOTO_NEXT_INST; |
| @@ -1378,23 +1378,23 @@ VSTR_INST: | |||
| 1378 | 1378 | ||
| 1379 | if (inst_cream->single) | 1379 | if (inst_cream->single) |
| 1380 | { | 1380 | { |
| 1381 | WriteMemory32(cpu, addr, cpu->ExtReg[inst_cream->d]); | 1381 | cpu->WriteMemory32(addr, cpu->ExtReg[inst_cream->d]); |
| 1382 | } | 1382 | } |
| 1383 | else | 1383 | else |
| 1384 | { | 1384 | { |
| 1385 | const u32 word1 = cpu->ExtReg[inst_cream->d*2+0]; | 1385 | const u32 word1 = cpu->ExtReg[inst_cream->d*2+0]; |
| 1386 | const u32 word2 = cpu->ExtReg[inst_cream->d*2+1]; | 1386 | const u32 word2 = cpu->ExtReg[inst_cream->d*2+1]; |
| 1387 | 1387 | ||
| 1388 | if (InBigEndianMode(cpu)) { | 1388 | if (cpu->InBigEndianMode()) { |
| 1389 | WriteMemory32(cpu, addr + 0, word2); | 1389 | cpu->WriteMemory32(addr + 0, word2); |
| 1390 | WriteMemory32(cpu, addr + 4, word1); | 1390 | cpu->WriteMemory32(addr + 4, word1); |
| 1391 | } else { | 1391 | } else { |
| 1392 | WriteMemory32(cpu, addr + 0, word1); | 1392 | cpu->WriteMemory32(addr + 0, word1); |
| 1393 | WriteMemory32(cpu, addr + 4, word2); | 1393 | cpu->WriteMemory32(addr + 4, word2); |
| 1394 | } | 1394 | } |
| 1395 | } | 1395 | } |
| 1396 | } | 1396 | } |
| 1397 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 1397 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 1398 | INC_PC(sizeof(vstr_inst)); | 1398 | INC_PC(sizeof(vstr_inst)); |
| 1399 | FETCH_INST; | 1399 | FETCH_INST; |
| 1400 | GOTO_NEXT_INST; | 1400 | GOTO_NEXT_INST; |
| @@ -1444,7 +1444,7 @@ VPUSH_INST: | |||
| 1444 | { | 1444 | { |
| 1445 | if (inst_cream->single) | 1445 | if (inst_cream->single) |
| 1446 | { | 1446 | { |
| 1447 | WriteMemory32(cpu, addr, cpu->ExtReg[inst_cream->d+i]); | 1447 | cpu->WriteMemory32(addr, cpu->ExtReg[inst_cream->d+i]); |
| 1448 | addr += 4; | 1448 | addr += 4; |
| 1449 | } | 1449 | } |
| 1450 | else | 1450 | else |
| @@ -1452,12 +1452,12 @@ VPUSH_INST: | |||
| 1452 | const u32 word1 = cpu->ExtReg[(inst_cream->d+i)*2+0]; | 1452 | const u32 word1 = cpu->ExtReg[(inst_cream->d+i)*2+0]; |
| 1453 | const u32 word2 = cpu->ExtReg[(inst_cream->d+i)*2+1]; | 1453 | const u32 word2 = cpu->ExtReg[(inst_cream->d+i)*2+1]; |
| 1454 | 1454 | ||
| 1455 | if (InBigEndianMode(cpu)) { | 1455 | if (cpu->InBigEndianMode()) { |
| 1456 | WriteMemory32(cpu, addr + 0, word2); | 1456 | cpu->WriteMemory32(addr + 0, word2); |
| 1457 | WriteMemory32(cpu, addr + 4, word1); | 1457 | cpu->WriteMemory32(addr + 4, word1); |
| 1458 | } else { | 1458 | } else { |
| 1459 | WriteMemory32(cpu, addr + 0, word1); | 1459 | cpu->WriteMemory32(addr + 0, word1); |
| 1460 | WriteMemory32(cpu, addr + 4, word2); | 1460 | cpu->WriteMemory32(addr + 4, word2); |
| 1461 | } | 1461 | } |
| 1462 | 1462 | ||
| 1463 | addr += 8; | 1463 | addr += 8; |
| @@ -1466,7 +1466,7 @@ VPUSH_INST: | |||
| 1466 | 1466 | ||
| 1467 | cpu->Reg[R13] -= inst_cream->imm32; | 1467 | cpu->Reg[R13] -= inst_cream->imm32; |
| 1468 | } | 1468 | } |
| 1469 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 1469 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 1470 | INC_PC(sizeof(vpush_inst)); | 1470 | INC_PC(sizeof(vpush_inst)); |
| 1471 | FETCH_INST; | 1471 | FETCH_INST; |
| 1472 | GOTO_NEXT_INST; | 1472 | GOTO_NEXT_INST; |
| @@ -1522,7 +1522,7 @@ VSTM_INST: /* encoding 1 */ | |||
| 1522 | { | 1522 | { |
| 1523 | if (inst_cream->single) | 1523 | if (inst_cream->single) |
| 1524 | { | 1524 | { |
| 1525 | WriteMemory32(cpu, addr, cpu->ExtReg[inst_cream->d+i]); | 1525 | cpu->WriteMemory32(addr, cpu->ExtReg[inst_cream->d+i]); |
| 1526 | addr += 4; | 1526 | addr += 4; |
| 1527 | } | 1527 | } |
| 1528 | else | 1528 | else |
| @@ -1530,12 +1530,12 @@ VSTM_INST: /* encoding 1 */ | |||
| 1530 | const u32 word1 = cpu->ExtReg[(inst_cream->d+i)*2+0]; | 1530 | const u32 word1 = cpu->ExtReg[(inst_cream->d+i)*2+0]; |
| 1531 | const u32 word2 = cpu->ExtReg[(inst_cream->d+i)*2+1]; | 1531 | const u32 word2 = cpu->ExtReg[(inst_cream->d+i)*2+1]; |
| 1532 | 1532 | ||
| 1533 | if (InBigEndianMode(cpu)) { | 1533 | if (cpu->InBigEndianMode()) { |
| 1534 | WriteMemory32(cpu, addr + 0, word2); | 1534 | cpu->WriteMemory32(addr + 0, word2); |
| 1535 | WriteMemory32(cpu, addr + 4, word1); | 1535 | cpu->WriteMemory32(addr + 4, word1); |
| 1536 | } else { | 1536 | } else { |
| 1537 | WriteMemory32(cpu, addr + 0, word1); | 1537 | cpu->WriteMemory32(addr + 0, word1); |
| 1538 | WriteMemory32(cpu, addr + 4, word2); | 1538 | cpu->WriteMemory32(addr + 4, word2); |
| 1539 | } | 1539 | } |
| 1540 | 1540 | ||
| 1541 | addr += 8; | 1541 | addr += 8; |
| @@ -1597,15 +1597,15 @@ VPOP_INST: | |||
| 1597 | { | 1597 | { |
| 1598 | if (inst_cream->single) | 1598 | if (inst_cream->single) |
| 1599 | { | 1599 | { |
| 1600 | cpu->ExtReg[inst_cream->d+i] = ReadMemory32(cpu, addr); | 1600 | cpu->ExtReg[inst_cream->d+i] = cpu->ReadMemory32(addr); |
| 1601 | addr += 4; | 1601 | addr += 4; |
| 1602 | } | 1602 | } |
| 1603 | else | 1603 | else |
| 1604 | { | 1604 | { |
| 1605 | const u32 word1 = ReadMemory32(cpu, addr + 0); | 1605 | const u32 word1 = cpu->ReadMemory32(addr + 0); |
| 1606 | const u32 word2 = ReadMemory32(cpu, addr + 4); | 1606 | const u32 word2 = cpu->ReadMemory32(addr + 4); |
| 1607 | 1607 | ||
| 1608 | if (InBigEndianMode(cpu)) { | 1608 | if (cpu->InBigEndianMode()) { |
| 1609 | cpu->ExtReg[(inst_cream->d+i)*2+0] = word2; | 1609 | cpu->ExtReg[(inst_cream->d+i)*2+0] = word2; |
| 1610 | cpu->ExtReg[(inst_cream->d+i)*2+1] = word1; | 1610 | cpu->ExtReg[(inst_cream->d+i)*2+1] = word1; |
| 1611 | } else { | 1611 | } else { |
| @@ -1618,7 +1618,7 @@ VPOP_INST: | |||
| 1618 | } | 1618 | } |
| 1619 | cpu->Reg[R13] += inst_cream->imm32; | 1619 | cpu->Reg[R13] += inst_cream->imm32; |
| 1620 | } | 1620 | } |
| 1621 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 1621 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 1622 | INC_PC(sizeof(vpop_inst)); | 1622 | INC_PC(sizeof(vpop_inst)); |
| 1623 | FETCH_INST; | 1623 | FETCH_INST; |
| 1624 | GOTO_NEXT_INST; | 1624 | GOTO_NEXT_INST; |
| @@ -1670,14 +1670,14 @@ VLDR_INST: | |||
| 1670 | 1670 | ||
| 1671 | if (inst_cream->single) | 1671 | if (inst_cream->single) |
| 1672 | { | 1672 | { |
| 1673 | cpu->ExtReg[inst_cream->d] = ReadMemory32(cpu, addr); | 1673 | cpu->ExtReg[inst_cream->d] = cpu->ReadMemory32(addr); |
| 1674 | } | 1674 | } |
| 1675 | else | 1675 | else |
| 1676 | { | 1676 | { |
| 1677 | const u32 word1 = ReadMemory32(cpu, addr + 0); | 1677 | const u32 word1 = cpu->ReadMemory32(addr + 0); |
| 1678 | const u32 word2 = ReadMemory32(cpu, addr + 4); | 1678 | const u32 word2 = cpu->ReadMemory32(addr + 4); |
| 1679 | 1679 | ||
| 1680 | if (InBigEndianMode(cpu)) { | 1680 | if (cpu->InBigEndianMode()) { |
| 1681 | cpu->ExtReg[inst_cream->d*2+0] = word2; | 1681 | cpu->ExtReg[inst_cream->d*2+0] = word2; |
| 1682 | cpu->ExtReg[inst_cream->d*2+1] = word1; | 1682 | cpu->ExtReg[inst_cream->d*2+1] = word1; |
| 1683 | } else { | 1683 | } else { |
| @@ -1686,7 +1686,7 @@ VLDR_INST: | |||
| 1686 | } | 1686 | } |
| 1687 | } | 1687 | } |
| 1688 | } | 1688 | } |
| 1689 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 1689 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 1690 | INC_PC(sizeof(vldr_inst)); | 1690 | INC_PC(sizeof(vldr_inst)); |
| 1691 | FETCH_INST; | 1691 | FETCH_INST; |
| 1692 | GOTO_NEXT_INST; | 1692 | GOTO_NEXT_INST; |
| @@ -1742,15 +1742,15 @@ VLDM_INST: | |||
| 1742 | { | 1742 | { |
| 1743 | if (inst_cream->single) | 1743 | if (inst_cream->single) |
| 1744 | { | 1744 | { |
| 1745 | cpu->ExtReg[inst_cream->d+i] = ReadMemory32(cpu, addr); | 1745 | cpu->ExtReg[inst_cream->d+i] = cpu->ReadMemory32(addr); |
| 1746 | addr += 4; | 1746 | addr += 4; |
| 1747 | } | 1747 | } |
| 1748 | else | 1748 | else |
| 1749 | { | 1749 | { |
| 1750 | const u32 word1 = ReadMemory32(cpu, addr + 0); | 1750 | const u32 word1 = cpu->ReadMemory32(addr + 0); |
| 1751 | const u32 word2 = ReadMemory32(cpu, addr + 4); | 1751 | const u32 word2 = cpu->ReadMemory32(addr + 4); |
| 1752 | 1752 | ||
| 1753 | if (InBigEndianMode(cpu)) { | 1753 | if (cpu->InBigEndianMode()) { |
| 1754 | cpu->ExtReg[(inst_cream->d+i)*2+0] = word2; | 1754 | cpu->ExtReg[(inst_cream->d+i)*2+0] = word2; |
| 1755 | cpu->ExtReg[(inst_cream->d+i)*2+1] = word1; | 1755 | cpu->ExtReg[(inst_cream->d+i)*2+1] = word1; |
| 1756 | } else { | 1756 | } else { |
| @@ -1766,7 +1766,7 @@ VLDM_INST: | |||
| 1766 | cpu->Reg[inst_cream->n] - inst_cream->imm32); | 1766 | cpu->Reg[inst_cream->n] - inst_cream->imm32); |
| 1767 | } | 1767 | } |
| 1768 | } | 1768 | } |
| 1769 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 1769 | cpu->Reg[15] += cpu->GetInstructionSize(); |
| 1770 | INC_PC(sizeof(vldm_inst)); | 1770 | INC_PC(sizeof(vldm_inst)); |
| 1771 | FETCH_INST; | 1771 | FETCH_INST; |
| 1772 | GOTO_NEXT_INST; | 1772 | GOTO_NEXT_INST; |
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index 72006a53e..20f2da0fe 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp | |||
| @@ -502,7 +502,7 @@ void Advance() { | |||
| 502 | Core::g_app_core->down_count += diff; | 502 | Core::g_app_core->down_count += diff; |
| 503 | } | 503 | } |
| 504 | if (advance_callback) | 504 | if (advance_callback) |
| 505 | advance_callback(cycles_executed); | 505 | advance_callback(static_cast<int>(cycles_executed)); |
| 506 | } | 506 | } |
| 507 | 507 | ||
| 508 | void LogPendingEvents() { | 508 | void LogPendingEvents() { |
diff --git a/src/core/hle/applets/applet.cpp b/src/core/hle/applets/applet.cpp index 826f6cbb6..bc2a1829e 100644 --- a/src/core/hle/applets/applet.cpp +++ b/src/core/hle/applets/applet.cpp | |||
| @@ -89,12 +89,21 @@ ResultCode Applet::Start(const Service::APT::AppletStartupParameter& parameter) | |||
| 89 | return result; | 89 | return result; |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | bool IsLibraryAppletRunning() { | ||
| 93 | // Check the applets map for instances of any applet | ||
| 94 | for (auto itr = applets.begin(); itr != applets.end(); ++itr) | ||
| 95 | if (itr->second != nullptr) | ||
| 96 | return true; | ||
| 97 | return false; | ||
| 98 | } | ||
| 99 | |||
| 92 | void Init() { | 100 | void Init() { |
| 93 | // Register the applet update callback | 101 | // Register the applet update callback |
| 94 | applet_update_event = CoreTiming::RegisterEvent("HLE Applet Update Event", AppletUpdateEvent); | 102 | applet_update_event = CoreTiming::RegisterEvent("HLE Applet Update Event", AppletUpdateEvent); |
| 95 | } | 103 | } |
| 96 | 104 | ||
| 97 | void Shutdown() { | 105 | void Shutdown() { |
| 106 | CoreTiming::RemoveEvent(applet_update_event); | ||
| 98 | } | 107 | } |
| 99 | 108 | ||
| 100 | } | 109 | } |
diff --git a/src/core/hle/applets/applet.h b/src/core/hle/applets/applet.h index b235d0b8a..af442f81d 100644 --- a/src/core/hle/applets/applet.h +++ b/src/core/hle/applets/applet.h | |||
| @@ -67,6 +67,9 @@ protected: | |||
| 67 | Service::APT::AppletId id; ///< Id of this Applet | 67 | Service::APT::AppletId id; ///< Id of this Applet |
| 68 | }; | 68 | }; |
| 69 | 69 | ||
| 70 | /// Returns whether a library applet is currently running | ||
| 71 | bool IsLibraryAppletRunning(); | ||
| 72 | |||
| 70 | /// Initializes the HLE applets | 73 | /// Initializes the HLE applets |
| 71 | void Init(); | 74 | void Init(); |
| 72 | 75 | ||
diff --git a/src/core/hle/function_wrappers.h b/src/core/hle/function_wrappers.h index 9294789ec..1a0518926 100644 --- a/src/core/hle/function_wrappers.h +++ b/src/core/hle/function_wrappers.h | |||
| @@ -133,7 +133,7 @@ template<ResultCode func(u32)> void Wrap() { | |||
| 133 | FuncReturn(func(PARAM(0)).raw); | 133 | FuncReturn(func(PARAM(0)).raw); |
| 134 | } | 134 | } |
| 135 | 135 | ||
| 136 | template<ResultCode func(s64*, u32, u32*, s32)> void Wrap(){ | 136 | template<ResultCode func(s64*, u32, u32*, u32)> void Wrap(){ |
| 137 | FuncReturn(func((s64*)Memory::GetPointer(PARAM(0)), PARAM(1), (u32*)Memory::GetPointer(PARAM(2)), | 137 | FuncReturn(func((s64*)Memory::GetPointer(PARAM(0)), PARAM(1), (u32*)Memory::GetPointer(PARAM(2)), |
| 138 | (s32)PARAM(3)).raw); | 138 | (s32)PARAM(3)).raw); |
| 139 | } | 139 | } |
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 8b49fc7df..29ea6d531 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp | |||
| @@ -13,7 +13,7 @@ | |||
| 13 | #include "common/thread_queue_list.h" | 13 | #include "common/thread_queue_list.h" |
| 14 | 14 | ||
| 15 | #include "core/arm/arm_interface.h" | 15 | #include "core/arm/arm_interface.h" |
| 16 | #include "core/arm/skyeye_common/armdefs.h" | 16 | #include "core/arm/skyeye_common/armstate.h" |
| 17 | #include "core/core.h" | 17 | #include "core/core.h" |
| 18 | #include "core/core_timing.h" | 18 | #include "core/core_timing.h" |
| 19 | #include "core/hle/hle.h" | 19 | #include "core/hle/hle.h" |
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 7332478fb..64f3bc7e9 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #include "common/logging/log.h" | 5 | #include "common/logging/log.h" |
| 6 | 6 | ||
| 7 | #include "core/hle/service/service.h" | 7 | #include "core/hle/service/service.h" |
| 8 | #include "core/hle/service/am/am.h" | ||
| 8 | #include "core/hle/service/am/am_app.h" | 9 | #include "core/hle/service/am/am_app.h" |
| 9 | #include "core/hle/service/am/am_net.h" | 10 | #include "core/hle/service/am/am_net.h" |
| 10 | #include "core/hle/service/am/am_sys.h" | 11 | #include "core/hle/service/am/am_sys.h" |
diff --git a/src/core/hle/service/am/am_net.cpp b/src/core/hle/service/am/am_net.cpp index b1af0e9d8..aa391f3b2 100644 --- a/src/core/hle/service/am/am_net.cpp +++ b/src/core/hle/service/am/am_net.cpp | |||
| @@ -28,7 +28,8 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 28 | {0x08130000, nullptr, "GetTotalContents"}, | 28 | {0x08130000, nullptr, "GetTotalContents"}, |
| 29 | {0x08140042, nullptr, "GetContentIndexes"}, | 29 | {0x08140042, nullptr, "GetContentIndexes"}, |
| 30 | {0x08150044, nullptr, "GetContentsInfo"}, | 30 | {0x08150044, nullptr, "GetContentsInfo"}, |
| 31 | {0x08190108, nullptr, "Unknown"}, | 31 | {0x08180042, nullptr, "GetCTCert"}, |
| 32 | {0x08190108, nullptr, "SetCertificates"}, | ||
| 32 | {0x081B00C2, nullptr, "InstallTitlesFinish"}, | 33 | {0x081B00C2, nullptr, "InstallTitlesFinish"}, |
| 33 | }; | 34 | }; |
| 34 | 35 | ||
diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp index 7b6ab4ce0..35402341b 100644 --- a/src/core/hle/service/apt/apt.cpp +++ b/src/core/hle/service/apt/apt.cpp | |||
| @@ -101,18 +101,19 @@ void NotifyToWait(Service::Interface* self) { | |||
| 101 | 101 | ||
| 102 | void GetLockHandle(Service::Interface* self) { | 102 | void GetLockHandle(Service::Interface* self) { |
| 103 | u32* cmd_buff = Kernel::GetCommandBuffer(); | 103 | u32* cmd_buff = Kernel::GetCommandBuffer(); |
| 104 | u32 flags = cmd_buff[1]; // TODO(bunnei): Figure out the purpose of the flag field | 104 | // Bits [0:2] are the applet type (System, Library, etc) |
| 105 | // Bit 5 tells the application that there's a pending APT parameter, | ||
| 106 | // this will cause the app to wait until parameter_event is signaled. | ||
| 107 | u32 applet_attributes = cmd_buff[1]; | ||
| 105 | 108 | ||
| 106 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error | 109 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error |
| 107 | 110 | ||
| 108 | // Not sure what these parameters are used for, but retail apps check that they are 0 after | 111 | cmd_buff[2] = applet_attributes; // Applet Attributes, this value is passed to Enable. |
| 109 | // GetLockHandle has been called. | 112 | cmd_buff[3] = 0; // Least significant bit = power button state |
| 110 | cmd_buff[2] = 0; // Applet Attributes, this value is passed to Enable. | 113 | cmd_buff[4] = IPC::CopyHandleDesc(); |
| 111 | cmd_buff[3] = 0; | ||
| 112 | cmd_buff[4] = 0; | ||
| 113 | |||
| 114 | cmd_buff[5] = Kernel::g_handle_table.Create(lock).MoveFrom(); | 114 | cmd_buff[5] = Kernel::g_handle_table.Create(lock).MoveFrom(); |
| 115 | LOG_TRACE(Service_APT, "called handle=0x%08X", cmd_buff[5]); | 115 | |
| 116 | LOG_WARNING(Service_APT, "(STUBBED) called handle=0x%08X applet_attributes=0x%08X", cmd_buff[5], applet_attributes); | ||
| 116 | } | 117 | } |
| 117 | 118 | ||
| 118 | void Enable(Service::Interface* self) { | 119 | void Enable(Service::Interface* self) { |
| @@ -139,13 +140,16 @@ void IsRegistered(Service::Interface* self) { | |||
| 139 | u32* cmd_buff = Kernel::GetCommandBuffer(); | 140 | u32* cmd_buff = Kernel::GetCommandBuffer(); |
| 140 | u32 app_id = cmd_buff[1]; | 141 | u32 app_id = cmd_buff[1]; |
| 141 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error | 142 | cmd_buff[1] = RESULT_SUCCESS.raw; // No error |
| 142 | /// TODO(Subv): It is currently unknown what this value (0x400) means, | 143 | |
| 143 | /// but i believe it is used as a global "LibraryApplet" id, to verify if there's | 144 | // TODO(Subv): An application is considered "registered" if it has already called APT::Enable |
| 144 | /// any LibApplet currently running. This is not verified. | 145 | // handle this properly once we implement multiprocess support. |
| 145 | if (app_id != 0x400) | 146 | cmd_buff[2] = 0; // Set to not registered by default |
| 147 | |||
| 148 | if (app_id == static_cast<u32>(AppletId::AnyLibraryApplet)) { | ||
| 149 | cmd_buff[2] = HLE::Applets::IsLibraryAppletRunning() ? 1 : 0; | ||
| 150 | } else if (auto applet = HLE::Applets::Applet::Get(static_cast<AppletId>(app_id))) { | ||
| 146 | cmd_buff[2] = 1; // Set to registered | 151 | cmd_buff[2] = 1; // Set to registered |
| 147 | else | 152 | } |
| 148 | cmd_buff[2] = 0; // Set to not registered | ||
| 149 | LOG_WARNING(Service_APT, "(STUBBED) called app_id=0x%08X", app_id); | 153 | LOG_WARNING(Service_APT, "(STUBBED) called app_id=0x%08X", app_id); |
| 150 | } | 154 | } |
| 151 | 155 | ||
| @@ -330,7 +334,26 @@ void GetAppCpuTimeLimit(Service::Interface* self) { | |||
| 330 | void PrepareToStartLibraryApplet(Service::Interface* self) { | 334 | void PrepareToStartLibraryApplet(Service::Interface* self) { |
| 331 | u32* cmd_buff = Kernel::GetCommandBuffer(); | 335 | u32* cmd_buff = Kernel::GetCommandBuffer(); |
| 332 | AppletId applet_id = static_cast<AppletId>(cmd_buff[1]); | 336 | AppletId applet_id = static_cast<AppletId>(cmd_buff[1]); |
| 333 | cmd_buff[1] = HLE::Applets::Applet::Create(applet_id).raw; | 337 | auto applet = HLE::Applets::Applet::Get(applet_id); |
| 338 | if (applet) { | ||
| 339 | LOG_WARNING(Service_APT, "applet has already been started id=%08X", applet_id); | ||
| 340 | cmd_buff[1] = RESULT_SUCCESS.raw; | ||
| 341 | } else { | ||
| 342 | cmd_buff[1] = HLE::Applets::Applet::Create(applet_id).raw; | ||
| 343 | } | ||
| 344 | LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id); | ||
| 345 | } | ||
| 346 | |||
| 347 | void PreloadLibraryApplet(Service::Interface* self) { | ||
| 348 | u32* cmd_buff = Kernel::GetCommandBuffer(); | ||
| 349 | AppletId applet_id = static_cast<AppletId>(cmd_buff[1]); | ||
| 350 | auto applet = HLE::Applets::Applet::Get(applet_id); | ||
| 351 | if (applet) { | ||
| 352 | LOG_WARNING(Service_APT, "applet has already been started id=%08X", applet_id); | ||
| 353 | cmd_buff[1] = RESULT_SUCCESS.raw; | ||
| 354 | } else { | ||
| 355 | cmd_buff[1] = HLE::Applets::Applet::Create(applet_id).raw; | ||
| 356 | } | ||
| 334 | LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id); | 357 | LOG_DEBUG(Service_APT, "called applet_id=%08X", applet_id); |
| 335 | } | 358 | } |
| 336 | 359 | ||
diff --git a/src/core/hle/service/apt/apt.h b/src/core/hle/service/apt/apt.h index 72972d05b..4a72b6b5c 100644 --- a/src/core/hle/service/apt/apt.h +++ b/src/core/hle/service/apt/apt.h | |||
| @@ -62,6 +62,7 @@ enum class AppletId : u32 { | |||
| 62 | Extrapad = 0x208, | 62 | Extrapad = 0x208, |
| 63 | Memolib = 0x209, | 63 | Memolib = 0x209, |
| 64 | Application = 0x300, | 64 | Application = 0x300, |
| 65 | AnyLibraryApplet = 0x400, | ||
| 65 | SoftwareKeyboard2 = 0x401, | 66 | SoftwareKeyboard2 = 0x401, |
| 66 | }; | 67 | }; |
| 67 | 68 | ||
| @@ -96,8 +97,26 @@ void GetSharedFont(Service::Interface* self); | |||
| 96 | */ | 97 | */ |
| 97 | void NotifyToWait(Service::Interface* self); | 98 | void NotifyToWait(Service::Interface* self); |
| 98 | 99 | ||
| 100 | /** | ||
| 101 | * APT::GetLockHandle service function | ||
| 102 | * Inputs: | ||
| 103 | * 1 : Applet attributes | ||
| 104 | * Outputs: | ||
| 105 | * 1 : Result of function, 0 on success, otherwise error code | ||
| 106 | * 2 : Applet attributes | ||
| 107 | * 3 : Power button state | ||
| 108 | * 4 : IPC handle descriptor | ||
| 109 | * 5 : APT mutex handle | ||
| 110 | */ | ||
| 99 | void GetLockHandle(Service::Interface* self); | 111 | void GetLockHandle(Service::Interface* self); |
| 100 | 112 | ||
| 113 | /** | ||
| 114 | * APT::Enable service function | ||
| 115 | * Inputs: | ||
| 116 | * 1 : Applet attributes | ||
| 117 | * Outputs: | ||
| 118 | * 1 : Result of function, 0 on success, otherwise error code | ||
| 119 | */ | ||
| 101 | void Enable(Service::Interface* self); | 120 | void Enable(Service::Interface* self); |
| 102 | 121 | ||
| 103 | /** | 122 | /** |
| @@ -284,6 +303,17 @@ void GetAppCpuTimeLimit(Service::Interface* self); | |||
| 284 | void PrepareToStartLibraryApplet(Service::Interface* self); | 303 | void PrepareToStartLibraryApplet(Service::Interface* self); |
| 285 | 304 | ||
| 286 | /** | 305 | /** |
| 306 | * APT::PreloadLibraryApplet service function | ||
| 307 | * Inputs: | ||
| 308 | * 0 : Command header [0x00160040] | ||
| 309 | * 1 : Id of the applet to start | ||
| 310 | * Outputs: | ||
| 311 | * 0 : Return header | ||
| 312 | * 1 : Result of function, 0 on success, otherwise error code | ||
| 313 | */ | ||
| 314 | void PreloadLibraryApplet(Service::Interface* self); | ||
| 315 | |||
| 316 | /** | ||
| 287 | * APT::StartLibraryApplet service function | 317 | * APT::StartLibraryApplet service function |
| 288 | * Inputs: | 318 | * Inputs: |
| 289 | * 0 : Command header [0x001E0084] | 319 | * 0 : Command header [0x001E0084] |
diff --git a/src/core/hle/service/apt/apt_a.cpp b/src/core/hle/service/apt/apt_a.cpp index 88de339f9..22800c56f 100644 --- a/src/core/hle/service/apt/apt_a.cpp +++ b/src/core/hle/service/apt/apt_a.cpp | |||
| @@ -21,6 +21,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 21 | {0x000D0080, ReceiveParameter, "ReceiveParameter"}, | 21 | {0x000D0080, ReceiveParameter, "ReceiveParameter"}, |
| 22 | {0x000E0080, GlanceParameter, "GlanceParameter"}, | 22 | {0x000E0080, GlanceParameter, "GlanceParameter"}, |
| 23 | {0x000F0100, CancelParameter, "CancelParameter"}, | 23 | {0x000F0100, CancelParameter, "CancelParameter"}, |
| 24 | {0x00160040, PreloadLibraryApplet, "PreloadLibraryApplet"}, | ||
| 24 | {0x00180040, PrepareToStartLibraryApplet, "PrepareToStartLibraryApplet"}, | 25 | {0x00180040, PrepareToStartLibraryApplet, "PrepareToStartLibraryApplet"}, |
| 25 | {0x001E0084, StartLibraryApplet, "StartLibraryApplet"}, | 26 | {0x001E0084, StartLibraryApplet, "StartLibraryApplet"}, |
| 26 | {0x003B0040, nullptr, "CancelLibraryApplet?"}, | 27 | {0x003B0040, nullptr, "CancelLibraryApplet?"}, |
diff --git a/src/core/hle/service/apt/apt_s.cpp b/src/core/hle/service/apt/apt_s.cpp index 396d1f04a..3ac6ff94f 100644 --- a/src/core/hle/service/apt/apt_s.cpp +++ b/src/core/hle/service/apt/apt_s.cpp | |||
| @@ -32,9 +32,9 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 32 | {0x00130000, nullptr, "GetPreparationState"}, | 32 | {0x00130000, nullptr, "GetPreparationState"}, |
| 33 | {0x00140040, nullptr, "SetPreparationState"}, | 33 | {0x00140040, nullptr, "SetPreparationState"}, |
| 34 | {0x00150140, nullptr, "PrepareToStartApplication"}, | 34 | {0x00150140, nullptr, "PrepareToStartApplication"}, |
| 35 | {0x00160040, nullptr, "PreloadLibraryApplet"}, | 35 | {0x00160040, PreloadLibraryApplet, "PreloadLibraryApplet"}, |
| 36 | {0x00170040, nullptr, "FinishPreloadingLibraryApplet"}, | 36 | {0x00170040, nullptr, "FinishPreloadingLibraryApplet"}, |
| 37 | {0x00180040, nullptr, "PrepareToStartLibraryApplet"}, | 37 | {0x00180040, PrepareToStartLibraryApplet,"PrepareToStartLibraryApplet"}, |
| 38 | {0x00190040, nullptr, "PrepareToStartSystemApplet"}, | 38 | {0x00190040, nullptr, "PrepareToStartSystemApplet"}, |
| 39 | {0x001A0000, nullptr, "PrepareToStartNewestHomeMenu"}, | 39 | {0x001A0000, nullptr, "PrepareToStartNewestHomeMenu"}, |
| 40 | {0x001B00C4, nullptr, "StartApplication"}, | 40 | {0x001B00C4, nullptr, "StartApplication"}, |
diff --git a/src/core/hle/service/apt/apt_u.cpp b/src/core/hle/service/apt/apt_u.cpp index b724cd72b..146bfd595 100644 --- a/src/core/hle/service/apt/apt_u.cpp +++ b/src/core/hle/service/apt/apt_u.cpp | |||
| @@ -33,7 +33,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 33 | {0x00130000, nullptr, "GetPreparationState"}, | 33 | {0x00130000, nullptr, "GetPreparationState"}, |
| 34 | {0x00140040, nullptr, "SetPreparationState"}, | 34 | {0x00140040, nullptr, "SetPreparationState"}, |
| 35 | {0x00150140, nullptr, "PrepareToStartApplication"}, | 35 | {0x00150140, nullptr, "PrepareToStartApplication"}, |
| 36 | {0x00160040, nullptr, "PreloadLibraryApplet"}, | 36 | {0x00160040, PreloadLibraryApplet, "PreloadLibraryApplet"}, |
| 37 | {0x00170040, nullptr, "FinishPreloadingLibraryApplet"}, | 37 | {0x00170040, nullptr, "FinishPreloadingLibraryApplet"}, |
| 38 | {0x00180040, PrepareToStartLibraryApplet, "PrepareToStartLibraryApplet"}, | 38 | {0x00180040, PrepareToStartLibraryApplet, "PrepareToStartLibraryApplet"}, |
| 39 | {0x00190040, nullptr, "PrepareToStartSystemApplet"}, | 39 | {0x00190040, nullptr, "PrepareToStartSystemApplet"}, |
diff --git a/src/core/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp index 8b40ba376..e93c1b436 100644 --- a/src/core/hle/service/gsp_gpu.cpp +++ b/src/core/hle/service/gsp_gpu.cpp | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include "core/hw/lcd.h" | 14 | #include "core/hw/lcd.h" |
| 15 | 15 | ||
| 16 | #include "video_core/gpu_debugger.h" | 16 | #include "video_core/gpu_debugger.h" |
| 17 | #include "video_core/debug_utils/debug_utils.h" | ||
| 17 | #include "video_core/renderer_base.h" | 18 | #include "video_core/renderer_base.h" |
| 18 | #include "video_core/video_core.h" | 19 | #include "video_core/video_core.h" |
| 19 | 20 | ||
| @@ -226,6 +227,9 @@ void SetBufferSwap(u32 screen_id, const FrameBufferInfo& info) { | |||
| 226 | &info.format); | 227 | &info.format); |
| 227 | WriteHWRegs(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].active_fb)), 4, | 228 | WriteHWRegs(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].active_fb)), 4, |
| 228 | &info.shown_fb); | 229 | &info.shown_fb); |
| 230 | |||
| 231 | if (Pica::g_debug_context) | ||
| 232 | Pica::g_debug_context->OnEvent(Pica::DebugContext::Event::BufferSwapped, nullptr); | ||
| 229 | } | 233 | } |
| 230 | 234 | ||
| 231 | /** | 235 | /** |
| @@ -391,19 +395,24 @@ static void ExecuteCommand(const Command& command, u32 thread_id) { | |||
| 391 | case CommandId::SET_MEMORY_FILL: | 395 | case CommandId::SET_MEMORY_FILL: |
| 392 | { | 396 | { |
| 393 | auto& params = command.memory_fill; | 397 | auto& params = command.memory_fill; |
| 394 | WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[0].address_start)), | 398 | |
| 395 | Memory::VirtualToPhysicalAddress(params.start1) >> 3); | 399 | if (params.start1 != 0) { |
| 396 | WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[0].address_end)), | 400 | WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[0].address_start)), |
| 397 | Memory::VirtualToPhysicalAddress(params.end1) >> 3); | 401 | Memory::VirtualToPhysicalAddress(params.start1) >> 3); |
| 398 | WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[0].value_32bit)), params.value1); | 402 | WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[0].address_end)), |
| 399 | WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[0].control)), params.control1); | 403 | Memory::VirtualToPhysicalAddress(params.end1) >> 3); |
| 400 | 404 | WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[0].value_32bit)), params.value1); | |
| 401 | WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[1].address_start)), | 405 | WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[0].control)), params.control1); |
| 402 | Memory::VirtualToPhysicalAddress(params.start2) >> 3); | 406 | } |
| 403 | WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[1].address_end)), | 407 | |
| 404 | Memory::VirtualToPhysicalAddress(params.end2) >> 3); | 408 | if (params.start2 != 0) { |
| 405 | WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[1].value_32bit)), params.value2); | 409 | WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[1].address_start)), |
| 406 | WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[1].control)), params.control2); | 410 | Memory::VirtualToPhysicalAddress(params.start2) >> 3); |
| 411 | WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[1].address_end)), | ||
| 412 | Memory::VirtualToPhysicalAddress(params.end2) >> 3); | ||
| 413 | WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[1].value_32bit)), params.value2); | ||
| 414 | WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[1].control)), params.control2); | ||
| 415 | } | ||
| 407 | break; | 416 | break; |
| 408 | } | 417 | } |
| 409 | 418 | ||
| @@ -448,6 +457,9 @@ static void ExecuteCommand(const Command& command, u32 thread_id) { | |||
| 448 | default: | 457 | default: |
| 449 | LOG_ERROR(Service_GSP, "unknown command 0x%08X", (int)command.id.Value()); | 458 | LOG_ERROR(Service_GSP, "unknown command 0x%08X", (int)command.id.Value()); |
| 450 | } | 459 | } |
| 460 | |||
| 461 | if (Pica::g_debug_context) | ||
| 462 | Pica::g_debug_context->OnEvent(Pica::DebugContext::Event::GSPCommandProcessed, (void*)&command); | ||
| 451 | } | 463 | } |
| 452 | 464 | ||
| 453 | /** | 465 | /** |
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 70caa7d80..c35b13b25 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp | |||
| @@ -35,6 +35,16 @@ static Kernel::SharedPtr<Kernel::Event> event_debug_pad; | |||
| 35 | static u32 next_pad_index; | 35 | static u32 next_pad_index; |
| 36 | static u32 next_touch_index; | 36 | static u32 next_touch_index; |
| 37 | 37 | ||
| 38 | const std::array<Service::HID::PadState, Settings::NativeInput::NUM_INPUTS> pad_mapping = { | ||
| 39 | Service::HID::PAD_A, Service::HID::PAD_B, Service::HID::PAD_X, Service::HID::PAD_Y, | ||
| 40 | Service::HID::PAD_L, Service::HID::PAD_R, Service::HID::PAD_ZL, Service::HID::PAD_ZR, | ||
| 41 | Service::HID::PAD_START, Service::HID::PAD_SELECT, Service::HID::PAD_NONE, | ||
| 42 | Service::HID::PAD_UP, Service::HID::PAD_DOWN, Service::HID::PAD_LEFT, Service::HID::PAD_RIGHT, | ||
| 43 | Service::HID::PAD_CIRCLE_UP, Service::HID::PAD_CIRCLE_DOWN, Service::HID::PAD_CIRCLE_LEFT, Service::HID::PAD_CIRCLE_RIGHT, | ||
| 44 | Service::HID::PAD_C_UP, Service::HID::PAD_C_DOWN, Service::HID::PAD_C_LEFT, Service::HID::PAD_C_RIGHT | ||
| 45 | }; | ||
| 46 | |||
| 47 | |||
| 38 | // TODO(peachum): | 48 | // TODO(peachum): |
| 39 | // Add a method for setting analog input from joystick device for the circle Pad. | 49 | // Add a method for setting analog input from joystick device for the circle Pad. |
| 40 | // | 50 | // |
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index d50d479f8..517f4f2ae 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | #ifndef _MSC_VER | 9 | #ifndef _MSC_VER |
| 10 | #include <cstddef> | 10 | #include <cstddef> |
| 11 | #endif | 11 | #endif |
| 12 | 12 | #include "core/settings.h" | |
| 13 | #include "common/bit_field.h" | 13 | #include "common/bit_field.h" |
| 14 | #include "common/common_funcs.h" | 14 | #include "common/common_funcs.h" |
| 15 | #include "common/common_types.h" | 15 | #include "common/common_types.h" |
| @@ -157,6 +157,9 @@ const PadState PAD_CIRCLE_LEFT = {{1u << 29}}; | |||
| 157 | const PadState PAD_CIRCLE_UP = {{1u << 30}}; | 157 | const PadState PAD_CIRCLE_UP = {{1u << 30}}; |
| 158 | const PadState PAD_CIRCLE_DOWN = {{1u << 31}}; | 158 | const PadState PAD_CIRCLE_DOWN = {{1u << 31}}; |
| 159 | 159 | ||
| 160 | |||
| 161 | extern const std::array<Service::HID::PadState, Settings::NativeInput::NUM_INPUTS> pad_mapping; | ||
| 162 | |||
| 160 | /** | 163 | /** |
| 161 | * HID::GetIPCHandles service function | 164 | * HID::GetIPCHandles service function |
| 162 | * Inputs: | 165 | * Inputs: |
diff --git a/src/core/hle/service/soc_u.cpp b/src/core/hle/service/soc_u.cpp index d0e166fdf..d768a3fc7 100644 --- a/src/core/hle/service/soc_u.cpp +++ b/src/core/hle/service/soc_u.cpp | |||
| @@ -481,11 +481,17 @@ static void GetHostId(Service::Interface* self) { | |||
| 481 | 481 | ||
| 482 | char name[128]; | 482 | char name[128]; |
| 483 | gethostname(name, sizeof(name)); | 483 | gethostname(name, sizeof(name)); |
| 484 | hostent* host = gethostbyname(name); | 484 | addrinfo hints = {}; |
| 485 | in_addr* addr = reinterpret_cast<in_addr*>(host->h_addr); | 485 | addrinfo* res; |
| 486 | |||
| 487 | hints.ai_family = AF_INET; | ||
| 488 | getaddrinfo(name, NULL, &hints, &res); | ||
| 489 | sockaddr_in* sock_addr = reinterpret_cast<sockaddr_in*>(res->ai_addr); | ||
| 490 | in_addr* addr = &sock_addr->sin_addr; | ||
| 486 | 491 | ||
| 487 | cmd_buffer[2] = addr->s_addr; | 492 | cmd_buffer[2] = addr->s_addr; |
| 488 | cmd_buffer[1] = 0; | 493 | cmd_buffer[1] = 0; |
| 494 | freeaddrinfo(res); | ||
| 489 | } | 495 | } |
| 490 | 496 | ||
| 491 | static void Close(Service::Interface* self) { | 497 | static void Close(Service::Interface* self) { |
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp index bdede964e..bb64fdfb7 100644 --- a/src/core/hle/svc.cpp +++ b/src/core/hle/svc.cpp | |||
| @@ -334,7 +334,7 @@ static ResultCode GetResourceLimit(Handle* resource_limit, Handle process_handle | |||
| 334 | 334 | ||
| 335 | /// Get resource limit current values | 335 | /// Get resource limit current values |
| 336 | static ResultCode GetResourceLimitCurrentValues(s64* values, Handle resource_limit_handle, u32* names, | 336 | static ResultCode GetResourceLimitCurrentValues(s64* values, Handle resource_limit_handle, u32* names, |
| 337 | s32 name_count) { | 337 | u32 name_count) { |
| 338 | LOG_TRACE(Kernel_SVC, "called resource_limit=%08X, names=%p, name_count=%d", | 338 | LOG_TRACE(Kernel_SVC, "called resource_limit=%08X, names=%p, name_count=%d", |
| 339 | resource_limit_handle, names, name_count); | 339 | resource_limit_handle, names, name_count); |
| 340 | 340 | ||
| @@ -350,7 +350,7 @@ static ResultCode GetResourceLimitCurrentValues(s64* values, Handle resource_lim | |||
| 350 | 350 | ||
| 351 | /// Get resource limit max values | 351 | /// Get resource limit max values |
| 352 | static ResultCode GetResourceLimitLimitValues(s64* values, Handle resource_limit_handle, u32* names, | 352 | static ResultCode GetResourceLimitLimitValues(s64* values, Handle resource_limit_handle, u32* names, |
| 353 | s32 name_count) { | 353 | u32 name_count) { |
| 354 | LOG_TRACE(Kernel_SVC, "called resource_limit=%08X, names=%p, name_count=%d", | 354 | LOG_TRACE(Kernel_SVC, "called resource_limit=%08X, names=%p, name_count=%d", |
| 355 | resource_limit_handle, names, name_count); | 355 | resource_limit_handle, names, name_count); |
| 356 | 356 | ||
diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp index 2a338e8fc..3ccbc03b2 100644 --- a/src/core/hw/gpu.cpp +++ b/src/core/hw/gpu.cpp | |||
| @@ -151,6 +151,10 @@ inline void Write(u32 addr, const T data) { | |||
| 151 | { | 151 | { |
| 152 | const auto& config = g_regs.display_transfer_config; | 152 | const auto& config = g_regs.display_transfer_config; |
| 153 | if (config.trigger & 1) { | 153 | if (config.trigger & 1) { |
| 154 | |||
| 155 | if (Pica::g_debug_context) | ||
| 156 | Pica::g_debug_context->OnEvent(Pica::DebugContext::Event::IncomingDisplayTransfer, nullptr); | ||
| 157 | |||
| 154 | u8* src_pointer = Memory::GetPhysicalPointer(config.GetPhysicalInputAddress()); | 158 | u8* src_pointer = Memory::GetPhysicalPointer(config.GetPhysicalInputAddress()); |
| 155 | u8* dst_pointer = Memory::GetPhysicalPointer(config.GetPhysicalOutputAddress()); | 159 | u8* dst_pointer = Memory::GetPhysicalPointer(config.GetPhysicalOutputAddress()); |
| 156 | 160 | ||
diff --git a/src/core/hw/y2r.cpp b/src/core/hw/y2r.cpp index f80e26ecd..082a4db82 100644 --- a/src/core/hw/y2r.cpp +++ b/src/core/hw/y2r.cpp | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include "common/vector_math.h" | 14 | #include "common/vector_math.h" |
| 15 | 15 | ||
| 16 | #include "core/hle/service/y2r_u.h" | 16 | #include "core/hle/service/y2r_u.h" |
| 17 | #include "core/hw/y2r.h" | ||
| 17 | #include "core/memory.h" | 18 | #include "core/memory.h" |
| 18 | 19 | ||
| 19 | namespace HW { | 20 | namespace HW { |
diff --git a/src/core/loader/3dsx.cpp b/src/core/loader/3dsx.cpp index d043fa9bd..530837d08 100644 --- a/src/core/loader/3dsx.cpp +++ b/src/core/loader/3dsx.cpp | |||
| @@ -191,7 +191,7 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, Shared | |||
| 191 | *pos = (addr); | 191 | *pos = (addr); |
| 192 | break; | 192 | break; |
| 193 | case 1: | 193 | case 1: |
| 194 | *pos = (addr - in_addr); | 194 | *pos = static_cast<u32>(addr - in_addr); |
| 195 | break; | 195 | break; |
| 196 | default: | 196 | default: |
| 197 | break; //this should never happen | 197 | break; //this should never happen |
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index 9ef2f8900..f5b349a77 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp | |||
| @@ -56,18 +56,18 @@ static FileType IdentifyFile(FileUtil::IOFile& file) { | |||
| 56 | static FileType GuessFromExtension(const std::string& extension_) { | 56 | static FileType GuessFromExtension(const std::string& extension_) { |
| 57 | std::string extension = Common::ToLower(extension_); | 57 | std::string extension = Common::ToLower(extension_); |
| 58 | 58 | ||
| 59 | if (extension == ".elf") | 59 | if (extension == ".elf" || extension == ".axf") |
| 60 | return FileType::ELF; | 60 | return FileType::ELF; |
| 61 | else if (extension == ".axf") | 61 | |
| 62 | return FileType::ELF; | 62 | if (extension == ".cci" || extension == ".3ds") |
| 63 | else if (extension == ".cxi") | ||
| 64 | return FileType::CXI; | ||
| 65 | else if (extension == ".cci") | ||
| 66 | return FileType::CCI; | ||
| 67 | else if (extension == ".3ds") | ||
| 68 | return FileType::CCI; | 63 | return FileType::CCI; |
| 69 | else if (extension == ".3dsx") | 64 | |
| 65 | if (extension == ".cxi") | ||
| 66 | return FileType::CXI; | ||
| 67 | |||
| 68 | if (extension == ".3dsx") | ||
| 70 | return FileType::THREEDSX; | 69 | return FileType::THREEDSX; |
| 70 | |||
| 71 | return FileType::Unknown; | 71 | return FileType::Unknown; |
| 72 | } | 72 | } |
| 73 | 73 | ||
diff --git a/src/core/settings.h b/src/core/settings.h index 5a70d157a..2775ee257 100644 --- a/src/core/settings.h +++ b/src/core/settings.h | |||
| @@ -5,34 +5,42 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <string> | 7 | #include <string> |
| 8 | #include <array> | ||
| 8 | 9 | ||
| 9 | namespace Settings { | 10 | namespace Settings { |
| 10 | 11 | ||
| 12 | namespace NativeInput { | ||
| 13 | enum Values { | ||
| 14 | A, B, X, Y, | ||
| 15 | L, R, ZL, ZR, | ||
| 16 | START, SELECT, HOME, | ||
| 17 | DUP, DDOWN, DLEFT, DRIGHT, | ||
| 18 | SUP, SDOWN, SLEFT, SRIGHT, | ||
| 19 | CUP, CDOWN, CLEFT, CRIGHT, | ||
| 20 | NUM_INPUTS | ||
| 21 | }; | ||
| 22 | static const std::array<const char*, NUM_INPUTS> Mapping = { | ||
| 23 | "pad_a", "pad_b", "pad_x", "pad_y", | ||
| 24 | "pad_l", "pad_r", "pad_zl", "pad_zr", | ||
| 25 | "pad_start", "pad_select", "pad_home", | ||
| 26 | "pad_dup", "pad_ddown", "pad_dleft", "pad_dright", | ||
| 27 | "pad_sup", "pad_sdown", "pad_sleft", "pad_sright", | ||
| 28 | "pad_cup", "pad_cdown", "pad_cleft", "pad_cright" | ||
| 29 | }; | ||
| 30 | static const std::array<Values, NUM_INPUTS> All = { | ||
| 31 | A, B, X, Y, | ||
| 32 | L, R, ZL, ZR, | ||
| 33 | START, SELECT, HOME, | ||
| 34 | DUP, DDOWN, DLEFT, DRIGHT, | ||
| 35 | SUP, SDOWN, SLEFT, SRIGHT, | ||
| 36 | CUP, CDOWN, CLEFT, CRIGHT | ||
| 37 | }; | ||
| 38 | } | ||
| 39 | |||
| 40 | |||
| 11 | struct Values { | 41 | struct Values { |
| 12 | // Controls | 42 | // Controls |
| 13 | int pad_a_key; | 43 | std::array<int, NativeInput::NUM_INPUTS> input_mappings; |
| 14 | int pad_b_key; | ||
| 15 | int pad_x_key; | ||
| 16 | int pad_y_key; | ||
| 17 | int pad_l_key; | ||
| 18 | int pad_r_key; | ||
| 19 | int pad_zl_key; | ||
| 20 | int pad_zr_key; | ||
| 21 | int pad_start_key; | ||
| 22 | int pad_select_key; | ||
| 23 | int pad_home_key; | ||
| 24 | int pad_dup_key; | ||
| 25 | int pad_ddown_key; | ||
| 26 | int pad_dleft_key; | ||
| 27 | int pad_dright_key; | ||
| 28 | int pad_sup_key; | ||
| 29 | int pad_sdown_key; | ||
| 30 | int pad_sleft_key; | ||
| 31 | int pad_sright_key; | ||
| 32 | int pad_cup_key; | ||
| 33 | int pad_cdown_key; | ||
| 34 | int pad_cleft_key; | ||
| 35 | int pad_cright_key; | ||
| 36 | 44 | ||
| 37 | // Core | 45 | // Core |
| 38 | int frame_skip; | 46 | int frame_skip; |