OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stdarg.h> | 5 #include <stdarg.h> |
6 #include <stdlib.h> | 6 #include <stdlib.h> |
7 #include <cmath> | 7 #include <cmath> |
8 | 8 |
9 #if V8_TARGET_ARCH_PPC | 9 #if V8_TARGET_ARCH_PPC |
10 | 10 |
(...skipping 1602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1613 case BC_CTR_REG: | 1613 case BC_CTR_REG: |
1614 set_pc(special_reg_ctr_); | 1614 set_pc(special_reg_ctr_); |
1615 break; | 1615 break; |
1616 } | 1616 } |
1617 | 1617 |
1618 if (instr->Bit(0) == 1) { // LK flag set | 1618 if (instr->Bit(0) == 1) { // LK flag set |
1619 special_reg_lr_ = old_pc + 4; | 1619 special_reg_lr_ = old_pc + 4; |
1620 } | 1620 } |
1621 } | 1621 } |
1622 | 1622 |
1623 | 1623 void Simulator::ExecuteGeneric(Instruction* instr) { |
1624 // Handle execution based on instruction types. | 1624 uint32_t opcode = instr->OpcodeBase(); |
1625 void Simulator::ExecuteExt1(Instruction* instr) { | |
1626 uint32_t opcode = EXT1 | instr->BitField(10, 1); | |
1627 switch (opcode) { | 1625 switch (opcode) { |
| 1626 case SUBFIC: { |
| 1627 int rt = instr->RTValue(); |
| 1628 int ra = instr->RAValue(); |
| 1629 intptr_t ra_val = get_register(ra); |
| 1630 int32_t im_val = instr->Bits(15, 0); |
| 1631 im_val = SIGN_EXT_IMM16(im_val); |
| 1632 intptr_t alu_out = im_val - ra_val; |
| 1633 set_register(rt, alu_out); |
| 1634 // todo - handle RC bit |
| 1635 break; |
| 1636 } |
| 1637 case CMPLI: { |
| 1638 int ra = instr->RAValue(); |
| 1639 uint32_t im_val = instr->Bits(15, 0); |
| 1640 int cr = instr->Bits(25, 23); |
| 1641 uint32_t bf = 0; |
| 1642 #if V8_TARGET_ARCH_PPC64 |
| 1643 int L = instr->Bit(21); |
| 1644 if (L) { |
| 1645 #endif |
| 1646 uintptr_t ra_val = get_register(ra); |
| 1647 if (ra_val < im_val) { |
| 1648 bf |= 0x80000000; |
| 1649 } |
| 1650 if (ra_val > im_val) { |
| 1651 bf |= 0x40000000; |
| 1652 } |
| 1653 if (ra_val == im_val) { |
| 1654 bf |= 0x20000000; |
| 1655 } |
| 1656 #if V8_TARGET_ARCH_PPC64 |
| 1657 } else { |
| 1658 uint32_t ra_val = get_register(ra); |
| 1659 if (ra_val < im_val) { |
| 1660 bf |= 0x80000000; |
| 1661 } |
| 1662 if (ra_val > im_val) { |
| 1663 bf |= 0x40000000; |
| 1664 } |
| 1665 if (ra_val == im_val) { |
| 1666 bf |= 0x20000000; |
| 1667 } |
| 1668 } |
| 1669 #endif |
| 1670 uint32_t condition_mask = 0xF0000000U >> (cr * 4); |
| 1671 uint32_t condition = bf >> (cr * 4); |
| 1672 condition_reg_ = (condition_reg_ & ~condition_mask) | condition; |
| 1673 break; |
| 1674 } |
| 1675 case CMPI: { |
| 1676 int ra = instr->RAValue(); |
| 1677 int32_t im_val = instr->Bits(15, 0); |
| 1678 im_val = SIGN_EXT_IMM16(im_val); |
| 1679 int cr = instr->Bits(25, 23); |
| 1680 uint32_t bf = 0; |
| 1681 #if V8_TARGET_ARCH_PPC64 |
| 1682 int L = instr->Bit(21); |
| 1683 if (L) { |
| 1684 #endif |
| 1685 intptr_t ra_val = get_register(ra); |
| 1686 if (ra_val < im_val) { |
| 1687 bf |= 0x80000000; |
| 1688 } |
| 1689 if (ra_val > im_val) { |
| 1690 bf |= 0x40000000; |
| 1691 } |
| 1692 if (ra_val == im_val) { |
| 1693 bf |= 0x20000000; |
| 1694 } |
| 1695 #if V8_TARGET_ARCH_PPC64 |
| 1696 } else { |
| 1697 int32_t ra_val = get_register(ra); |
| 1698 if (ra_val < im_val) { |
| 1699 bf |= 0x80000000; |
| 1700 } |
| 1701 if (ra_val > im_val) { |
| 1702 bf |= 0x40000000; |
| 1703 } |
| 1704 if (ra_val == im_val) { |
| 1705 bf |= 0x20000000; |
| 1706 } |
| 1707 } |
| 1708 #endif |
| 1709 uint32_t condition_mask = 0xF0000000U >> (cr * 4); |
| 1710 uint32_t condition = bf >> (cr * 4); |
| 1711 condition_reg_ = (condition_reg_ & ~condition_mask) | condition; |
| 1712 break; |
| 1713 } |
| 1714 case ADDIC: { |
| 1715 int rt = instr->RTValue(); |
| 1716 int ra = instr->RAValue(); |
| 1717 uintptr_t ra_val = get_register(ra); |
| 1718 uintptr_t im_val = SIGN_EXT_IMM16(instr->Bits(15, 0)); |
| 1719 uintptr_t alu_out = ra_val + im_val; |
| 1720 // Check overflow |
| 1721 if (~ra_val < im_val) { |
| 1722 special_reg_xer_ = (special_reg_xer_ & ~0xF0000000) | 0x20000000; |
| 1723 } else { |
| 1724 special_reg_xer_ &= ~0xF0000000; |
| 1725 } |
| 1726 set_register(rt, alu_out); |
| 1727 break; |
| 1728 } |
| 1729 case ADDI: { |
| 1730 int rt = instr->RTValue(); |
| 1731 int ra = instr->RAValue(); |
| 1732 int32_t im_val = SIGN_EXT_IMM16(instr->Bits(15, 0)); |
| 1733 intptr_t alu_out; |
| 1734 if (ra == 0) { |
| 1735 alu_out = im_val; |
| 1736 } else { |
| 1737 intptr_t ra_val = get_register(ra); |
| 1738 alu_out = ra_val + im_val; |
| 1739 } |
| 1740 set_register(rt, alu_out); |
| 1741 // todo - handle RC bit |
| 1742 break; |
| 1743 } |
| 1744 case ADDIS: { |
| 1745 int rt = instr->RTValue(); |
| 1746 int ra = instr->RAValue(); |
| 1747 int32_t im_val = (instr->Bits(15, 0) << 16); |
| 1748 intptr_t alu_out; |
| 1749 if (ra == 0) { // treat r0 as zero |
| 1750 alu_out = im_val; |
| 1751 } else { |
| 1752 intptr_t ra_val = get_register(ra); |
| 1753 alu_out = ra_val + im_val; |
| 1754 } |
| 1755 set_register(rt, alu_out); |
| 1756 break; |
| 1757 } |
| 1758 case BCX: { |
| 1759 ExecuteBranchConditional(instr, BC_OFFSET); |
| 1760 break; |
| 1761 } |
| 1762 case BX: { |
| 1763 int offset = (instr->Bits(25, 2) << 8) >> 6; |
| 1764 if (instr->Bit(0) == 1) { // LK flag set |
| 1765 special_reg_lr_ = get_pc() + 4; |
| 1766 } |
| 1767 set_pc(get_pc() + offset); |
| 1768 // todo - AA flag |
| 1769 break; |
| 1770 } |
1628 case MCRF: | 1771 case MCRF: |
1629 UNIMPLEMENTED(); // Not used by V8. | 1772 UNIMPLEMENTED(); // Not used by V8. |
1630 case BCLRX: | 1773 case BCLRX: |
1631 ExecuteBranchConditional(instr, BC_LINK_REG); | 1774 ExecuteBranchConditional(instr, BC_LINK_REG); |
1632 break; | 1775 break; |
1633 case BCCTRX: | 1776 case BCCTRX: |
1634 ExecuteBranchConditional(instr, BC_CTR_REG); | 1777 ExecuteBranchConditional(instr, BC_CTR_REG); |
1635 break; | 1778 break; |
1636 case CRNOR: | 1779 case CRNOR: |
1637 case RFI: | 1780 case RFI: |
(...skipping 23 matching lines...) Expand all Loading... |
1661 int bb_val = ((0x80000000 >> bb) & condition_reg_) == 0 ? 0 : 1; | 1804 int bb_val = ((0x80000000 >> bb) & condition_reg_) == 0 ? 0 : 1; |
1662 int bt_val = 1 - (ba_val ^ bb_val); | 1805 int bt_val = 1 - (ba_val ^ bb_val); |
1663 bt_val = bt_val << (31 - bt); // shift bit to correct destination | 1806 bt_val = bt_val << (31 - bt); // shift bit to correct destination |
1664 condition_reg_ &= ~(0x80000000 >> bt); | 1807 condition_reg_ &= ~(0x80000000 >> bt); |
1665 condition_reg_ |= bt_val; | 1808 condition_reg_ |= bt_val; |
1666 break; | 1809 break; |
1667 } | 1810 } |
1668 case CRNAND: | 1811 case CRNAND: |
1669 case CRAND: | 1812 case CRAND: |
1670 case CRORC: | 1813 case CRORC: |
1671 case CROR: | 1814 case CROR: { |
1672 default: { | |
1673 UNIMPLEMENTED(); // Not used by V8. | 1815 UNIMPLEMENTED(); // Not used by V8. |
| 1816 break; |
1674 } | 1817 } |
1675 } | 1818 case RLWIMIX: { |
1676 } | 1819 int ra = instr->RAValue(); |
1677 | 1820 int rs = instr->RSValue(); |
1678 | 1821 uint32_t rs_val = get_register(rs); |
1679 bool Simulator::ExecuteExt2_10bit(Instruction* instr) { | 1822 int32_t ra_val = get_register(ra); |
1680 bool found = true; | 1823 int sh = instr->Bits(15, 11); |
1681 | 1824 int mb = instr->Bits(10, 6); |
1682 uint32_t opcode = EXT2 | instr->BitField(10, 1); | 1825 int me = instr->Bits(5, 1); |
1683 switch (opcode) { | 1826 uint32_t result = base::bits::RotateLeft32(rs_val, sh); |
| 1827 int mask = 0; |
| 1828 if (mb < me + 1) { |
| 1829 int bit = 0x80000000 >> mb; |
| 1830 for (; mb <= me; mb++) { |
| 1831 mask |= bit; |
| 1832 bit >>= 1; |
| 1833 } |
| 1834 } else if (mb == me + 1) { |
| 1835 mask = 0xffffffff; |
| 1836 } else { // mb > me+1 |
| 1837 int bit = 0x80000000 >> (me + 1); // needs to be tested |
| 1838 mask = 0xffffffff; |
| 1839 for (; me < mb; me++) { |
| 1840 mask ^= bit; |
| 1841 bit >>= 1; |
| 1842 } |
| 1843 } |
| 1844 result &= mask; |
| 1845 ra_val &= ~mask; |
| 1846 result |= ra_val; |
| 1847 set_register(ra, result); |
| 1848 if (instr->Bit(0)) { // RC bit set |
| 1849 SetCR0(result); |
| 1850 } |
| 1851 break; |
| 1852 } |
| 1853 case RLWINMX: |
| 1854 case RLWNMX: { |
| 1855 int ra = instr->RAValue(); |
| 1856 int rs = instr->RSValue(); |
| 1857 uint32_t rs_val = get_register(rs); |
| 1858 int sh = 0; |
| 1859 if (opcode == RLWINMX) { |
| 1860 sh = instr->Bits(15, 11); |
| 1861 } else { |
| 1862 int rb = instr->RBValue(); |
| 1863 uint32_t rb_val = get_register(rb); |
| 1864 sh = (rb_val & 0x1f); |
| 1865 } |
| 1866 int mb = instr->Bits(10, 6); |
| 1867 int me = instr->Bits(5, 1); |
| 1868 uint32_t result = base::bits::RotateLeft32(rs_val, sh); |
| 1869 int mask = 0; |
| 1870 if (mb < me + 1) { |
| 1871 int bit = 0x80000000 >> mb; |
| 1872 for (; mb <= me; mb++) { |
| 1873 mask |= bit; |
| 1874 bit >>= 1; |
| 1875 } |
| 1876 } else if (mb == me + 1) { |
| 1877 mask = 0xffffffff; |
| 1878 } else { // mb > me+1 |
| 1879 int bit = 0x80000000 >> (me + 1); // needs to be tested |
| 1880 mask = 0xffffffff; |
| 1881 for (; me < mb; me++) { |
| 1882 mask ^= bit; |
| 1883 bit >>= 1; |
| 1884 } |
| 1885 } |
| 1886 result &= mask; |
| 1887 set_register(ra, result); |
| 1888 if (instr->Bit(0)) { // RC bit set |
| 1889 SetCR0(result); |
| 1890 } |
| 1891 break; |
| 1892 } |
| 1893 case ORI: { |
| 1894 int rs = instr->RSValue(); |
| 1895 int ra = instr->RAValue(); |
| 1896 intptr_t rs_val = get_register(rs); |
| 1897 uint32_t im_val = instr->Bits(15, 0); |
| 1898 intptr_t alu_out = rs_val | im_val; |
| 1899 set_register(ra, alu_out); |
| 1900 break; |
| 1901 } |
| 1902 case ORIS: { |
| 1903 int rs = instr->RSValue(); |
| 1904 int ra = instr->RAValue(); |
| 1905 intptr_t rs_val = get_register(rs); |
| 1906 uint32_t im_val = instr->Bits(15, 0); |
| 1907 intptr_t alu_out = rs_val | (im_val << 16); |
| 1908 set_register(ra, alu_out); |
| 1909 break; |
| 1910 } |
| 1911 case XORI: { |
| 1912 int rs = instr->RSValue(); |
| 1913 int ra = instr->RAValue(); |
| 1914 intptr_t rs_val = get_register(rs); |
| 1915 uint32_t im_val = instr->Bits(15, 0); |
| 1916 intptr_t alu_out = rs_val ^ im_val; |
| 1917 set_register(ra, alu_out); |
| 1918 // todo - set condition based SO bit |
| 1919 break; |
| 1920 } |
| 1921 case XORIS: { |
| 1922 int rs = instr->RSValue(); |
| 1923 int ra = instr->RAValue(); |
| 1924 intptr_t rs_val = get_register(rs); |
| 1925 uint32_t im_val = instr->Bits(15, 0); |
| 1926 intptr_t alu_out = rs_val ^ (im_val << 16); |
| 1927 set_register(ra, alu_out); |
| 1928 break; |
| 1929 } |
| 1930 case ANDIx: { |
| 1931 int rs = instr->RSValue(); |
| 1932 int ra = instr->RAValue(); |
| 1933 intptr_t rs_val = get_register(rs); |
| 1934 uint32_t im_val = instr->Bits(15, 0); |
| 1935 intptr_t alu_out = rs_val & im_val; |
| 1936 set_register(ra, alu_out); |
| 1937 SetCR0(alu_out); |
| 1938 break; |
| 1939 } |
| 1940 case ANDISx: { |
| 1941 int rs = instr->RSValue(); |
| 1942 int ra = instr->RAValue(); |
| 1943 intptr_t rs_val = get_register(rs); |
| 1944 uint32_t im_val = instr->Bits(15, 0); |
| 1945 intptr_t alu_out = rs_val & (im_val << 16); |
| 1946 set_register(ra, alu_out); |
| 1947 SetCR0(alu_out); |
| 1948 break; |
| 1949 } |
1684 case SRWX: { | 1950 case SRWX: { |
1685 int rs = instr->RSValue(); | 1951 int rs = instr->RSValue(); |
1686 int ra = instr->RAValue(); | 1952 int ra = instr->RAValue(); |
1687 int rb = instr->RBValue(); | 1953 int rb = instr->RBValue(); |
1688 uint32_t rs_val = get_register(rs); | 1954 uint32_t rs_val = get_register(rs); |
1689 uintptr_t rb_val = get_register(rb) & 0x3f; | 1955 uintptr_t rb_val = get_register(rb) & 0x3f; |
1690 intptr_t result = (rb_val > 31) ? 0 : rs_val >> rb_val; | 1956 intptr_t result = (rb_val > 31) ? 0 : rs_val >> rb_val; |
1691 set_register(ra, result); | 1957 set_register(ra, result); |
1692 if (instr->Bit(0)) { // RC bit set | 1958 if (instr->Bit(0)) { // RC bit set |
1693 SetCR0(result); | 1959 SetCR0(result); |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1934 } | 2200 } |
1935 #endif | 2201 #endif |
1936 case SYNC: { | 2202 case SYNC: { |
1937 // todo - simulate sync | 2203 // todo - simulate sync |
1938 break; | 2204 break; |
1939 } | 2205 } |
1940 case ICBI: { | 2206 case ICBI: { |
1941 // todo - simulate icbi | 2207 // todo - simulate icbi |
1942 break; | 2208 break; |
1943 } | 2209 } |
1944 default: { | 2210 |
1945 found = false; | 2211 case LWZU: |
| 2212 case LWZ: { |
| 2213 int ra = instr->RAValue(); |
| 2214 int rt = instr->RTValue(); |
| 2215 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); |
| 2216 int offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); |
| 2217 set_register(rt, ReadWU(ra_val + offset, instr)); |
| 2218 if (opcode == LWZU) { |
| 2219 DCHECK(ra != 0); |
| 2220 set_register(ra, ra_val + offset); |
| 2221 } |
1946 break; | 2222 break; |
1947 } | 2223 } |
1948 } | |
1949 | 2224 |
1950 if (found) return found; | 2225 case LBZU: |
| 2226 case LBZ: { |
| 2227 int ra = instr->RAValue(); |
| 2228 int rt = instr->RTValue(); |
| 2229 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); |
| 2230 int offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); |
| 2231 set_register(rt, ReadB(ra_val + offset) & 0xFF); |
| 2232 if (opcode == LBZU) { |
| 2233 DCHECK(ra != 0); |
| 2234 set_register(ra, ra_val + offset); |
| 2235 } |
| 2236 break; |
| 2237 } |
1951 | 2238 |
1952 found = true; | 2239 case STWU: |
1953 opcode = EXT2 | instr->BitField(10, 2); | 2240 case STW: { |
1954 switch (opcode) { | 2241 int ra = instr->RAValue(); |
| 2242 int rs = instr->RSValue(); |
| 2243 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); |
| 2244 int32_t rs_val = get_register(rs); |
| 2245 int offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); |
| 2246 WriteW(ra_val + offset, rs_val, instr); |
| 2247 if (opcode == STWU) { |
| 2248 DCHECK(ra != 0); |
| 2249 set_register(ra, ra_val + offset); |
| 2250 } |
| 2251 break; |
| 2252 } |
1955 case SRADIX: { | 2253 case SRADIX: { |
1956 int ra = instr->RAValue(); | 2254 int ra = instr->RAValue(); |
1957 int rs = instr->RSValue(); | 2255 int rs = instr->RSValue(); |
1958 int sh = (instr->Bits(15, 11) | (instr->Bit(1) << 5)); | 2256 int sh = (instr->Bits(15, 11) | (instr->Bit(1) << 5)); |
1959 intptr_t rs_val = get_register(rs); | 2257 intptr_t rs_val = get_register(rs); |
1960 intptr_t result = rs_val >> sh; | 2258 intptr_t result = rs_val >> sh; |
1961 set_register(ra, result); | 2259 set_register(ra, result); |
1962 if (instr->Bit(0)) { // RC bit set | 2260 if (instr->Bit(0)) { // RC bit set |
1963 SetCR0(result); | 2261 SetCR0(result); |
1964 } | 2262 } |
1965 break; | 2263 break; |
1966 } | 2264 } |
1967 default: { | |
1968 found = false; | |
1969 break; | |
1970 } | |
1971 } | |
1972 | |
1973 return found; | |
1974 } | |
1975 | |
1976 | |
1977 bool Simulator::ExecuteExt2_9bit_part1(Instruction* instr) { | |
1978 bool found = true; | |
1979 | |
1980 uint32_t opcode = EXT2 | instr->BitField(9, 1); | |
1981 switch (opcode) { | |
1982 case TW: { | 2265 case TW: { |
1983 // used for call redirection in simulation mode | 2266 // used for call redirection in simulation mode |
1984 SoftwareInterrupt(instr); | 2267 SoftwareInterrupt(instr); |
1985 break; | 2268 break; |
1986 } | 2269 } |
1987 case CMP: { | 2270 case CMP: { |
1988 int ra = instr->RAValue(); | 2271 int ra = instr->RAValue(); |
1989 int rb = instr->RBValue(); | 2272 int rb = instr->RBValue(); |
1990 int cr = instr->Bits(25, 23); | 2273 int cr = instr->Bits(25, 23); |
1991 uint32_t bf = 0; | 2274 uint32_t bf = 0; |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2216 } | 2499 } |
2217 case MTVSRWZ: { | 2500 case MTVSRWZ: { |
2218 DCHECK(!instr->Bit(0)); | 2501 DCHECK(!instr->Bit(0)); |
2219 int frt = instr->RTValue(); | 2502 int frt = instr->RTValue(); |
2220 int ra = instr->RAValue(); | 2503 int ra = instr->RAValue(); |
2221 uint64_t ra_val = static_cast<uint32_t>(get_register(ra)); | 2504 uint64_t ra_val = static_cast<uint32_t>(get_register(ra)); |
2222 set_d_register(frt, ra_val); | 2505 set_d_register(frt, ra_val); |
2223 break; | 2506 break; |
2224 } | 2507 } |
2225 #endif | 2508 #endif |
2226 default: { | |
2227 found = false; | |
2228 break; | |
2229 } | |
2230 } | |
2231 | |
2232 return found; | |
2233 } | |
2234 | |
2235 | |
2236 bool Simulator::ExecuteExt2_9bit_part2(Instruction* instr) { | |
2237 bool found = true; | |
2238 uint32_t opcode = EXT2 | instr->BitField(9, 1); | |
2239 switch (opcode) { | |
2240 case CNTLZWX: { | 2509 case CNTLZWX: { |
2241 int rs = instr->RSValue(); | 2510 int rs = instr->RSValue(); |
2242 int ra = instr->RAValue(); | 2511 int ra = instr->RAValue(); |
2243 uintptr_t rs_val = get_register(rs); | 2512 uintptr_t rs_val = get_register(rs); |
2244 uintptr_t count = 0; | 2513 uintptr_t count = 0; |
2245 int n = 0; | 2514 int n = 0; |
2246 uintptr_t bit = 0x80000000; | 2515 uintptr_t bit = 0x80000000; |
2247 for (; n < 32; n++) { | 2516 for (; n < 32; n++) { |
2248 if (bit & rs_val) break; | 2517 if (bit & rs_val) break; |
2249 count++; | 2518 count++; |
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2735 if (opcode == LHAUX) { | 3004 if (opcode == LHAUX) { |
2736 DCHECK(ra != 0 && ra != rt); | 3005 DCHECK(ra != 0 && ra != rt); |
2737 set_register(ra, ra_val + rb_val); | 3006 set_register(ra, ra_val + rb_val); |
2738 } | 3007 } |
2739 break; | 3008 break; |
2740 } | 3009 } |
2741 case DCBF: { | 3010 case DCBF: { |
2742 // todo - simulate dcbf | 3011 // todo - simulate dcbf |
2743 break; | 3012 break; |
2744 } | 3013 } |
2745 default: { | |
2746 found = false; | |
2747 break; | |
2748 } | |
2749 } | |
2750 | |
2751 return found; | |
2752 } | |
2753 | |
2754 | |
2755 void Simulator::ExecuteExt2_5bit(Instruction* instr) { | |
2756 uint32_t opcode = EXT2 | instr->BitField(5, 1); | |
2757 switch (opcode) { | |
2758 case ISEL: { | 3014 case ISEL: { |
2759 int rt = instr->RTValue(); | 3015 int rt = instr->RTValue(); |
2760 int ra = instr->RAValue(); | 3016 int ra = instr->RAValue(); |
2761 int rb = instr->RBValue(); | 3017 int rb = instr->RBValue(); |
2762 int condition_bit = instr->RCValue(); | 3018 int condition_bit = instr->RCValue(); |
2763 int condition_mask = 0x80000000 >> condition_bit; | 3019 int condition_mask = 0x80000000 >> condition_bit; |
2764 intptr_t ra_val = (ra == 0) ? 0 : get_register(ra); | 3020 intptr_t ra_val = (ra == 0) ? 0 : get_register(ra); |
2765 intptr_t rb_val = get_register(rb); | 3021 intptr_t rb_val = get_register(rb); |
2766 intptr_t value = (condition_reg_ & condition_mask) ? ra_val : rb_val; | 3022 intptr_t value = (condition_reg_ & condition_mask) ? ra_val : rb_val; |
2767 set_register(rt, value); | 3023 set_register(rt, value); |
2768 break; | 3024 break; |
2769 } | 3025 } |
2770 default: { | 3026 |
2771 PrintF("Unimplemented: %08x\n", instr->InstructionBits()); | 3027 case STBU: |
2772 UNIMPLEMENTED(); // Not used by V8. | 3028 case STB: { |
| 3029 int ra = instr->RAValue(); |
| 3030 int rs = instr->RSValue(); |
| 3031 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); |
| 3032 int8_t rs_val = get_register(rs); |
| 3033 int offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); |
| 3034 WriteB(ra_val + offset, rs_val); |
| 3035 if (opcode == STBU) { |
| 3036 DCHECK(ra != 0); |
| 3037 set_register(ra, ra_val + offset); |
| 3038 } |
| 3039 break; |
2773 } | 3040 } |
2774 } | |
2775 } | |
2776 | 3041 |
| 3042 case LHZU: |
| 3043 case LHZ: { |
| 3044 int ra = instr->RAValue(); |
| 3045 int rt = instr->RTValue(); |
| 3046 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); |
| 3047 int offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); |
| 3048 uintptr_t result = ReadHU(ra_val + offset, instr) & 0xffff; |
| 3049 set_register(rt, result); |
| 3050 if (opcode == LHZU) { |
| 3051 set_register(ra, ra_val + offset); |
| 3052 } |
| 3053 break; |
| 3054 } |
2777 | 3055 |
2778 void Simulator::ExecuteExt2(Instruction* instr) { | 3056 case LHA: |
2779 // Check first the 10-1 bit versions | 3057 case LHAU: { |
2780 if (ExecuteExt2_10bit(instr)) return; | 3058 int ra = instr->RAValue(); |
2781 // Now look at the lesser encodings | 3059 int rt = instr->RTValue(); |
2782 if (ExecuteExt2_9bit_part1(instr)) return; | 3060 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); |
2783 if (ExecuteExt2_9bit_part2(instr)) return; | 3061 int offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); |
2784 ExecuteExt2_5bit(instr); | 3062 intptr_t result = ReadH(ra_val + offset, instr); |
2785 } | 3063 set_register(rt, result); |
| 3064 if (opcode == LHAU) { |
| 3065 set_register(ra, ra_val + offset); |
| 3066 } |
| 3067 break; |
| 3068 } |
2786 | 3069 |
| 3070 case STHU: |
| 3071 case STH: { |
| 3072 int ra = instr->RAValue(); |
| 3073 int rs = instr->RSValue(); |
| 3074 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); |
| 3075 int16_t rs_val = get_register(rs); |
| 3076 int offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); |
| 3077 WriteH(ra_val + offset, rs_val, instr); |
| 3078 if (opcode == STHU) { |
| 3079 DCHECK(ra != 0); |
| 3080 set_register(ra, ra_val + offset); |
| 3081 } |
| 3082 break; |
| 3083 } |
2787 | 3084 |
2788 void Simulator::ExecuteExt3(Instruction* instr) { | 3085 case LMW: |
2789 uint32_t opcode = EXT3 | instr->BitField(10, 1); | 3086 case STMW: { |
2790 switch (opcode) { | 3087 UNIMPLEMENTED(); |
| 3088 break; |
| 3089 } |
| 3090 |
| 3091 case LFSU: |
| 3092 case LFS: { |
| 3093 int frt = instr->RTValue(); |
| 3094 int ra = instr->RAValue(); |
| 3095 int32_t offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); |
| 3096 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); |
| 3097 int32_t val = ReadW(ra_val + offset, instr); |
| 3098 float* fptr = reinterpret_cast<float*>(&val); |
| 3099 // Conversion using double changes sNan to qNan on ia32/x64 |
| 3100 #if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64 |
| 3101 if (val == 0x7fa00000) { |
| 3102 set_d_register(frt, 0x7ff4000000000000); |
| 3103 } else { |
| 3104 #endif |
| 3105 set_d_register_from_double(frt, static_cast<double>(*fptr)); |
| 3106 #if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64 |
| 3107 } |
| 3108 #endif |
| 3109 if (opcode == LFSU) { |
| 3110 DCHECK(ra != 0); |
| 3111 set_register(ra, ra_val + offset); |
| 3112 } |
| 3113 break; |
| 3114 } |
| 3115 |
| 3116 case LFDU: |
| 3117 case LFD: { |
| 3118 int frt = instr->RTValue(); |
| 3119 int ra = instr->RAValue(); |
| 3120 int32_t offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); |
| 3121 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); |
| 3122 int64_t* dptr = reinterpret_cast<int64_t*>(ReadDW(ra_val + offset)); |
| 3123 set_d_register(frt, *dptr); |
| 3124 if (opcode == LFDU) { |
| 3125 DCHECK(ra != 0); |
| 3126 set_register(ra, ra_val + offset); |
| 3127 } |
| 3128 break; |
| 3129 } |
| 3130 |
| 3131 case STFSU: { |
| 3132 case STFS: |
| 3133 int frs = instr->RSValue(); |
| 3134 int ra = instr->RAValue(); |
| 3135 int32_t offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); |
| 3136 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); |
| 3137 float frs_val = static_cast<float>(get_double_from_d_register(frs)); |
| 3138 int32_t* p; |
| 3139 // Conversion using double changes sNan to qNan on ia32/x64 |
| 3140 #if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64 |
| 3141 int64_t frs_isnan = get_d_register(frs); |
| 3142 int32_t frs_nan_single = 0x7fa00000; |
| 3143 if (frs_isnan == 0x7ff4000000000000) { |
| 3144 p = &frs_nan_single; |
| 3145 } else { |
| 3146 #endif |
| 3147 p = reinterpret_cast<int32_t*>(&frs_val); |
| 3148 #if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64 |
| 3149 } |
| 3150 #endif |
| 3151 WriteW(ra_val + offset, *p, instr); |
| 3152 if (opcode == STFSU) { |
| 3153 DCHECK(ra != 0); |
| 3154 set_register(ra, ra_val + offset); |
| 3155 } |
| 3156 break; |
| 3157 } |
| 3158 |
| 3159 case STFDU: |
| 3160 case STFD: { |
| 3161 int frs = instr->RSValue(); |
| 3162 int ra = instr->RAValue(); |
| 3163 int32_t offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); |
| 3164 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); |
| 3165 int64_t frs_val = get_d_register(frs); |
| 3166 WriteDW(ra_val + offset, frs_val); |
| 3167 if (opcode == STFDU) { |
| 3168 DCHECK(ra != 0); |
| 3169 set_register(ra, ra_val + offset); |
| 3170 } |
| 3171 break; |
| 3172 } |
| 3173 |
2791 case FCFIDS: { | 3174 case FCFIDS: { |
2792 // fcfids | 3175 // fcfids |
2793 int frt = instr->RTValue(); | 3176 int frt = instr->RTValue(); |
2794 int frb = instr->RBValue(); | 3177 int frb = instr->RBValue(); |
2795 int64_t frb_val = get_d_register(frb); | 3178 int64_t frb_val = get_d_register(frb); |
2796 double frt_val = static_cast<float>(frb_val); | 3179 double frt_val = static_cast<float>(frb_val); |
2797 set_d_register_from_double(frt, frt_val); | 3180 set_d_register_from_double(frt, frt_val); |
2798 return; | 3181 return; |
2799 } | 3182 } |
2800 case FCFIDUS: { | 3183 case FCFIDUS: { |
2801 // fcfidus | 3184 // fcfidus |
2802 int frt = instr->RTValue(); | 3185 int frt = instr->RTValue(); |
2803 int frb = instr->RBValue(); | 3186 int frb = instr->RBValue(); |
2804 uint64_t frb_val = get_d_register(frb); | 3187 uint64_t frb_val = get_d_register(frb); |
2805 double frt_val = static_cast<float>(frb_val); | 3188 double frt_val = static_cast<float>(frb_val); |
2806 set_d_register_from_double(frt, frt_val); | 3189 set_d_register_from_double(frt, frt_val); |
2807 return; | 3190 return; |
2808 } | 3191 } |
2809 } | |
2810 UNIMPLEMENTED(); // Not used by V8. | |
2811 } | |
2812 | 3192 |
2813 | |
2814 void Simulator::ExecuteExt4(Instruction* instr) { | |
2815 uint32_t opcode = EXT4 | instr->BitField(5, 1); | |
2816 switch (opcode) { | |
2817 case FDIV: { | 3193 case FDIV: { |
2818 int frt = instr->RTValue(); | 3194 int frt = instr->RTValue(); |
2819 int fra = instr->RAValue(); | 3195 int fra = instr->RAValue(); |
2820 int frb = instr->RBValue(); | 3196 int frb = instr->RBValue(); |
2821 double fra_val = get_double_from_d_register(fra); | 3197 double fra_val = get_double_from_d_register(fra); |
2822 double frb_val = get_double_from_d_register(frb); | 3198 double frb_val = get_double_from_d_register(frb); |
2823 double frt_val = fra_val / frb_val; | 3199 double frt_val = fra_val / frb_val; |
2824 set_d_register_from_double(frt, frt_val); | 3200 set_d_register_from_double(frt, frt_val); |
2825 return; | 3201 return; |
2826 } | 3202 } |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2892 int fra = instr->RAValue(); | 3268 int fra = instr->RAValue(); |
2893 int frb = instr->RBValue(); | 3269 int frb = instr->RBValue(); |
2894 int frc = instr->RCValue(); | 3270 int frc = instr->RCValue(); |
2895 double fra_val = get_double_from_d_register(fra); | 3271 double fra_val = get_double_from_d_register(fra); |
2896 double frb_val = get_double_from_d_register(frb); | 3272 double frb_val = get_double_from_d_register(frb); |
2897 double frc_val = get_double_from_d_register(frc); | 3273 double frc_val = get_double_from_d_register(frc); |
2898 double frt_val = (fra_val * frc_val) + frb_val; | 3274 double frt_val = (fra_val * frc_val) + frb_val; |
2899 set_d_register_from_double(frt, frt_val); | 3275 set_d_register_from_double(frt, frt_val); |
2900 return; | 3276 return; |
2901 } | 3277 } |
2902 } | |
2903 opcode = EXT4 | instr->BitField(10, 1); | |
2904 switch (opcode) { | |
2905 case FCMPU: { | 3278 case FCMPU: { |
2906 int fra = instr->RAValue(); | 3279 int fra = instr->RAValue(); |
2907 int frb = instr->RBValue(); | 3280 int frb = instr->RBValue(); |
2908 double fra_val = get_double_from_d_register(fra); | 3281 double fra_val = get_double_from_d_register(fra); |
2909 double frb_val = get_double_from_d_register(frb); | 3282 double frb_val = get_double_from_d_register(frb); |
2910 int cr = instr->Bits(25, 23); | 3283 int cr = instr->Bits(25, 23); |
2911 int bf = 0; | 3284 int bf = 0; |
2912 if (fra_val < frb_val) { | 3285 if (fra_val < frb_val) { |
2913 bf |= 0x80000000; | 3286 bf |= 0x80000000; |
2914 } | 3287 } |
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3225 return; | 3598 return; |
3226 } | 3599 } |
3227 case FABS: { | 3600 case FABS: { |
3228 int frt = instr->RTValue(); | 3601 int frt = instr->RTValue(); |
3229 int frb = instr->RBValue(); | 3602 int frb = instr->RBValue(); |
3230 double frb_val = get_double_from_d_register(frb); | 3603 double frb_val = get_double_from_d_register(frb); |
3231 double frt_val = std::fabs(frb_val); | 3604 double frt_val = std::fabs(frb_val); |
3232 set_d_register_from_double(frt, frt_val); | 3605 set_d_register_from_double(frt, frt_val); |
3233 return; | 3606 return; |
3234 } | 3607 } |
3235 } | 3608 |
3236 UNIMPLEMENTED(); // Not used by V8. | |
3237 } | |
3238 | 3609 |
3239 #if V8_TARGET_ARCH_PPC64 | 3610 #if V8_TARGET_ARCH_PPC64 |
3240 void Simulator::ExecuteExt5(Instruction* instr) { | |
3241 uint32_t opcode = EXT5 | instr->BitField(4, 2); | |
3242 switch (opcode) { | |
3243 case RLDICL: { | 3611 case RLDICL: { |
3244 int ra = instr->RAValue(); | 3612 int ra = instr->RAValue(); |
3245 int rs = instr->RSValue(); | 3613 int rs = instr->RSValue(); |
3246 uintptr_t rs_val = get_register(rs); | 3614 uintptr_t rs_val = get_register(rs); |
3247 int sh = (instr->Bits(15, 11) | (instr->Bit(1) << 5)); | 3615 int sh = (instr->Bits(15, 11) | (instr->Bit(1) << 5)); |
3248 int mb = (instr->Bits(10, 6) | (instr->Bit(5) << 5)); | 3616 int mb = (instr->Bits(10, 6) | (instr->Bit(5) << 5)); |
3249 DCHECK(sh >= 0 && sh <= 63); | 3617 DCHECK(sh >= 0 && sh <= 63); |
3250 DCHECK(mb >= 0 && mb <= 63); | 3618 DCHECK(mb >= 0 && mb <= 63); |
3251 uintptr_t result = base::bits::RotateLeft64(rs_val, sh); | 3619 uintptr_t result = base::bits::RotateLeft64(rs_val, sh); |
3252 uintptr_t mask = 0xffffffffffffffff >> mb; | 3620 uintptr_t mask = 0xffffffffffffffff >> mb; |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3319 } | 3687 } |
3320 result &= mask; | 3688 result &= mask; |
3321 ra_val &= ~mask; | 3689 ra_val &= ~mask; |
3322 result |= ra_val; | 3690 result |= ra_val; |
3323 set_register(ra, result); | 3691 set_register(ra, result); |
3324 if (instr->Bit(0)) { // RC bit set | 3692 if (instr->Bit(0)) { // RC bit set |
3325 SetCR0(result); | 3693 SetCR0(result); |
3326 } | 3694 } |
3327 return; | 3695 return; |
3328 } | 3696 } |
3329 } | |
3330 opcode = EXT5 | instr->BitField(4, 1); | |
3331 switch (opcode) { | |
3332 case RLDCL: { | 3697 case RLDCL: { |
3333 int ra = instr->RAValue(); | 3698 int ra = instr->RAValue(); |
3334 int rs = instr->RSValue(); | 3699 int rs = instr->RSValue(); |
3335 int rb = instr->RBValue(); | 3700 int rb = instr->RBValue(); |
3336 uintptr_t rs_val = get_register(rs); | 3701 uintptr_t rs_val = get_register(rs); |
3337 uintptr_t rb_val = get_register(rb); | 3702 uintptr_t rb_val = get_register(rb); |
3338 int sh = (rb_val & 0x3f); | 3703 int sh = (rb_val & 0x3f); |
3339 int mb = (instr->Bits(10, 6) | (instr->Bit(5) << 5)); | 3704 int mb = (instr->Bits(10, 6) | (instr->Bit(5) << 5)); |
3340 DCHECK(sh >= 0 && sh <= 63); | 3705 DCHECK(sh >= 0 && sh <= 63); |
3341 DCHECK(mb >= 0 && mb <= 63); | 3706 DCHECK(mb >= 0 && mb <= 63); |
3342 uintptr_t result = base::bits::RotateLeft64(rs_val, sh); | 3707 uintptr_t result = base::bits::RotateLeft64(rs_val, sh); |
3343 uintptr_t mask = 0xffffffffffffffff >> mb; | 3708 uintptr_t mask = 0xffffffffffffffff >> mb; |
3344 result &= mask; | 3709 result &= mask; |
3345 set_register(ra, result); | 3710 set_register(ra, result); |
3346 if (instr->Bit(0)) { // RC bit set | 3711 if (instr->Bit(0)) { // RC bit set |
3347 SetCR0(result); | 3712 SetCR0(result); |
3348 } | 3713 } |
3349 return; | 3714 return; |
3350 } | 3715 } |
3351 } | 3716 |
3352 UNIMPLEMENTED(); // Not used by V8. | 3717 case LD: |
3353 } | 3718 case LDU: |
| 3719 case LWA: { |
| 3720 int ra = instr->RAValue(); |
| 3721 int rt = instr->RTValue(); |
| 3722 int64_t ra_val = ra == 0 ? 0 : get_register(ra); |
| 3723 int offset = SIGN_EXT_IMM16(instr->Bits(15, 0) & ~3); |
| 3724 switch (instr->Bits(1, 0)) { |
| 3725 case 0: { // ld |
| 3726 intptr_t* result = ReadDW(ra_val + offset); |
| 3727 set_register(rt, *result); |
| 3728 break; |
| 3729 } |
| 3730 case 1: { // ldu |
| 3731 intptr_t* result = ReadDW(ra_val + offset); |
| 3732 set_register(rt, *result); |
| 3733 DCHECK(ra != 0); |
| 3734 set_register(ra, ra_val + offset); |
| 3735 break; |
| 3736 } |
| 3737 case 2: { // lwa |
| 3738 intptr_t result = ReadW(ra_val + offset, instr); |
| 3739 set_register(rt, result); |
| 3740 break; |
| 3741 } |
| 3742 } |
| 3743 break; |
| 3744 } |
| 3745 |
| 3746 case STD: |
| 3747 case STDU: { |
| 3748 int ra = instr->RAValue(); |
| 3749 int rs = instr->RSValue(); |
| 3750 int64_t ra_val = ra == 0 ? 0 : get_register(ra); |
| 3751 int64_t rs_val = get_register(rs); |
| 3752 int offset = SIGN_EXT_IMM16(instr->Bits(15, 0) & ~3); |
| 3753 WriteDW(ra_val + offset, rs_val); |
| 3754 if (opcode == STDU) { |
| 3755 DCHECK(ra != 0); |
| 3756 set_register(ra, ra_val + offset); |
| 3757 } |
| 3758 break; |
| 3759 } |
3354 #endif | 3760 #endif |
3355 | 3761 |
3356 void Simulator::ExecuteExt6(Instruction* instr) { | |
3357 uint32_t opcode = EXT6 | instr->BitField(10, 3); | |
3358 switch (opcode) { | |
3359 case XSADDDP: { | 3762 case XSADDDP: { |
3360 int frt = instr->RTValue(); | 3763 int frt = instr->RTValue(); |
3361 int fra = instr->RAValue(); | 3764 int fra = instr->RAValue(); |
3362 int frb = instr->RBValue(); | 3765 int frb = instr->RBValue(); |
3363 double fra_val = get_double_from_d_register(fra); | 3766 double fra_val = get_double_from_d_register(fra); |
3364 double frb_val = get_double_from_d_register(frb); | 3767 double frb_val = get_double_from_d_register(frb); |
3365 double frt_val = fra_val + frb_val; | 3768 double frt_val = fra_val + frb_val; |
3366 set_d_register_from_double(frt, frt_val); | 3769 set_d_register_from_double(frt, frt_val); |
3367 return; | 3770 return; |
3368 } | 3771 } |
(...skipping 20 matching lines...) Expand all Loading... |
3389 case XSDIVDP: { | 3792 case XSDIVDP: { |
3390 int frt = instr->RTValue(); | 3793 int frt = instr->RTValue(); |
3391 int fra = instr->RAValue(); | 3794 int fra = instr->RAValue(); |
3392 int frb = instr->RBValue(); | 3795 int frb = instr->RBValue(); |
3393 double fra_val = get_double_from_d_register(fra); | 3796 double fra_val = get_double_from_d_register(fra); |
3394 double frb_val = get_double_from_d_register(frb); | 3797 double frb_val = get_double_from_d_register(frb); |
3395 double frt_val = fra_val / frb_val; | 3798 double frt_val = fra_val / frb_val; |
3396 set_d_register_from_double(frt, frt_val); | 3799 set_d_register_from_double(frt, frt_val); |
3397 return; | 3800 return; |
3398 } | 3801 } |
3399 } | |
3400 UNIMPLEMENTED(); // Not used by V8. | |
3401 } | |
3402 | 3802 |
3403 void Simulator::ExecuteGeneric(Instruction* instr) { | 3803 default: { |
3404 uint32_t opcode = instr->OpcodeField(); | 3804 printf("opcode = %x \n", instr->InstructionBits()); |
3405 switch (opcode) { | |
3406 case SUBFIC: { | |
3407 int rt = instr->RTValue(); | |
3408 int ra = instr->RAValue(); | |
3409 intptr_t ra_val = get_register(ra); | |
3410 int32_t im_val = instr->Bits(15, 0); | |
3411 im_val = SIGN_EXT_IMM16(im_val); | |
3412 intptr_t alu_out = im_val - ra_val; | |
3413 set_register(rt, alu_out); | |
3414 // todo - handle RC bit | |
3415 break; | |
3416 } | |
3417 case CMPLI: { | |
3418 int ra = instr->RAValue(); | |
3419 uint32_t im_val = instr->Bits(15, 0); | |
3420 int cr = instr->Bits(25, 23); | |
3421 uint32_t bf = 0; | |
3422 #if V8_TARGET_ARCH_PPC64 | |
3423 int L = instr->Bit(21); | |
3424 if (L) { | |
3425 #endif | |
3426 uintptr_t ra_val = get_register(ra); | |
3427 if (ra_val < im_val) { | |
3428 bf |= 0x80000000; | |
3429 } | |
3430 if (ra_val > im_val) { | |
3431 bf |= 0x40000000; | |
3432 } | |
3433 if (ra_val == im_val) { | |
3434 bf |= 0x20000000; | |
3435 } | |
3436 #if V8_TARGET_ARCH_PPC64 | |
3437 } else { | |
3438 uint32_t ra_val = get_register(ra); | |
3439 if (ra_val < im_val) { | |
3440 bf |= 0x80000000; | |
3441 } | |
3442 if (ra_val > im_val) { | |
3443 bf |= 0x40000000; | |
3444 } | |
3445 if (ra_val == im_val) { | |
3446 bf |= 0x20000000; | |
3447 } | |
3448 } | |
3449 #endif | |
3450 uint32_t condition_mask = 0xF0000000U >> (cr * 4); | |
3451 uint32_t condition = bf >> (cr * 4); | |
3452 condition_reg_ = (condition_reg_ & ~condition_mask) | condition; | |
3453 break; | |
3454 } | |
3455 case CMPI: { | |
3456 int ra = instr->RAValue(); | |
3457 int32_t im_val = instr->Bits(15, 0); | |
3458 im_val = SIGN_EXT_IMM16(im_val); | |
3459 int cr = instr->Bits(25, 23); | |
3460 uint32_t bf = 0; | |
3461 #if V8_TARGET_ARCH_PPC64 | |
3462 int L = instr->Bit(21); | |
3463 if (L) { | |
3464 #endif | |
3465 intptr_t ra_val = get_register(ra); | |
3466 if (ra_val < im_val) { | |
3467 bf |= 0x80000000; | |
3468 } | |
3469 if (ra_val > im_val) { | |
3470 bf |= 0x40000000; | |
3471 } | |
3472 if (ra_val == im_val) { | |
3473 bf |= 0x20000000; | |
3474 } | |
3475 #if V8_TARGET_ARCH_PPC64 | |
3476 } else { | |
3477 int32_t ra_val = get_register(ra); | |
3478 if (ra_val < im_val) { | |
3479 bf |= 0x80000000; | |
3480 } | |
3481 if (ra_val > im_val) { | |
3482 bf |= 0x40000000; | |
3483 } | |
3484 if (ra_val == im_val) { | |
3485 bf |= 0x20000000; | |
3486 } | |
3487 } | |
3488 #endif | |
3489 uint32_t condition_mask = 0xF0000000U >> (cr * 4); | |
3490 uint32_t condition = bf >> (cr * 4); | |
3491 condition_reg_ = (condition_reg_ & ~condition_mask) | condition; | |
3492 break; | |
3493 } | |
3494 case ADDIC: { | |
3495 int rt = instr->RTValue(); | |
3496 int ra = instr->RAValue(); | |
3497 uintptr_t ra_val = get_register(ra); | |
3498 uintptr_t im_val = SIGN_EXT_IMM16(instr->Bits(15, 0)); | |
3499 uintptr_t alu_out = ra_val + im_val; | |
3500 // Check overflow | |
3501 if (~ra_val < im_val) { | |
3502 special_reg_xer_ = (special_reg_xer_ & ~0xF0000000) | 0x20000000; | |
3503 } else { | |
3504 special_reg_xer_ &= ~0xF0000000; | |
3505 } | |
3506 set_register(rt, alu_out); | |
3507 break; | |
3508 } | |
3509 case ADDI: { | |
3510 int rt = instr->RTValue(); | |
3511 int ra = instr->RAValue(); | |
3512 int32_t im_val = SIGN_EXT_IMM16(instr->Bits(15, 0)); | |
3513 intptr_t alu_out; | |
3514 if (ra == 0) { | |
3515 alu_out = im_val; | |
3516 } else { | |
3517 intptr_t ra_val = get_register(ra); | |
3518 alu_out = ra_val + im_val; | |
3519 } | |
3520 set_register(rt, alu_out); | |
3521 // todo - handle RC bit | |
3522 break; | |
3523 } | |
3524 case ADDIS: { | |
3525 int rt = instr->RTValue(); | |
3526 int ra = instr->RAValue(); | |
3527 int32_t im_val = (instr->Bits(15, 0) << 16); | |
3528 intptr_t alu_out; | |
3529 if (ra == 0) { // treat r0 as zero | |
3530 alu_out = im_val; | |
3531 } else { | |
3532 intptr_t ra_val = get_register(ra); | |
3533 alu_out = ra_val + im_val; | |
3534 } | |
3535 set_register(rt, alu_out); | |
3536 break; | |
3537 } | |
3538 case BCX: { | |
3539 ExecuteBranchConditional(instr, BC_OFFSET); | |
3540 break; | |
3541 } | |
3542 case BX: { | |
3543 int offset = (instr->Bits(25, 2) << 8) >> 6; | |
3544 if (instr->Bit(0) == 1) { // LK flag set | |
3545 special_reg_lr_ = get_pc() + 4; | |
3546 } | |
3547 set_pc(get_pc() + offset); | |
3548 // todo - AA flag | |
3549 break; | |
3550 } | |
3551 case EXT1: { | |
3552 ExecuteExt1(instr); | |
3553 break; | |
3554 } | |
3555 case RLWIMIX: { | |
3556 int ra = instr->RAValue(); | |
3557 int rs = instr->RSValue(); | |
3558 uint32_t rs_val = get_register(rs); | |
3559 int32_t ra_val = get_register(ra); | |
3560 int sh = instr->Bits(15, 11); | |
3561 int mb = instr->Bits(10, 6); | |
3562 int me = instr->Bits(5, 1); | |
3563 uint32_t result = base::bits::RotateLeft32(rs_val, sh); | |
3564 int mask = 0; | |
3565 if (mb < me + 1) { | |
3566 int bit = 0x80000000 >> mb; | |
3567 for (; mb <= me; mb++) { | |
3568 mask |= bit; | |
3569 bit >>= 1; | |
3570 } | |
3571 } else if (mb == me + 1) { | |
3572 mask = 0xffffffff; | |
3573 } else { // mb > me+1 | |
3574 int bit = 0x80000000 >> (me + 1); // needs to be tested | |
3575 mask = 0xffffffff; | |
3576 for (; me < mb; me++) { | |
3577 mask ^= bit; | |
3578 bit >>= 1; | |
3579 } | |
3580 } | |
3581 result &= mask; | |
3582 ra_val &= ~mask; | |
3583 result |= ra_val; | |
3584 set_register(ra, result); | |
3585 if (instr->Bit(0)) { // RC bit set | |
3586 SetCR0(result); | |
3587 } | |
3588 break; | |
3589 } | |
3590 case RLWINMX: | |
3591 case RLWNMX: { | |
3592 int ra = instr->RAValue(); | |
3593 int rs = instr->RSValue(); | |
3594 uint32_t rs_val = get_register(rs); | |
3595 int sh = 0; | |
3596 if (opcode == RLWINMX) { | |
3597 sh = instr->Bits(15, 11); | |
3598 } else { | |
3599 int rb = instr->RBValue(); | |
3600 uint32_t rb_val = get_register(rb); | |
3601 sh = (rb_val & 0x1f); | |
3602 } | |
3603 int mb = instr->Bits(10, 6); | |
3604 int me = instr->Bits(5, 1); | |
3605 uint32_t result = base::bits::RotateLeft32(rs_val, sh); | |
3606 int mask = 0; | |
3607 if (mb < me + 1) { | |
3608 int bit = 0x80000000 >> mb; | |
3609 for (; mb <= me; mb++) { | |
3610 mask |= bit; | |
3611 bit >>= 1; | |
3612 } | |
3613 } else if (mb == me + 1) { | |
3614 mask = 0xffffffff; | |
3615 } else { // mb > me+1 | |
3616 int bit = 0x80000000 >> (me + 1); // needs to be tested | |
3617 mask = 0xffffffff; | |
3618 for (; me < mb; me++) { | |
3619 mask ^= bit; | |
3620 bit >>= 1; | |
3621 } | |
3622 } | |
3623 result &= mask; | |
3624 set_register(ra, result); | |
3625 if (instr->Bit(0)) { // RC bit set | |
3626 SetCR0(result); | |
3627 } | |
3628 break; | |
3629 } | |
3630 case ORI: { | |
3631 int rs = instr->RSValue(); | |
3632 int ra = instr->RAValue(); | |
3633 intptr_t rs_val = get_register(rs); | |
3634 uint32_t im_val = instr->Bits(15, 0); | |
3635 intptr_t alu_out = rs_val | im_val; | |
3636 set_register(ra, alu_out); | |
3637 break; | |
3638 } | |
3639 case ORIS: { | |
3640 int rs = instr->RSValue(); | |
3641 int ra = instr->RAValue(); | |
3642 intptr_t rs_val = get_register(rs); | |
3643 uint32_t im_val = instr->Bits(15, 0); | |
3644 intptr_t alu_out = rs_val | (im_val << 16); | |
3645 set_register(ra, alu_out); | |
3646 break; | |
3647 } | |
3648 case XORI: { | |
3649 int rs = instr->RSValue(); | |
3650 int ra = instr->RAValue(); | |
3651 intptr_t rs_val = get_register(rs); | |
3652 uint32_t im_val = instr->Bits(15, 0); | |
3653 intptr_t alu_out = rs_val ^ im_val; | |
3654 set_register(ra, alu_out); | |
3655 // todo - set condition based SO bit | |
3656 break; | |
3657 } | |
3658 case XORIS: { | |
3659 int rs = instr->RSValue(); | |
3660 int ra = instr->RAValue(); | |
3661 intptr_t rs_val = get_register(rs); | |
3662 uint32_t im_val = instr->Bits(15, 0); | |
3663 intptr_t alu_out = rs_val ^ (im_val << 16); | |
3664 set_register(ra, alu_out); | |
3665 break; | |
3666 } | |
3667 case ANDIx: { | |
3668 int rs = instr->RSValue(); | |
3669 int ra = instr->RAValue(); | |
3670 intptr_t rs_val = get_register(rs); | |
3671 uint32_t im_val = instr->Bits(15, 0); | |
3672 intptr_t alu_out = rs_val & im_val; | |
3673 set_register(ra, alu_out); | |
3674 SetCR0(alu_out); | |
3675 break; | |
3676 } | |
3677 case ANDISx: { | |
3678 int rs = instr->RSValue(); | |
3679 int ra = instr->RAValue(); | |
3680 intptr_t rs_val = get_register(rs); | |
3681 uint32_t im_val = instr->Bits(15, 0); | |
3682 intptr_t alu_out = rs_val & (im_val << 16); | |
3683 set_register(ra, alu_out); | |
3684 SetCR0(alu_out); | |
3685 break; | |
3686 } | |
3687 case EXT2: { | |
3688 ExecuteExt2(instr); | |
3689 break; | |
3690 } | |
3691 | |
3692 case LWZU: | |
3693 case LWZ: { | |
3694 int ra = instr->RAValue(); | |
3695 int rt = instr->RTValue(); | |
3696 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); | |
3697 int offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); | |
3698 set_register(rt, ReadWU(ra_val + offset, instr)); | |
3699 if (opcode == LWZU) { | |
3700 DCHECK(ra != 0); | |
3701 set_register(ra, ra_val + offset); | |
3702 } | |
3703 break; | |
3704 } | |
3705 | |
3706 case LBZU: | |
3707 case LBZ: { | |
3708 int ra = instr->RAValue(); | |
3709 int rt = instr->RTValue(); | |
3710 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); | |
3711 int offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); | |
3712 set_register(rt, ReadB(ra_val + offset) & 0xFF); | |
3713 if (opcode == LBZU) { | |
3714 DCHECK(ra != 0); | |
3715 set_register(ra, ra_val + offset); | |
3716 } | |
3717 break; | |
3718 } | |
3719 | |
3720 case STWU: | |
3721 case STW: { | |
3722 int ra = instr->RAValue(); | |
3723 int rs = instr->RSValue(); | |
3724 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); | |
3725 int32_t rs_val = get_register(rs); | |
3726 int offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); | |
3727 WriteW(ra_val + offset, rs_val, instr); | |
3728 if (opcode == STWU) { | |
3729 DCHECK(ra != 0); | |
3730 set_register(ra, ra_val + offset); | |
3731 } | |
3732 // printf("r%d %08x -> %08x\n", rs, rs_val, offset); // 0xdead | |
3733 break; | |
3734 } | |
3735 | |
3736 case STBU: | |
3737 case STB: { | |
3738 int ra = instr->RAValue(); | |
3739 int rs = instr->RSValue(); | |
3740 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); | |
3741 int8_t rs_val = get_register(rs); | |
3742 int offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); | |
3743 WriteB(ra_val + offset, rs_val); | |
3744 if (opcode == STBU) { | |
3745 DCHECK(ra != 0); | |
3746 set_register(ra, ra_val + offset); | |
3747 } | |
3748 break; | |
3749 } | |
3750 | |
3751 case LHZU: | |
3752 case LHZ: { | |
3753 int ra = instr->RAValue(); | |
3754 int rt = instr->RTValue(); | |
3755 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); | |
3756 int offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); | |
3757 uintptr_t result = ReadHU(ra_val + offset, instr) & 0xffff; | |
3758 set_register(rt, result); | |
3759 if (opcode == LHZU) { | |
3760 set_register(ra, ra_val + offset); | |
3761 } | |
3762 break; | |
3763 } | |
3764 | |
3765 case LHA: | |
3766 case LHAU: { | |
3767 int ra = instr->RAValue(); | |
3768 int rt = instr->RTValue(); | |
3769 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); | |
3770 int offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); | |
3771 intptr_t result = ReadH(ra_val + offset, instr); | |
3772 set_register(rt, result); | |
3773 if (opcode == LHAU) { | |
3774 set_register(ra, ra_val + offset); | |
3775 } | |
3776 break; | |
3777 } | |
3778 | |
3779 case STHU: | |
3780 case STH: { | |
3781 int ra = instr->RAValue(); | |
3782 int rs = instr->RSValue(); | |
3783 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); | |
3784 int16_t rs_val = get_register(rs); | |
3785 int offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); | |
3786 WriteH(ra_val + offset, rs_val, instr); | |
3787 if (opcode == STHU) { | |
3788 DCHECK(ra != 0); | |
3789 set_register(ra, ra_val + offset); | |
3790 } | |
3791 break; | |
3792 } | |
3793 | |
3794 case LMW: | |
3795 case STMW: { | |
3796 UNIMPLEMENTED(); | 3805 UNIMPLEMENTED(); |
3797 break; | 3806 break; |
3798 } | 3807 } |
3799 | |
3800 case LFSU: | |
3801 case LFS: { | |
3802 int frt = instr->RTValue(); | |
3803 int ra = instr->RAValue(); | |
3804 int32_t offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); | |
3805 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); | |
3806 int32_t val = ReadW(ra_val + offset, instr); | |
3807 float* fptr = reinterpret_cast<float*>(&val); | |
3808 // Conversion using double changes sNan to qNan on ia32/x64 | |
3809 #if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64 | |
3810 if (val == 0x7fa00000) { | |
3811 set_d_register(frt, 0x7ff4000000000000); | |
3812 } else { | |
3813 #endif | |
3814 set_d_register_from_double(frt, static_cast<double>(*fptr)); | |
3815 #if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64 | |
3816 } | |
3817 #endif | |
3818 if (opcode == LFSU) { | |
3819 DCHECK(ra != 0); | |
3820 set_register(ra, ra_val + offset); | |
3821 } | |
3822 break; | |
3823 } | |
3824 | |
3825 case LFDU: | |
3826 case LFD: { | |
3827 int frt = instr->RTValue(); | |
3828 int ra = instr->RAValue(); | |
3829 int32_t offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); | |
3830 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); | |
3831 int64_t* dptr = reinterpret_cast<int64_t*>(ReadDW(ra_val + offset)); | |
3832 set_d_register(frt, *dptr); | |
3833 if (opcode == LFDU) { | |
3834 DCHECK(ra != 0); | |
3835 set_register(ra, ra_val + offset); | |
3836 } | |
3837 break; | |
3838 } | |
3839 | |
3840 case STFSU: { | |
3841 case STFS: | |
3842 int frs = instr->RSValue(); | |
3843 int ra = instr->RAValue(); | |
3844 int32_t offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); | |
3845 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); | |
3846 float frs_val = static_cast<float>(get_double_from_d_register(frs)); | |
3847 int32_t* p; | |
3848 // Conversion using double changes sNan to qNan on ia32/x64 | |
3849 #if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64 | |
3850 int64_t frs_isnan = get_d_register(frs); | |
3851 int32_t frs_nan_single = 0x7fa00000; | |
3852 if (frs_isnan == 0x7ff4000000000000) { | |
3853 p = &frs_nan_single; | |
3854 } else { | |
3855 #endif | |
3856 p = reinterpret_cast<int32_t*>(&frs_val); | |
3857 #if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64 | |
3858 } | |
3859 #endif | |
3860 WriteW(ra_val + offset, *p, instr); | |
3861 if (opcode == STFSU) { | |
3862 DCHECK(ra != 0); | |
3863 set_register(ra, ra_val + offset); | |
3864 } | |
3865 break; | |
3866 } | |
3867 | |
3868 case STFDU: | |
3869 case STFD: { | |
3870 int frs = instr->RSValue(); | |
3871 int ra = instr->RAValue(); | |
3872 int32_t offset = SIGN_EXT_IMM16(instr->Bits(15, 0)); | |
3873 intptr_t ra_val = ra == 0 ? 0 : get_register(ra); | |
3874 int64_t frs_val = get_d_register(frs); | |
3875 WriteDW(ra_val + offset, frs_val); | |
3876 if (opcode == STFDU) { | |
3877 DCHECK(ra != 0); | |
3878 set_register(ra, ra_val + offset); | |
3879 } | |
3880 break; | |
3881 } | |
3882 | |
3883 case EXT3: { | |
3884 ExecuteExt3(instr); | |
3885 break; | |
3886 } | |
3887 case EXT4: { | |
3888 ExecuteExt4(instr); | |
3889 break; | |
3890 } | |
3891 | |
3892 #if V8_TARGET_ARCH_PPC64 | |
3893 case EXT5: { | |
3894 ExecuteExt5(instr); | |
3895 break; | |
3896 } | |
3897 case LD: { | |
3898 int ra = instr->RAValue(); | |
3899 int rt = instr->RTValue(); | |
3900 int64_t ra_val = ra == 0 ? 0 : get_register(ra); | |
3901 int offset = SIGN_EXT_IMM16(instr->Bits(15, 0) & ~3); | |
3902 switch (instr->Bits(1, 0)) { | |
3903 case 0: { // ld | |
3904 intptr_t* result = ReadDW(ra_val + offset); | |
3905 set_register(rt, *result); | |
3906 break; | |
3907 } | |
3908 case 1: { // ldu | |
3909 intptr_t* result = ReadDW(ra_val + offset); | |
3910 set_register(rt, *result); | |
3911 DCHECK(ra != 0); | |
3912 set_register(ra, ra_val + offset); | |
3913 break; | |
3914 } | |
3915 case 2: { // lwa | |
3916 intptr_t result = ReadW(ra_val + offset, instr); | |
3917 set_register(rt, result); | |
3918 break; | |
3919 } | |
3920 } | |
3921 break; | |
3922 } | |
3923 | |
3924 case STD: { | |
3925 int ra = instr->RAValue(); | |
3926 int rs = instr->RSValue(); | |
3927 int64_t ra_val = ra == 0 ? 0 : get_register(ra); | |
3928 int64_t rs_val = get_register(rs); | |
3929 int offset = SIGN_EXT_IMM16(instr->Bits(15, 0) & ~3); | |
3930 WriteDW(ra_val + offset, rs_val); | |
3931 if (instr->Bit(0) == 1) { // This is the STDU form | |
3932 DCHECK(ra != 0); | |
3933 set_register(ra, ra_val + offset); | |
3934 } | |
3935 break; | |
3936 } | |
3937 #endif | |
3938 case EXT6: { | |
3939 ExecuteExt6(instr); | |
3940 break; | |
3941 } | |
3942 | |
3943 default: { | |
3944 UNIMPLEMENTED(); | |
3945 break; | |
3946 } | |
3947 } | 3808 } |
3948 } // NOLINT | 3809 } // NOLINT |
3949 | 3810 |
3950 | 3811 |
3951 void Simulator::Trace(Instruction* instr) { | 3812 void Simulator::Trace(Instruction* instr) { |
3952 disasm::NameConverter converter; | 3813 disasm::NameConverter converter; |
3953 disasm::Disassembler dasm(converter); | 3814 disasm::Disassembler dasm(converter); |
3954 // use a reasonably large buffer | 3815 // use a reasonably large buffer |
3955 v8::internal::EmbeddedVector<char, 256> buffer; | 3816 v8::internal::EmbeddedVector<char, 256> buffer; |
3956 dasm.InstructionDecode(buffer, reinterpret_cast<byte*>(instr)); | 3817 dasm.InstructionDecode(buffer, reinterpret_cast<byte*>(instr)); |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4210 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp); | 4071 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp); |
4211 uintptr_t address = *stack_slot; | 4072 uintptr_t address = *stack_slot; |
4212 set_register(sp, current_sp + sizeof(uintptr_t)); | 4073 set_register(sp, current_sp + sizeof(uintptr_t)); |
4213 return address; | 4074 return address; |
4214 } | 4075 } |
4215 } // namespace internal | 4076 } // namespace internal |
4216 } // namespace v8 | 4077 } // namespace v8 |
4217 | 4078 |
4218 #endif // USE_SIMULATOR | 4079 #endif // USE_SIMULATOR |
4219 #endif // V8_TARGET_ARCH_PPC | 4080 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |