Recompiler now handles instruction and cycle counting.
This commit is contained in:
parent
93ec6b0692
commit
774f4201ee
8 changed files with 99 additions and 7 deletions
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
50
src/codegen_accumulate.c
Normal 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
13
src/codegen_accumulate.h
Normal 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();
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue