mirror of https://github.com/inolen/redream.git
use cycle count from opdef in interpreter main loop
This commit is contained in:
parent
c703da40f7
commit
371aa5d94c
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue