mirror of
https://github.com/citra-mirror/citra.git
synced 2024-08-19 18:13:21 +02:00
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:
parent
ac8b38e54d
commit
3409790668
@ -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 =
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,4 +4,4 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
void InterpreterMainLoop(ARMul_State* state);
|
unsigned InterpreterMainLoop(ARMul_State* state);
|
||||||
|
Loading…
Reference in New Issue
Block a user