From 3dd3396a2c2a947abb6bd6d64ae7421a142a8ef5 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 6 May 2020 03:41:46 +0200 Subject: [PATCH] Backported the codegen_accumulate functionality to the old recompiler, so Windows 98 first edition on i686 CPU's can stay fixed without i686 timings getting messed up. --- src/cpu/codegen_accumulate.h | 13 +++++ src/cpu/codegen_accumulate_x86-64.c | 50 ++++++++++++++++++ src/cpu/codegen_accumulate_x86.c | 49 ++++++++++++++++++ src/cpu/codegen_x86-64.c | 68 +++++------------------- src/cpu/codegen_x86.c | 80 ++++++----------------------- src/win/Makefile.mingw | 4 +- 6 files changed, 141 insertions(+), 123 deletions(-) create mode 100644 src/cpu/codegen_accumulate.h create mode 100644 src/cpu/codegen_accumulate_x86-64.c create mode 100644 src/cpu/codegen_accumulate_x86.c diff --git a/src/cpu/codegen_accumulate.h b/src/cpu/codegen_accumulate.h new file mode 100644 index 000000000..8f9f6c95b --- /dev/null +++ b/src/cpu/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(void); +void codegen_accumulate_reset(); diff --git a/src/cpu/codegen_accumulate_x86-64.c b/src/cpu/codegen_accumulate_x86-64.c new file mode 100644 index 000000000..415b04401 --- /dev/null +++ b/src/cpu/codegen_accumulate_x86-64.c @@ -0,0 +1,50 @@ +#include +#include +#include <86box/86box.h> +#include "cpu.h" +#include <86box/mem.h> + +#include "codegen.h" +#include "codegen_accumulate.h" + +static struct +{ + int count; + uintptr_t dest_reg; +} acc_regs[] = +{ + [ACCREG_ins] = {0, (uintptr_t) &(ins)}, + [ACCREG_cycles] = {0, (uintptr_t) &(cycles)}, +}; + +void codegen_accumulate(int acc_reg, int delta) +{ + acc_regs[acc_reg].count += delta; +} + +void codegen_accumulate_flush(void) +{ + int c; + + for (c = 0; c < ACCREG_COUNT; c++) + { + if (acc_regs[c].count) + { + addbyte(0x81); /*ADD $acc_regs[c].count,acc_regs[c].dest*/ + addbyte(0x04); + addbyte(0x25); + addlong((uint32_t) acc_regs[c].dest_reg); + addlong(codegen_block_full_ins); + } + + 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/cpu/codegen_accumulate_x86.c b/src/cpu/codegen_accumulate_x86.c new file mode 100644 index 000000000..2b99d4c66 --- /dev/null +++ b/src/cpu/codegen_accumulate_x86.c @@ -0,0 +1,49 @@ +#include +#include +#include <86box/86box.h> +#include "cpu.h" +#include <86box/mem.h> + +#include "codegen.h" +#include "codegen_accumulate.h" + +static struct +{ + int count; + uintptr_t dest_reg; +} acc_regs[] = +{ + [ACCREG_ins] = {0, (uintptr_t) &(ins)}, + [ACCREG_cycles] = {0, (uintptr_t) &(cycles)}, +}; + +void codegen_accumulate(int acc_reg, int delta) +{ + acc_regs[acc_reg].count += delta; +} + +void codegen_accumulate_flush(void) +{ + int c; + + for (c = 0; c < ACCREG_COUNT; c++) + { + if (acc_regs[c].count) + { + addbyte(0x81); /*ADD $acc_regs[c].count,acc_regs[c].dest*/ + addbyte(0x05); + addlong((uint32_t) acc_regs[c].dest_reg); + addlong(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/cpu/codegen_x86-64.c b/src/cpu/codegen_x86-64.c index 8c3d87387..f674df1e4 100644 --- a/src/cpu/codegen_x86-64.c +++ b/src/cpu/codegen_x86-64.c @@ -16,6 +16,7 @@ #include "386_common.h" #include "codegen.h" +#include "codegen_accumulate.h" #include "codegen_ops.h" #include "codegen_ops_x86-64.h" @@ -466,31 +467,10 @@ void codegen_block_end() void codegen_block_end_recompile(codeblock_t *block) { codegen_timing_block_end(); + codegen_accumulate(ACCREG_cycles, -codegen_block_cycles); + + codegen_accumulate_flush(); - if (codegen_block_cycles) - { - addbyte(0x81); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addlong((uint32_t)codegen_block_cycles); - } - if (codegen_block_ins) - { - addbyte(0x81); /*ADD $codegen_block_ins,ins*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(cpu_recomp_ins)); - addlong(codegen_block_ins); - } -#if 0 - if (codegen_block_full_ins) - { - addbyte(0x81); /*ADD $codegen_block_ins,ins*/ - addbyte(0x04); - addbyte(0x25); - addlong((uint32_t)&cpu_recomp_full_ins); - addlong(codegen_block_full_ins); - } -#endif addbyte(0x48); /*ADDL $40,%rsp*/ addbyte(0x83); addbyte(0xC4); @@ -1068,6 +1048,10 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t generate_call: codegen_timing_opcode(opcode, fetchdat, op_32, op_pc); + + 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 || @@ -1086,39 +1070,10 @@ generate_call: jump_cycles = codegen_timing_jump_cycles(); if (jump_cycles) - { - addbyte(0x81); /*SUB $jump_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addlong((uint32_t)jump_cycles); - } - - /*Opcode is likely to cause block to exit, update cycle count*/ - if (codegen_block_cycles) - { - addbyte(0x81); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addlong((uint32_t)codegen_block_cycles); - codegen_block_cycles = 0; - } - if (codegen_block_ins) - { - addbyte(0x81); /*ADD $codegen_block_ins,ins*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(cpu_recomp_ins)); - addlong(codegen_block_ins); - codegen_block_ins = 0; - } - + codegen_accumulate(ACCREG_cycles, -jump_cycles); + codegen_accumulate_flush(); if (jump_cycles) - { - addbyte(0x81); /*SUB $jump_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addlong((uint32_t)jump_cycles); - jump_cycles = 0; - } + codegen_accumulate(ACCREG_cycles, jump_cycles); } if ((op_table == x86_dynarec_opcodes_REPNE || op_table == x86_dynarec_opcodes_REPE) && !op_table[opcode | op_32]) @@ -1186,6 +1141,7 @@ generate_call: addlong((uint32_t)(uintptr_t)op_ea_seg); } + codegen_accumulate_flush(); addbyte(0xC7); /*MOVL [pc],new_pc*/ addbyte(0x45); diff --git a/src/cpu/codegen_x86.c b/src/cpu/codegen_x86.c index 85e2af2b1..222e7c2c7 100644 --- a/src/cpu/codegen_x86.c +++ b/src/cpu/codegen_x86.c @@ -54,6 +54,7 @@ #include "386_common.h" #include "codegen.h" +#include "codegen_accumulate.h" #include "codegen_ops.h" #include "codegen_ops_x86.h" @@ -1502,6 +1503,8 @@ void codegen_block_start_recompile(codeblock_t *block) codegen_flat_ds = !(cpu_cur_status & CPU_STATUS_NOTFLATDS); codegen_flat_ss = !(cpu_cur_status & CPU_STATUS_NOTFLATSS); + + codegen_accumulate_reset(); } void codegen_block_remove() @@ -1585,30 +1588,10 @@ void codegen_block_end() void codegen_block_end_recompile(codeblock_t *block) { codegen_timing_block_end(); + codegen_accumulate(ACCREG_cycles, -codegen_block_cycles); + + codegen_accumulate_flush(); - if (codegen_block_cycles) - { - addbyte(0x81); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addlong(codegen_block_cycles); - } - if (codegen_block_ins) - { - addbyte(0x81); /*ADD $codegen_block_ins,ins*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(cpu_recomp_ins)); - addlong(codegen_block_ins); - } -#if 0 - if (codegen_block_full_ins) - { - addbyte(0x81); /*ADD $codegen_block_ins,ins*/ - addbyte(0x05); - addlong((uint32_t)&cpu_recomp_full_ins); - addlong(codegen_block_full_ins); - } -#endif addbyte(0x83); /*ADDL $16,%esp*/ addbyte(0xC4); addbyte(0x10); @@ -2033,6 +2016,10 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t generate_call: codegen_timing_opcode(opcode, fetchdat, op_32, op_pc); + 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 || @@ -2050,49 +2037,10 @@ generate_call: jump_cycles = codegen_timing_jump_cycles(); if (jump_cycles) - { - addbyte(0x81); /*SUB $jump_cycles, cycles*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addlong(jump_cycles); - } - - /*Opcode is likely to cause block to exit, update cycle count*/ - if (codegen_block_cycles) - { - addbyte(0x81); /*SUB $codegen_block_cycles, cycles*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addlong(codegen_block_cycles); - codegen_block_cycles = 0; - } - if (codegen_block_ins) - { - addbyte(0x81); /*ADD $codegen_block_ins,ins*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(cpu_recomp_ins)); - addlong(codegen_block_ins); - codegen_block_ins = 0; - } -#if 0 - if (codegen_block_full_ins) - { - addbyte(0x81); /*ADD $codegen_block_ins,ins*/ - addbyte(0x05); - addlong((uint32_t)&cpu_recomp_full_ins); - addlong(codegen_block_full_ins); - codegen_block_full_ins = 0; - } -#endif - + codegen_accumulate(ACCREG_cycles, -jump_cycles); + codegen_accumulate_flush(); if (jump_cycles) - { - addbyte(0x81); /*SUB $jump_cycles, cycles*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addlong(jump_cycles); - jump_cycles = 0; - } + codegen_accumulate(ACCREG_cycles, jump_cycles); } if ((op_table == x86_dynarec_opcodes_REPNE || op_table == x86_dynarec_opcodes_REPE) && !op_table[opcode | op_32]) @@ -2164,6 +2112,8 @@ generate_call: addlong((uint32_t)op_ea_seg); } + codegen_accumulate_flush(); + addbyte(0xC7); /*MOVL pc,new_pc*/ addbyte(0x45); addbyte((uint8_t)cpu_state_offset(pc)); diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 381e446fb..cebd6d8d3 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -353,9 +353,9 @@ endif # Optional modules. ifeq ($(DYNAREC), y) ifeq ($(X64), y) -PLATCG := codegen_x86-64.o +PLATCG := codegen_x86-64.o codegen_accumulate_x86-64.o else -PLATCG := codegen_x86.o +PLATCG := codegen_x86.o codegen_accumulate_x86.o endif OPTS += -DUSE_DYNAREC