Recompiler now handles instruction and cycle counting.

This commit is contained in:
SarahW 2018-07-06 17:51:22 +01:00
commit 774f4201ee
8 changed files with 99 additions and 7 deletions

View file

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

View file

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

50
src/codegen_accumulate.c Normal file
View file

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

13
src/codegen_accumulate.h Normal file
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(struct ir_data_t *ir);
void codegen_accumulate_reset();

View file

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

View file

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

View file

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

View file

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