diff --git a/src/codegen.c b/src/codegen.c index d06438c..dfa9ea4 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -310,7 +310,9 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t int over = 0; int test_modrm = 1; int pc_off = 0; - +#ifdef DEBUG_EXTRA + uint8_t last_prefix = 0; +#endif op_ea_seg = &cpu_state.seg_ds; op_ssegs = 0; @@ -321,6 +323,9 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t switch (opcode) { case 0x0f: +#ifdef DEBUG_EXTRA + last_prefix = 0x0f; +#endif op_table = x86_dynarec_opcodes_0f; recomp_op_table = recomp_opcodes_0f; over = 1; @@ -359,6 +364,9 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t break; case 0xd8: +#ifdef DEBUG_EXTRA + last_prefix = 0xd8; +#endif op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d8_a32 : x86_dynarec_opcodes_d8_a16; recomp_op_table = recomp_opcodes_d8; opcode_shift = 3; @@ -369,6 +377,9 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t block->flags |= CODEBLOCK_HAS_FPU; break; case 0xd9: +#ifdef DEBUG_EXTRA + last_prefix = 0xd9; +#endif op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16; recomp_op_table = recomp_opcodes_d9; opcode_mask = 0xff; @@ -378,6 +389,9 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t block->flags |= CODEBLOCK_HAS_FPU; break; case 0xda: +#ifdef DEBUG_EXTRA + last_prefix = 0xda; +#endif op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16; recomp_op_table = recomp_opcodes_da; opcode_mask = 0xff; @@ -387,6 +401,9 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t block->flags |= CODEBLOCK_HAS_FPU; break; case 0xdb: +#ifdef DEBUG_EXTRA + last_prefix = 0xdb; +#endif op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16; recomp_op_table = recomp_opcodes_db; opcode_mask = 0xff; @@ -396,6 +413,9 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t block->flags |= CODEBLOCK_HAS_FPU; break; case 0xdc: +#ifdef DEBUG_EXTRA + last_prefix = 0xdc; +#endif op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16; recomp_op_table = recomp_opcodes_dc; opcode_shift = 3; @@ -406,6 +426,9 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t block->flags |= CODEBLOCK_HAS_FPU; break; case 0xdd: +#ifdef DEBUG_EXTRA + last_prefix = 0xdd; +#endif op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16; recomp_op_table = recomp_opcodes_dd; opcode_mask = 0xff; @@ -415,6 +438,9 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t block->flags |= CODEBLOCK_HAS_FPU; break; case 0xde: +#ifdef DEBUG_EXTRA + last_prefix = 0xde; +#endif op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16; recomp_op_table = recomp_opcodes_de; opcode_mask = 0xff; @@ -424,6 +450,9 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t block->flags |= CODEBLOCK_HAS_FPU; break; case 0xdf: +#ifdef DEBUG_EXTRA + last_prefix = 0xdf; +#endif op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16; recomp_op_table = recomp_opcodes_df; opcode_mask = 0xff; @@ -437,10 +466,16 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t break; case 0xf2: /*REPNE*/ +#ifdef DEBUG_EXTRA + last_prefix = 0xf2; +#endif op_table = x86_dynarec_opcodes_REPNE; recomp_op_table = NULL;//recomp_opcodes_REPNE; break; case 0xf3: /*REPE*/ +#ifdef DEBUG_EXTRA + last_prefix = 0xf3; +#endif op_table = x86_dynarec_opcodes_REPE; recomp_op_table = NULL;//recomp_opcodes_REPE; break; @@ -525,6 +560,9 @@ generate_call: op_pc -= pc_off; } +#ifdef DEBUG_EXTRA + uop_LOG_INSTR(ir, opcode | (last_prefix << 8)); +#endif uop_MOV_IMM(ir, IREG_pc, op_pc+pc_off); uop_MOV_IMM(ir, IREG_oldpc, old_pc); diff --git a/src/codegen.h b/src/codegen.h index 7136330..dcca68b 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -252,6 +252,7 @@ extern codeblock_t *codeblock; extern codeblock_t **codeblock_hash; void codegen_init(); +void codegen_close(); void codegen_reset(); void codegen_block_init(uint32_t phys_addr); void codegen_block_remove(); @@ -330,4 +331,10 @@ extern int codegen_reg_loaded[8]; extern int codegen_in_recompile; void codegen_generate_reset(); + + +#ifdef DEBUG_EXTRA +extern uint32_t instr_counts[256*256]; +#endif + #endif diff --git a/src/codegen_backend.c b/src/codegen_backend.c index 7d96ec3..fa01aa8 100644 --- a/src/codegen_backend.c +++ b/src/codegen_backend.c @@ -46,10 +46,45 @@ static uint32_t last_op32; static x86seg *last_ea_seg; static int last_ssegs; +#ifdef DEBUG_EXTRA +uint32_t instr_counts[256*256]; +#endif void codegen_init() { codegen_backend_init(); +#ifdef DEBUG_EXTRA + memset(instr_counts, 0, sizeof(instr_counts)); +#endif +} + +void codegen_close() +{ +#ifdef DEBUG_EXTRA + pclog("Instruction counts :\n"); + while (1) + { + int c; + uint32_t highest_num = 0, highest_idx = 0; + + for (c = 0; c < 256*256; c++) + { + if (instr_counts[c] > highest_num) + { + highest_num = instr_counts[c]; + highest_idx = c; + } + } + if (!highest_num) + break; + + instr_counts[highest_idx] = 0; + if (highest_idx > 256) + pclog(" %02x %02x = %u\n", highest_idx >> 8, highest_idx & 0xff, highest_num); + else + pclog(" %02x = %u\n", highest_idx & 0xff, highest_num); + } +#endif } void codegen_reset() diff --git a/src/codegen_backend_x86_ops.c b/src/codegen_backend_x86_ops.c index e477122..33dc124 100644 --- a/src/codegen_backend_x86_ops.c +++ b/src/codegen_backend_x86_ops.c @@ -343,6 +343,12 @@ void host_x86_DIVSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) codegen_addbyte4(block, 0xf2, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); } +void host_x86_INC32_ABS(codeblock_t *block, void *p) +{ + codegen_addbyte2(block, 0xff, 0x05); /*INC p*/ + codegen_addlong(block, (uint32_t)p); +} + void host_x86_JMP(codeblock_t *block, void *p) { codegen_addbyte(block, 0xe9); /*JMP*/ diff --git a/src/codegen_backend_x86_ops.h b/src/codegen_backend_x86_ops.h index cd9eb4e..5084c5e 100644 --- a/src/codegen_backend_x86_ops.h +++ b/src/codegen_backend_x86_ops.h @@ -39,6 +39,8 @@ void host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base void host_x86_DIVSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); +void host_x86_INC32_ABS(codeblock_t *block, void *p); + void host_x86_JMP(codeblock_t *block, void *p); uint32_t *host_x86_JMP_short(codeblock_t *block); uint32_t *host_x86_JMP_long(codeblock_t *block); diff --git a/src/codegen_backend_x86_uops.c b/src/codegen_backend_x86_uops.c index c977bae..a5ff9d9 100644 --- a/src/codegen_backend_x86_uops.c +++ b/src/codegen_backend_x86_uops.c @@ -2192,6 +2192,16 @@ static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) return 0; } +#ifdef DEBUG_EXTRA +static int codegen_LOG_INSTR(codeblock_t *block, uop_t *uop) +{ + if (uop->imm_data > 256*256) + fatal("LOG_INSTR %08x\n", uop->imm_data); + host_x86_INC32_ABS(block, &instr_counts[uop->imm_data]); + return 0; +} +#endif + const uOpFn uop_handlers[UOP_MAX] = { [UOP_CALL_FUNC & UOP_MASK] = codegen_CALL_FUNC, @@ -2334,7 +2344,11 @@ const uOpFn uop_handlers[UOP_MAX] = [UOP_PUNPCKHDQ & UOP_MASK] = codegen_PUNPCKHDQ, [UOP_PUNPCKLBW & UOP_MASK] = codegen_PUNPCKLBW, [UOP_PUNPCKLWD & UOP_MASK] = codegen_PUNPCKLWD, - [UOP_PUNPCKLDQ & UOP_MASK] = codegen_PUNPCKLDQ + [UOP_PUNPCKLDQ & UOP_MASK] = codegen_PUNPCKLDQ, + +#ifdef DEBUG_EXTRA + [UOP_LOG_INSTR & UOP_MASK] = codegen_LOG_INSTR +#endif }; void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) diff --git a/src/codegen_ir_defs.h b/src/codegen_ir_defs.h index eea588f..4a32aa7 100644 --- a/src/codegen_ir_defs.h +++ b/src/codegen_ir_defs.h @@ -54,6 +54,12 @@ #define UOP_CALL_FUNC_RESULT (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x16 | UOP_TYPE_BARRIER) /*UOP_JMP_DEST - jump to ptr*/ #define UOP_JMP_DEST (UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x17 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) + +#ifdef DEBUG_EXTRA +/*UOP_LOG_INSTR - log non-recompiled instruction in imm_data*/ +#define UOP_LOG_INSTR (UOP_TYPE_PARAMS_IMM | 0x1f) +#endif + /*UOP_MOV_PTR - dest_reg = p*/ #define UOP_MOV_PTR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x20) /*UOP_MOV_IMM - dest_reg = imm_data*/ @@ -661,6 +667,10 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, #define uop_TEST_JNS_DEST(ir, src_reg) uop_gen_reg_src1(UOP_TEST_JNS_DEST, ir, src_reg) #define uop_TEST_JS_DEST(ir, src_reg) uop_gen_reg_src1(UOP_TEST_JS_DEST, ir, src_reg) +#ifdef DEBUG_EXTRA +#define uop_LOG_INSTR(ir, imm) uop_gen_imm(UOP_LOG_INSTR, ir, imm) +#endif + void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p); void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p); void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p); diff --git a/src/pc.c b/src/pc.c index faeaa1a..ea77535 100644 --- a/src/pc.c +++ b/src/pc.c @@ -624,6 +624,7 @@ void speedchanged() void closepc() { + codegen_close(); atapi->exit(); // ioctl_close(); dumppic();