Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1090)

Side by Side Diff: src/ppc/simulator-ppc.cc

Issue 2760983003: PPC: Clean up simulator code by introducing a OpcodeBase function (Closed)
Patch Set: Add missing cases in simulator Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/ppc/constants-ppc.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/ppc/constants-ppc.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698