Mercurial > repos > blastem
comparison m68k_to_x86.c @ 132:0969d8363a20
Support more address modes for jmp
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 30 Dec 2012 07:52:44 -0800 |
parents | 691e4b147cea |
children | c4d10c2aaee2 |
comparison
equal
deleted
inserted
replaced
131:8fc8e46be691 | 132:0969d8363a20 |
---|---|
1518 return dst; | 1518 return dst; |
1519 } | 1519 } |
1520 | 1520 |
1521 uint8_t * translate_m68k_jmp(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) | 1521 uint8_t * translate_m68k_jmp(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) |
1522 { | 1522 { |
1523 uint8_t * dest_addr; | 1523 uint8_t * dest_addr, sec_reg; |
1524 uint32_t m68k_addr; | 1524 uint32_t m68k_addr; |
1525 switch(inst->src.addr_mode) | 1525 switch(inst->src.addr_mode) |
1526 { | 1526 { |
1527 case MODE_AREG_INDIRECT: | 1527 case MODE_AREG_INDIRECT: |
1528 dst = cycles(dst, BUS*2); | 1528 dst = cycles(dst, BUS*2); |
1529 if (opts->aregs[inst->src.params.regs.pri] >= 0) { | 1529 if (opts->aregs[inst->src.params.regs.pri] >= 0) { |
1530 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); | 1530 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); |
1531 } else { | 1531 } else { |
1532 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, SCRATCH1, SZ_D); | 1532 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, SCRATCH1, SZ_D); |
1533 } | |
1534 dst = call(dst, (uint8_t *)m68k_native_addr); | |
1535 dst = jmp_r(dst, SCRATCH1); | |
1536 break; | |
1537 case MODE_AREG_INDEX_DISP8: | |
1538 dst = cycles(dst, BUS*3);//TODO: CHeck that this is correct | |
1539 if (opts->aregs[inst->src.params.regs.pri] >= 0) { | |
1540 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); | |
1541 } else { | |
1542 dst = mov_rdisp8r(dst, CONTEXT, reg_offset(&(inst->src)), SCRATCH1, SZ_D); | |
1543 } | |
1544 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7; | |
1545 if (inst->src.params.regs.sec & 1) { | |
1546 if (inst->src.params.regs.sec & 0x10) { | |
1547 if (opts->aregs[sec_reg] >= 0) { | |
1548 dst = add_rr(dst, opts->aregs[sec_reg], SCRATCH1, SZ_D); | |
1549 } else { | |
1550 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D); | |
1551 } | |
1552 } else { | |
1553 if (opts->dregs[sec_reg] >= 0) { | |
1554 dst = add_rr(dst, opts->dregs[sec_reg], SCRATCH1, SZ_D); | |
1555 } else { | |
1556 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D); | |
1557 } | |
1558 } | |
1559 } else { | |
1560 if (inst->src.params.regs.sec & 0x10) { | |
1561 if (opts->aregs[sec_reg] >= 0) { | |
1562 dst = movsx_rr(dst, opts->aregs[sec_reg], SCRATCH2, SZ_W, SZ_D); | |
1563 } else { | |
1564 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D); | |
1565 } | |
1566 } else { | |
1567 if (opts->dregs[sec_reg] >= 0) { | |
1568 dst = movsx_rr(dst, opts->dregs[sec_reg], SCRATCH2, SZ_W, SZ_D); | |
1569 } else { | |
1570 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D); | |
1571 } | |
1572 } | |
1573 dst = add_rr(dst, SCRATCH2, SCRATCH1, SZ_D); | |
1574 } | |
1575 if (inst->src.params.regs.displacement) { | |
1576 dst = add_ir(dst, inst->src.params.regs.displacement, SCRATCH1, SZ_D); | |
1533 } | 1577 } |
1534 dst = call(dst, (uint8_t *)m68k_native_addr); | 1578 dst = call(dst, (uint8_t *)m68k_native_addr); |
1535 dst = jmp_r(dst, SCRATCH1); | 1579 dst = jmp_r(dst, SCRATCH1); |
1536 break; | 1580 break; |
1537 case MODE_PC_DISPLACE: | 1581 case MODE_PC_DISPLACE: |
1548 } else { | 1592 } else { |
1549 dst = mov_ir(dst, m68k_addr, SCRATCH1, SZ_D); | 1593 dst = mov_ir(dst, m68k_addr, SCRATCH1, SZ_D); |
1550 dst = call(dst, (uint8_t *)m68k_native_addr); | 1594 dst = call(dst, (uint8_t *)m68k_native_addr); |
1551 dst = jmp_r(dst, SCRATCH1); | 1595 dst = jmp_r(dst, SCRATCH1); |
1552 } | 1596 } |
1597 break; | |
1598 case MODE_PC_INDEX_DISP8: | |
1599 dst = cycles(dst, BUS*3);//TODO: CHeck that this is correct | |
1600 dst = mov_ir(dst, inst->address+2, SCRATCH1, SZ_D); | |
1601 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7; | |
1602 if (inst->src.params.regs.sec & 1) { | |
1603 if (inst->src.params.regs.sec & 0x10) { | |
1604 if (opts->aregs[sec_reg] >= 0) { | |
1605 dst = add_rr(dst, opts->aregs[sec_reg], SCRATCH1, SZ_D); | |
1606 } else { | |
1607 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D); | |
1608 } | |
1609 } else { | |
1610 if (opts->dregs[sec_reg] >= 0) { | |
1611 dst = add_rr(dst, opts->dregs[sec_reg], SCRATCH1, SZ_D); | |
1612 } else { | |
1613 dst = add_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH1, SZ_D); | |
1614 } | |
1615 } | |
1616 } else { | |
1617 if (inst->src.params.regs.sec & 0x10) { | |
1618 if (opts->aregs[sec_reg] >= 0) { | |
1619 dst = movsx_rr(dst, opts->aregs[sec_reg], SCRATCH2, SZ_W, SZ_D); | |
1620 } else { | |
1621 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D); | |
1622 } | |
1623 } else { | |
1624 if (opts->dregs[sec_reg] >= 0) { | |
1625 dst = movsx_rr(dst, opts->dregs[sec_reg], SCRATCH2, SZ_W, SZ_D); | |
1626 } else { | |
1627 dst = movsx_rdisp8r(dst, CONTEXT, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, SCRATCH2, SZ_W, SZ_D); | |
1628 } | |
1629 } | |
1630 dst = add_rr(dst, SCRATCH2, SCRATCH1, SZ_D); | |
1631 } | |
1632 if (inst->src.params.regs.displacement) { | |
1633 dst = add_ir(dst, inst->src.params.regs.displacement, SCRATCH1, SZ_D); | |
1634 } | |
1635 dst = call(dst, (uint8_t *)m68k_native_addr); | |
1636 dst = jmp_r(dst, SCRATCH1); | |
1553 break; | 1637 break; |
1554 case MODE_ABSOLUTE: | 1638 case MODE_ABSOLUTE: |
1555 case MODE_ABSOLUTE_SHORT: | 1639 case MODE_ABSOLUTE_SHORT: |
1556 dst = cycles(dst, inst->src.addr_mode == MODE_ABSOLUTE ? 12 : 10); | 1640 dst = cycles(dst, inst->src.addr_mode == MODE_ABSOLUTE ? 12 : 10); |
1557 m68k_addr = inst->src.params.immed; | 1641 m68k_addr = inst->src.params.immed; |