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);