From cb6b7bb76577383468d92aecf5d91a7907912551 Mon Sep 17 00:00:00 2001 From: Anthony Pesch Date: Sun, 18 Jun 2017 18:01:24 -0400 Subject: [PATCH] add default handlers for all invalid memory accesses set arm wave ram to 2mb instead of 8mb don't mirror arm memory emit invalid instruction ops in armv3 frontend be careful to emit blocks even when end address overflows --- src/guest/arm7/arm7.c | 6 +-- src/guest/memory.c | 7 ++- src/guest/sh4/sh4.c | 2 +- src/host/sdl_host.c | 2 +- src/jit/backend/interp/interp_backend.c | 2 +- src/jit/backend/jit_backend.h | 2 +- src/jit/backend/x64/x64_backend.cc | 6 ++- src/jit/frontend/armv3/armv3_disasm.c | 3 +- src/jit/frontend/armv3/armv3_disasm.h | 3 +- src/jit/frontend/armv3/armv3_fallback.c | 2 + src/jit/frontend/armv3/armv3_frontend.c | 37 ++++++-------- src/jit/frontend/armv3/armv3_instr.inc | 68 +++++++++++++------------ src/jit/frontend/jit_frontend.h | 2 +- src/jit/frontend/sh4/sh4_frontend.c | 27 ++++------ src/jit/jit.c | 4 ++ 15 files changed, 85 insertions(+), 88 deletions(-) diff --git a/src/guest/arm7/arm7.c b/src/guest/arm7/arm7.c index 687663f0..810f4cf6 100644 --- a/src/guest/arm7/arm7.c +++ b/src/guest/arm7/arm7.c @@ -190,7 +190,7 @@ static int arm7_init(struct device *dev) { { arm->guest = armv3_guest_create(); - arm->guest->addr_mask = 0x007ffffc; + arm->guest->addr_mask = 0x001ffffc; arm->guest->offset_pc = (int)offsetof(struct armv3_context, r[15]); arm->guest->offset_cycles = (int)offsetof(struct armv3_context, run_cycles); arm->guest->offset_instrs = (int)offsetof(struct armv3_context, ran_instrs); @@ -244,7 +244,7 @@ struct arm7 *arm7_create(struct dreamcast *dc) { /* clang-format off */ AM_BEGIN(struct arm7, arm7_data_map); - AM_RANGE(0x00000000, 0x007fffff) AM_MASK(0x00ffffff) AM_DEVICE("aica", aica_data_map) - AM_RANGE(0x00800000, 0x00810fff) AM_MASK(0x00ffffff) AM_DEVICE("aica", aica_reg_map) + AM_RANGE(0x00000000, 0x001fffff) AM_DEVICE("aica", aica_data_map) + AM_RANGE(0x00800000, 0x00810fff) AM_DEVICE("aica", aica_reg_map) AM_END(); /* clang-format on */ diff --git a/src/guest/memory.c b/src/guest/memory.c index cdef3196..d0b2f95b 100644 --- a/src/guest/memory.c +++ b/src/guest/memory.c @@ -374,8 +374,9 @@ struct memory *memory_create(struct dreamcast *dc) { memory->dc = dc; memory->shmem = SHMEM_INVALID; - /* 0 page is reserved, meaning all valid page entries must be non-zero */ - memory->num_regions = 1; + + /* create default region for unmapped pages */ + memory_create_mmio_region(memory, "default", 0, NULL, NULL, NULL, NULL, NULL); return memory; } @@ -500,7 +501,6 @@ void as_memcpy_to_guest(struct address_space *space, uint32_t dst, #define define_read_bytes(name, data_type) \ data_type as_##name(struct address_space *space, uint32_t addr) { \ page_entry_t page = space->pages[get_page_index(addr)]; \ - DCHECK(page); \ int region_handle = get_region_handle(page); \ struct memory_region *region = &space->dc->memory->regions[region_handle]; \ if (region->type == REGION_PHYSICAL) { \ @@ -520,7 +520,6 @@ define_read_bytes(read32, uint32_t); #define define_write_bytes(name, data_type) \ void as_##name(struct address_space *space, uint32_t addr, data_type data) { \ page_entry_t page = space->pages[get_page_index(addr)]; \ - DCHECK(page); \ int region_handle = get_region_handle(page); \ struct memory_region *region = &space->dc->memory->regions[region_handle]; \ if (region->type == REGION_PHYSICAL) { \ diff --git a/src/guest/sh4/sh4.c b/src/guest/sh4/sh4.c index 5a6d7dd6..59c810fa 100644 --- a/src/guest/sh4/sh4.c +++ b/src/guest/sh4/sh4.c @@ -322,7 +322,7 @@ AM_BEGIN(struct sh4, sh4_data_map) AM_RANGE(0x005f8000, 0x005f9fff) AM_DEVICE("pvr", pvr_reg_map) AM_RANGE(0x00600000, 0x0067ffff) AM_DEVICE("holly", holly_modem_map) AM_RANGE(0x00700000, 0x00710fff) AM_DEVICE("aica", aica_reg_map) - AM_RANGE(0x00800000, 0x00ffffff) AM_DEVICE("aica", aica_data_map) + AM_RANGE(0x00800000, 0x009fffff) AM_DEVICE("aica", aica_data_map) AM_RANGE(0x01000000, 0x01ffffff) AM_DEVICE("holly", holly_expansion0_map) AM_RANGE(0x02700000, 0x02ffffff) AM_DEVICE("holly", holly_expansion1_map) AM_RANGE(0x04000000, 0x057fffff) AM_DEVICE("pvr", pvr_vram_map) diff --git a/src/host/sdl_host.c b/src/host/sdl_host.c index 5cd24c7c..1fdf155a 100644 --- a/src/host/sdl_host.c +++ b/src/host/sdl_host.c @@ -13,7 +13,7 @@ #include "tracer.h" DEFINE_OPTION_INT(audio, 1, "Enable audio"); -DEFINE_OPTION_INT(latency, 20, "Preferred audio latency in ms"); +DEFINE_OPTION_INT(latency, 50, "Preferred audio latency in ms"); DEFINE_OPTION_INT(help, 0, "Show help"); #define AUDIO_FREQ 44100 diff --git a/src/jit/backend/interp/interp_backend.c b/src/jit/backend/interp/interp_backend.c index 7e3d499d..d26f24be 100644 --- a/src/jit/backend/interp/interp_backend.c +++ b/src/jit/backend/interp/interp_backend.c @@ -47,7 +47,7 @@ static int interp_backend_handle_exception(struct jit_backend *base, } static void interp_backend_dump_code(struct jit_backend *base, - const uint8_t *code, int size) {} + const struct jit_block *block) {} static void interp_backend_reset(struct jit_backend *base) {} diff --git a/src/jit/backend/jit_backend.h b/src/jit/backend/jit_backend.h index ed445fcb..c4bad29e 100644 --- a/src/jit/backend/jit_backend.h +++ b/src/jit/backend/jit_backend.h @@ -26,7 +26,7 @@ struct jit_backend { /* compile interface */ void (*reset)(struct jit_backend *); int (*assemble_code)(struct jit_backend *, struct jit_block *, struct ir *); - void (*dump_code)(struct jit_backend *, const uint8_t *, int); + void (*dump_code)(struct jit_backend *, const struct jit_block *); int (*handle_exception)(struct jit_backend *, struct exception_state *); /* dispatch interface */ diff --git a/src/jit/backend/x64/x64_backend.cc b/src/jit/backend/x64/x64_backend.cc index 62fda04a..26e2c199 100644 --- a/src/jit/backend/x64/x64_backend.cc +++ b/src/jit/backend/x64/x64_backend.cc @@ -593,9 +593,11 @@ static int x64_backend_handle_exception(struct jit_backend *base, return 1; } -static void x64_backend_dump_code(struct jit_backend *base, const uint8_t *code, - int size) { +static void x64_backend_dump_code(struct jit_backend *base, + const struct jit_block *block) { struct x64_backend *backend = container_of(base, struct x64_backend, base); + const uint8_t *code = (const uint8_t *)block->host_addr; + int size = block->host_size; cs_insn *insns; size_t count = cs_disasm(backend->capstone_handle, code, size, 0, 0, &insns); diff --git a/src/jit/frontend/armv3/armv3_disasm.c b/src/jit/frontend/armv3/armv3_disasm.c index 114bd0b7..91f83369 100644 --- a/src/jit/frontend/armv3/armv3_disasm.c +++ b/src/jit/frontend/armv3/armv3_disasm.c @@ -7,7 +7,6 @@ int armv3_optable[ARMV3_LOOKUP_SIZE]; struct jit_opdef armv3_opdefs[NUM_ARMV3_OPS] = { - {ARMV3_OP_INVALID, NULL, NULL, 0, 0, NULL}, #define ARMV3_INSTR(name, desc, sig, cycles, flags) \ {ARMV3_OP_##name, desc, #sig, \ cycles, flags, (jit_fallback)&armv3_fallback_##name}, @@ -141,7 +140,7 @@ void armv3_format(uint32_t addr, uint32_t instr, char *buffer, value_len = snprintf(value, sizeof(value), "%s", armv3_format_cond[cond]); strnrep(buffer, buffer_size, "{cond}", 6, value, value_len); - if (def->flags & FLAG_BRANCH) { + if (def->flags & FLAG_SET_PC) { /* expr */ int32_t offset = armv3_disasm_offset(i.branch.offset); uint32_t dest = addr + 8 /* account for prefetch */ + offset; diff --git a/src/jit/frontend/armv3/armv3_disasm.h b/src/jit/frontend/armv3/armv3_disasm.h index 63a7a4c4..85c49673 100644 --- a/src/jit/frontend/armv3/armv3_disasm.h +++ b/src/jit/frontend/armv3/armv3_disasm.h @@ -5,7 +5,7 @@ #include "jit/frontend/jit_frontend.h" enum armv3_op_flag { - FLAG_BRANCH = 0x1, + FLAG_SET_PC = 0x1, FLAG_DATA = 0x2, FLAG_PSR = 0x4, FLAG_MUL = 0x8, @@ -229,7 +229,6 @@ union armv3_instr { }; enum armv3_op { - ARMV3_OP_INVALID, #define ARMV3_INSTR(name, desc, instr_code, cycles, flags) ARMV3_OP_##name, #include "armv3_instr.inc" #undef ARMV3_INSTR diff --git a/src/jit/frontend/armv3/armv3_fallback.c b/src/jit/frontend/armv3/armv3_fallback.c index 2d3a4461..57c6d694 100644 --- a/src/jit/frontend/armv3/armv3_fallback.c +++ b/src/jit/frontend/armv3/armv3_fallback.c @@ -293,6 +293,8 @@ static inline void armv3_fallback_update_flags_add(struct armv3_context *ctx, ctx->r[CPSR] = MAKE_CPSR(ctx->r[CPSR], n, z, c, v); } +FALLBACK(INVALID) {} + FALLBACK(AND) { CHECK_COND(); diff --git a/src/jit/frontend/armv3/armv3_frontend.c b/src/jit/frontend/armv3/armv3_frontend.c index 6c1f148d..c7279316 100644 --- a/src/jit/frontend/armv3/armv3_frontend.c +++ b/src/jit/frontend/armv3/armv3_frontend.c @@ -28,18 +28,17 @@ static void armv3_analyze_block(const struct armv3_guest *guest, block->num_cycles += 12; block->num_instrs++; - /* end block on invalid instruction */ - if (def->op == ARMV3_OP_INVALID) { - break; - } - /* stop emitting when pc is changed */ - if ((def->flags & FLAG_BRANCH) || - ((def->flags & FLAG_DATA) && i.data.rd == 15) || - (def->flags & FLAG_PSR) || - ((def->flags & FLAG_XFR) && i.xfr.rd == 15) || - ((def->flags & FLAG_BLK) && i.blk.rlist & (1 << 15)) || - (def->flags & FLAG_SWI)) { + int mov_to_pc = 0; + + mov_to_pc |= (def->flags & FLAG_SET_PC); + mov_to_pc |= (def->flags & FLAG_DATA) && i.data.rd == 15; + mov_to_pc |= (def->flags & FLAG_PSR); + mov_to_pc |= (def->flags & FLAG_XFR) && i.xfr.rd == 15; + mov_to_pc |= (def->flags & FLAG_BLK) && (i.blk.rlist & (1 << 15)); + mov_to_pc |= (def->flags & FLAG_SWI); + + if (mov_to_pc) { break; } } @@ -50,14 +49,15 @@ static const struct jit_opdef *armv3_frontend_lookup_op( return armv3_get_opdef(*(const uint32_t *)instr); } -static void armv3_frontend_dump_code(struct jit_frontend *base, uint32_t addr, - int size) { +static void armv3_frontend_dump_code(struct jit_frontend *base, + const struct jit_block *block) { struct armv3_frontend *frontend = (struct armv3_frontend *)base; struct jit_guest *guest = frontend->jit->guest; char buffer[128]; - for (int i = 0; i < size; i += 4) { + for (int offset = 0; offset < block->guest_size; offset += 4) { + uint32_t addr = block->guest_addr + offset; uint32_t data = guest->r32(guest->space, addr); armv3_format(addr, data, buffer, sizeof(buffer)); @@ -75,17 +75,12 @@ static void armv3_frontend_translate_code(struct jit_frontend *base, armv3_analyze_block(guest, block); - /* emit fallbacks */ - uint32_t addr = block->guest_addr; - uint32_t end = block->guest_addr + block->guest_size; - - while (addr < end) { + for (int offset = 0; offset < block->guest_size; offset += 4) { + uint32_t addr = block->guest_addr + offset; uint32_t data = guest->r32(guest->space, addr); struct jit_opdef *def = armv3_get_opdef(data); ir_fallback(ir, def->fallback, addr, data); - - addr += 4; } } diff --git a/src/jit/frontend/armv3/armv3_instr.inc b/src/jit/frontend/armv3/armv3_instr.inc index ea02dc98..9ffb91bc 100644 --- a/src/jit/frontend/armv3/armv3_instr.inc +++ b/src/jit/frontend/armv3/armv3_instr.inc @@ -1,54 +1,56 @@ +ARMV3_INSTR(INVALID, "invalid", 00000000000000000000000000000000, 0, FLAG_SET_PC) + // branches -ARMV3_INSTR(B, "b{cond} {expr}", xxxx1010xxxxxxxxxxxxxxxxxxxxxxxx, 1, FLAG_BRANCH) -ARMV3_INSTR(BL, "bl{cond} {expr}", xxxx1011xxxxxxxxxxxxxxxxxxxxxxxx, 1, FLAG_BRANCH) +ARMV3_INSTR(B, "b{cond} {expr}", xxxx1010xxxxxxxxxxxxxxxxxxxxxxxx, 1, FLAG_SET_PC) +ARMV3_INSTR(BL, "bl{cond} {expr}", xxxx1011xxxxxxxxxxxxxxxxxxxxxxxx, 1, FLAG_SET_PC) // data processing -ARMV3_INSTR(AND, "and{cond}{s} {rd}, {rn}, {expr}", xxxx00x0000xxxxxxxxxxxxxxxxxxxxx, 1, FLAG_DATA) -ARMV3_INSTR(EOR, "eor{cond}{s} {rd}, {rn}, {expr}", xxxx00x0001xxxxxxxxxxxxxxxxxxxxx, 1, FLAG_DATA) -ARMV3_INSTR(SUB, "sub{cond}{s} {rd}, {rn}, {expr}", xxxx00x0010xxxxxxxxxxxxxxxxxxxxx, 1, FLAG_DATA) -ARMV3_INSTR(RSB, "rsb{cond}{s} {rd}, {rn}, {expr}", xxxx00x0011xxxxxxxxxxxxxxxxxxxxx, 1, FLAG_DATA) -ARMV3_INSTR(ADD, "add{cond}{s} {rd}, {rn}, {expr}", xxxx00x0100xxxxxxxxxxxxxxxxxxxxx, 1, FLAG_DATA) -ARMV3_INSTR(ADC, "adc{cond}{s} {rd}, {rn}, {expr}", xxxx00x0101xxxxxxxxxxxxxxxxxxxxx, 1, FLAG_DATA) -ARMV3_INSTR(SBC, "sbc{cond}{s} {rd}, {rn}, {expr}", xxxx00x0110xxxxxxxxxxxxxxxxxxxxx, 1, FLAG_DATA) -ARMV3_INSTR(RSC, "rsc{cond}{s} {rd}, {rn}, {expr}", xxxx00x0111xxxxxxxxxxxxxxxxxxxxx, 1, FLAG_DATA) -ARMV3_INSTR(TST, "tst{cond} {rn}, {expr}", xxxx00x10001xxxx0000xxxxxxxxxxxx, 1, FLAG_DATA) -ARMV3_INSTR(TEQ, "teq{cond} {rn}, {expr}", xxxx00x10011xxxx0000xxxxxxxxxxxx, 1, FLAG_DATA) -ARMV3_INSTR(CMP, "cmp{cond} {rn}, {expr}", xxxx00x10101xxxx0000xxxxxxxxxxxx, 1, FLAG_DATA) -ARMV3_INSTR(CMN, "cmn{cond} {rn}, {expr}", xxxx00x10111xxxx0000xxxxxxxxxxxx, 1, FLAG_DATA) -ARMV3_INSTR(ORR, "orr{cond}{s} {rd}, {rn}, {expr}", xxxx00x1100xxxxxxxxxxxxxxxxxxxxx, 1, FLAG_DATA) -ARMV3_INSTR(MOV, "mov{cond}{s} {rd}, {expr}", xxxx00x1101x0000xxxxxxxxxxxxxxxx, 1, FLAG_DATA) -ARMV3_INSTR(BIC, "bic{cond}{s} {rd}, {rn}, {expr}", xxxx00x1110xxxxxxxxxxxxxxxxxxxxx, 1, FLAG_DATA) -ARMV3_INSTR(MVN, "mvn{cond}{s} {rd}, {expr}", xxxx00x1111x0000xxxxxxxxxxxxxxxx, 1, FLAG_DATA) +ARMV3_INSTR(AND, "and{cond}{s} {rd}, {rn}, {expr}", xxxx00x0000xxxxxxxxxxxxxxxxxxxxx, 1, FLAG_DATA) +ARMV3_INSTR(EOR, "eor{cond}{s} {rd}, {rn}, {expr}", xxxx00x0001xxxxxxxxxxxxxxxxxxxxx, 1, FLAG_DATA) +ARMV3_INSTR(SUB, "sub{cond}{s} {rd}, {rn}, {expr}", xxxx00x0010xxxxxxxxxxxxxxxxxxxxx, 1, FLAG_DATA) +ARMV3_INSTR(RSB, "rsb{cond}{s} {rd}, {rn}, {expr}", xxxx00x0011xxxxxxxxxxxxxxxxxxxxx, 1, FLAG_DATA) +ARMV3_INSTR(ADD, "add{cond}{s} {rd}, {rn}, {expr}", xxxx00x0100xxxxxxxxxxxxxxxxxxxxx, 1, FLAG_DATA) +ARMV3_INSTR(ADC, "adc{cond}{s} {rd}, {rn}, {expr}", xxxx00x0101xxxxxxxxxxxxxxxxxxxxx, 1, FLAG_DATA) +ARMV3_INSTR(SBC, "sbc{cond}{s} {rd}, {rn}, {expr}", xxxx00x0110xxxxxxxxxxxxxxxxxxxxx, 1, FLAG_DATA) +ARMV3_INSTR(RSC, "rsc{cond}{s} {rd}, {rn}, {expr}", xxxx00x0111xxxxxxxxxxxxxxxxxxxxx, 1, FLAG_DATA) +ARMV3_INSTR(TST, "tst{cond} {rn}, {expr}", xxxx00x10001xxxx0000xxxxxxxxxxxx, 1, FLAG_DATA) +ARMV3_INSTR(TEQ, "teq{cond} {rn}, {expr}", xxxx00x10011xxxx0000xxxxxxxxxxxx, 1, FLAG_DATA) +ARMV3_INSTR(CMP, "cmp{cond} {rn}, {expr}", xxxx00x10101xxxx0000xxxxxxxxxxxx, 1, FLAG_DATA) +ARMV3_INSTR(CMN, "cmn{cond} {rn}, {expr}", xxxx00x10111xxxx0000xxxxxxxxxxxx, 1, FLAG_DATA) +ARMV3_INSTR(ORR, "orr{cond}{s} {rd}, {rn}, {expr}", xxxx00x1100xxxxxxxxxxxxxxxxxxxxx, 1, FLAG_DATA) +ARMV3_INSTR(MOV, "mov{cond}{s} {rd}, {expr}", xxxx00x1101x0000xxxxxxxxxxxxxxxx, 1, FLAG_DATA) +ARMV3_INSTR(BIC, "bic{cond}{s} {rd}, {rn}, {expr}", xxxx00x1110xxxxxxxxxxxxxxxxxxxxx, 1, FLAG_DATA) +ARMV3_INSTR(MVN, "mvn{cond}{s} {rd}, {expr}", xxxx00x1111x0000xxxxxxxxxxxxxxxx, 1, FLAG_DATA) // psr transfers -ARMV3_INSTR(MRS, "mrs{cond} {rd}, {psr}", xxxx00010x001111xxxx000000000000, 1, FLAG_PSR) -ARMV3_INSTR(MSR, "msr{cond} {psr}, {expr}", xxxx00x10x10xxxx111100000000xxxx, 1, FLAG_PSR) +ARMV3_INSTR(MRS, "mrs{cond} {rd}, {psr}", xxxx00010x001111xxxx000000000000, 1, FLAG_PSR) +ARMV3_INSTR(MSR, "msr{cond} {psr}, {expr}", xxxx00x10x10xxxx111100000000xxxx, 1, FLAG_PSR) // multiply and multiply-accumulate -ARMV3_INSTR(MUL, "mul{cond}{s} {rd}, {rm}, {rs}", xxxx0000000xxxxxxxxxxxxx1001xxxx, 1, FLAG_MUL) -ARMV3_INSTR(MLA, "mla{cond}{s} {rd}, {rm}, {rs}, {rn}", xxxx0000001xxxxxxxxxxxxx1001xxxx, 1, FLAG_MUL) +ARMV3_INSTR(MUL, "mul{cond}{s} {rd}, {rm}, {rs}", xxxx0000000xxxxxxxxxxxxx1001xxxx, 1, FLAG_MUL) +ARMV3_INSTR(MLA, "mla{cond}{s} {rd}, {rm}, {rs}, {rn}", xxxx0000001xxxxxxxxxxxxx1001xxxx, 1, FLAG_MUL) // single data transfer -ARMV3_INSTR(LDR, "ldr{cond}{b}{t} {rd}, {addr}", xxxx01xxxxx1xxxxxxxxxxxxxxxxxxxx, 1, FLAG_XFR) -ARMV3_INSTR(STR, "str{cond}{b}{t} {rd}, {addr}", xxxx01xxxxx0xxxxxxxxxxxxxxxxxxxx, 1, FLAG_XFR) +ARMV3_INSTR(LDR, "ldr{cond}{b}{t} {rd}, {addr}", xxxx01xxxxx1xxxxxxxxxxxxxxxxxxxx, 1, FLAG_XFR) +ARMV3_INSTR(STR, "str{cond}{b}{t} {rd}, {addr}", xxxx01xxxxx0xxxxxxxxxxxxxxxxxxxx, 1, FLAG_XFR) // block data transfer -ARMV3_INSTR(LDM, "ldm{cond}{stack} {rn}{!}, {rlist}{^}", xxxx100xxxx1xxxxxxxxxxxxxxxxxxxx, 1, FLAG_BLK) -ARMV3_INSTR(STM, "stm{cond}{stack} {rn}{!}, {rlist}{^}", xxxx100xxxx0xxxxxxxxxxxxxxxxxxxx, 1, FLAG_BLK) +ARMV3_INSTR(LDM, "ldm{cond}{stack} {rn}{!}, {rlist}{^}", xxxx100xxxx1xxxxxxxxxxxxxxxxxxxx, 1, FLAG_BLK) +ARMV3_INSTR(STM, "stm{cond}{stack} {rn}{!}, {rlist}{^}", xxxx100xxxx0xxxxxxxxxxxxxxxxxxxx, 1, FLAG_BLK) // single data swap -ARMV3_INSTR(SWP, "swp{cond}{b} {rd}, {rm}, [{rn}]", xxxx00010x00xxxxxxxx00001001xxxx, 1, FLAG_SWP) +ARMV3_INSTR(SWP, "swp{cond}{b} {rd}, {rm}, [{rn}]", xxxx00010x00xxxxxxxx00001001xxxx, 1, FLAG_SWP) // software interrupt -ARMV3_INSTR(SWI, "swi{cond} {imm}", xxxx1111xxxxxxxxxxxxxxxxxxxxxxxx, 1, FLAG_SWI) +ARMV3_INSTR(SWI, "swi{cond} {imm}", xxxx1111xxxxxxxxxxxxxxxxxxxxxxxx, 1, FLAG_SWI) //// coprocessor data operations -//ARMV3_INSTR(CDP, "cdp{cond} p#, , cd, cn, cm{, }", xxxx1110xxxxxxxxxxxxyyyyzzz0xxxx, 1, 0) +//ARMV3_INSTR(CDP, "cdp{cond} p#, , cd, cn, cm{, }", xxxx1110xxxxxxxxxxxxyyyyzzz0xxxx, 1, 0) //// coprocessor data transfers -//ARMV3_INSTR(LDC, "ldc{cond}{l} p#, cd, {addr}", xxxx110PUNW1xxxxxxxxyyyyxxxxxxxx, 1, 0) -//ARMV3_INSTR(STC, "stc{cond}{l} p#, cd, {addr}", xxxx110PUNW0xxxxxxxxyyyyxxxxxxxx, 1, 0) +//ARMV3_INSTR(LDC, "ldc{cond}{l} p#, cd, {addr}", xxxx110PUNW1xxxxxxxxyyyyxxxxxxxx, 1, 0) +//ARMV3_INSTR(STC, "stc{cond}{l} p#, cd, {addr}", xxxx110PUNW0xxxxxxxxyyyyxxxxxxxx, 1, 0) //// coprocessor register transfers -//ARMV3_INSTR(MRC, "mrc{cond} p#, , {rd}, cn, cm{, }", xxxx1110xxx1xxxxxxxxyyyyzzz1xxxx, 1, 0) -//ARMV3_INSTR(MCR, "mcr{cond} p#, , {rd}, cn, cm{, }", xxxx1110xxx0xxxxxxxxyyyyzzz1xxxx, 1, 0) +//ARMV3_INSTR(MRC, "mrc{cond} p#, , {rd}, cn, cm{, }", xxxx1110xxx1xxxxxxxxyyyyzzz1xxxx, 1, 0) +//ARMV3_INSTR(MCR, "mcr{cond} p#, , {rd}, cn, cm{, }", xxxx1110xxx0xxxxxxxxyyyyzzz1xxxx, 1, 0) diff --git a/src/jit/frontend/jit_frontend.h b/src/jit/frontend/jit_frontend.h index 9369457f..76c15599 100644 --- a/src/jit/frontend/jit_frontend.h +++ b/src/jit/frontend/jit_frontend.h @@ -28,7 +28,7 @@ struct jit_frontend { void (*translate_code)(struct jit_frontend *, struct jit_block *, struct ir *); - void (*dump_code)(struct jit_frontend *, uint32_t, int); + void (*dump_code)(struct jit_frontend *, const struct jit_block *); const struct jit_opdef *(*lookup_op)(struct jit_frontend *, const void *); }; diff --git a/src/jit/frontend/sh4/sh4_frontend.c b/src/jit/frontend/sh4/sh4_frontend.c index b7df2f15..1940ca96 100644 --- a/src/jit/frontend/sh4/sh4_frontend.c +++ b/src/jit/frontend/sh4/sh4_frontend.c @@ -65,16 +65,15 @@ static const struct jit_opdef *sh4_frontend_lookup_op(struct jit_frontend *base, return sh4_get_opdef(*(const uint16_t *)instr); } -static void sh4_frontend_dump_code(struct jit_frontend *base, uint32_t addr, - int size) { +static void sh4_frontend_dump_code(struct jit_frontend *base, + const struct jit_block *block) { struct sh4_frontend *frontend = (struct sh4_frontend *)base; struct jit_guest *guest = frontend->jit->guest; char buffer[128]; - uint32_t end = addr + size; - - while (addr < end) { + for (int offset = 0; offset < block->guest_size; offset += 2) { + uint32_t addr = block->guest_addr + offset; uint16_t data = guest->r16(guest->space, addr); union sh4_instr instr = {data}; struct jit_opdef *def = sh4_get_opdef(data); @@ -82,16 +81,15 @@ static void sh4_frontend_dump_code(struct jit_frontend *base, uint32_t addr, sh4_format(addr, instr, buffer, sizeof(buffer)); LOG_INFO(buffer); - addr += 2; - if (def->flags & SH4_FLAG_DELAYED) { - uint16_t delay_data = guest->r16(guest->space, addr); + uint32_t delay_addr = addr + 2; + uint16_t delay_data = guest->r16(guest->space, delay_addr); union sh4_instr delay_instr = {delay_data}; sh4_format(addr, delay_instr, buffer, sizeof(buffer)); LOG_INFO(buffer); - addr += 2; + offset += 2; } } } @@ -119,11 +117,10 @@ static void sh4_frontend_translate_code(struct jit_frontend *base, sh4_analyze_block(guest, block); /* translate the actual block */ - uint32_t addr = block->guest_addr; - uint32_t end = block->guest_addr + block->guest_size; int end_flags = 0; - while (addr < end) { + for (int offset = 0; offset < block->guest_size; offset += 2) { + uint32_t addr = block->guest_addr + offset; uint16_t data = guest->r16(guest->space, addr); struct jit_opdef *def = sh4_get_opdef(data); sh4_translate_cb cb = sh4_get_translator(data); @@ -132,9 +129,7 @@ static void sh4_frontend_translate_code(struct jit_frontend *base, cb(guest, ir, flags, addr, instr); if (def->flags & SH4_FLAG_DELAYED) { - addr += 4; - } else { - addr += 2; + offset += 2; } end_flags = def->flags; @@ -160,7 +155,7 @@ static void sh4_frontend_translate_code(struct jit_frontend *base, struct ir_instr *tail_instr = list_last_entry(&tail_block->instrs, struct ir_instr, it); ir_set_current_instr(ir, tail_instr); - ir_branch(ir, ir_alloc_i32(ir, addr)); + ir_branch(ir, ir_alloc_i32(ir, block->guest_addr + block->guest_size)); } PROF_LEAVE(); diff --git a/src/jit/jit.c b/src/jit/jit.c index 574ceaeb..3afc0cf5 100644 --- a/src/jit/jit.c +++ b/src/jit/jit.c @@ -307,6 +307,10 @@ void jit_compile_block(struct jit *jit, uint32_t guest_addr) { ir.capacity = sizeof(jit->ir_buffer); jit->frontend->translate_code(jit->frontend, block, &ir); +#if 0 + jit->frontend->dump_code(jit->frontend, block); +#endif + /* dump unoptimized block */ if (jit->dump_blocks) { jit_dump_block(jit, guest_addr, &ir);