summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2014-11-09 01:26:03 -0500
committerGravatar bunnei2014-11-11 19:53:19 -0500
commit34097906684a80f1e131653ebb13659090c5233c (patch)
tree762b0ba25ee315d43d3b1463b7cde2b0d5d25dde /src
parentMerge pull request #189 from archshift/frdu (diff)
downloadyuzu-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.h2
-rw-r--r--src/core/arm/dyncom/arm_dyncom.cpp7
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp33
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.h2
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]
30cpu_core = ## 0: Interpreter (default), 1: FastInterpreter (experimental) 30cpu_core = ## 0: Interpreter (default), 1: FastInterpreter (experimental)
31gpu_refresh_rate = ## 60 (default), 1024 or 2048 may work better on the FastInterpreter 31gpu_refresh_rate = ## 60 (default)
32 32
33[Data Storage] 33[Data Storage]
34use_virtual_sd = 34use_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 */
112void ARM_DynCom::ExecuteInstructions(int num_instructions) { 112void 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 */
3721void InterpreterMainLoop(ARMul_State* state) 3721unsigned 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
7void InterpreterMainLoop(ARMul_State* state); 7unsigned InterpreterMainLoop(ARMul_State* state);