# HG changeset patch # User Michael Pavone # Date 1487536917 28800 # Node ID 15c5be05e6a9b441dc71dafb2cf838d8ab8a429e # Parent a477cc22a96028e5bf4745b9a140736a53c161d2 Ported correct but inefficient overlapping instruction handling from 68K core to Z80 core. Fixed remaining stack alignment issue for Z80 breakpoints on 64-bit. Probably still needs fixing for 32-bit diff -r a477cc22a960 -r 15c5be05e6a9 z80_to_x86.c --- a/z80_to_x86.c Sat Feb 18 05:42:37 2017 -0800 +++ b/z80_to_x86.c Sun Feb 19 12:41:57 2017 -0800 @@ -2959,8 +2959,10 @@ memset(map->offsets, 0xFF, sizeof(int32_t) * NATIVE_CHUNK_SIZE); } - //TODO: better handling of potentially overlapping instructions - map->offsets[address % NATIVE_CHUNK_SIZE] = EXTENSION_WORD; + if (map->offsets[address % NATIVE_CHUNK_SIZE] == INVALID_OFFSET) { + //TODO: better handling of potentially overlapping instructions + map->offsets[address % NATIVE_CHUNK_SIZE] = EXTENSION_WORD; + } } } @@ -2993,16 +2995,20 @@ return address; } +//Technically unbounded due to redundant prefixes, but this is the max useful size +#define Z80_MAX_INST_SIZE 4 + z80_context * z80_handle_code_write(uint32_t address, z80_context * context) { uint32_t inst_start = z80_get_instruction_start(context, address); - if (inst_start != INVALID_INSTRUCTION_START) { + while (inst_start != INVALID_INSTRUCTION_START && (address - inst_start) < Z80_MAX_INST_SIZE) { code_ptr dst = z80_get_native_address(context, inst_start); 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); call(&code, opts->retrans_stub); + inst_start = z80_get_instruction_start(context, inst_start - 1); } return context; } @@ -3712,7 +3718,7 @@ void zcreate_stub(z80_context * context) { - //FIXME: Stack offset stuff is still a bit broken + //FIXME: Stack offset stuff is probably broken on 32-bit z80_options * opts = context->options; code_info *code = &opts->gen.code; uint32_t start_stack_off = code->stack_off; @@ -3744,6 +3750,9 @@ jcc(code, CC_NS, code->cur + 7); pop_r(code, opts->gen.scratch1); add_ir(code, check_int_size - patch_size, opts->gen.scratch1, SZ_PTR); +#ifdef X86_64 + sub_ir(code, 8, RSP, SZ_PTR); +#endif push_r(code, opts->gen.scratch1); jmp(code, opts->gen.handle_cycle_limit_int); *jmp_off = code->cur - (jmp_off+1);