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)