diff options
| author | 2014-11-09 01:26:03 -0500 | |
|---|---|---|
| committer | 2014-11-11 19:53:19 -0500 | |
| commit | 34097906684a80f1e131653ebb13659090c5233c (patch) | |
| tree | 762b0ba25ee315d43d3b1463b7cde2b0d5d25dde /src | |
| parent | Merge pull request #189 from archshift/frdu (diff) | |
| download | yuzu-34097906684a80f1e131653ebb13659090c5233c.tar.gz yuzu-34097906684a80f1e131653ebb13659090c5233c.tar.xz yuzu-34097906684a80f1e131653ebb13659090c5233c.zip | |
ARM: Fixed several dyncom bugs.
- Fixed NZCVT flags to properly save state when function returns.
- Fixed counter to keep track of the actual number of instructions executed.
- Fixed single-step mode to only execute one instruction at a time.
- DefaultIni: Removed comment that no longer applied to dyncom.
Diffstat (limited to 'src')
| -rw-r--r-- | src/citra/default_ini.h | 2 | ||||
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom.cpp | 7 | ||||
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_interpreter.cpp | 33 | ||||
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_interpreter.h | 2 |
4 files changed, 26 insertions, 18 deletions
diff --git a/src/citra/default_ini.h b/src/citra/default_ini.h index 7352c70c2..557da881b 100644 --- a/src/citra/default_ini.h +++ b/src/citra/default_ini.h | |||
| @@ -28,7 +28,7 @@ pad_sright = | |||
| 28 | 28 | ||
| 29 | [Core] | 29 | [Core] |
| 30 | cpu_core = ## 0: Interpreter (default), 1: FastInterpreter (experimental) | 30 | cpu_core = ## 0: Interpreter (default), 1: FastInterpreter (experimental) |
| 31 | gpu_refresh_rate = ## 60 (default), 1024 or 2048 may work better on the FastInterpreter | 31 | gpu_refresh_rate = ## 60 (default) |
| 32 | 32 | ||
| 33 | [Data Storage] | 33 | [Data Storage] |
| 34 | use_virtual_sd = | 34 | use_virtual_sd = |
diff --git a/src/core/arm/dyncom/arm_dyncom.cpp b/src/core/arm/dyncom/arm_dyncom.cpp index 669b612fc..0b5dcccb9 100644 --- a/src/core/arm/dyncom/arm_dyncom.cpp +++ b/src/core/arm/dyncom/arm_dyncom.cpp | |||
| @@ -110,9 +110,12 @@ u64 ARM_DynCom::GetTicks() const { | |||
| 110 | * @param num_instructions Number of instructions to executes | 110 | * @param num_instructions Number of instructions to executes |
| 111 | */ | 111 | */ |
| 112 | void ARM_DynCom::ExecuteInstructions(int num_instructions) { | 112 | void ARM_DynCom::ExecuteInstructions(int num_instructions) { |
| 113 | ticks += num_instructions; | ||
| 114 | state->NumInstrsToExecute = num_instructions; | 113 | state->NumInstrsToExecute = num_instructions; |
| 115 | InterpreterMainLoop(state.get()); | 114 | |
| 115 | // Dyncom only breaks on instruction dispatch. This only happens on every instruction when | ||
| 116 | // executing one instruction at a time. Otherwise, if a block is being executed, more | ||
| 117 | // instructions may actually be executed than specified. | ||
| 118 | ticks += InterpreterMainLoop(state.get()); | ||
| 116 | } | 119 | } |
| 117 | 120 | ||
| 118 | /** | 121 | /** |
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp index fe1501b59..f56a84518 100644 --- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp +++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp | |||
| @@ -3718,7 +3718,7 @@ static bool InAPrivilegedMode(arm_core_t *core) | |||
| 3718 | } | 3718 | } |
| 3719 | 3719 | ||
| 3720 | /* r15 = r15 + 8 */ | 3720 | /* r15 = r15 + 8 */ |
| 3721 | void InterpreterMainLoop(ARMul_State* state) | 3721 | unsigned InterpreterMainLoop(ARMul_State* state) |
| 3722 | { | 3722 | { |
| 3723 | #define CRn inst_cream->crn | 3723 | #define CRn inst_cream->crn |
| 3724 | #define OPCODE_2 inst_cream->opcode_2 | 3724 | #define OPCODE_2 inst_cream->opcode_2 |
| @@ -3754,9 +3754,15 @@ void InterpreterMainLoop(ARMul_State* state) | |||
| 3754 | // GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback to a | 3754 | // GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback to a |
| 3755 | // clunky switch statement. | 3755 | // clunky switch statement. |
| 3756 | #if defined __GNUC__ || defined __clang__ | 3756 | #if defined __GNUC__ || defined __clang__ |
| 3757 | #define GOTO_NEXT_INST goto *InstLabel[inst_base->idx] | 3757 | #define GOTO_NEXT_INST \ |
| 3758 | if (num_instrs >= cpu->NumInstrsToExecute) goto END; \ | ||
| 3759 | num_instrs++; \ | ||
| 3760 | goto *InstLabel[inst_base->idx] | ||
| 3758 | #else | 3761 | #else |
| 3759 | #define GOTO_NEXT_INST switch(inst_base->idx) { \ | 3762 | #define GOTO_NEXT_INST \ |
| 3763 | if (num_instrs >= cpu->NumInstrsToExecute) goto END; \ | ||
| 3764 | num_instrs++; \ | ||
| 3765 | switch(inst_base->idx) { \ | ||
| 3760 | case 0: goto VMLA_INST; \ | 3766 | case 0: goto VMLA_INST; \ |
| 3761 | case 1: goto VMLS_INST; \ | 3767 | case 1: goto VMLS_INST; \ |
| 3762 | case 2: goto VNMLA_INST; \ | 3768 | case 2: goto VNMLA_INST; \ |
| @@ -4028,20 +4034,15 @@ void InterpreterMainLoop(ARMul_State* state) | |||
| 4028 | unsigned int addr; | 4034 | unsigned int addr; |
| 4029 | unsigned int phys_addr; | 4035 | unsigned int phys_addr; |
| 4030 | unsigned int last_pc = 0; | 4036 | unsigned int last_pc = 0; |
| 4037 | unsigned int num_instrs = 0; | ||
| 4031 | fault_t fault; | 4038 | fault_t fault; |
| 4032 | static unsigned int last_physical_base = 0, last_logical_base = 0; | 4039 | static unsigned int last_physical_base = 0, last_logical_base = 0; |
| 4033 | int ptr; | 4040 | int ptr; |
| 4041 | bool single_step = (cpu->NumInstrsToExecute == 1); | ||
| 4034 | 4042 | ||
| 4035 | LOAD_NZCVT; | 4043 | LOAD_NZCVT; |
| 4036 | DISPATCH: | 4044 | DISPATCH: |
| 4037 | { | 4045 | { |
| 4038 | if (cpu->NumInstrsToExecute == 0) | ||
| 4039 | return; | ||
| 4040 | |||
| 4041 | cpu->NumInstrsToExecute--; | ||
| 4042 | |||
| 4043 | //NOTICE_LOG(ARM11, "instr!"); | ||
| 4044 | |||
| 4045 | if (!cpu->NirqSig) { | 4046 | if (!cpu->NirqSig) { |
| 4046 | if (!(cpu->Cpsr & 0x80)) { | 4047 | if (!(cpu->Cpsr & 0x80)) { |
| 4047 | goto END; | 4048 | goto END; |
| @@ -4393,7 +4394,8 @@ void InterpreterMainLoop(ARMul_State* state) | |||
| 4393 | #define CP_ACCESS_ALLOW 0 | 4394 | #define CP_ACCESS_ALLOW 0 |
| 4394 | if(CP_ACCESS_ALLOW){ | 4395 | if(CP_ACCESS_ALLOW){ |
| 4395 | /* undefined instruction here */ | 4396 | /* undefined instruction here */ |
| 4396 | return; | 4397 | cpu->NumInstrsToExecute = 0; |
| 4398 | return num_instrs; | ||
| 4397 | } | 4399 | } |
| 4398 | ERROR_LOG(ARM11, "CDP insn inst=0x%x, pc=0x%x\n", inst_cream->inst, cpu->Reg[15]); | 4400 | ERROR_LOG(ARM11, "CDP insn inst=0x%x, pc=0x%x\n", inst_cream->inst, cpu->Reg[15]); |
| 4399 | unsigned cpab = (cpu->CDP[inst_cream->cp_num]) (cpu, ARMul_FIRST, inst_cream->inst); | 4401 | unsigned cpab = (cpu->CDP[inst_cream->cp_num]) (cpu, ARMul_FIRST, inst_cream->inst); |
| @@ -6532,12 +6534,14 @@ void InterpreterMainLoop(ARMul_State* state) | |||
| 6532 | cpu->AbortAddr = addr; | 6534 | cpu->AbortAddr = addr; |
| 6533 | cpu->CP15[CP15(CP15_FAULT_STATUS)] = fault & 0xff; | 6535 | cpu->CP15[CP15(CP15_FAULT_STATUS)] = fault & 0xff; |
| 6534 | cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = addr; | 6536 | cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = addr; |
| 6535 | return; | 6537 | cpu->NumInstrsToExecute = 0; |
| 6538 | return num_instrs; | ||
| 6536 | } | 6539 | } |
| 6537 | END: | 6540 | END: |
| 6538 | { | 6541 | { |
| 6539 | SAVE_NZCVT; | 6542 | SAVE_NZCVT; |
| 6540 | return; | 6543 | cpu->NumInstrsToExecute = 0; |
| 6544 | return num_instrs; | ||
| 6541 | } | 6545 | } |
| 6542 | INIT_INST_LENGTH: | 6546 | INIT_INST_LENGTH: |
| 6543 | { | 6547 | { |
| @@ -6557,7 +6561,8 @@ void InterpreterMainLoop(ARMul_State* state) | |||
| 6557 | DEBUG_LOG(ARM11, "%llx\n", InstLabel[1]); | 6561 | DEBUG_LOG(ARM11, "%llx\n", InstLabel[1]); |
| 6558 | DEBUG_LOG(ARM11, "%lld\n", (char *)InstEndLabel[1] - (char *)InstLabel[1]); | 6562 | DEBUG_LOG(ARM11, "%lld\n", (char *)InstEndLabel[1] - (char *)InstLabel[1]); |
| 6559 | #endif | 6563 | #endif |
| 6560 | return; | 6564 | cpu->NumInstrsToExecute = 0; |
| 6565 | return num_instrs; | ||
| 6561 | } | 6566 | } |
| 6562 | } | 6567 | } |
| 6563 | 6568 | ||
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.h b/src/core/arm/dyncom/arm_dyncom_interpreter.h index d73f8f65f..c65eb23f7 100644 --- a/src/core/arm/dyncom/arm_dyncom_interpreter.h +++ b/src/core/arm/dyncom/arm_dyncom_interpreter.h | |||
| @@ -4,4 +4,4 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | void InterpreterMainLoop(ARMul_State* state); | 7 | unsigned InterpreterMainLoop(ARMul_State* state); |