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;