# HG changeset patch # User Michael Pavone # Date 1448605841 28800 # Node ID 07bfbbbb4b2e6e03e5ad411eeff23cd8a8803f60 # Parent 2f1157f00dc6d2620155ebaabb8ed3be5690a5f2 Fix for Z80 retranslation post alignment rework diff -r 2f1157f00dc6 -r 07bfbbbb4b2e gen_x86.c --- a/gen_x86.c Thu Nov 26 00:10:36 2015 -0800 +++ b/gen_x86.c Thu Nov 26 22:30:41 2015 -0800 @@ -1968,15 +1968,8 @@ code->cur = out; } -void call(code_info *code, code_ptr fun) +void call_noalign(code_info *code, code_ptr fun) { - code->stack_off += sizeof(void *); - int32_t adjust = 0; - if (code->stack_off & 0xF) { - adjust = 16 - (code->stack_off & 0xF); - code->stack_off += adjust; - sub_ir(code, adjust, RSP, SZ_PTR); - } check_alloc_code(code, 5); code_ptr out = code->cur; ptrdiff_t disp = fun-(out+5); @@ -1994,12 +1987,24 @@ fatal_error("call: %p - %p = %lX which is out of range for a 32-bit displacement\n", fun, out + 5, (long)disp); } code->cur = out; +} + + +void call(code_info *code, code_ptr fun) +{ + code->stack_off += sizeof(void *); + int32_t adjust = 0; + if (code->stack_off & 0xF) { + adjust = 16 - (code->stack_off & 0xF); + code->stack_off += adjust; + sub_ir(code, adjust, RSP, SZ_PTR); + } + call_noalign(code, fun); if (adjust) { add_ir(code, adjust, RSP, SZ_PTR); } code->stack_off -= sizeof(void *) + adjust; } - void call_raxfallback(code_info *code, code_ptr fun) { check_alloc_code(code, 5); diff -r 2f1157f00dc6 -r 07bfbbbb4b2e gen_x86.h --- a/gen_x86.h Thu Nov 26 00:10:36 2015 -0800 +++ b/gen_x86.h Thu Nov 26 22:30:41 2015 -0800 @@ -210,6 +210,7 @@ void btc_irdisp(code_info *code, uint8_t val, uint8_t dst_base, int32_t dst_disp, uint8_t size); void jcc(code_info *code, uint8_t cc, code_ptr dest); void jmp_rind(code_info *code, uint8_t dst); +void call_noalign(code_info *code, code_ptr fun); void call_r(code_info *code, uint8_t dst); void retn(code_info *code); void cdq(code_info *code); diff -r 2f1157f00dc6 -r 07bfbbbb4b2e z80_to_x86.c --- a/z80_to_x86.c Thu Nov 26 00:10:36 2015 -0800 +++ b/z80_to_x86.c Thu Nov 26 22:30:41 2015 -0800 @@ -2095,7 +2095,7 @@ uint32_t inst_start = z80_get_instruction_start(context->static_code_map, address); if (inst_start != INVALID_INSTRUCTION_START) { code_ptr dst = z80_get_native_address(context, inst_start); - code_info code = {dst, dst+16}; + code_info code = {dst, dst+32, 0}; z80_options * opts = context->options; dprintf("patching code at %p for Z80 instruction at %X due to write to %X\n", code.cur, inst_start, address); mov_ir(&code, inst_start, opts->gen.scratch1, SZ_D); @@ -2536,13 +2536,24 @@ options->retrans_stub = code->cur; tmp_stack_off = code->stack_off; + //calculate size of patch + mov_ir(code, 0x7FFF, options->gen.scratch1, SZ_D); + code->stack_off += sizeof(void *); + if (code->stack_off & 0xF) { + sub_ir(code, 16 - (code->stack_off & 0xF), RSP, SZ_PTR); + } + call_noalign(code, options->retrans_stub); + uint32_t patch_size = code->cur - options->retrans_stub; + code->cur = options->retrans_stub; + code->stack_off = tmp_stack_off; + //pop return address pop_r(code, options->gen.scratch2); add_ir(code, 16-sizeof(void*), RSP, SZ_PTR); code->stack_off = tmp_stack_off; call(code, options->gen.save_context); //adjust pointer before move and call instructions that got us here - sub_ir(code, options->gen.scratch1 >= R8 ? 11 : 10, options->gen.scratch2, SZ_PTR); + sub_ir(code, patch_size, options->gen.scratch2, SZ_PTR); push_r(code, options->gen.context_reg); call_args(code, (code_ptr)z80_retranslate_inst, 3, options->gen.scratch1, options->gen.context_reg, options->gen.scratch2); pop_r(code, options->gen.context_reg);