1
0
Fork 0
forked from suyu/suyu

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.
This commit is contained in:
bunnei 2014-11-09 01:26:03 -05:00
parent ac8b38e54d
commit 3409790668
4 changed files with 26 additions and 18 deletions

View file

@ -28,7 +28,7 @@ pad_sright =
[Core] [Core]
cpu_core = ## 0: Interpreter (default), 1: FastInterpreter (experimental) cpu_core = ## 0: Interpreter (default), 1: FastInterpreter (experimental)
gpu_refresh_rate = ## 60 (default), 1024 or 2048 may work better on the FastInterpreter gpu_refresh_rate = ## 60 (default)
[Data Storage] [Data Storage]
use_virtual_sd = use_virtual_sd =

View file

@ -110,9 +110,12 @@ u64 ARM_DynCom::GetTicks() const {
* @param num_instructions Number of instructions to executes * @param num_instructions Number of instructions to executes
*/ */
void ARM_DynCom::ExecuteInstructions(int num_instructions) { void ARM_DynCom::ExecuteInstructions(int num_instructions) {
ticks += num_instructions;
state->NumInstrsToExecute = num_instructions; state->NumInstrsToExecute = num_instructions;
InterpreterMainLoop(state.get());
// Dyncom only breaks on instruction dispatch. This only happens on every instruction when
// executing one instruction at a time. Otherwise, if a block is being executed, more
// instructions may actually be executed than specified.
ticks += InterpreterMainLoop(state.get());
} }
/** /**

View file

@ -3718,7 +3718,7 @@ static bool InAPrivilegedMode(arm_core_t *core)
} }
/* r15 = r15 + 8 */ /* r15 = r15 + 8 */
void InterpreterMainLoop(ARMul_State* state) unsigned InterpreterMainLoop(ARMul_State* state)
{ {
#define CRn inst_cream->crn #define CRn inst_cream->crn
#define OPCODE_2 inst_cream->opcode_2 #define OPCODE_2 inst_cream->opcode_2
@ -3754,9 +3754,15 @@ void InterpreterMainLoop(ARMul_State* state)
// GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback to a // GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback to a
// clunky switch statement. // clunky switch statement.
#if defined __GNUC__ || defined __clang__ #if defined __GNUC__ || defined __clang__
#define GOTO_NEXT_INST goto *InstLabel[inst_base->idx] #define GOTO_NEXT_INST \
if (num_instrs >= cpu->NumInstrsToExecute) goto END; \
num_instrs++; \
goto *InstLabel[inst_base->idx]
#else #else
#define GOTO_NEXT_INST switch(inst_base->idx) { \ #define GOTO_NEXT_INST \
if (num_instrs >= cpu->NumInstrsToExecute) goto END; \
num_instrs++; \
switch(inst_base->idx) { \
case 0: goto VMLA_INST; \ case 0: goto VMLA_INST; \
case 1: goto VMLS_INST; \ case 1: goto VMLS_INST; \
case 2: goto VNMLA_INST; \ case 2: goto VNMLA_INST; \
@ -4028,20 +4034,15 @@ void InterpreterMainLoop(ARMul_State* state)
unsigned int addr; unsigned int addr;
unsigned int phys_addr; unsigned int phys_addr;
unsigned int last_pc = 0; unsigned int last_pc = 0;
unsigned int num_instrs = 0;
fault_t fault; fault_t fault;
static unsigned int last_physical_base = 0, last_logical_base = 0; static unsigned int last_physical_base = 0, last_logical_base = 0;
int ptr; int ptr;
bool single_step = (cpu->NumInstrsToExecute == 1);
LOAD_NZCVT; LOAD_NZCVT;
DISPATCH: DISPATCH:
{ {
if (cpu->NumInstrsToExecute == 0)
return;
cpu->NumInstrsToExecute--;
//NOTICE_LOG(ARM11, "instr!");
if (!cpu->NirqSig) { if (!cpu->NirqSig) {
if (!(cpu->Cpsr & 0x80)) { if (!(cpu->Cpsr & 0x80)) {
goto END; goto END;
@ -4393,7 +4394,8 @@ void InterpreterMainLoop(ARMul_State* state)
#define CP_ACCESS_ALLOW 0 #define CP_ACCESS_ALLOW 0
if(CP_ACCESS_ALLOW){ if(CP_ACCESS_ALLOW){
/* undefined instruction here */ /* undefined instruction here */
return; cpu->NumInstrsToExecute = 0;
return num_instrs;
} }
ERROR_LOG(ARM11, "CDP insn inst=0x%x, pc=0x%x\n", inst_cream->inst, cpu->Reg[15]); ERROR_LOG(ARM11, "CDP insn inst=0x%x, pc=0x%x\n", inst_cream->inst, cpu->Reg[15]);
unsigned cpab = (cpu->CDP[inst_cream->cp_num]) (cpu, ARMul_FIRST, inst_cream->inst); unsigned cpab = (cpu->CDP[inst_cream->cp_num]) (cpu, ARMul_FIRST, inst_cream->inst);
@ -6532,12 +6534,14 @@ void InterpreterMainLoop(ARMul_State* state)
cpu->AbortAddr = addr; cpu->AbortAddr = addr;
cpu->CP15[CP15(CP15_FAULT_STATUS)] = fault & 0xff; cpu->CP15[CP15(CP15_FAULT_STATUS)] = fault & 0xff;
cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = addr; cpu->CP15[CP15(CP15_FAULT_ADDRESS)] = addr;
return; cpu->NumInstrsToExecute = 0;
return num_instrs;
} }
END: END:
{ {
SAVE_NZCVT; SAVE_NZCVT;
return; cpu->NumInstrsToExecute = 0;
return num_instrs;
} }
INIT_INST_LENGTH: INIT_INST_LENGTH:
{ {
@ -6557,7 +6561,8 @@ void InterpreterMainLoop(ARMul_State* state)
DEBUG_LOG(ARM11, "%llx\n", InstLabel[1]); DEBUG_LOG(ARM11, "%llx\n", InstLabel[1]);
DEBUG_LOG(ARM11, "%lld\n", (char *)InstEndLabel[1] - (char *)InstLabel[1]); DEBUG_LOG(ARM11, "%lld\n", (char *)InstEndLabel[1] - (char *)InstLabel[1]);
#endif #endif
return; cpu->NumInstrsToExecute = 0;
return num_instrs;
} }
} }

View file

@ -4,4 +4,4 @@
#pragma once #pragma once
void InterpreterMainLoop(ARMul_State* state); unsigned InterpreterMainLoop(ARMul_State* state);