# HG changeset patch # User Michael Pavone # Date 1505361985 25200 # Node ID 5d41d0574863eb29d1ec1ad438cb0ce62df4dc1d # Parent ffe45c5b83906148f7f59c1e46836a80872c424b Preserve original address when retranslating instructions instead of switching to the lowest alias diff -r ffe45c5b8390 -r 5d41d0574863 backend.h --- a/backend.h Fri Sep 08 00:38:22 2017 -0700 +++ b/backend.h Wed Sep 13 21:06:25 2017 -0700 @@ -98,6 +98,8 @@ uint32_t max_address; uint32_t bus_cycles; uint32_t clock_divider; + uint32_t move_pc_off; + uint32_t move_pc_size; int32_t mem_ptr_off; int32_t ram_flags_off; uint8_t ram_flags_shift; @@ -123,6 +125,9 @@ void check_code_prologue(code_info *code); void log_address(cpu_options *opts, uint32_t address, char * format); +void retranslate_calc(cpu_options *opts); +void patch_for_retranslate(cpu_options *opts, code_ptr native_address, code_ptr handler); + code_ptr gen_mem_fun(cpu_options * opts, memmap_chunk const * memmap, uint32_t num_chunks, ftype fun_type, code_ptr *after_inc); void * get_native_pointer(uint32_t address, void ** mem_pointers, cpu_options * opts); uint16_t read_word(uint32_t address, void **mem_pointers, cpu_options *opts, void *context); diff -r ffe45c5b8390 -r 5d41d0574863 backend_x86.c --- a/backend_x86.c Fri Sep 08 00:38:22 2017 -0700 +++ b/backend_x86.c Wed Sep 13 21:06:25 2017 -0700 @@ -1,5 +1,6 @@ #include "backend.h" #include "gen_x86.h" +#include void cycles(cpu_options *opts, uint32_t num) { @@ -28,6 +29,41 @@ *jmp_off = code->cur - (jmp_off+1); } +void retranslate_calc(cpu_options *opts) +{ + code_info *code = &opts->code; + code_info tmp = *code; + uint8_t cc; + if (opts->limit < 0) { + cmp_ir(code, 1, opts->cycles, SZ_D); + cc = CC_NS; + } else { + cmp_rr(code, opts->cycles, opts->limit, SZ_D); + cc = CC_A; + } + jcc(code, cc, code->cur+2); + opts->move_pc_off = code->cur - tmp.cur; + mov_ir(code, 0x1234, opts->scratch1, SZ_D); + opts->move_pc_size = code->cur - tmp.cur - opts->move_pc_off; + *code = tmp; +} + +void patch_for_retranslate(cpu_options *opts, code_ptr native_address, code_ptr handler) +{ + if (!is_mov_ir(native_address)) { + //instruction is not already patched for either retranslation or a breakpoint + //copy original mov_ir instruction containing PC to beginning of native code area + memmove(native_address, native_address + opts->move_pc_off, opts->move_pc_size); + } + //jump to the retranslation handler + code_info tmp = { + .cur = native_address + opts->move_pc_size, + .last = native_address + 256, + .stack_off = 0 + }; + jmp(&tmp, handler); +} + void check_cycles(cpu_options * opts) { code_info *code = &opts->code; diff -r ffe45c5b8390 -r 5d41d0574863 gen_x86.c --- a/gen_x86.c Fri Sep 08 00:38:22 2017 -0700 +++ b/gen_x86.c Wed Sep 13 21:06:25 2017 -0700 @@ -1307,6 +1307,15 @@ code->cur = out; } +uint8_t is_mov_ir(code_ptr inst) +{ + while (*inst == PRE_SIZE || *inst == PRE_REX) + { + inst++; + } + return (*inst & 0xF8) == OP_MOV_I8R || (*inst & 0xF8) == OP_MOV_IR || (*inst & 0xFE) == OP_MOV_IEA; +} + void mov_irdisp(code_info *code, int32_t val, uint8_t dst, int32_t disp, uint8_t size) { check_alloc_code(code, 12); diff -r ffe45c5b8390 -r 5d41d0574863 gen_x86.h --- a/gen_x86.h Fri Sep 08 00:38:22 2017 -0700 +++ b/gen_x86.h Wed Sep 13 21:06:25 2017 -0700 @@ -216,6 +216,7 @@ void retn(code_info *code); void cdq(code_info *code); void loop(code_info *code, code_ptr dst); +uint8_t is_mov_ir(code_ptr inst); #endif //GEN_X86_H_ diff -r ffe45c5b8390 -r 5d41d0574863 m68k_core_x86.c --- a/m68k_core_x86.c Fri Sep 08 00:38:22 2017 -0700 +++ b/m68k_core_x86.c Wed Sep 13 21:06:25 2017 -0700 @@ -2498,11 +2498,8 @@ m68k_options * options = context->options; uint32_t inst_start = get_instruction_start(options, address); while (inst_start && (address - inst_start) < M68K_MAX_INST_SIZE) { - code_info *code = &options->gen.code; code_ptr dst = get_native_address(context->options, inst_start); - code_info orig = {dst, dst + 128, 0}; - mov_ir(&orig, inst_start, options->gen.scratch2, SZ_D); - jmp(&orig, options->retrans_stub); + patch_for_retranslate(&options->gen, dst, options->retrans_stub); inst_start = get_instruction_start(options, inst_start - 2); } return context; @@ -2531,12 +2528,13 @@ for (uint32_t offset = start_offset; offset < end_offset; offset++) { if (native_code_map[chunk].offsets[offset] != INVALID_OFFSET && native_code_map[chunk].offsets[offset] != EXTENSION_WORD) { - code_info code; + patch_for_retranslate(&opts->gen, native_code_map[chunk].base + native_code_map[chunk].offsets[offset], opts->retrans_stub); + /*code_info code; code.cur = native_code_map[chunk].base + native_code_map[chunk].offsets[offset]; code.last = code.cur + 32; code.stack_off = 0; mov_ir(&code, chunk * NATIVE_CHUNK_SIZE + offset, opts->gen.scratch2, SZ_D); - jmp(&code, opts->retrans_stub); + jmp(&code, opts->retrans_stub);*/ } } } @@ -3182,7 +3180,7 @@ opts->retrans_stub = code->cur; call(code, opts->gen.save_context); push_r(code, opts->gen.context_reg); - call_args(code,(code_ptr)m68k_retranslate_inst, 2, opts->gen.scratch2, opts->gen.context_reg); + call_args(code,(code_ptr)m68k_retranslate_inst, 2, opts->gen.scratch1, opts->gen.context_reg); pop_r(code, opts->gen.context_reg); mov_rr(code, RAX, opts->gen.scratch1, SZ_PTR); call(code, opts->gen.load_context); @@ -3225,4 +3223,6 @@ add_ir(code, check_int_size - patch_size, opts->gen.scratch1, SZ_PTR); jmp_r(code, opts->gen.scratch1); code->stack_off = tmp_stack_off; + + retranslate_calc(&opts->gen); }