Mercurial > repos > blastem
comparison m68k_to_x86.c @ 112:e3594572fb98
Implement scc (untested)
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Fri, 28 Dec 2012 17:57:43 -0800 |
parents | a575808dd90b |
children | d260996eea55 |
comparison
equal
deleted
inserted
replaced
111:8b50d2c975b2 | 112:e3594572fb98 |
---|---|
1333 //dummy address to be replaced later, make sure it generates a 4-byte displacement | 1333 //dummy address to be replaced later, make sure it generates a 4-byte displacement |
1334 dest_addr = dst + 256; | 1334 dest_addr = dst + 256; |
1335 } | 1335 } |
1336 dst = jcc(dst, cond, dest_addr); | 1336 dst = jcc(dst, cond, dest_addr); |
1337 } | 1337 } |
1338 return dst; | |
1339 } | |
1340 | |
1341 uint8_t * translate_m68k_scc(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) | |
1342 { | |
1343 uint8_t cond = inst->extra.cond; | |
1344 x86_ea dst_op; | |
1345 inst->extra.size = OPSIZE_BYTE; | |
1346 dst = translate_m68k_dst(inst, &dst_op, dst, opts, 1); | |
1347 if (cond == COND_TRUE || cond == COND_FALSE) { | |
1348 if ((inst->dst.addr_mode == MODE_REG || inst->dst.addr_mode == MODE_AREG) && inst->extra.cond == COND_TRUE) { | |
1349 dst = cycles(dst, 6); | |
1350 } else { | |
1351 dst = cycles(dst, BUS); | |
1352 } | |
1353 if (dst_op.mode == MODE_REG_DIRECT) { | |
1354 dst = mov_ir(dst, cond == COND_TRUE, dst_op.base, SZ_B); | |
1355 } else { | |
1356 dst = mov_irdisp8(dst, cond == COND_TRUE, dst_op.base, dst_op.disp, SZ_B); | |
1357 } | |
1358 } else { | |
1359 uint8_t cc = CC_NZ; | |
1360 switch (cond) | |
1361 { | |
1362 case COND_HIGH: | |
1363 cc = CC_Z; | |
1364 case COND_LOW_SAME: | |
1365 dst = mov_rr(dst, FLAG_Z, SCRATCH1, SZ_B); | |
1366 dst = or_rr(dst, FLAG_C, SCRATCH1, SZ_B); | |
1367 break; | |
1368 case COND_CARRY_CLR: | |
1369 cc = CC_Z; | |
1370 case COND_CARRY_SET: | |
1371 dst = cmp_ir(dst, 0, FLAG_C, SZ_B); | |
1372 break; | |
1373 case COND_NOT_EQ: | |
1374 cc = CC_Z; | |
1375 case COND_EQ: | |
1376 dst = cmp_ir(dst, 0, FLAG_Z, SZ_B); | |
1377 break; | |
1378 case COND_OVERF_CLR: | |
1379 cc = CC_Z; | |
1380 case COND_OVERF_SET: | |
1381 dst = cmp_ir(dst, 0, FLAG_V, SZ_B); | |
1382 break; | |
1383 case COND_PLUS: | |
1384 cc = CC_Z; | |
1385 case COND_MINUS: | |
1386 dst = cmp_ir(dst, 0, FLAG_N, SZ_B); | |
1387 break; | |
1388 case COND_GREATER_EQ: | |
1389 cc = CC_Z; | |
1390 case COND_LESS: | |
1391 dst = cmp_rr(dst, FLAG_N, FLAG_V, SZ_B); | |
1392 break; | |
1393 case COND_GREATER: | |
1394 cc = CC_Z; | |
1395 case COND_LESS_EQ: | |
1396 dst = mov_rr(dst, FLAG_V, SCRATCH1, SZ_B); | |
1397 dst = xor_rr(dst, FLAG_N, SCRATCH1, SZ_B); | |
1398 dst = or_rr(dst, FLAG_Z, SCRATCH1, SZ_B); | |
1399 break; | |
1400 } | |
1401 if ((inst->dst.addr_mode == MODE_REG || inst->dst.addr_mode == MODE_AREG)) { | |
1402 uint8_t *true_off = dst + 1; | |
1403 dst = jcc(dst, cc, dst+2); | |
1404 dst = cycles(dst, BUS); | |
1405 if (dst_op.mode == MODE_REG_DIRECT) { | |
1406 dst = mov_ir(dst, 0, dst_op.base, SZ_B); | |
1407 } else { | |
1408 dst = mov_irdisp8(dst, 0, dst_op.base, dst_op.disp, SZ_B); | |
1409 } | |
1410 uint8_t *end_off = dst+1; | |
1411 dst = jmp(dst, dst+2); | |
1412 *true_off = dst - (true_off+1); | |
1413 dst = cycles(dst, 6); | |
1414 if (dst_op.mode == MODE_REG_DIRECT) { | |
1415 dst = mov_ir(dst, 1, dst_op.base, SZ_B); | |
1416 } else { | |
1417 dst = mov_irdisp8(dst, 1, dst_op.base, dst_op.disp, SZ_B); | |
1418 } | |
1419 *end_off = dst - (end_off+1); | |
1420 } else { | |
1421 dst = cycles(dst, BUS); | |
1422 if (dst_op.mode == MODE_REG_DIRECT) { | |
1423 dst = setcc_r(dst, cc, dst_op.base); | |
1424 } else { | |
1425 dst = setcc_rdisp8(dst, cc, dst_op.base, dst_op.disp); | |
1426 } | |
1427 } | |
1428 } | |
1429 dst = m68k_save_result(inst, dst, opts); | |
1338 return dst; | 1430 return dst; |
1339 } | 1431 } |
1340 | 1432 |
1341 uint8_t * translate_m68k_jmp(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) | 1433 uint8_t * translate_m68k_jmp(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) |
1342 { | 1434 { |
1793 return translate_m68k_movem(dst, inst, opts); | 1885 return translate_m68k_movem(dst, inst, opts); |
1794 } else if(inst->op == M68K_LINK) { | 1886 } else if(inst->op == M68K_LINK) { |
1795 return translate_m68k_link(dst, inst, opts); | 1887 return translate_m68k_link(dst, inst, opts); |
1796 } else if(inst->op == M68K_EXT) { | 1888 } else if(inst->op == M68K_EXT) { |
1797 return translate_m68k_ext(dst, inst, opts); | 1889 return translate_m68k_ext(dst, inst, opts); |
1890 } else if(inst->op == M68K_SCC) { | |
1891 return translate_m68k_scc(dst, inst, opts); | |
1798 } | 1892 } |
1799 x86_ea src_op, dst_op; | 1893 x86_ea src_op, dst_op; |
1800 if (inst->src.addr_mode != MODE_UNUSED) { | 1894 if (inst->src.addr_mode != MODE_UNUSED) { |
1801 dst = translate_m68k_src(inst, &src_op, dst, opts); | 1895 dst = translate_m68k_src(inst, &src_op, dst, opts); |
1802 } | 1896 } |