comparison m68k_to_x86.c @ 155:94a65fb4e1c7

Don't use the native call stack for M68K calls by default
author Mike Pavone <pavone@retrodev.com>
date Fri, 04 Jan 2013 23:21:07 -0800
parents 4791c0204410
children 3900cfde9dbb
comparison
equal deleted inserted replaced
154:4791c0204410 155:94a65fb4e1c7
1396 int32_t disp = inst->src.params.immed; 1396 int32_t disp = inst->src.params.immed;
1397 uint32_t after = inst->address + (inst->variant == VAR_BYTE ? 2 : 4); 1397 uint32_t after = inst->address + (inst->variant == VAR_BYTE ? 2 : 4);
1398 //TODO: Add cycles in the right place relative to pushing the return address on the stack 1398 //TODO: Add cycles in the right place relative to pushing the return address on the stack
1399 dst = cycles(dst, 10); 1399 dst = cycles(dst, 10);
1400 dst = mov_ir(dst, after, SCRATCH1, SZ_D); 1400 dst = mov_ir(dst, after, SCRATCH1, SZ_D);
1401 dst = push_r(dst, SCRATCH1); 1401 if (opts->flags & OPT_NATIVE_CALL_STACK) {
1402 dst = push_r(dst, SCRATCH1);
1403 }
1402 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 1404 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
1403 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 1405 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
1404 dst = call(dst, (char *)m68k_write_long_highfirst); 1406 dst = call(dst, (char *)m68k_write_long_highfirst);
1405 uint8_t * dest_addr = get_native_address(opts->native_code_map, (inst->address+2) + disp); 1407 uint8_t * dest_addr = get_native_address(opts->native_code_map, (inst->address+2) + disp);
1406 if (!dest_addr) { 1408 if (!dest_addr) {
1407 opts->deferred = defer_address(opts->deferred, (inst->address+2) + disp, dst + 1); 1409 opts->deferred = defer_address(opts->deferred, (inst->address+2) + disp, dst + 1);
1408 //dummy address to be replaced later 1410 //dummy address to be replaced later
1409 dest_addr = dst + 5; 1411 dest_addr = dst + 256;
1410 } 1412 }
1411 dst = call(dst, (char *)dest_addr); 1413 if (opts->flags & OPT_NATIVE_CALL_STACK) {
1412 //would add_ir(dst, 8, RSP, SZ_Q) be faster here? 1414 dst = call(dst, (char *)dest_addr);
1413 dst = pop_r(dst, SCRATCH1); 1415 //would add_ir(dst, 8, RSP, SZ_Q) be faster here?
1416 dst = pop_r(dst, SCRATCH1);
1417 } else {
1418 dst = jmp(dst, (char *)dest_addr);
1419 }
1414 return dst; 1420 return dst;
1415 } 1421 }
1416 1422
1417 uint8_t * translate_m68k_bcc(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) 1423 uint8_t * translate_m68k_bcc(uint8_t * dst, m68kinst * inst, x86_68k_options * opts)
1418 { 1424 {
1723 switch(inst->src.addr_mode) 1729 switch(inst->src.addr_mode)
1724 { 1730 {
1725 case MODE_AREG_INDIRECT: 1731 case MODE_AREG_INDIRECT:
1726 dst = cycles(dst, BUS*2); 1732 dst = cycles(dst, BUS*2);
1727 dst = mov_ir(dst, inst->address + 2, SCRATCH1, SZ_D); 1733 dst = mov_ir(dst, inst->address + 2, SCRATCH1, SZ_D);
1728 dst = push_r(dst, SCRATCH1); 1734 if (opts->flags & OPT_NATIVE_CALL_STACK) {
1735 dst = push_r(dst, SCRATCH1);
1736 }
1729 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 1737 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
1730 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 1738 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
1731 dst = call(dst, (char *)m68k_write_long_highfirst); 1739 dst = call(dst, (char *)m68k_write_long_highfirst);
1732 if (opts->aregs[inst->src.params.regs.pri] >= 0) { 1740 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
1733 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); 1741 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D);
1734 } else { 1742 } else {
1735 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, SCRATCH1, SZ_D); 1743 dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, SCRATCH1, SZ_D);
1736 } 1744 }
1737 dst = call(dst, (uint8_t *)m68k_native_addr); 1745 dst = call(dst, (uint8_t *)m68k_native_addr);
1738 dst = call_r(dst, SCRATCH1); 1746 if (opts->flags & OPT_NATIVE_CALL_STACK) {
1739 //would add_ir(dst, 8, RSP, SZ_Q) be faster here? 1747 dst = call_r(dst, SCRATCH1);
1740 dst = pop_r(dst, SCRATCH1); 1748 //would add_ir(dst, 8, RSP, SZ_Q) be faster here?
1749 dst = pop_r(dst, SCRATCH1);
1750 } else {
1751 dst = jmp_r(dst, SCRATCH1);
1752 }
1741 break; 1753 break;
1742 case MODE_AREG_INDEX_DISP8: 1754 case MODE_AREG_INDEX_DISP8:
1743 dst = cycles(dst, BUS*3);//TODO: CHeck that this is correct 1755 dst = cycles(dst, BUS*3);//TODO: CHeck that this is correct
1744 dst = mov_ir(dst, inst->address + 4, SCRATCH1, SZ_D); 1756 dst = mov_ir(dst, inst->address + 4, SCRATCH1, SZ_D);
1745 dst = push_r(dst, SCRATCH1); 1757 if (opts->flags & OPT_NATIVE_CALL_STACK) {
1758 dst = push_r(dst, SCRATCH1);
1759 }
1746 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 1760 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
1747 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 1761 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
1748 dst = call(dst, (char *)m68k_write_long_highfirst); 1762 dst = call(dst, (char *)m68k_write_long_highfirst);
1749 if (opts->aregs[inst->src.params.regs.pri] >= 0) { 1763 if (opts->aregs[inst->src.params.regs.pri] >= 0) {
1750 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D); 1764 dst = mov_rr(dst, opts->aregs[inst->src.params.regs.pri], SCRATCH1, SZ_D);
1784 } 1798 }
1785 if (inst->src.params.regs.displacement) { 1799 if (inst->src.params.regs.displacement) {
1786 dst = add_ir(dst, inst->src.params.regs.displacement, SCRATCH1, SZ_D); 1800 dst = add_ir(dst, inst->src.params.regs.displacement, SCRATCH1, SZ_D);
1787 } 1801 }
1788 dst = call(dst, (uint8_t *)m68k_native_addr); 1802 dst = call(dst, (uint8_t *)m68k_native_addr);
1789 dst = call_r(dst, SCRATCH1); 1803 if (opts->flags & OPT_NATIVE_CALL_STACK) {
1790 //would add_ir(dst, 8, RSP, SZ_Q) be faster here? 1804 dst = call_r(dst, SCRATCH1);
1791 dst = pop_r(dst, SCRATCH1); 1805 //would add_ir(dst, 8, RSP, SZ_Q) be faster here?
1806 dst = pop_r(dst, SCRATCH1);
1807 } else {
1808 dst = jmp_r(dst, SCRATCH1);
1809 }
1792 break; 1810 break;
1793 case MODE_PC_DISPLACE: 1811 case MODE_PC_DISPLACE:
1794 //TODO: Add cycles in the right place relative to pushing the return address on the stack 1812 //TODO: Add cycles in the right place relative to pushing the return address on the stack
1795 dst = cycles(dst, 10); 1813 dst = cycles(dst, 10);
1796 dst = mov_ir(dst, inst->address + 4, SCRATCH1, SZ_D); 1814 dst = mov_ir(dst, inst->address + 4, SCRATCH1, SZ_D);
1797 dst = push_r(dst, SCRATCH1); 1815 if (opts->flags & OPT_NATIVE_CALL_STACK) {
1816 dst = push_r(dst, SCRATCH1);
1817 }
1798 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 1818 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
1799 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 1819 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
1800 dst = call(dst, (char *)m68k_write_long_highfirst); 1820 dst = call(dst, (char *)m68k_write_long_highfirst);
1801 m68k_addr = inst->src.params.regs.displacement + inst->address + 2; 1821 m68k_addr = inst->src.params.regs.displacement + inst->address + 2;
1802 if ((m68k_addr & 0xFFFFFF) < 0x400000) { 1822 if ((m68k_addr & 0xFFFFFF) < 0x400000) {
1803 dest_addr = get_native_address(opts->native_code_map, m68k_addr); 1823 dest_addr = get_native_address(opts->native_code_map, m68k_addr);
1804 if (!dest_addr) { 1824 if (!dest_addr) {
1805 opts->deferred = defer_address(opts->deferred, m68k_addr, dst + 1); 1825 opts->deferred = defer_address(opts->deferred, m68k_addr, dst + 1);
1806 //dummy address to be replaced later, make sure it generates a 4-byte displacement 1826 //dummy address to be replaced later, make sure it generates a 4-byte displacement
1807 dest_addr = dst + 5; 1827 dest_addr = dst + 256;
1808 } 1828 }
1809 dst = call(dst, (char *)dest_addr); 1829 if (opts->flags & OPT_NATIVE_CALL_STACK) {
1830 dst = call(dst, (char *)dest_addr);
1831 } else {
1832 dst = jmp(dst, dest_addr);
1833 }
1810 } else { 1834 } else {
1811 dst = mov_ir(dst, m68k_addr, SCRATCH1, SZ_D); 1835 dst = mov_ir(dst, m68k_addr, SCRATCH1, SZ_D);
1812 dst = call(dst, (uint8_t *)m68k_native_addr); 1836 dst = call(dst, (uint8_t *)m68k_native_addr);
1813 dst = call_r(dst, SCRATCH1); 1837 if (opts->flags & OPT_NATIVE_CALL_STACK) {
1814 } 1838 dst = call_r(dst, SCRATCH1);
1815 //would add_ir(dst, 8, RSP, SZ_Q) be faster here? 1839 } else {
1816 dst = pop_r(dst, SCRATCH1); 1840 dst = jmp_r(dst, SCRATCH1);
1841 }
1842 }
1843 if (opts->flags & OPT_NATIVE_CALL_STACK) {
1844 //would add_ir(dst, 8, RSP, SZ_Q) be faster here?
1845 dst = pop_r(dst, SCRATCH1);
1846 }
1817 break; 1847 break;
1818 case MODE_PC_INDEX_DISP8: 1848 case MODE_PC_INDEX_DISP8:
1819 dst = cycles(dst, BUS*3);//TODO: CHeck that this is correct 1849 dst = cycles(dst, BUS*3);//TODO: CHeck that this is correct
1820 dst = mov_ir(dst, inst->address + 4, SCRATCH1, SZ_D); 1850 dst = mov_ir(dst, inst->address + 4, SCRATCH1, SZ_D);
1821 dst = push_r(dst, SCRATCH1); 1851 if (opts->flags & OPT_NATIVE_CALL_STACK) {
1852 dst = push_r(dst, SCRATCH1);
1853 }
1822 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 1854 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
1823 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 1855 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
1824 dst = call(dst, (char *)m68k_write_long_highfirst); 1856 dst = call(dst, (char *)m68k_write_long_highfirst);
1825 dst = mov_ir(dst, inst->address+2, SCRATCH1, SZ_D); 1857 dst = mov_ir(dst, inst->address+2, SCRATCH1, SZ_D);
1826 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7; 1858 sec_reg = (inst->src.params.regs.sec >> 1) & 0x7;
1856 } 1888 }
1857 if (inst->src.params.regs.displacement) { 1889 if (inst->src.params.regs.displacement) {
1858 dst = add_ir(dst, inst->src.params.regs.displacement, SCRATCH1, SZ_D); 1890 dst = add_ir(dst, inst->src.params.regs.displacement, SCRATCH1, SZ_D);
1859 } 1891 }
1860 dst = call(dst, (uint8_t *)m68k_native_addr); 1892 dst = call(dst, (uint8_t *)m68k_native_addr);
1861 dst = call_r(dst, SCRATCH1); 1893 if (opts->flags & OPT_NATIVE_CALL_STACK) {
1862 //would add_ir(dst, 8, RSP, SZ_Q) be faster here? 1894 dst = call_r(dst, SCRATCH1);
1863 dst = pop_r(dst, SCRATCH1); 1895 //would add_ir(dst, 8, RSP, SZ_Q) be faster here?
1896 dst = pop_r(dst, SCRATCH1);
1897 } else {
1898 dst = jmp_r(dst, SCRATCH1);
1899 }
1864 break; 1900 break;
1865 case MODE_ABSOLUTE: 1901 case MODE_ABSOLUTE:
1866 case MODE_ABSOLUTE_SHORT: 1902 case MODE_ABSOLUTE_SHORT:
1867 //TODO: Add cycles in the right place relative to pushing the return address on the stack 1903 //TODO: Add cycles in the right place relative to pushing the return address on the stack
1868 dst = cycles(dst, inst->src.addr_mode == MODE_ABSOLUTE ? 12 : 10); 1904 dst = cycles(dst, inst->src.addr_mode == MODE_ABSOLUTE ? 12 : 10);
1869 dst = mov_ir(dst, inst->address + (inst->src.addr_mode == MODE_ABSOLUTE ? 6 : 4), SCRATCH1, SZ_D); 1905 dst = mov_ir(dst, inst->address + (inst->src.addr_mode == MODE_ABSOLUTE ? 6 : 4), SCRATCH1, SZ_D);
1870 dst = push_r(dst, SCRATCH1); 1906 if (opts->flags & OPT_NATIVE_CALL_STACK) {
1907 dst = push_r(dst, SCRATCH1);
1908 }
1871 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D); 1909 dst = sub_ir(dst, 4, opts->aregs[7], SZ_D);
1872 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); 1910 dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D);
1873 dst = call(dst, (char *)m68k_write_long_highfirst); 1911 dst = call(dst, (char *)m68k_write_long_highfirst);
1874 m68k_addr = inst->src.params.immed; 1912 m68k_addr = inst->src.params.immed;
1875 if ((m68k_addr & 0xFFFFFF) < 0x400000) { 1913 if ((m68k_addr & 0xFFFFFF) < 0x400000) {
1876 dest_addr = get_native_address(opts->native_code_map, m68k_addr); 1914 dest_addr = get_native_address(opts->native_code_map, m68k_addr);
1877 if (!dest_addr) { 1915 if (!dest_addr) {
1878 opts->deferred = defer_address(opts->deferred, m68k_addr, dst + 1); 1916 opts->deferred = defer_address(opts->deferred, m68k_addr, dst + 1);
1879 //dummy address to be replaced later, make sure it generates a 4-byte displacement 1917 //dummy address to be replaced later, make sure it generates a 4-byte displacement
1880 dest_addr = dst + 5; 1918 dest_addr = dst + 256;
1881 } 1919 }
1882 dst = call(dst, (char *)dest_addr); 1920 if (opts->flags & OPT_NATIVE_CALL_STACK) {
1921 dst = call(dst, (char *)dest_addr);
1922 } else {
1923 dst = jmp(dst, dest_addr);
1924 }
1883 } else { 1925 } else {
1884 dst = mov_ir(dst, m68k_addr, SCRATCH1, SZ_D); 1926 dst = mov_ir(dst, m68k_addr, SCRATCH1, SZ_D);
1885 dst = call(dst, (uint8_t *)m68k_native_addr); 1927 dst = call(dst, (uint8_t *)m68k_native_addr);
1886 dst = call_r(dst, SCRATCH1); 1928 if (opts->flags & OPT_NATIVE_CALL_STACK) {
1887 } 1929 dst = call_r(dst, SCRATCH1);
1888 //would add_ir(dst, 8, RSP, SZ_Q) be faster here? 1930 } else {
1889 dst = pop_r(dst, SCRATCH1); 1931 dst = jmp_r(dst, SCRATCH1);
1932 }
1933 }
1934 if (opts->flags & OPT_NATIVE_CALL_STACK) {
1935 //would add_ir(dst, 8, RSP, SZ_Q) be faster here?
1936 dst = pop_r(dst, SCRATCH1);
1937 }
1890 break; 1938 break;
1891 default: 1939 default:
1892 m68k_disasm(inst, disasm_buf); 1940 m68k_disasm(inst, disasm_buf);
1893 printf("%s\naddress mode %d not yet supported (jsr)\n", disasm_buf, inst->src.addr_mode); 1941 printf("%s\naddress mode %d not yet supported (jsr)\n", disasm_buf, inst->src.addr_mode);
1894 exit(1); 1942 exit(1);
1900 { 1948 {
1901 //TODO: Add cycles 1949 //TODO: Add cycles
1902 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); 1950 dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D);
1903 dst = add_ir(dst, 4, opts->aregs[7], SZ_D); 1951 dst = add_ir(dst, 4, opts->aregs[7], SZ_D);
1904 dst = call(dst, (char *)m68k_read_long_scratch1); 1952 dst = call(dst, (char *)m68k_read_long_scratch1);
1905 dst = cmp_rdisp8r(dst, RSP, 8, SCRATCH1, SZ_D); 1953 if (opts->flags & OPT_NATIVE_CALL_STACK) {
1906 dst = jcc(dst, CC_NZ, dst+3); 1954 dst = cmp_rdisp8r(dst, RSP, 8, SCRATCH1, SZ_D);
1907 dst = retn(dst); 1955 dst = jcc(dst, CC_NZ, dst+3);
1908 dst = jmp(dst, (char *)m68k_modified_ret_addr); 1956 dst = retn(dst);
1957 dst = jmp(dst, (char *)m68k_modified_ret_addr);
1958 } else {
1959 dst = call(dst, (uint8_t *)m68k_native_addr);
1960 dst = jmp_r(dst, SCRATCH1);
1961 }
1909 return dst; 1962 return dst;
1910 } 1963 }
1911 1964
1912 uint8_t * translate_m68k_dbcc(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) 1965 uint8_t * translate_m68k_dbcc(uint8_t * dst, m68kinst * inst, x86_68k_options * opts)
1913 { 1966 {