Mercurial > repos > blastem
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) { |