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 |