Mercurial > repos > blastem
comparison m68k_to_x86.c @ 116:9eaba47c429d
Implement pea (untested).
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Fri, 28 Dec 2012 21:20:14 -0800 |
parents | d260996eea55 |
children | d9ff99ef5533 |
comparison
equal
deleted
inserted
replaced
115:11d72e471104 | 116:9eaba47c429d |
---|---|
1244 break; | 1244 break; |
1245 default: | 1245 default: |
1246 printf("address mode %d not implemented (lea src)\n", inst->src.addr_mode); | 1246 printf("address mode %d not implemented (lea src)\n", inst->src.addr_mode); |
1247 exit(1); | 1247 exit(1); |
1248 } | 1248 } |
1249 return dst; | |
1250 } | |
1251 | |
1252 uint8_t * translate_m68k_pea(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) | |
1253 { | |
1254 uint8_t sec_reg; | |
1255 switch(inst->src.addr_mode) | |
1256 { | |
1257 case MODE_AREG_INDIRECT: | |
1258 dst = cycles(dst, BUS); | |
1259 if (opts->aregs[inst->src.params.regs.pri] >= 0) { | |
1260 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); | |
1261 } else { | |
1262 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, SCRATCH1, SZ_D); | |
1263 } | |
1264 break; | |
1265 case MODE_AREG_DISPLACE: | |
1266 dst = cycles(dst, 8); | |
1267 if (opts->aregs[inst->src.params.regs.pri] >= 0) { | |
1268 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); | |
1269 } else { | |
1270 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_D); | |
1271 } | |
1272 dst = add_ir(dst, inst->src.params.regs.displacement, SCRATCH1, SZ_D); | |
1273 break; | |
1274 case MODE_AREG_INDEX_DISP8: | |
1275 dst = cycles(dst, 6);//TODO: Check to make sure this is correct | |
1276 if (opts->aregs[inst->src.params.regs.pri] >= 0) { | |
1277 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); | |
1278 } else { | |
1279 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_D); | |
1280 } | |
1281 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7; | |
1282 if (inst->src.params.regs.sec & 1) { | |
1283 if (inst->src.params.regs.sec & 0x10) { | |
1284 if (opts->aregs[sec_reg] >= 0) { | |
1285 dst = add_rr(dst, opts->aregs[sec_reg], SCRATCH1, SZ_D); | |
1286 } else { | |
1287 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D); | |
1288 } | |
1289 } else { | |
1290 if (opts->dregs[sec_reg] >= 0) { | |
1291 dst = add_rr(dst, opts->dregs[sec_reg], SCRATCH1, SZ_D); | |
1292 } else { | |
1293 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D); | |
1294 } | |
1295 } | |
1296 } else { | |
1297 if (inst->src.params.regs.sec & 0x10) { | |
1298 if (opts->aregs[sec_reg] >= 0) { | |
1299 dst = movsx_rr(dst, opts->aregs[sec_reg], SCRATCH2, SZ_W, SZ_D); | |
1300 } else { | |
1301 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D); | |
1302 } | |
1303 } else { | |
1304 if (opts->dregs[sec_reg] >= 0) { | |
1305 dst = movsx_rr(dst, opts->dregs[sec_reg], SCRATCH2, SZ_W, SZ_D); | |
1306 } else { | |
1307 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D); | |
1308 } | |
1309 } | |
1310 dst = add_rr(dst, SCRATCH2, SCRATCH1, SZ_D); | |
1311 } | |
1312 if (inst->src.params.regs.displacement) { | |
1313 dst = add_ir(dst, inst->src.params.regs.displacement, SCRATCH1, SZ_D); | |
1314 } | |
1315 break; | |
1316 case MODE_PC_DISPLACE: | |
1317 dst = cycles(dst, 8); | |
1318 dst = mov_ir(dst, inst->src.params.regs.displacement + inst->address+2, SCRATCH1, SZ_D); | |
1319 break; | |
1320 case MODE_ABSOLUTE: | |
1321 case MODE_ABSOLUTE_SHORT: | |
1322 dst = cycles(dst, (inst->src.addr_mode == MODE_ABSOLUTE) ? BUS * 3 : BUS * 2); | |
1323 dst = mov_ir(dst, inst->src.params.immed, SCRATCH1, SZ_D); | |
1324 break; | |
1325 default: | |
1326 printf("address mode %d not implemented (lea src)\n", inst->src.addr_mode); | |
1327 exit(1); | |
1328 } | |
1329 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); | |
1330 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); | |
1331 dst = call(dst, (uint8_t *)m68k_write_long_lowfirst); | |
1249 return dst; | 1332 return dst; |
1250 } | 1333 } |
1251 | 1334 |
1252 uint8_t * translate_m68k_bsr(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) | 1335 uint8_t * translate_m68k_bsr(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) |
1253 { | 1336 { |
1865 dst = check_cycles_int(dst, inst->address); | 1948 dst = check_cycles_int(dst, inst->address); |
1866 if (inst->op == M68K_MOVE) { | 1949 if (inst->op == M68K_MOVE) { |
1867 return translate_m68k_move(dst, inst, opts); | 1950 return translate_m68k_move(dst, inst, opts); |
1868 } else if(inst->op == M68K_LEA) { | 1951 } else if(inst->op == M68K_LEA) { |
1869 return translate_m68k_lea(dst, inst, opts); | 1952 return translate_m68k_lea(dst, inst, opts); |
1953 } else if(inst->op == M68K_PEA) { | |
1954 return translate_m68k_pea(dst, inst, opts); | |
1870 } else if(inst->op == M68K_BSR) { | 1955 } else if(inst->op == M68K_BSR) { |
1871 return translate_m68k_bsr(dst, inst, opts); | 1956 return translate_m68k_bsr(dst, inst, opts); |
1872 } else if(inst->op == M68K_BCC) { | 1957 } else if(inst->op == M68K_BCC) { |
1873 return translate_m68k_bcc(dst, inst, opts); | 1958 return translate_m68k_bcc(dst, inst, opts); |
1874 } else if(inst->op == M68K_JMP) { | 1959 } else if(inst->op == M68K_JMP) { |