Mercurial > repos > blastem
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 { |