Mercurial > repos > blastem
comparison m68k_to_x86.c @ 319:0bcab0475a7f
Port instruction retranslation improvements from Z80 core to M68K core
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 11 May 2013 01:38:57 -0700 |
parents | d9bf8e61c33c |
children | 146c87616b05 |
comparison
equal
deleted
inserted
replaced
318:789f2f5f2277 | 319:0bcab0475a7f |
---|---|
3863 exit(1); | 3863 exit(1); |
3864 } | 3864 } |
3865 return dst; | 3865 return dst; |
3866 } | 3866 } |
3867 | 3867 |
3868 uint8_t m68k_is_terminal(m68kinst * inst) | |
3869 { | |
3870 return inst->op == M68K_RTS || inst->op == M68K_RTE || inst->op == M68K_RTR || inst->op == M68K_JMP | |
3871 || inst->op == M68K_TRAP || inst->op == M68K_ILLEGAL || inst->op == M68K_INVALID || inst->op == M68K_RESET | |
3872 || (inst->op == M68K_BCC && inst->extra.cond == COND_TRUE); | |
3873 } | |
3874 | |
3875 void m68k_handle_deferred(m68k_context * context) | |
3876 { | |
3877 x86_68k_options * opts = context->options; | |
3878 process_deferred(&opts->deferred, context, (native_addr_func)get_native_from_context); | |
3879 if (opts->deferred) { | |
3880 translate_m68k_stream(opts->deferred->address, context); | |
3881 } | |
3882 } | |
3883 | |
3868 uint8_t * translate_m68k_stream(uint32_t address, m68k_context * context) | 3884 uint8_t * translate_m68k_stream(uint32_t address, m68k_context * context) |
3869 { | 3885 { |
3870 m68kinst instbuf; | 3886 m68kinst instbuf; |
3871 x86_68k_options * opts = context->options; | 3887 x86_68k_options * opts = context->options; |
3872 uint8_t * dst = opts->cur_code; | 3888 uint8_t * dst = opts->cur_code; |
3922 //m68k_disasm(&instbuf, disbuf); | 3938 //m68k_disasm(&instbuf, disbuf); |
3923 //printf("%X: %s\n", instbuf.address, disbuf); | 3939 //printf("%X: %s\n", instbuf.address, disbuf); |
3924 uint8_t * after = translate_m68k(dst, &instbuf, opts); | 3940 uint8_t * after = translate_m68k(dst, &instbuf, opts); |
3925 map_native_address(context, instbuf.address, dst, m68k_size, after-dst); | 3941 map_native_address(context, instbuf.address, dst, m68k_size, after-dst); |
3926 dst = after; | 3942 dst = after; |
3927 } while(instbuf.op != M68K_ILLEGAL && instbuf.op != M68K_RESET && instbuf.op != M68K_INVALID && instbuf.op != M68K_TRAP && instbuf.op != M68K_RTS && instbuf.op != M68K_RTR && instbuf.op != M68K_RTE && !(instbuf.op == M68K_BCC && instbuf.extra.cond == COND_TRUE) && instbuf.op != M68K_JMP); | 3943 } while(!m68k_is_terminal(&instbuf)); |
3928 process_deferred(&opts->deferred, context, (native_addr_func)get_native_from_context); | 3944 process_deferred(&opts->deferred, context, (native_addr_func)get_native_from_context); |
3929 if (opts->deferred) { | 3945 if (opts->deferred) { |
3930 address = opts->deferred->address; | 3946 address = opts->deferred->address; |
3931 if ((address & 0xFFFFFF) < 0x400000) { | 3947 if ((address & 0xFFFFFF) < 0x400000) { |
3932 encoded = context->mem_pointers[0] + (address & 0xFFFFFF)/2; | 3948 encoded = context->mem_pointers[0] + (address & 0xFFFFFF)/2; |
3972 size_t size = 1024*1024; | 3988 size_t size = 1024*1024; |
3973 dst = alloc_code(&size); | 3989 dst = alloc_code(&size); |
3974 opts->code_end = dst_end = dst + size; | 3990 opts->code_end = dst_end = dst + size; |
3975 opts->cur_code = dst; | 3991 opts->cur_code = dst; |
3976 } | 3992 } |
3993 deferred_addr * orig_deferred = opts->deferred; | |
3977 uint8_t * native_end = translate_m68k(dst, &instbuf, opts); | 3994 uint8_t * native_end = translate_m68k(dst, &instbuf, opts); |
3995 uint8_t is_terminal = m68k_is_terminal(&instbuf); | |
3978 if ((native_end - dst) <= orig_size) { | 3996 if ((native_end - dst) <= orig_size) { |
3979 native_end = translate_m68k(orig_start, &instbuf, opts); | 3997 uint8_t * native_next; |
3980 while (native_end < orig_start + orig_size) { | 3998 if (!is_terminal) { |
3981 *(native_end++) = 0x90; //NOP | 3999 native_next = get_native_address(context->native_code_map, orig + (after-inst)*2); |
3982 } | 4000 } |
3983 return orig_start; | 4001 if (is_terminal || (native_next && ((native_next == orig_start + orig_size) || (orig_size - (native_end - dst)) > 5))) { |
3984 } else { | 4002 remove_deferred_until(&opts->deferred, orig_deferred); |
3985 map_native_address(context, instbuf.address, dst, (after-inst)*2, MAX_NATIVE_SIZE); | 4003 native_end = translate_m68k(orig_start, &instbuf, opts); |
3986 opts->code_end = dst+MAX_NATIVE_SIZE; | 4004 if (!is_terminal) { |
3987 if (instbuf.op != M68K_RTS && instbuf.op != M68K_RTE && instbuf.op != M68K_RTR && instbuf.op != M68K_JMP && (instbuf.op != M68K_BCC || instbuf.extra.cond != COND_TRUE)) { | 4005 if (native_next == orig_start + orig_size && (native_next-native_end) < 2) { |
3988 jmp(native_end, get_native_address(context->native_code_map, address + (after-inst)*2)); | 4006 while (native_end < orig_start + orig_size) { |
3989 } | 4007 *(native_end++) = 0x90; //NOP |
3990 return dst; | 4008 } |
3991 } | 4009 } else { |
4010 jmp(native_end, native_next); | |
4011 } | |
4012 } | |
4013 m68k_handle_deferred(context); | |
4014 return orig_start; | |
4015 } | |
4016 } | |
4017 | |
4018 map_native_address(context, instbuf.address, dst, (after-inst)*2, MAX_NATIVE_SIZE); | |
4019 opts->cur_code = dst+MAX_NATIVE_SIZE; | |
4020 jmp(orig_start, dst); | |
4021 if (!m68k_is_terminal(&instbuf)) { | |
4022 jmp(native_end, get_native_address_trans(context, orig + (after-inst)*2)); | |
4023 } | |
4024 m68k_handle_deferred(context); | |
4025 return dst; | |
3992 } else { | 4026 } else { |
3993 dst = translate_m68k(orig_start, &instbuf, opts); | 4027 dst = translate_m68k(orig_start, &instbuf, opts); |
3994 if (instbuf.op != M68K_RTS && instbuf.op != M68K_RTE && instbuf.op != M68K_RTR && instbuf.op != M68K_JMP && (instbuf.op != M68K_BCC || instbuf.extra.cond != COND_TRUE)) { | 4028 if (!m68k_is_terminal(&instbuf)) { |
3995 dst = jmp(dst, get_native_address(context->native_code_map, address + (after-inst)*2)); | 4029 dst = jmp(dst, get_native_address_trans(context, orig + (after-inst)*2)); |
3996 } | 4030 } |
4031 m68k_handle_deferred(context); | |
3997 return orig_start; | 4032 return orig_start; |
3998 } | 4033 } |
3999 } | 4034 } |
4000 | 4035 |
4001 m68k_context * m68k_handle_code_write(uint32_t address, m68k_context * context) | 4036 m68k_context * m68k_handle_code_write(uint32_t address, m68k_context * context) |