Add instruction tracing, for testing purposes
This commit is contained in:
parent
8c14ac9619
commit
5b5a4db6c2
6 changed files with 93 additions and 4 deletions
1
Makefile
1
Makefile
|
@ -434,6 +434,7 @@ ifeq ($(FORCE_32BIT_ARCH), 1)
|
||||||
fpic :=
|
fpic :=
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# Add -DTRACE_INSTRUCTIONS to trace instruction execution
|
||||||
ifeq ($(DEBUG), 1)
|
ifeq ($(DEBUG), 1)
|
||||||
OPTIMIZE_SAFE := -O0 -g
|
OPTIMIZE_SAFE := -O0 -g
|
||||||
OPTIMIZE := -O0 -g
|
OPTIMIZE := -O0 -g
|
||||||
|
|
|
@ -1227,6 +1227,30 @@ u32 execute_store_cpsr_body(u32 _cpsr, u32 store_mask, u32 address)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TRACE_INSTRUCTIONS
|
||||||
|
void trace_instruction(u32 pc)
|
||||||
|
{
|
||||||
|
printf("Executed %x\n", pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define emit_trace_instruction(pc) \
|
||||||
|
generate_save_flags(); \
|
||||||
|
ARM_LDR_IMM(0, ARMREG_SP, reg_base, 34*4); \
|
||||||
|
ARM_STMDB_WB(0, ARMREG_SP, 0x500C); \
|
||||||
|
arm_load_imm_32bit(reg_a0, pc); \
|
||||||
|
generate_function_call(trace_instruction); \
|
||||||
|
ARM_LDMIA_WB(0, ARMREG_SP, 0x500C); \
|
||||||
|
arm_load_imm_32bit(ARMREG_SP, (u32)reg); \
|
||||||
|
generate_restore_flags();
|
||||||
|
#define emit_trace_thumb_instruction(pc) \
|
||||||
|
emit_trace_instruction(pc)
|
||||||
|
#define emit_trace_arm_instruction(pc) \
|
||||||
|
emit_trace_instruction(pc)
|
||||||
|
#else
|
||||||
|
#define emit_trace_thumb_instruction(pc)
|
||||||
|
#define emit_trace_arm_instruction(pc)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define arm_psr_load_new_reg() \
|
#define arm_psr_load_new_reg() \
|
||||||
generate_load_reg(reg_a0, rm) \
|
generate_load_reg(reg_a0, rm) \
|
||||||
|
|
||||||
|
|
|
@ -168,10 +168,25 @@ defsymbl(arm_indirect_branch_##mode) ;\
|
||||||
execute_pc_##mode: ;\
|
execute_pc_##mode: ;\
|
||||||
bic r0, r0, #(align) /* Align PC */;\
|
bic r0, r0, #(align) /* Align PC */;\
|
||||||
mov r1, r0, lsr #24 /* Get region */;\
|
mov r1, r0, lsr #24 /* Get region */;\
|
||||||
cmp r1, #2 ;\
|
ldr pc, [pc, r1, lsl #2] ;\
|
||||||
beq 1f /* ewram */;\
|
nop ;\
|
||||||
cmp r1, #3 ;\
|
.long 3f /* 0 BIOS (like ROM) */;\
|
||||||
beq 2f /* iwram */;\
|
.long 3f /* 1 Bad region */;\
|
||||||
|
.long 1f /* 2 EWRAM */;\
|
||||||
|
.long 2f /* 3 IWRAM */;\
|
||||||
|
.long 3f /* 4 Not supported */;\
|
||||||
|
.long 3f /* 5 Not supported */;\
|
||||||
|
.long 3f /* 6 Not supported */;\
|
||||||
|
.long 3f /* 7 Not supported */;\
|
||||||
|
.long 3f /* 8 ROM */;\
|
||||||
|
.long 3f /* 9 ROM */;\
|
||||||
|
.long 3f /* A ROM */;\
|
||||||
|
.long 3f /* B ROM */;\
|
||||||
|
.long 3f /* C ROM */;\
|
||||||
|
.long 3f /* D ROM */;\
|
||||||
|
.long 3f /* E ROM */;\
|
||||||
|
.long 3f /* F Bad region */;\
|
||||||
|
;\
|
||||||
3: ;\
|
3: ;\
|
||||||
call_c_function(block_lookup_address_##mode) ;\
|
call_c_function(block_lookup_address_##mode) ;\
|
||||||
restore_flags() ;\
|
restore_flags() ;\
|
||||||
|
|
|
@ -264,6 +264,7 @@ void translate_icache_sync() {
|
||||||
check_pc_region(pc); \
|
check_pc_region(pc); \
|
||||||
opcode = address32(pc_address_block, (pc & 0x7FFF)); \
|
opcode = address32(pc_address_block, (pc & 0x7FFF)); \
|
||||||
condition = block_data[block_data_position].condition; \
|
condition = block_data[block_data_position].condition; \
|
||||||
|
emit_trace_arm_instruction(pc); \
|
||||||
\
|
\
|
||||||
if((condition != last_condition) || (condition >= 0x20)) \
|
if((condition != last_condition) || (condition >= 0x20)) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -1703,6 +1704,7 @@ void translate_icache_sync() {
|
||||||
check_pc_region(pc); \
|
check_pc_region(pc); \
|
||||||
last_opcode = opcode; \
|
last_opcode = opcode; \
|
||||||
opcode = address16(pc_address_block, (pc & 0x7FFF)); \
|
opcode = address16(pc_address_block, (pc & 0x7FFF)); \
|
||||||
|
emit_trace_thumb_instruction(pc); \
|
||||||
\
|
\
|
||||||
switch((opcode >> 8) & 0xFF) \
|
switch((opcode >> 8) & 0xFF) \
|
||||||
{ \
|
{ \
|
||||||
|
|
|
@ -2422,6 +2422,24 @@ u32 execute_store_cpsr_body(u32 _cpsr, u32 store_mask, u32 address)
|
||||||
generate_indirect_branch_cycle_update(dual); \
|
generate_indirect_branch_cycle_update(dual); \
|
||||||
} \
|
} \
|
||||||
|
|
||||||
|
#ifdef TRACE_INSTRUCTIONS
|
||||||
|
void trace_instruction(u32 pc)
|
||||||
|
{
|
||||||
|
printf("Executed %x\n", pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define emit_trace_instruction(pc) \
|
||||||
|
emit_save_regs(false); \
|
||||||
|
generate_load_imm(reg_a0, pc); \
|
||||||
|
genccall(&trace_instruction); \
|
||||||
|
emit_restore_regs(false)
|
||||||
|
#define emit_trace_thumb_instruction(pc) emit_trace_instruction(pc)
|
||||||
|
#define emit_trace_arm_instruction(pc) emit_trace_instruction(pc)
|
||||||
|
#else
|
||||||
|
#define emit_trace_thumb_instruction(pc)
|
||||||
|
#define emit_trace_arm_instruction(pc)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define thumb_swi() \
|
#define thumb_swi() \
|
||||||
generate_swi_hle_handler(opcode & 0xFF); \
|
generate_swi_hle_handler(opcode & 0xFF); \
|
||||||
generate_load_pc(reg_a0, (pc + 2)); \
|
generate_load_pc(reg_a0, (pc + 2)); \
|
||||||
|
|
|
@ -96,6 +96,7 @@ typedef enum
|
||||||
x86_opcode_push_reg = 0x50,
|
x86_opcode_push_reg = 0x50,
|
||||||
x86_opcode_push_rm = 0xFF,
|
x86_opcode_push_rm = 0xFF,
|
||||||
x86_opcode_push_imm = 0x0668,
|
x86_opcode_push_imm = 0x0668,
|
||||||
|
x86_opcode_pop_reg = 0x58,
|
||||||
x86_opcode_call_offset = 0xE8,
|
x86_opcode_call_offset = 0xE8,
|
||||||
x86_opcode_ret = 0xC3,
|
x86_opcode_ret = 0xC3,
|
||||||
x86_opcode_test_rm_imm = 0x00F7,
|
x86_opcode_test_rm_imm = 0x00F7,
|
||||||
|
@ -266,6 +267,12 @@ typedef enum
|
||||||
#define x86_emit_idiv_eax_reg(source) \
|
#define x86_emit_idiv_eax_reg(source) \
|
||||||
x86_emit_opcode_1b_ext_reg(idiv_eax_rm, source) \
|
x86_emit_opcode_1b_ext_reg(idiv_eax_rm, source) \
|
||||||
|
|
||||||
|
#define x86_emit_pop_reg(regn) \
|
||||||
|
x86_emit_opcode_1b(pop_reg, regn) \
|
||||||
|
|
||||||
|
#define x86_emit_push_reg(regn) \
|
||||||
|
x86_emit_opcode_1b(push_reg, regn) \
|
||||||
|
|
||||||
#define x86_emit_push_mem(base, offset) \
|
#define x86_emit_push_mem(base, offset) \
|
||||||
x86_emit_opcode_1b_mem(push_rm, 0x06, base, offset) \
|
x86_emit_opcode_1b_mem(push_rm, 0x06, base, offset) \
|
||||||
|
|
||||||
|
@ -523,6 +530,28 @@ typedef enum
|
||||||
generate_function_call(execute_##name##_##flags_op##_reg); \
|
generate_function_call(execute_##name##_##flags_op##_reg); \
|
||||||
generate_mov(ireg, rv) \
|
generate_mov(ireg, rv) \
|
||||||
|
|
||||||
|
#ifdef TRACE_INSTRUCTIONS
|
||||||
|
void function_cc trace_instruction(u32 pc)
|
||||||
|
{
|
||||||
|
printf("Executed %x\n", pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define emit_trace_thumb_instruction(pc) \
|
||||||
|
x86_emit_push_reg(eax); \
|
||||||
|
x86_emit_push_reg(ecx); \
|
||||||
|
x86_emit_push_reg(edx); \
|
||||||
|
x86_emit_mov_reg_imm(eax, pc); \
|
||||||
|
generate_function_call(trace_instruction); \
|
||||||
|
x86_emit_pop_reg(edx); \
|
||||||
|
x86_emit_pop_reg(ecx); \
|
||||||
|
x86_emit_pop_reg(eax);
|
||||||
|
#define emit_trace_arm_instruction(pc) \
|
||||||
|
emit_trace_thumb_instruction(pc)
|
||||||
|
#else
|
||||||
|
#define emit_trace_thumb_instruction(pc)
|
||||||
|
#define emit_trace_arm_instruction(pc)
|
||||||
|
#endif
|
||||||
|
|
||||||
u32 function_cc execute_lsl_no_flags_reg(u32 value, u32 shift)
|
u32 function_cc execute_lsl_no_flags_reg(u32 value, u32 shift)
|
||||||
{
|
{
|
||||||
if(shift != 0)
|
if(shift != 0)
|
||||||
|
|
Loading…
Add table
Reference in a new issue