comparison m68k_to_x86.c @ 76:187c65f40a64

Implement JSR for some addressing modes
author Mike Pavone <pavone@retrodev.com>
date Fri, 21 Dec 2012 21:19:03 -0800
parents 6396dc91f61e
children 313a0e2228f1
comparison
equal deleted inserted replaced
75:108e587165c0 76:187c65f40a64
910 return dst; 910 return dst;
911 } 911 }
912 912
913 uint8_t * translate_m68k_bsr(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) 913 uint8_t * translate_m68k_bsr(uint8_t * dst, m68kinst * inst, x86_68k_options * opts)
914 { 914 {
915 //TODO: Add cycles
916 int32_t disp = inst->src.params.immed; 915 int32_t disp = inst->src.params.immed;
917 uint32_t after = inst->address + 2; 916 uint32_t after = inst->address + 2;
917 //TODO: Add cycles in the right place relative to pushing the return address on the stack
918 dst = cycles(dst, 10);
918 dst = mov_ir(dst, after, SCRATCH1, SZ_D); 919 dst = mov_ir(dst, after, SCRATCH1, SZ_D);
919 dst = push_r(dst, SCRATCH1); 920 dst = push_r(dst, SCRATCH1);
920 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 921 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
921 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 922 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
922 dst = call(dst, (char *)m68k_write_long_highfirst); 923 dst = call(dst, (char *)m68k_write_long_highfirst);
1004 { 1005 {
1005 uint8_t * dest_addr; 1006 uint8_t * dest_addr;
1006 switch(inst->src.addr_mode) 1007 switch(inst->src.addr_mode)
1007 { 1008 {
1008 case MODE_AREG_INDIRECT: 1009 case MODE_AREG_INDIRECT:
1009 dst = cycles(dst, BUS); 1010 dst = cycles(dst, BUS*2);
1010 if (opts->aregs[inst->src.params.regs.pri] >= 0) { 1011 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
1011 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); 1012 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D);
1012 } else { 1013 } else {
1013 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, SCRATCH1, SZ_D); 1014 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, SCRATCH1, SZ_D);
1014 } 1015 }
1015 dst = call(dst, (uint8_t *)m68k_native_addr); 1016 dst = call(dst, (uint8_t *)m68k_native_addr);
1016 //TODO: Finish me 1017 //TODO: Finish me
1017 //TODO: Fix timing 1018 printf("address mode %d not yet supported (jmp)\n", inst->src.addr_mode);
1019 break;
1020 case MODE_PC_DISPLACE:
1021 dst = cycles(dst, 10);
1022 dest_addr = get_native_address(opts->native_code_map, inst->src.params.regs.displacement + inst->address + 2);
1023 if (!dest_addr) {
1024 opts->deferred = defer_address(opts->deferred, inst->src.params.immed, dst + 1);
1025 //dummy address to be replaced later, make sure it generates a 4-byte displacement
1026 dest_addr = dst + 256;
1027 }
1028 dst = jmp(dst, dest_addr);
1018 break; 1029 break;
1019 case MODE_ABSOLUTE: 1030 case MODE_ABSOLUTE:
1020 case MODE_ABSOLUTE_SHORT: 1031 case MODE_ABSOLUTE_SHORT:
1021 dst = cycles(dst, inst->src.addr_mode == MODE_ABSOLUTE ? 12 : 10); 1032 dst = cycles(dst, inst->src.addr_mode == MODE_ABSOLUTE ? 12 : 10);
1022 dest_addr = get_native_address(opts->native_code_map, inst->src.params.immed); 1033 dest_addr = get_native_address(opts->native_code_map, inst->src.params.immed);
1025 //dummy address to be replaced later, make sure it generates a 4-byte displacement 1036 //dummy address to be replaced later, make sure it generates a 4-byte displacement
1026 dest_addr = dst + 256; 1037 dest_addr = dst + 256;
1027 } 1038 }
1028 dst = jmp(dst, dest_addr); 1039 dst = jmp(dst, dest_addr);
1029 break; 1040 break;
1041 default:
1042 printf("address mode %d not yet supported (jmp)\n", inst->src.addr_mode);
1043 }
1044 return dst;
1045 }
1046
1047 uint8_t * translate_m68k_jsr(uint8_t * dst, m68kinst * inst, x86_68k_options * opts)
1048 {
1049 uint8_t * dest_addr;
1050 uint32_t after;
1051 switch(inst->src.addr_mode)
1052 {
1053 case MODE_AREG_INDIRECT:
1054 dst = cycles(dst, BUS*2);
1055 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
1056 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D);
1057 } else {
1058 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, SCRATCH1, SZ_D);
1059 }
1060 dst = call(dst, (uint8_t *)m68k_native_addr);
1061 //TODO: Finish me
1062 printf("address mode %d not yet supported (jsr)\n", inst->src.addr_mode);
1063 break;
1064 case MODE_PC_DISPLACE:
1065 //TODO: Add cycles in the right place relative to pushing the return address on the stack
1066 dst = cycles(dst, 10);
1067 dst = mov_ir(dst, inst->address + 8, SCRATCH1, SZ_D);
1068 dst = push_r(dst, SCRATCH1);
1069 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
1070 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
1071 dst = call(dst, (char *)m68k_write_long_highfirst);
1072 dest_addr = get_native_address(opts->native_code_map, inst->src.params.regs.displacement + inst->address + 2);
1073 if (!dest_addr) {
1074 opts->deferred = defer_address(opts->deferred, inst->src.params.immed, dst + 1);
1075 //dummy address to be replaced later, make sure it generates a 4-byte displacement
1076 dest_addr = dst + 5;
1077 }
1078 dst = call(dst, (char *)dest_addr);
1079 //would add_ir(dst, 8, RSP, SZ_Q) be faster here?
1080 dst = pop_r(dst, SCRATCH1);
1081 break;
1082 case MODE_ABSOLUTE:
1083 case MODE_ABSOLUTE_SHORT:
1084 //TODO: Add cycles in the right place relative to pushing the return address on the stack
1085 dst = cycles(dst, inst->src.addr_mode == MODE_ABSOLUTE ? 12 : 10);
1086 dst = mov_ir(dst, inst->address + 8, SCRATCH1, SZ_D);
1087 dst = push_r(dst, SCRATCH1);
1088 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
1089 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
1090 dst = call(dst, (char *)m68k_write_long_highfirst);
1091 dest_addr = get_native_address(opts->native_code_map, inst->src.params.immed);
1092 if (!dest_addr) {
1093 opts->deferred = defer_address(opts->deferred, inst->src.params.immed, dst + 1);
1094 //dummy address to be replaced later, make sure it generates a 4-byte displacement
1095 dest_addr = dst + 5;
1096 }
1097 dst = call(dst, (char *)dest_addr);
1098 //would add_ir(dst, 8, RSP, SZ_Q) be faster here?
1099 dst = pop_r(dst, SCRATCH1);
1100 break;
1101 default:
1102 printf("address mode %d not yet supported (jsr)\n", inst->src.addr_mode);
1030 } 1103 }
1031 return dst; 1104 return dst;
1032 } 1105 }
1033 1106
1034 uint8_t * translate_m68k_rts(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) 1107 uint8_t * translate_m68k_rts(uint8_t * dst, m68kinst * inst, x86_68k_options * opts)
1239 return translate_m68k_bsr(dst, inst, opts); 1312 return translate_m68k_bsr(dst, inst, opts);
1240 } else if(inst->op == M68K_BCC) { 1313 } else if(inst->op == M68K_BCC) {
1241 return translate_m68k_bcc(dst, inst, opts); 1314 return translate_m68k_bcc(dst, inst, opts);
1242 } else if(inst->op == M68K_JMP) { 1315 } else if(inst->op == M68K_JMP) {
1243 return translate_m68k_jmp(dst, inst, opts); 1316 return translate_m68k_jmp(dst, inst, opts);
1317 } else if(inst->op == M68K_JSR) {
1318 return translate_m68k_jsr(dst, inst, opts);
1244 } else if(inst->op == M68K_RTS) { 1319 } else if(inst->op == M68K_RTS) {
1245 return translate_m68k_rts(dst, inst, opts); 1320 return translate_m68k_rts(dst, inst, opts);
1246 } else if(inst->op == M68K_DBCC) { 1321 } else if(inst->op == M68K_DBCC) {
1247 return translate_m68k_dbcc(dst, inst, opts); 1322 return translate_m68k_dbcc(dst, inst, opts);
1248 } else if(inst->op == M68K_CLR) { 1323 } else if(inst->op == M68K_CLR) {