Mercurial > repos > blastem
comparison m68k_to_x86.c @ 124:da95566514f3
Some fixes for translating code in located in RAM
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 29 Dec 2012 21:55:42 -0800 |
parents | bd3858121ab0 |
children | dc5fc3adf705 |
comparison
equal
deleted
inserted
replaced
123:bd3858121ab0 | 124:da95566514f3 |
---|---|
1515 } | 1515 } |
1516 | 1516 |
1517 uint8_t * translate_m68k_jmp(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) | 1517 uint8_t * translate_m68k_jmp(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) |
1518 { | 1518 { |
1519 uint8_t * dest_addr; | 1519 uint8_t * dest_addr; |
1520 uint32_t m68k_addr; | |
1520 switch(inst->src.addr_mode) | 1521 switch(inst->src.addr_mode) |
1521 { | 1522 { |
1522 case MODE_AREG_INDIRECT: | 1523 case MODE_AREG_INDIRECT: |
1523 dst = cycles(dst, BUS*2); | 1524 dst = cycles(dst, BUS*2); |
1524 if (opts->aregs[inst->src.params.regs.pri] >= 0) { | 1525 if (opts->aregs[inst->src.params.regs.pri] >= 0) { |
1529 dst = call(dst, (uint8_t *)m68k_native_addr); | 1530 dst = call(dst, (uint8_t *)m68k_native_addr); |
1530 dst = jmp_r(dst, SCRATCH1); | 1531 dst = jmp_r(dst, SCRATCH1); |
1531 break; | 1532 break; |
1532 case MODE_PC_DISPLACE: | 1533 case MODE_PC_DISPLACE: |
1533 dst = cycles(dst, 10); | 1534 dst = cycles(dst, 10); |
1534 dest_addr = get_native_address(opts->native_code_map, inst->src.params.regs.displacement + inst->address + 2); | 1535 m68k_addr = inst->src.params.regs.displacement + inst->address + 2; |
1535 if (!dest_addr) { | 1536 if ((m68k_addr & 0xFFFFFF) < 0x400000) { |
1536 opts->deferred = defer_address(opts->deferred, inst->src.params.regs.displacement + inst->address + 2, dst + 1); | 1537 dest_addr = get_native_address(opts->native_code_map, m68k_addr); |
1537 //dummy address to be replaced later, make sure it generates a 4-byte displacement | 1538 if (!dest_addr) { |
1538 dest_addr = dst + 256; | 1539 opts->deferred = defer_address(opts->deferred, m68k_addr, dst + 1); |
1539 } | 1540 //dummy address to be replaced later, make sure it generates a 4-byte displacement |
1540 dst = jmp(dst, dest_addr); | 1541 dest_addr = dst + 256; |
1542 } | |
1543 dst = jmp(dst, dest_addr); | |
1544 } else { | |
1545 dst = mov_ir(dst, m68k_addr, SCRATCH1, SZ_D); | |
1546 dst = call(dst, (uint8_t *)m68k_native_addr); | |
1547 dst = jmp_r(dst, SCRATCH1); | |
1548 } | |
1541 break; | 1549 break; |
1542 case MODE_ABSOLUTE: | 1550 case MODE_ABSOLUTE: |
1543 case MODE_ABSOLUTE_SHORT: | 1551 case MODE_ABSOLUTE_SHORT: |
1544 dst = cycles(dst, inst->src.addr_mode == MODE_ABSOLUTE ? 12 : 10); | 1552 dst = cycles(dst, inst->src.addr_mode == MODE_ABSOLUTE ? 12 : 10); |
1545 dest_addr = get_native_address(opts->native_code_map, inst->src.params.immed); | 1553 m68k_addr = inst->src.params.immed; |
1546 if (!dest_addr) { | 1554 if ((m68k_addr & 0xFFFFFF) < 0x400000) { |
1547 opts->deferred = defer_address(opts->deferred, inst->src.params.immed, dst + 1); | 1555 dest_addr = get_native_address(opts->native_code_map, m68k_addr); |
1548 //dummy address to be replaced later, make sure it generates a 4-byte displacement | 1556 if (!dest_addr) { |
1549 dest_addr = dst + 256; | 1557 opts->deferred = defer_address(opts->deferred, m68k_addr, dst + 1); |
1550 } | 1558 //dummy address to be replaced later, make sure it generates a 4-byte displacement |
1551 dst = jmp(dst, dest_addr); | 1559 dest_addr = dst + 256; |
1560 } | |
1561 dst = jmp(dst, dest_addr); | |
1562 } else { | |
1563 dst = mov_ir(dst, m68k_addr, SCRATCH1, SZ_D); | |
1564 dst = call(dst, (uint8_t *)m68k_native_addr); | |
1565 dst = jmp_r(dst, SCRATCH1); | |
1566 } | |
1552 break; | 1567 break; |
1553 default: | 1568 default: |
1554 printf("address mode %d not yet supported (jmp)\n", inst->src.addr_mode); | 1569 printf("address mode %d not yet supported (jmp)\n", inst->src.addr_mode); |
1555 exit(1); | 1570 exit(1); |
1556 } | 1571 } |
1559 | 1574 |
1560 uint8_t * translate_m68k_jsr(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) | 1575 uint8_t * translate_m68k_jsr(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) |
1561 { | 1576 { |
1562 uint8_t * dest_addr, sec_reg; | 1577 uint8_t * dest_addr, sec_reg; |
1563 uint32_t after; | 1578 uint32_t after; |
1579 uint32_t m68k_addr; | |
1564 switch(inst->src.addr_mode) | 1580 switch(inst->src.addr_mode) |
1565 { | 1581 { |
1566 case MODE_AREG_INDIRECT: | 1582 case MODE_AREG_INDIRECT: |
1567 dst = cycles(dst, BUS*2); | 1583 dst = cycles(dst, BUS*2); |
1568 dst = mov_ir(dst, inst->address + 2, SCRATCH1, SZ_D); | 1584 dst = mov_ir(dst, inst->address + 2, SCRATCH1, SZ_D); |
1637 dst = mov_ir(dst, inst->address + 4, SCRATCH1, SZ_D); | 1653 dst = mov_ir(dst, inst->address + 4, SCRATCH1, SZ_D); |
1638 dst = push_r(dst, SCRATCH1); | 1654 dst = push_r(dst, SCRATCH1); |
1639 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); | 1655 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); |
1640 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); | 1656 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); |
1641 dst = call(dst, (char *)m68k_write_long_highfirst); | 1657 dst = call(dst, (char *)m68k_write_long_highfirst); |
1642 dest_addr = get_native_address(opts->native_code_map, inst->src.params.regs.displacement + inst->address + 2); | 1658 m68k_addr = inst->src.params.regs.displacement + inst->address + 2; |
1643 if (!dest_addr) { | 1659 if ((m68k_addr & 0xFFFFFF) < 0x400000) { |
1644 opts->deferred = defer_address(opts->deferred, inst->src.params.regs.displacement + inst->address + 2, dst + 1); | 1660 dest_addr = get_native_address(opts->native_code_map, m68k_addr); |
1645 //dummy address to be replaced later, make sure it generates a 4-byte displacement | 1661 if (!dest_addr) { |
1646 dest_addr = dst + 5; | 1662 opts->deferred = defer_address(opts->deferred, m68k_addr, dst + 1); |
1647 } | 1663 //dummy address to be replaced later, make sure it generates a 4-byte displacement |
1648 dst = call(dst, (char *)dest_addr); | 1664 dest_addr = dst + 5; |
1665 } | |
1666 dst = call(dst, (char *)dest_addr); | |
1667 } else { | |
1668 dst = mov_ir(dst, m68k_addr, SCRATCH1, SZ_D); | |
1669 dst = call(dst, (uint8_t *)m68k_native_addr); | |
1670 dst = call_r(dst, SCRATCH1); | |
1671 } | |
1649 //would add_ir(dst, 8, RSP, SZ_Q) be faster here? | 1672 //would add_ir(dst, 8, RSP, SZ_Q) be faster here? |
1650 dst = pop_r(dst, SCRATCH1); | 1673 dst = pop_r(dst, SCRATCH1); |
1651 break; | 1674 break; |
1652 case MODE_PC_INDEX_DISP8: | 1675 case MODE_PC_INDEX_DISP8: |
1653 dst = cycles(dst, BUS*3);//TODO: CHeck that this is correct | 1676 dst = cycles(dst, BUS*3);//TODO: CHeck that this is correct |
1703 dst = mov_ir(dst, inst->address + (inst->src.addr_mode == MODE_ABSOLUTE ? 6 : 4), SCRATCH1, SZ_D); | 1726 dst = mov_ir(dst, inst->address + (inst->src.addr_mode == MODE_ABSOLUTE ? 6 : 4), SCRATCH1, SZ_D); |
1704 dst = push_r(dst, SCRATCH1); | 1727 dst = push_r(dst, SCRATCH1); |
1705 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); | 1728 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); |
1706 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); | 1729 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); |
1707 dst = call(dst, (char *)m68k_write_long_highfirst); | 1730 dst = call(dst, (char *)m68k_write_long_highfirst); |
1708 dest_addr = get_native_address(opts->native_code_map, inst->src.params.immed); | 1731 m68k_addr = inst->src.params.immed; |
1709 if (!dest_addr) { | 1732 if ((m68k_addr & 0xFFFFFF) < 0x400000) { |
1710 opts->deferred = defer_address(opts->deferred, inst->src.params.immed, dst + 1); | 1733 dest_addr = get_native_address(opts->native_code_map, m68k_addr); |
1711 //dummy address to be replaced later, make sure it generates a 4-byte displacement | 1734 if (!dest_addr) { |
1712 dest_addr = dst + 5; | 1735 opts->deferred = defer_address(opts->deferred, m68k_addr, dst + 1); |
1713 } | 1736 //dummy address to be replaced later, make sure it generates a 4-byte displacement |
1714 dst = call(dst, (char *)dest_addr); | 1737 dest_addr = dst + 5; |
1738 } | |
1739 dst = call(dst, (char *)dest_addr); | |
1740 } else { | |
1741 dst = mov_ir(dst, m68k_addr, SCRATCH1, SZ_D); | |
1742 dst = call(dst, (uint8_t *)m68k_native_addr); | |
1743 dst = call_r(dst, SCRATCH1); | |
1744 } | |
1715 //would add_ir(dst, 8, RSP, SZ_Q) be faster here? | 1745 //would add_ir(dst, 8, RSP, SZ_Q) be faster here? |
1716 dst = pop_r(dst, SCRATCH1); | 1746 dst = pop_r(dst, SCRATCH1); |
1717 break; | 1747 break; |
1718 default: | 1748 default: |
1719 printf("address mode %d not yet supported (jsr)\n", inst->src.addr_mode); | 1749 printf("address mode %d not yet supported (jsr)\n", inst->src.addr_mode); |
2620 dst = translate_m68k(dst, &instbuf, opts); | 2650 dst = translate_m68k(dst, &instbuf, opts); |
2621 } while(instbuf.op != M68K_ILLEGAL && instbuf.op != M68K_RTS && instbuf.op != M68K_RTE && !(instbuf.op == M68K_BCC && instbuf.extra.cond == COND_TRUE) && instbuf.op != M68K_JMP); | 2651 } while(instbuf.op != M68K_ILLEGAL && instbuf.op != M68K_RTS && instbuf.op != M68K_RTE && !(instbuf.op == M68K_BCC && instbuf.extra.cond == COND_TRUE) && instbuf.op != M68K_JMP); |
2622 process_deferred(opts); | 2652 process_deferred(opts); |
2623 if (opts->deferred) { | 2653 if (opts->deferred) { |
2624 address = opts->deferred->address; | 2654 address = opts->deferred->address; |
2625 encoded = context->mem_pointers[0] + address/2; | 2655 if ((address & 0xFFFFFF) < 0x400000) { |
2656 encoded = context->mem_pointers[0] + (address & 0xFFFFFF)/2; | |
2657 } else if ((address & 0xFFFFFF) > 0xE00000) { | |
2658 encoded = context->mem_pointers[1] + (address & 0xFFFF)/2; | |
2659 } else { | |
2660 printf("attempt to translate non-memory address: %X\n", address); | |
2661 exit(1); | |
2662 } | |
2626 } else { | 2663 } else { |
2627 encoded = NULL; | 2664 encoded = NULL; |
2628 } | 2665 } |
2629 } while(encoded != NULL); | 2666 } while(encoded != NULL); |
2630 opts->cur_code = dst; | 2667 opts->cur_code = dst; |