| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 <limits.h> | 5 #include <limits.h> |
| 6 #include <stdarg.h> | 6 #include <stdarg.h> |
| 7 #include <stdlib.h> | 7 #include <stdlib.h> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 | 9 |
| 10 #include "src/v8.h" | 10 #include "src/v8.h" |
| (...skipping 1688 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1699 if (exceptions[i] != 0) { | 1699 if (exceptions[i] != 0) { |
| 1700 V8_Fatal(__FILE__, __LINE__, "Error: Exception %i raised.", i); | 1700 V8_Fatal(__FILE__, __LINE__, "Error: Exception %i raised.", i); |
| 1701 } | 1701 } |
| 1702 } | 1702 } |
| 1703 } | 1703 } |
| 1704 | 1704 |
| 1705 | 1705 |
| 1706 // Handle execution based on instruction types. | 1706 // Handle execution based on instruction types. |
| 1707 | 1707 |
| 1708 void Simulator::ConfigureTypeRegister(Instruction* instr, | 1708 void Simulator::ConfigureTypeRegister(Instruction* instr, |
| 1709 int32_t& alu_out, | 1709 int32_t* alu_out, |
| 1710 int64_t& i64hilo, | 1710 int64_t* i64hilo, |
| 1711 uint64_t& u64hilo, | 1711 uint64_t* u64hilo, |
| 1712 int32_t& next_pc, | 1712 int32_t* next_pc, |
| 1713 int32_t& return_addr_reg, | 1713 int32_t* return_addr_reg, |
| 1714 bool& do_interrupt) { | 1714 bool* do_interrupt) { |
| 1715 // Every local variable declared here needs to be const. | 1715 // Every local variable declared here needs to be const. |
| 1716 // This is to make sure that changed values are sent back to | 1716 // This is to make sure that changed values are sent back to |
| 1717 // DecodeTypeRegister correctly. | 1717 // DecodeTypeRegister correctly. |
| 1718 | 1718 |
| 1719 // Instruction fields. | 1719 // Instruction fields. |
| 1720 const Opcode op = instr->OpcodeFieldRaw(); | 1720 const Opcode op = instr->OpcodeFieldRaw(); |
| 1721 const int32_t rs_reg = instr->RsValue(); | 1721 const int32_t rs_reg = instr->RsValue(); |
| 1722 const int32_t rs = get_register(rs_reg); | 1722 const int32_t rs = get_register(rs_reg); |
| 1723 const uint32_t rs_u = static_cast<uint32_t>(rs); | 1723 const uint32_t rs_u = static_cast<uint32_t>(rs); |
| 1724 const int32_t rt_reg = instr->RtValue(); | 1724 const int32_t rt_reg = instr->RtValue(); |
| 1725 const int32_t rt = get_register(rt_reg); | 1725 const int32_t rt = get_register(rt_reg); |
| 1726 const uint32_t rt_u = static_cast<uint32_t>(rt); | 1726 const uint32_t rt_u = static_cast<uint32_t>(rt); |
| 1727 const int32_t rd_reg = instr->RdValue(); | 1727 const int32_t rd_reg = instr->RdValue(); |
| 1728 const uint32_t sa = instr->SaValue(); | 1728 const uint32_t sa = instr->SaValue(); |
| 1729 | 1729 |
| 1730 const int32_t fs_reg = instr->FsValue(); | 1730 const int32_t fs_reg = instr->FsValue(); |
| 1731 | 1731 |
| 1732 | 1732 |
| 1733 // ---------- Configuration. | 1733 // ---------- Configuration. |
| 1734 switch (op) { | 1734 switch (op) { |
| 1735 case COP1: // Coprocessor instructions. | 1735 case COP1: // Coprocessor instructions. |
| 1736 switch (instr->RsFieldRaw()) { | 1736 switch (instr->RsFieldRaw()) { |
| 1737 case BC1: // Handled in DecodeTypeImmed, should never come here. | 1737 case BC1: // Handled in DecodeTypeImmed, should never come here. |
| 1738 UNREACHABLE(); | 1738 UNREACHABLE(); |
| 1739 break; | 1739 break; |
| 1740 case CFC1: | 1740 case CFC1: |
| 1741 // At the moment only FCSR is supported. | 1741 // At the moment only FCSR is supported. |
| 1742 ASSERT(fs_reg == kFCSRRegister); | 1742 ASSERT(fs_reg == kFCSRRegister); |
| 1743 alu_out = FCSR_; | 1743 *alu_out = FCSR_; |
| 1744 break; | 1744 break; |
| 1745 case MFC1: | 1745 case MFC1: |
| 1746 alu_out = get_fpu_register(fs_reg); | 1746 *alu_out = get_fpu_register(fs_reg); |
| 1747 break; | 1747 break; |
| 1748 case MFHC1: | 1748 case MFHC1: |
| 1749 UNIMPLEMENTED_MIPS(); | 1749 UNIMPLEMENTED_MIPS(); |
| 1750 break; | 1750 break; |
| 1751 case CTC1: | 1751 case CTC1: |
| 1752 case MTC1: | 1752 case MTC1: |
| 1753 case MTHC1: | 1753 case MTHC1: |
| 1754 // Do the store in the execution step. | 1754 // Do the store in the execution step. |
| 1755 break; | 1755 break; |
| 1756 case S: | 1756 case S: |
| 1757 case D: | 1757 case D: |
| 1758 case W: | 1758 case W: |
| 1759 case L: | 1759 case L: |
| 1760 case PS: | 1760 case PS: |
| 1761 // Do everything in the execution step. | 1761 // Do everything in the execution step. |
| 1762 break; | 1762 break; |
| 1763 default: | 1763 default: |
| 1764 UNIMPLEMENTED_MIPS(); | 1764 UNIMPLEMENTED_MIPS(); |
| 1765 } | 1765 } |
| 1766 break; | 1766 break; |
| 1767 case COP1X: | 1767 case COP1X: |
| 1768 break; | 1768 break; |
| 1769 case SPECIAL: | 1769 case SPECIAL: |
| 1770 switch (instr->FunctionFieldRaw()) { | 1770 switch (instr->FunctionFieldRaw()) { |
| 1771 case JR: | 1771 case JR: |
| 1772 case JALR: | 1772 case JALR: |
| 1773 next_pc = get_register(instr->RsValue()); | 1773 *next_pc = get_register(instr->RsValue()); |
| 1774 return_addr_reg = instr->RdValue(); | 1774 *return_addr_reg = instr->RdValue(); |
| 1775 break; | 1775 break; |
| 1776 case SLL: | 1776 case SLL: |
| 1777 alu_out = rt << sa; | 1777 *alu_out = rt << sa; |
| 1778 break; | 1778 break; |
| 1779 case SRL: | 1779 case SRL: |
| 1780 if (rs_reg == 0) { | 1780 if (rs_reg == 0) { |
| 1781 // Regular logical right shift of a word by a fixed number of | 1781 // Regular logical right shift of a word by a fixed number of |
| 1782 // bits instruction. RS field is always equal to 0. | 1782 // bits instruction. RS field is always equal to 0. |
| 1783 alu_out = rt_u >> sa; | 1783 *alu_out = rt_u >> sa; |
| 1784 } else { | 1784 } else { |
| 1785 // Logical right-rotate of a word by a fixed number of bits. This | 1785 // Logical right-rotate of a word by a fixed number of bits. This |
| 1786 // is special case of SRL instruction, added in MIPS32 Release 2. | 1786 // is special case of SRL instruction, added in MIPS32 Release 2. |
| 1787 // RS field is equal to 00001. | 1787 // RS field is equal to 00001. |
| 1788 alu_out = (rt_u >> sa) | (rt_u << (32 - sa)); | 1788 *alu_out = (rt_u >> sa) | (rt_u << (32 - sa)); |
| 1789 } | 1789 } |
| 1790 break; | 1790 break; |
| 1791 case SRA: | 1791 case SRA: |
| 1792 alu_out = rt >> sa; | 1792 *alu_out = rt >> sa; |
| 1793 break; | 1793 break; |
| 1794 case SLLV: | 1794 case SLLV: |
| 1795 alu_out = rt << rs; | 1795 *alu_out = rt << rs; |
| 1796 break; | 1796 break; |
| 1797 case SRLV: | 1797 case SRLV: |
| 1798 if (sa == 0) { | 1798 if (sa == 0) { |
| 1799 // Regular logical right-shift of a word by a variable number of | 1799 // Regular logical right-shift of a word by a variable number of |
| 1800 // bits instruction. SA field is always equal to 0. | 1800 // bits instruction. SA field is always equal to 0. |
| 1801 alu_out = rt_u >> rs; | 1801 *alu_out = rt_u >> rs; |
| 1802 } else { | 1802 } else { |
| 1803 // Logical right-rotate of a word by a variable number of bits. | 1803 // Logical right-rotate of a word by a variable number of bits. |
| 1804 // This is special case od SRLV instruction, added in MIPS32 | 1804 // This is special case od SRLV instruction, added in MIPS32 |
| 1805 // Release 2. SA field is equal to 00001. | 1805 // Release 2. SA field is equal to 00001. |
| 1806 alu_out = (rt_u >> rs_u) | (rt_u << (32 - rs_u)); | 1806 *alu_out = (rt_u >> rs_u) | (rt_u << (32 - rs_u)); |
| 1807 } | 1807 } |
| 1808 break; | 1808 break; |
| 1809 case SRAV: | 1809 case SRAV: |
| 1810 alu_out = rt >> rs; | 1810 *alu_out = rt >> rs; |
| 1811 break; | 1811 break; |
| 1812 case MFHI: | 1812 case MFHI: |
| 1813 alu_out = get_register(HI); | 1813 *alu_out = get_register(HI); |
| 1814 break; | 1814 break; |
| 1815 case MFLO: | 1815 case MFLO: |
| 1816 alu_out = get_register(LO); | 1816 *alu_out = get_register(LO); |
| 1817 break; | 1817 break; |
| 1818 case MULT: | 1818 case MULT: |
| 1819 i64hilo = static_cast<int64_t>(rs) * static_cast<int64_t>(rt); | 1819 *i64hilo = static_cast<int64_t>(rs) * static_cast<int64_t>(rt); |
| 1820 break; | 1820 break; |
| 1821 case MULTU: | 1821 case MULTU: |
| 1822 u64hilo = static_cast<uint64_t>(rs_u) * static_cast<uint64_t>(rt_u); | 1822 *u64hilo = static_cast<uint64_t>(rs_u) * static_cast<uint64_t>(rt_u); |
| 1823 break; | 1823 break; |
| 1824 case ADD: | 1824 case ADD: |
| 1825 if (HaveSameSign(rs, rt)) { | 1825 if (HaveSameSign(rs, rt)) { |
| 1826 if (rs > 0) { | 1826 if (rs > 0) { |
| 1827 exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue - rt); | 1827 exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue - rt); |
| 1828 } else if (rs < 0) { | 1828 } else if (rs < 0) { |
| 1829 exceptions[kIntegerUnderflow] = rs < (Registers::kMinValue - rt); | 1829 exceptions[kIntegerUnderflow] = rs < (Registers::kMinValue - rt); |
| 1830 } | 1830 } |
| 1831 } | 1831 } |
| 1832 alu_out = rs + rt; | 1832 *alu_out = rs + rt; |
| 1833 break; | 1833 break; |
| 1834 case ADDU: | 1834 case ADDU: |
| 1835 alu_out = rs + rt; | 1835 *alu_out = rs + rt; |
| 1836 break; | 1836 break; |
| 1837 case SUB: | 1837 case SUB: |
| 1838 if (!HaveSameSign(rs, rt)) { | 1838 if (!HaveSameSign(rs, rt)) { |
| 1839 if (rs > 0) { | 1839 if (rs > 0) { |
| 1840 exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue + rt); | 1840 exceptions[kIntegerOverflow] = rs > (Registers::kMaxValue + rt); |
| 1841 } else if (rs < 0) { | 1841 } else if (rs < 0) { |
| 1842 exceptions[kIntegerUnderflow] = rs < (Registers::kMinValue + rt); | 1842 exceptions[kIntegerUnderflow] = rs < (Registers::kMinValue + rt); |
| 1843 } | 1843 } |
| 1844 } | 1844 } |
| 1845 alu_out = rs - rt; | 1845 *alu_out = rs - rt; |
| 1846 break; | 1846 break; |
| 1847 case SUBU: | 1847 case SUBU: |
| 1848 alu_out = rs - rt; | 1848 *alu_out = rs - rt; |
| 1849 break; | 1849 break; |
| 1850 case AND: | 1850 case AND: |
| 1851 alu_out = rs & rt; | 1851 *alu_out = rs & rt; |
| 1852 break; | 1852 break; |
| 1853 case OR: | 1853 case OR: |
| 1854 alu_out = rs | rt; | 1854 *alu_out = rs | rt; |
| 1855 break; | 1855 break; |
| 1856 case XOR: | 1856 case XOR: |
| 1857 alu_out = rs ^ rt; | 1857 *alu_out = rs ^ rt; |
| 1858 break; | 1858 break; |
| 1859 case NOR: | 1859 case NOR: |
| 1860 alu_out = ~(rs | rt); | 1860 *alu_out = ~(rs | rt); |
| 1861 break; | 1861 break; |
| 1862 case SLT: | 1862 case SLT: |
| 1863 alu_out = rs < rt ? 1 : 0; | 1863 *alu_out = rs < rt ? 1 : 0; |
| 1864 break; | 1864 break; |
| 1865 case SLTU: | 1865 case SLTU: |
| 1866 alu_out = rs_u < rt_u ? 1 : 0; | 1866 *alu_out = rs_u < rt_u ? 1 : 0; |
| 1867 break; | 1867 break; |
| 1868 // Break and trap instructions. | 1868 // Break and trap instructions. |
| 1869 case BREAK: | 1869 case BREAK: |
| 1870 | 1870 *do_interrupt = true; |
| 1871 do_interrupt = true; | |
| 1872 break; | 1871 break; |
| 1873 case TGE: | 1872 case TGE: |
| 1874 do_interrupt = rs >= rt; | 1873 *do_interrupt = rs >= rt; |
| 1875 break; | 1874 break; |
| 1876 case TGEU: | 1875 case TGEU: |
| 1877 do_interrupt = rs_u >= rt_u; | 1876 *do_interrupt = rs_u >= rt_u; |
| 1878 break; | 1877 break; |
| 1879 case TLT: | 1878 case TLT: |
| 1880 do_interrupt = rs < rt; | 1879 *do_interrupt = rs < rt; |
| 1881 break; | 1880 break; |
| 1882 case TLTU: | 1881 case TLTU: |
| 1883 do_interrupt = rs_u < rt_u; | 1882 *do_interrupt = rs_u < rt_u; |
| 1884 break; | 1883 break; |
| 1885 case TEQ: | 1884 case TEQ: |
| 1886 do_interrupt = rs == rt; | 1885 *do_interrupt = rs == rt; |
| 1887 break; | 1886 break; |
| 1888 case TNE: | 1887 case TNE: |
| 1889 do_interrupt = rs != rt; | 1888 *do_interrupt = rs != rt; |
| 1890 break; | 1889 break; |
| 1891 case MOVN: | 1890 case MOVN: |
| 1892 case MOVZ: | 1891 case MOVZ: |
| 1893 case MOVCI: | 1892 case MOVCI: |
| 1894 // No action taken on decode. | 1893 // No action taken on decode. |
| 1895 break; | 1894 break; |
| 1896 case DIV: | 1895 case DIV: |
| 1897 case DIVU: | 1896 case DIVU: |
| 1898 // div and divu never raise exceptions. | 1897 // div and divu never raise exceptions. |
| 1899 break; | 1898 break; |
| 1900 default: | 1899 default: |
| 1901 UNREACHABLE(); | 1900 UNREACHABLE(); |
| 1902 } | 1901 } |
| 1903 break; | 1902 break; |
| 1904 case SPECIAL2: | 1903 case SPECIAL2: |
| 1905 switch (instr->FunctionFieldRaw()) { | 1904 switch (instr->FunctionFieldRaw()) { |
| 1906 case MUL: | 1905 case MUL: |
| 1907 alu_out = rs_u * rt_u; // Only the lower 32 bits are kept. | 1906 *alu_out = rs_u * rt_u; // Only the lower 32 bits are kept. |
| 1908 break; | 1907 break; |
| 1909 case CLZ: | 1908 case CLZ: |
| 1910 // MIPS32 spec: If no bits were set in GPR rs, the result written to | 1909 // MIPS32 spec: If no bits were set in GPR rs, the result written to |
| 1911 // GPR rd is 32. | 1910 // GPR rd is 32. |
| 1912 // GCC __builtin_clz: If input is 0, the result is undefined. | 1911 // GCC __builtin_clz: If input is 0, the result is undefined. |
| 1913 alu_out = | 1912 *alu_out = |
| 1914 rs_u == 0 ? 32 : CompilerIntrinsics::CountLeadingZeros(rs_u); | 1913 rs_u == 0 ? 32 : CompilerIntrinsics::CountLeadingZeros(rs_u); |
| 1915 break; | 1914 break; |
| 1916 default: | 1915 default: |
| 1917 UNREACHABLE(); | 1916 UNREACHABLE(); |
| 1918 } | 1917 } |
| 1919 break; | 1918 break; |
| 1920 case SPECIAL3: | 1919 case SPECIAL3: |
| 1921 switch (instr->FunctionFieldRaw()) { | 1920 switch (instr->FunctionFieldRaw()) { |
| 1922 case INS: { // Mips32r2 instruction. | 1921 case INS: { // Mips32r2 instruction. |
| 1923 // Interpret rd field as 5-bit msb of insert. | 1922 // Interpret rd field as 5-bit msb of insert. |
| 1924 uint16_t msb = rd_reg; | 1923 uint16_t msb = rd_reg; |
| 1925 // Interpret sa field as 5-bit lsb of insert. | 1924 // Interpret sa field as 5-bit lsb of insert. |
| 1926 uint16_t lsb = sa; | 1925 uint16_t lsb = sa; |
| 1927 uint16_t size = msb - lsb + 1; | 1926 uint16_t size = msb - lsb + 1; |
| 1928 uint32_t mask = (1 << size) - 1; | 1927 uint32_t mask = (1 << size) - 1; |
| 1929 alu_out = (rt_u & ~(mask << lsb)) | ((rs_u & mask) << lsb); | 1928 *alu_out = (rt_u & ~(mask << lsb)) | ((rs_u & mask) << lsb); |
| 1930 break; | 1929 break; |
| 1931 } | 1930 } |
| 1932 case EXT: { // Mips32r2 instruction. | 1931 case EXT: { // Mips32r2 instruction. |
| 1933 // Interpret rd field as 5-bit msb of extract. | 1932 // Interpret rd field as 5-bit msb of extract. |
| 1934 uint16_t msb = rd_reg; | 1933 uint16_t msb = rd_reg; |
| 1935 // Interpret sa field as 5-bit lsb of extract. | 1934 // Interpret sa field as 5-bit lsb of extract. |
| 1936 uint16_t lsb = sa; | 1935 uint16_t lsb = sa; |
| 1937 uint16_t size = msb + 1; | 1936 uint16_t size = msb + 1; |
| 1938 uint32_t mask = (1 << size) - 1; | 1937 uint32_t mask = (1 << size) - 1; |
| 1939 alu_out = (rs_u & (mask << lsb)) >> lsb; | 1938 *alu_out = (rs_u & (mask << lsb)) >> lsb; |
| 1940 break; | 1939 break; |
| 1941 } | 1940 } |
| 1942 default: | 1941 default: |
| 1943 UNREACHABLE(); | 1942 UNREACHABLE(); |
| 1944 } | 1943 } |
| 1945 break; | 1944 break; |
| 1946 default: | 1945 default: |
| 1947 UNREACHABLE(); | 1946 UNREACHABLE(); |
| 1948 } | 1947 } |
| 1949 } | 1948 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1977 | 1976 |
| 1978 // For jr and jalr. | 1977 // For jr and jalr. |
| 1979 // Get current pc. | 1978 // Get current pc. |
| 1980 int32_t current_pc = get_pc(); | 1979 int32_t current_pc = get_pc(); |
| 1981 // Next pc | 1980 // Next pc |
| 1982 int32_t next_pc = 0; | 1981 int32_t next_pc = 0; |
| 1983 int32_t return_addr_reg = 31; | 1982 int32_t return_addr_reg = 31; |
| 1984 | 1983 |
| 1985 // Set up the variables if needed before executing the instruction. | 1984 // Set up the variables if needed before executing the instruction. |
| 1986 ConfigureTypeRegister(instr, | 1985 ConfigureTypeRegister(instr, |
| 1987 alu_out, | 1986 &alu_out, |
| 1988 i64hilo, | 1987 &i64hilo, |
| 1989 u64hilo, | 1988 &u64hilo, |
| 1990 next_pc, | 1989 &next_pc, |
| 1991 return_addr_reg, | 1990 &return_addr_reg, |
| 1992 do_interrupt); | 1991 &do_interrupt); |
| 1993 | 1992 |
| 1994 // ---------- Raise exceptions triggered. | 1993 // ---------- Raise exceptions triggered. |
| 1995 SignalExceptions(); | 1994 SignalExceptions(); |
| 1996 | 1995 |
| 1997 // ---------- Execution. | 1996 // ---------- Execution. |
| 1998 switch (op) { | 1997 switch (op) { |
| 1999 case COP1: | 1998 case COP1: |
| 2000 switch (instr->RsFieldRaw()) { | 1999 switch (instr->RsFieldRaw()) { |
| 2001 case BC1: // Branch on coprocessor condition. | 2000 case BC1: // Branch on coprocessor condition. |
| 2002 UNREACHABLE(); | 2001 UNREACHABLE(); |
| (...skipping 916 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2919 } | 2918 } |
| 2920 | 2919 |
| 2921 | 2920 |
| 2922 #undef UNSUPPORTED | 2921 #undef UNSUPPORTED |
| 2923 | 2922 |
| 2924 } } // namespace v8::internal | 2923 } } // namespace v8::internal |
| 2925 | 2924 |
| 2926 #endif // USE_SIMULATOR | 2925 #endif // USE_SIMULATOR |
| 2927 | 2926 |
| 2928 #endif // V8_TARGET_ARCH_MIPS | 2927 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |