From 774f4201ee9239670577e2aaf78982fbbeb0a46c Mon Sep 17 00:00:00 2001 From: SarahW Date: Fri, 6 Jul 2018 17:51:22 +0100 Subject: [PATCH] Recompiler now handles instruction and cycle counting. --- src/386_dynarec_ops.c | 2 +- src/codegen.c | 18 +++++++++++++-- src/codegen_accumulate.c | 50 ++++++++++++++++++++++++++++++++++++++++ src/codegen_accumulate.h | 13 +++++++++++ src/codegen_backend.c | 3 +++ src/codegen_ir.c | 2 ++ src/codegen_reg.c | 7 ++++++ src/codegen_reg.h | 11 +++++---- 8 files changed, 99 insertions(+), 7 deletions(-) create mode 100644 src/codegen_accumulate.c create mode 100644 src/codegen_accumulate.h diff --git a/src/386_dynarec_ops.c b/src/386_dynarec_ops.c index 5377a27..342e138 100644 --- a/src/386_dynarec_ops.c +++ b/src/386_dynarec_ops.c @@ -58,7 +58,7 @@ static inline void fetch_ea_16_long(uint32_t rmdat) #define OP_TABLE(name) dynarec_ops_ ## name /*Temporary*/ -#define CLOCK_CYCLES(c) cycles -= (c) +#define CLOCK_CYCLES(c) #define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) #include "386_ops.h" diff --git a/src/codegen.c b/src/codegen.c index eb7bd78..87184da 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -6,6 +6,7 @@ #include "386_common.h" +#include "codegen_accumulate.h" #include "codegen_backend.h" #include "codegen_ir.h" @@ -262,7 +263,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t op_ea_seg = &_ds; - op_ea_seg = &_ds; + codegen_timing_start(); while (!over) { @@ -397,7 +398,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t goto generate_call; } fetchdat = fastreadl(cs + op_pc); -// codegen_timing_prefix(opcode, fetchdat); + codegen_timing_prefix(opcode, fetchdat); if (cpu_state.abrt) return; opcode = fetchdat & 0xff; @@ -408,6 +409,19 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t } generate_call: + codegen_timing_opcode(opcode, fetchdat, op_32); + + codegen_accumulate(ACCREG_ins, 1); + codegen_accumulate(ACCREG_cycles, -codegen_block_cycles); + codegen_block_cycles = 0; + + if ((op_table == x86_dynarec_opcodes && + ((opcode & 0xf0) == 0x70 || (opcode & 0xfc) == 0xe0 || opcode == 0xc2 || + (opcode & 0xfe) == 0xca || (opcode & 0xfc) == 0xcc || (opcode & 0xfc) == 0xe8 || + (opcode == 0xff && ((fetchdat & 0x38) >= 0x10 && (fetchdat & 0x38) < 0x30)))) || + (op_table == x86_dynarec_opcodes_0f && ((opcode & 0xf0) == 0x80))) + codegen_accumulate_flush(ir); + //pclog("%04x:%08x : %02x\n", CS, new_pc, opcode); op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask]; diff --git a/src/codegen_accumulate.c b/src/codegen_accumulate.c new file mode 100644 index 0000000..968b7a5 --- /dev/null +++ b/src/codegen_accumulate.c @@ -0,0 +1,50 @@ +#include "ibm.h" +#include "codegen.h" +#include "codegen_accumulate.h" +#include "codegen_ir.h" + +static struct +{ + int count; + int dest_reg; +} acc_regs[] = +{ + [ACCREG_ins] = {0, IREG_ins}, + [ACCREG_cycles] = {0, IREG_cycles}, +}; + +void codegen_accumulate(int acc_reg, int delta) +{ + if (acc_reg == ACCREG_cycles) + { +// pclog("cycles %04x:%04x %i\n", CS, cpu_state.pc, delta); +// if (CS == 0x1000 && cpu_state.pc == 0x863) +// fatal("Here\n"); + } + acc_regs[acc_reg].count += delta; +} + +void codegen_accumulate_flush(ir_data_t *ir) +{ + int c; + + for (c = 0; c < ACCREG_COUNT; c++) + { + if (acc_regs[c].count) + { +// if (c == ACCREG_cycles) +// pclog("accumulate %i %i %i\n", c, acc_regs[c].dest_reg, acc_regs[c].count); + uop_ADD_IMM(ir, acc_regs[c].dest_reg, acc_regs[c].dest_reg, acc_regs[c].count); + } + + acc_regs[c].count = 0; + } +} + +void codegen_accumulate_reset() +{ + int c; + + for (c = 0; c < ACCREG_COUNT; c++) + acc_regs[c].count = 0; +} diff --git a/src/codegen_accumulate.h b/src/codegen_accumulate.h new file mode 100644 index 0000000..6c19499 --- /dev/null +++ b/src/codegen_accumulate.h @@ -0,0 +1,13 @@ +enum +{ + ACCREG_ins = 0, + ACCREG_cycles = 1, + + ACCREG_COUNT +}; + +struct ir_data_t; + +void codegen_accumulate(int acc_reg, int delta); +void codegen_accumulate_flush(struct ir_data_t *ir); +void codegen_accumulate_reset(); diff --git a/src/codegen_backend.c b/src/codegen_backend.c index 2754f5e..afc6716 100644 --- a/src/codegen_backend.c +++ b/src/codegen_backend.c @@ -10,6 +10,7 @@ #include "386_common.h" #include "codegen.h" +#include "codegen_accumulate.h" #include "codegen_backend.h" #include "codegen_ir.h" #include "codegen_reg.h" @@ -310,6 +311,7 @@ void codegen_block_start_recompile(codeblock_t *block) ir_data = codegen_ir_init(); codegen_reg_reset(); + codegen_accumulate_reset(); codegen_generate_reset(); } @@ -410,6 +412,7 @@ void codegen_block_end_recompile(codeblock_t *block) if (!(block->flags & CODEBLOCK_HAS_FPU)) block->flags &= ~CODEBLOCK_STATIC_TOP; + codegen_accumulate_flush(ir_data); codegen_ir_compile(ir_data, block); } diff --git a/src/codegen_ir.c b/src/codegen_ir.c index 9099aea..36bea69 100644 --- a/src/codegen_ir.c +++ b/src/codegen_ir.c @@ -50,6 +50,8 @@ void codegen_ir_compile(ir_data_t *ir, codeblock_t *block) uop_handlers[uop->type & UOP_MASK](block, uop); } + codegen_reg_flush(ir, block); + codegen_backend_epilogue(block); // if (has_ea) diff --git a/src/codegen_reg.c b/src/codegen_reg.c index c2ca44d..e8e1410 100644 --- a/src/codegen_reg.c +++ b/src/codegen_reg.c @@ -54,6 +54,9 @@ struct [IREG_rm_mod_reg] = {REG_DWORD, &cpu_state.rm_data.rm_mod_reg_data}, + [IREG_ins] = {REG_DWORD, &cpu_state.cpu_recomp_ins}, + [IREG_cycles] = {REG_DWORD, &cpu_state._cycles}, + /*Temporary registers are stored on the stack, and are not guaranteed to be preserved across uOPs. They will not be written back if they will not be read again.*/ @@ -73,7 +76,10 @@ void codegen_reg_reset() reg_version_refcount[c][0] = 0; } for (c = 0; c < CODEGEN_HOST_REGS; c++) + { host_regs[c] = invalid_ir_reg; + host_reg_dirty[c] = 0; + } } static inline int ir_reg_is_invalid(ir_reg_t ir_reg) @@ -119,6 +125,7 @@ static void codegen_reg_writeback(codeblock_t *block, int c) } host_regs[c] = invalid_ir_reg; + host_reg_dirty[c] = 0; } void codegen_reg_alloc_register(ir_reg_t dest_reg_a, ir_reg_t src_reg_a, ir_reg_t src_reg_b) diff --git a/src/codegen_reg.h b/src/codegen_reg.h index d1d81a2..e854fe1 100644 --- a/src/codegen_reg.h +++ b/src/codegen_reg.h @@ -31,14 +31,17 @@ enum IREG_ssegs = 17, IREG_rm_mod_reg = 18, + + IREG_ins = 19, + IREG_cycles = 20, /*Temporary registers are stored on the stack, and are not guaranteed to be preserved across uOPs. They will not be written back if they will not be read again.*/ - IREG_temp0 = 20, - IREG_temp1 = 21, - IREG_temp2 = 22, - IREG_temp3 = 23, + IREG_temp0 = 21, + IREG_temp1 = 22, + IREG_temp2 = 23, + IREG_temp3 = 24, IREG_COUNT,