Mercurial > repos > blastem
comparison z80_to_x86.c @ 1224:15c5be05e6a9
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
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 19 Feb 2017 12:41:57 -0800 |
parents | 60d73f42a606 |
children | 197cb199a35b |
comparison
equal
deleted
inserted
replaced
1223:a477cc22a960 | 1224:15c5be05e6a9 |
---|---|
2957 map->base = native_address; | 2957 map->base = native_address; |
2958 map->offsets = malloc(sizeof(int32_t) * NATIVE_CHUNK_SIZE); | 2958 map->offsets = malloc(sizeof(int32_t) * NATIVE_CHUNK_SIZE); |
2959 memset(map->offsets, 0xFF, sizeof(int32_t) * NATIVE_CHUNK_SIZE); | 2959 memset(map->offsets, 0xFF, sizeof(int32_t) * NATIVE_CHUNK_SIZE); |
2960 } | 2960 } |
2961 | 2961 |
2962 //TODO: better handling of potentially overlapping instructions | 2962 if (map->offsets[address % NATIVE_CHUNK_SIZE] == INVALID_OFFSET) { |
2963 map->offsets[address % NATIVE_CHUNK_SIZE] = EXTENSION_WORD; | 2963 //TODO: better handling of potentially overlapping instructions |
2964 map->offsets[address % NATIVE_CHUNK_SIZE] = EXTENSION_WORD; | |
2965 } | |
2964 } | 2966 } |
2965 } | 2967 } |
2966 | 2968 |
2967 #define INVALID_INSTRUCTION_START 0xFEEDFEED | 2969 #define INVALID_INSTRUCTION_START 0xFEEDFEED |
2968 | 2970 |
2991 offset = address % NATIVE_CHUNK_SIZE; | 2993 offset = address % NATIVE_CHUNK_SIZE; |
2992 } | 2994 } |
2993 return address; | 2995 return address; |
2994 } | 2996 } |
2995 | 2997 |
2998 //Technically unbounded due to redundant prefixes, but this is the max useful size | |
2999 #define Z80_MAX_INST_SIZE 4 | |
3000 | |
2996 z80_context * z80_handle_code_write(uint32_t address, z80_context * context) | 3001 z80_context * z80_handle_code_write(uint32_t address, z80_context * context) |
2997 { | 3002 { |
2998 uint32_t inst_start = z80_get_instruction_start(context, address); | 3003 uint32_t inst_start = z80_get_instruction_start(context, address); |
2999 if (inst_start != INVALID_INSTRUCTION_START) { | 3004 while (inst_start != INVALID_INSTRUCTION_START && (address - inst_start) < Z80_MAX_INST_SIZE) { |
3000 code_ptr dst = z80_get_native_address(context, inst_start); | 3005 code_ptr dst = z80_get_native_address(context, inst_start); |
3001 code_info code = {dst, dst+32, 0}; | 3006 code_info code = {dst, dst+32, 0}; |
3002 z80_options * opts = context->options; | 3007 z80_options * opts = context->options; |
3003 dprintf("patching code at %p for Z80 instruction at %X due to write to %X\n", code.cur, inst_start, address); | 3008 dprintf("patching code at %p for Z80 instruction at %X due to write to %X\n", code.cur, inst_start, address); |
3004 mov_ir(&code, inst_start, opts->gen.scratch1, SZ_D); | 3009 mov_ir(&code, inst_start, opts->gen.scratch1, SZ_D); |
3005 call(&code, opts->retrans_stub); | 3010 call(&code, opts->retrans_stub); |
3011 inst_start = z80_get_instruction_start(context, inst_start - 1); | |
3006 } | 3012 } |
3007 return context; | 3013 return context; |
3008 } | 3014 } |
3009 | 3015 |
3010 void z80_invalidate_code_range(z80_context *context, uint32_t start, uint32_t end) | 3016 void z80_invalidate_code_range(z80_context *context, uint32_t start, uint32_t end) |
3710 return code.cur-dst; | 3716 return code.cur-dst; |
3711 } | 3717 } |
3712 | 3718 |
3713 void zcreate_stub(z80_context * context) | 3719 void zcreate_stub(z80_context * context) |
3714 { | 3720 { |
3715 //FIXME: Stack offset stuff is still a bit broken | 3721 //FIXME: Stack offset stuff is probably broken on 32-bit |
3716 z80_options * opts = context->options; | 3722 z80_options * opts = context->options; |
3717 code_info *code = &opts->gen.code; | 3723 code_info *code = &opts->gen.code; |
3718 uint32_t start_stack_off = code->stack_off; | 3724 uint32_t start_stack_off = code->stack_off; |
3719 check_code_prologue(code); | 3725 check_code_prologue(code); |
3720 context->bp_stub = code->cur; | 3726 context->bp_stub = code->cur; |
3742 cmp_ir(code, 1, opts->gen.cycles, SZ_D); | 3748 cmp_ir(code, 1, opts->gen.cycles, SZ_D); |
3743 uint8_t * jmp_off = code->cur+1; | 3749 uint8_t * jmp_off = code->cur+1; |
3744 jcc(code, CC_NS, code->cur + 7); | 3750 jcc(code, CC_NS, code->cur + 7); |
3745 pop_r(code, opts->gen.scratch1); | 3751 pop_r(code, opts->gen.scratch1); |
3746 add_ir(code, check_int_size - patch_size, opts->gen.scratch1, SZ_PTR); | 3752 add_ir(code, check_int_size - patch_size, opts->gen.scratch1, SZ_PTR); |
3753 #ifdef X86_64 | |
3754 sub_ir(code, 8, RSP, SZ_PTR); | |
3755 #endif | |
3747 push_r(code, opts->gen.scratch1); | 3756 push_r(code, opts->gen.scratch1); |
3748 jmp(code, opts->gen.handle_cycle_limit_int); | 3757 jmp(code, opts->gen.handle_cycle_limit_int); |
3749 *jmp_off = code->cur - (jmp_off+1); | 3758 *jmp_off = code->cur - (jmp_off+1); |
3750 //jump back to body of translated instruction | 3759 //jump back to body of translated instruction |
3751 pop_r(code, opts->gen.scratch1); | 3760 pop_r(code, opts->gen.scratch1); |