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.

This commit is contained in:
OBattler
2020-05-06 03:41:46 +02:00
parent 9c6cfc9a15
commit 3dd3396a2c
6 changed files with 141 additions and 123 deletions

View File

@@ -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();

View File

@@ -0,0 +1,50 @@
#include <stdint.h>
#include <stdio.h>
#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;
}

View File

@@ -0,0 +1,49 @@
#include <stdint.h>
#include <stdio.h>
#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;
}

View File

@@ -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);

View File

@@ -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));

View File

@@ -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