Mercurial > repos > blastem
comparison m68k_to_x86.c @ 110:a575808dd90b
Implement more address modes for jsr
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Fri, 28 Dec 2012 15:16:36 -0800 |
parents | 9705075fcf36 |
children | e3594572fb98 |
comparison
equal
deleted
inserted
replaced
109:004dd46e0a97 | 110:a575808dd90b |
---|---|
1381 return dst; | 1381 return dst; |
1382 } | 1382 } |
1383 | 1383 |
1384 uint8_t * translate_m68k_jsr(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) | 1384 uint8_t * translate_m68k_jsr(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) |
1385 { | 1385 { |
1386 uint8_t * dest_addr; | 1386 uint8_t * dest_addr, sec_reg; |
1387 uint32_t after; | 1387 uint32_t after; |
1388 switch(inst->src.addr_mode) | 1388 switch(inst->src.addr_mode) |
1389 { | 1389 { |
1390 case MODE_AREG_INDIRECT: | 1390 case MODE_AREG_INDIRECT: |
1391 dst = cycles(dst, BUS*2); | 1391 dst = cycles(dst, BUS*2); |
1396 dst = call(dst, (char *)m68k_write_long_highfirst); | 1396 dst = call(dst, (char *)m68k_write_long_highfirst); |
1397 if (opts->aregs[inst->src.params.regs.pri] >= 0) { | 1397 if (opts->aregs[inst->src.params.regs.pri] >= 0) { |
1398 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); | 1398 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); |
1399 } else { | 1399 } else { |
1400 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, SCRATCH1, SZ_D); | 1400 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, SCRATCH1, SZ_D); |
1401 } | |
1402 dst = call(dst, (uint8_t *)m68k_native_addr); | |
1403 dst = call_r(dst, SCRATCH1); | |
1404 //would add_ir(dst, 8, RSP, SZ_Q) be faster here? | |
1405 dst = pop_r(dst, SCRATCH1); | |
1406 break; | |
1407 case MODE_AREG_INDEX_DISP8: | |
1408 dst = cycles(dst, BUS*3);//TODO: CHeck that this is correct | |
1409 dst = mov_ir(dst, inst->address + 8, SCRATCH1, SZ_D); | |
1410 dst = push_r(dst, SCRATCH1); | |
1411 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); | |
1412 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); | |
1413 dst = call(dst, (char *)m68k_write_long_highfirst); | |
1414 if (opts->aregs[inst->src.params.regs.pri] >= 0) { | |
1415 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); | |
1416 } else { | |
1417 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_D); | |
1418 } | |
1419 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7; | |
1420 if (inst->src.params.regs.sec & 1) { | |
1421 if (inst->src.params.regs.sec & 0x10) { | |
1422 if (opts->aregs[sec_reg] >= 0) { | |
1423 dst = add_rr(dst, opts->aregs[sec_reg], SCRATCH1, SZ_D); | |
1424 } else { | |
1425 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D); | |
1426 } | |
1427 } else { | |
1428 if (opts->dregs[sec_reg] >= 0) { | |
1429 dst = add_rr(dst, opts->dregs[sec_reg], SCRATCH1, SZ_D); | |
1430 } else { | |
1431 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D); | |
1432 } | |
1433 } | |
1434 } else { | |
1435 if (inst->src.params.regs.sec & 0x10) { | |
1436 if (opts->aregs[sec_reg] >= 0) { | |
1437 dst = movsx_rr(dst, opts->aregs[sec_reg], SCRATCH2, SZ_W, SZ_D); | |
1438 } else { | |
1439 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D); | |
1440 } | |
1441 } else { | |
1442 if (opts->dregs[sec_reg] >= 0) { | |
1443 dst = movsx_rr(dst, opts->dregs[sec_reg], SCRATCH2, SZ_W, SZ_D); | |
1444 } else { | |
1445 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D); | |
1446 } | |
1447 } | |
1448 dst = add_rr(dst, SCRATCH2, SCRATCH1, SZ_D); | |
1449 } | |
1450 if (inst->src.params.regs.displacement) { | |
1451 dst = add_ir(dst, inst->src.params.regs.displacement, SCRATCH1, SZ_D); | |
1401 } | 1452 } |
1402 dst = call(dst, (uint8_t *)m68k_native_addr); | 1453 dst = call(dst, (uint8_t *)m68k_native_addr); |
1403 dst = call_r(dst, SCRATCH1); | 1454 dst = call_r(dst, SCRATCH1); |
1404 //would add_ir(dst, 8, RSP, SZ_Q) be faster here? | 1455 //would add_ir(dst, 8, RSP, SZ_Q) be faster here? |
1405 dst = pop_r(dst, SCRATCH1); | 1456 dst = pop_r(dst, SCRATCH1); |
1417 opts->deferred = defer_address(opts->deferred, inst->src.params.immed, dst + 1); | 1468 opts->deferred = defer_address(opts->deferred, inst->src.params.immed, dst + 1); |
1418 //dummy address to be replaced later, make sure it generates a 4-byte displacement | 1469 //dummy address to be replaced later, make sure it generates a 4-byte displacement |
1419 dest_addr = dst + 5; | 1470 dest_addr = dst + 5; |
1420 } | 1471 } |
1421 dst = call(dst, (char *)dest_addr); | 1472 dst = call(dst, (char *)dest_addr); |
1473 //would add_ir(dst, 8, RSP, SZ_Q) be faster here? | |
1474 dst = pop_r(dst, SCRATCH1); | |
1475 break; | |
1476 case MODE_PC_INDEX_DISP8: | |
1477 dst = cycles(dst, BUS*3);//TODO: CHeck that this is correct | |
1478 dst = mov_ir(dst, inst->address + 8, SCRATCH1, SZ_D); | |
1479 dst = push_r(dst, SCRATCH1); | |
1480 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); | |
1481 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); | |
1482 dst = call(dst, (char *)m68k_write_long_highfirst); | |
1483 dst = mov_ir(dst, inst->address+2, SCRATCH1, SZ_D); | |
1484 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7; | |
1485 if (inst->src.params.regs.sec & 1) { | |
1486 if (inst->src.params.regs.sec & 0x10) { | |
1487 if (opts->aregs[sec_reg] >= 0) { | |
1488 dst = add_rr(dst, opts->aregs[sec_reg], SCRATCH1, SZ_D); | |
1489 } else { | |
1490 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D); | |
1491 } | |
1492 } else { | |
1493 if (opts->dregs[sec_reg] >= 0) { | |
1494 dst = add_rr(dst, opts->dregs[sec_reg], SCRATCH1, SZ_D); | |
1495 } else { | |
1496 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D); | |
1497 } | |
1498 } | |
1499 } else { | |
1500 if (inst->src.params.regs.sec & 0x10) { | |
1501 if (opts->aregs[sec_reg] >= 0) { | |
1502 dst = movsx_rr(dst, opts->aregs[sec_reg], SCRATCH2, SZ_W, SZ_D); | |
1503 } else { | |
1504 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D); | |
1505 } | |
1506 } else { | |
1507 if (opts->dregs[sec_reg] >= 0) { | |
1508 dst = movsx_rr(dst, opts->dregs[sec_reg], SCRATCH2, SZ_W, SZ_D); | |
1509 } else { | |
1510 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D); | |
1511 } | |
1512 } | |
1513 dst = add_rr(dst, SCRATCH2, SCRATCH1, SZ_D); | |
1514 } | |
1515 if (inst->src.params.regs.displacement) { | |
1516 dst = add_ir(dst, inst->src.params.regs.displacement, SCRATCH1, SZ_D); | |
1517 } | |
1518 dst = call(dst, (uint8_t *)m68k_native_addr); | |
1519 dst = call_r(dst, SCRATCH1); | |
1422 //would add_ir(dst, 8, RSP, SZ_Q) be faster here? | 1520 //would add_ir(dst, 8, RSP, SZ_Q) be faster here? |
1423 dst = pop_r(dst, SCRATCH1); | 1521 dst = pop_r(dst, SCRATCH1); |
1424 break; | 1522 break; |
1425 case MODE_ABSOLUTE: | 1523 case MODE_ABSOLUTE: |
1426 case MODE_ABSOLUTE_SHORT: | 1524 case MODE_ABSOLUTE_SHORT: |