From 371aa5d94cfe9ffddce24b5003fc06ec38af06a8 Mon Sep 17 00:00:00 2001 From: Anthony Pesch Date: Mon, 15 May 2017 00:06:27 -0400 Subject: [PATCH] use cycle count from opdef in interpreter main loop --- src/hw/sh4/sh4.c | 4 +++- src/jit/frontend/sh4/sh4_disasm.c | 4 ++-- src/jit/frontend/sh4/sh4_disasm.h | 21 +++++++++++---------- src/jit/frontend/sh4/sh4_fallbacks.h | 2 +- src/jit/frontend/sh4/sh4_frontend.c | 22 +++++++++++----------- src/jit/frontend/sh4/sh4_instr.inc | 2 +- src/jit/frontend/sh4/sh4_translate.h | 2 +- 7 files changed, 30 insertions(+), 27 deletions(-) diff --git a/src/hw/sh4/sh4.c b/src/hw/sh4/sh4.c index c8be7de2..ea3c257c 100644 --- a/src/hw/sh4/sh4.c +++ b/src/hw/sh4/sh4.c @@ -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++; } } diff --git a/src/jit/frontend/sh4/sh4_disasm.c b/src/jit/frontend/sh4/sh4_disasm.c index cc77d589..8a14acc2 100644 --- a/src/jit/frontend/sh4/sh4_disasm.c +++ b/src/jit/frontend/sh4/sh4_disasm.c @@ -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; } diff --git a/src/jit/frontend/sh4/sh4_disasm.h b/src/jit/frontend/sh4/sh4_disasm.h index e614917e..35f88474 100644 --- a/src/jit/frontend/sh4/sh4_disasm.h +++ b/src/jit/frontend/sh4/sh4_disasm.h @@ -5,13 +5,14 @@ #include 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, diff --git a/src/jit/frontend/sh4/sh4_fallbacks.h b/src/jit/frontend/sh4/sh4_fallbacks.h index 50ddd1b2..6cd30e80 100644 --- a/src/jit/frontend/sh4/sh4_fallbacks.h +++ b/src/jit/frontend/sh4/sh4_fallbacks.h @@ -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 diff --git a/src/jit/frontend/sh4/sh4_frontend.c b/src/jit/frontend/sh4/sh4_frontend.c index cb8e59b7..67090dbf 100644 --- a/src/jit/frontend/sh4/sh4_frontend.c +++ b/src/jit/frontend/sh4/sh4_frontend.c @@ -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); diff --git a/src/jit/frontend/sh4/sh4_instr.inc b/src/jit/frontend/sh4/sh4_instr.inc index 2cd7d9cc..4b91dcb0 100644 --- a/src/jit/frontend/sh4/sh4_instr.inc +++ b/src/jit/frontend/sh4/sh4_instr.inc @@ -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) diff --git a/src/jit/frontend/sh4/sh4_translate.h b/src/jit/frontend/sh4/sh4_translate.h index 1736e51d..80d82f80 100644 --- a/src/jit/frontend/sh4/sh4_translate.h +++ b/src/jit/frontend/sh4/sh4_translate.h @@ -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