use cycle count from opdef in interpreter main loop

This commit is contained in:
Anthony Pesch 2017-05-15 00:06:27 -04:00
parent c703da40f7
commit 371aa5d94c
7 changed files with 30 additions and 27 deletions

View File

@ -153,15 +153,17 @@ static void sh4_run(struct device *dev, int64_t ns) {
ctx->run_cycles = cycles;
ctx->ran_instrs = 0;
while (ctx->run_cycles-- > 0) {
while (ctx->run_cycles > 0) {
sh4_intc_check_pending(sh4);
uint16_t data = as_read16(sh4->memory_if->space, ctx->pc);
union sh4_instr instr = {data};
struct sh4_opdef *def = sh4_get_opdef(data);
sh4_fallback_cb cb = sh4_get_fallback(data);
cb(sh4->guest, ctx->pc, instr);
ctx->run_cycles -= def->cycles;
ctx->ran_instrs++;
}
}

View File

@ -52,9 +52,9 @@ static void sh4_init_op_table() {
void sh4_format(uint32_t addr, union sh4_instr i, char *buffer,
size_t buffer_size) {
struct sh4_opdef *def = sh4_opdef(i.raw);
struct sh4_opdef *def = sh4_get_opdef(i.raw);
if (!def) {
if (def->flags & SH4_FLAG_INVALID) {
snprintf(buffer, buffer_size, "%08x .word 0x%04x", addr, i.raw);
return;
}

View File

@ -5,13 +5,14 @@
#include <stdint.h>
enum {
SH4_FLAG_LOAD = 0x1,
SH4_FLAG_STORE = 0x2,
SH4_FLAG_BRANCH = 0x4,
SH4_FLAG_CONDITIONAL = 0x8,
SH4_FLAG_DELAYED = 0x10,
SH4_FLAG_SET_FPSCR = 0x20,
SH4_FLAG_SET_SR = 0x40,
SH4_FLAG_INVALID = 0x1,
SH4_FLAG_LOAD = 0x2,
SH4_FLAG_STORE = 0x4,
SH4_FLAG_BRANCH = 0x8,
SH4_FLAG_CONDITIONAL = 0x10,
SH4_FLAG_DELAYED = 0x20,
SH4_FLAG_SET_FPSCR = 0x40,
SH4_FLAG_SET_SR = 0x80,
};
enum sh4_op {
@ -66,12 +67,12 @@ union sh4_instr {
extern int sh4_optable[UINT16_MAX + 1];
extern struct sh4_opdef sh4_opdefs[NUM_SH4_OPS];
static inline int sh4_op(uint16_t instr) {
static inline int sh4_get_op(uint16_t instr) {
return sh4_optable[instr];
}
static struct sh4_opdef *sh4_opdef(uint16_t instr) {
return &sh4_opdefs[sh4_op(instr)];
static struct sh4_opdef *sh4_get_opdef(uint16_t instr) {
return &sh4_opdefs[sh4_get_op(instr)];
}
void sh4_format(uint32_t addr, union sh4_instr i, char *buffer,

View File

@ -10,7 +10,7 @@ typedef void (*sh4_fallback_cb)(struct sh4_guest *, uint32_t, union sh4_instr);
extern sh4_fallback_cb sh4_fallbacks[NUM_SH4_OPS];
static inline sh4_fallback_cb sh4_get_fallback(uint16_t instr) {
return sh4_fallbacks[sh4_op(instr)];
return sh4_fallbacks[sh4_get_op(instr)];
}
#endif

View File

@ -30,22 +30,22 @@ static void sh4_analyze_block(const struct sh4_guest *guest,
while (1) {
uint32_t data = guest->r16(guest->space, addr);
struct sh4_opdef *def = sh4_opdef(data);
int valid = def != NULL;
struct sh4_opdef *def = sh4_get_opdef(data);
int invalid = (def->flags & SH4_FLAG_INVALID) == SH4_FLAG_INVALID;
addr += 2;
block->guest_size += 2;
block->num_cycles += def ? def->cycles : 0;
block->num_cycles += def->cycles;
block->num_instrs++;
if (def->flags & SH4_FLAG_DELAYED) {
uint32_t delay_data = guest->r16(guest->space, addr);
struct sh4_opdef *delay_def = sh4_opdef(delay_data);
valid |= delay_def != NULL;
struct sh4_opdef *delay_def = sh4_get_opdef(delay_data);
invalid |= (delay_def->flags & SH4_FLAG_INVALID) == SH4_FLAG_INVALID;
addr += 2;
block->guest_size += 2;
block->num_cycles += delay_def ? delay_def->cycles : 0;
block->num_cycles += delay_def->cycles;
block->num_instrs++;
/* delay slots can't have another delay slot */
@ -53,7 +53,7 @@ static void sh4_analyze_block(const struct sh4_guest *guest,
}
/* end block on invalid instruction */
if (!valid) {
if (invalid) {
break;
}
@ -96,7 +96,7 @@ static void sh4_frontend_translate_code(struct jit_frontend *base,
while (addr < end) {
uint16_t data = guest->r16(guest->space, addr);
union sh4_instr instr = {data};
struct sh4_opdef *def = sh4_opdef(data);
struct sh4_opdef *def = sh4_get_opdef(data);
sh4_translate_cb cb = sh4_get_translator(data);
cb(guest, ir, flags, addr, instr);
@ -126,9 +126,9 @@ static void sh4_frontend_translate_code(struct jit_frontend *base,
int ends_in_branch = tail_instr->op == OP_BRANCH;
if (tail_instr->op == OP_FALLBACK) {
struct sh4_opdef *opdef = sh4_opdef(tail_instr->arg[2]->i32);
struct sh4_opdef *def = sh4_get_opdef(tail_instr->arg[2]->i32);
if (opdef->flags & SH4_FLAG_BRANCH) {
if (def->flags & SH4_FLAG_BRANCH) {
ends_in_branch = 1;
}
}
@ -153,7 +153,7 @@ static void sh4_frontend_dump_code(struct jit_frontend *base, uint32_t addr,
while (addr < end) {
uint16_t data = guest->r16(guest->space, addr);
union sh4_instr instr = {data};
struct sh4_opdef *def = sh4_opdef(data);
struct sh4_opdef *def = sh4_get_opdef(data);
sh4_format(addr, instr, buffer, sizeof(buffer));
LOG_INFO(buffer);

View File

@ -2,7 +2,7 @@
// NAME DESC INSTR_CODE CYCLES FLAGS
//
SH4_INSTR(INVALID, "invalid", 0000000000000000, 1, 0)
SH4_INSTR(INVALID, "invalid", 0000000000000000, 1, SH4_FLAG_INVALID)
// fixed-point transfer instructions
SH4_INSTR(MOVI, "mov #imm8, rn", 1110nnnniiiiiiii, 1, 0)

View File

@ -12,7 +12,7 @@ typedef void (*sh4_translate_cb)(struct sh4_guest *, struct ir *, int, uint32_t,
extern sh4_translate_cb sh4_translators[NUM_SH4_OPS];
static inline sh4_translate_cb sh4_get_translator(uint16_t instr) {
return sh4_translators[sh4_op(instr)];
return sh4_translators[sh4_get_op(instr)];
}
#endif