From 5b5a4db6c2963ba72a3adcace6ec055ac65f2f3d Mon Sep 17 00:00:00 2001 From: David Guillen Fandos Date: Sat, 3 Apr 2021 00:37:42 +0200 Subject: Add instruction tracing, for testing purposes --- Makefile | 1 + arm/arm_emit.h | 24 ++++++++++++++++++++++++ arm/arm_stub.S | 23 +++++++++++++++++++---- cpu_threaded.c | 2 ++ psp/mips_emit.h | 18 ++++++++++++++++++ x86/x86_emit.h | 29 +++++++++++++++++++++++++++++ 6 files changed, 93 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 4a5806d..5d28045 100644 --- a/Makefile +++ b/Makefile @@ -434,6 +434,7 @@ ifeq ($(FORCE_32BIT_ARCH), 1) fpic := endif +# Add -DTRACE_INSTRUCTIONS to trace instruction execution ifeq ($(DEBUG), 1) OPTIMIZE_SAFE := -O0 -g OPTIMIZE := -O0 -g diff --git a/arm/arm_emit.h b/arm/arm_emit.h index a5dc930..a6951c2 100644 --- a/arm/arm_emit.h +++ b/arm/arm_emit.h @@ -1227,6 +1227,30 @@ u32 execute_store_cpsr_body(u32 _cpsr, u32 store_mask, u32 address) 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() \ generate_load_reg(reg_a0, rm) \ diff --git a/arm/arm_stub.S b/arm/arm_stub.S index 9779aa5..b8651cf 100644 --- a/arm/arm_stub.S +++ b/arm/arm_stub.S @@ -168,10 +168,25 @@ defsymbl(arm_indirect_branch_##mode) ;\ execute_pc_##mode: ;\ bic r0, r0, #(align) /* Align PC */;\ mov r1, r0, lsr #24 /* Get region */;\ - cmp r1, #2 ;\ - beq 1f /* ewram */;\ - cmp r1, #3 ;\ - beq 2f /* iwram */;\ + ldr pc, [pc, r1, lsl #2] ;\ + nop ;\ + .long 3f /* 0 BIOS (like ROM) */;\ + .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: ;\ call_c_function(block_lookup_address_##mode) ;\ restore_flags() ;\ diff --git a/cpu_threaded.c b/cpu_threaded.c index e5c027e..a32b1b8 100644 --- a/cpu_threaded.c +++ b/cpu_threaded.c @@ -264,6 +264,7 @@ void translate_icache_sync() { check_pc_region(pc); \ opcode = address32(pc_address_block, (pc & 0x7FFF)); \ condition = block_data[block_data_position].condition; \ + emit_trace_arm_instruction(pc); \ \ if((condition != last_condition) || (condition >= 0x20)) \ { \ @@ -1703,6 +1704,7 @@ void translate_icache_sync() { check_pc_region(pc); \ last_opcode = opcode; \ opcode = address16(pc_address_block, (pc & 0x7FFF)); \ + emit_trace_thumb_instruction(pc); \ \ switch((opcode >> 8) & 0xFF) \ { \ diff --git a/psp/mips_emit.h b/psp/mips_emit.h index 818b724..a435e63 100644 --- a/psp/mips_emit.h +++ b/psp/mips_emit.h @@ -2422,6 +2422,24 @@ u32 execute_store_cpsr_body(u32 _cpsr, u32 store_mask, u32 address) 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() \ generate_swi_hle_handler(opcode & 0xFF); \ generate_load_pc(reg_a0, (pc + 2)); \ diff --git a/x86/x86_emit.h b/x86/x86_emit.h index 68930e1..ef79110 100644 --- a/x86/x86_emit.h +++ b/x86/x86_emit.h @@ -96,6 +96,7 @@ typedef enum x86_opcode_push_reg = 0x50, x86_opcode_push_rm = 0xFF, x86_opcode_push_imm = 0x0668, + x86_opcode_pop_reg = 0x58, x86_opcode_call_offset = 0xE8, x86_opcode_ret = 0xC3, x86_opcode_test_rm_imm = 0x00F7, @@ -266,6 +267,12 @@ typedef enum #define x86_emit_idiv_eax_reg(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) \ 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_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) { if(shift != 0) -- cgit v1.2.3