OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 <stdlib.h> | 5 #include <stdlib.h> |
6 #include <cmath> | 6 #include <cmath> |
7 #include <cstdarg> | 7 #include <cstdarg> |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #if V8_TARGET_ARCH_ARM64 | 10 #if V8_TARGET_ARCH_ARM64 |
(...skipping 885 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
896 return value; | 896 return value; |
897 } | 897 } |
898 | 898 |
899 switch (shift_type) { | 899 switch (shift_type) { |
900 case LSL: | 900 case LSL: |
901 return value << amount; | 901 return value << amount; |
902 case LSR: | 902 case LSR: |
903 return static_cast<unsignedT>(value) >> amount; | 903 return static_cast<unsignedT>(value) >> amount; |
904 case ASR: | 904 case ASR: |
905 return value >> amount; | 905 return value >> amount; |
906 case ROR: | 906 case ROR: { |
| 907 unsignedT mask = (static_cast<unsignedT>(1) << amount) - 1; |
907 return (static_cast<unsignedT>(value) >> amount) | | 908 return (static_cast<unsignedT>(value) >> amount) | |
908 ((value & ((1L << amount) - 1L)) << | 909 ((value & mask) << (sizeof(mask) * 8 - amount)); |
909 (sizeof(unsignedT) * 8 - amount)); | 910 } |
910 default: | 911 default: |
911 UNIMPLEMENTED(); | 912 UNIMPLEMENTED(); |
912 return 0; | 913 return 0; |
913 } | 914 } |
914 } | 915 } |
915 | 916 |
916 | 917 |
917 template <typename T> | 918 template <typename T> |
918 T Simulator::ExtendValue(T value, Extend extend_type, unsigned left_shift) { | 919 T Simulator::ExtendValue(T value, Extend extend_type, unsigned left_shift) { |
919 const unsigned kSignExtendBShift = (sizeof(T) - 1) * 8; | 920 const unsigned kSignExtendBShift = (sizeof(T) - 1) * 8; |
(...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1392 | 1393 |
1393 | 1394 |
1394 void Simulator::VisitAddSubShifted(Instruction* instr) { | 1395 void Simulator::VisitAddSubShifted(Instruction* instr) { |
1395 Shift shift_type = static_cast<Shift>(instr->ShiftDP()); | 1396 Shift shift_type = static_cast<Shift>(instr->ShiftDP()); |
1396 unsigned shift_amount = instr->ImmDPShift(); | 1397 unsigned shift_amount = instr->ImmDPShift(); |
1397 | 1398 |
1398 if (instr->SixtyFourBits()) { | 1399 if (instr->SixtyFourBits()) { |
1399 int64_t op2 = ShiftOperand(xreg(instr->Rm()), shift_type, shift_amount); | 1400 int64_t op2 = ShiftOperand(xreg(instr->Rm()), shift_type, shift_amount); |
1400 AddSubHelper(instr, op2); | 1401 AddSubHelper(instr, op2); |
1401 } else { | 1402 } else { |
1402 int32_t op2 = ShiftOperand(wreg(instr->Rm()), shift_type, shift_amount); | 1403 int32_t op2 = static_cast<int32_t>( |
| 1404 ShiftOperand(wreg(instr->Rm()), shift_type, shift_amount)); |
1403 AddSubHelper(instr, op2); | 1405 AddSubHelper(instr, op2); |
1404 } | 1406 } |
1405 } | 1407 } |
1406 | 1408 |
1407 | 1409 |
1408 void Simulator::VisitAddSubImmediate(Instruction* instr) { | 1410 void Simulator::VisitAddSubImmediate(Instruction* instr) { |
1409 int64_t op2 = instr->ImmAddSub() << ((instr->ShiftAddSub() == 1) ? 12 : 0); | 1411 int64_t op2 = instr->ImmAddSub() << ((instr->ShiftAddSub() == 1) ? 12 : 0); |
1410 if (instr->SixtyFourBits()) { | 1412 if (instr->SixtyFourBits()) { |
1411 AddSubHelper<int64_t>(instr, op2); | 1413 AddSubHelper<int64_t>(instr, op2); |
1412 } else { | 1414 } else { |
1413 AddSubHelper<int32_t>(instr, op2); | 1415 AddSubHelper<int32_t>(instr, static_cast<int32_t>(op2)); |
1414 } | 1416 } |
1415 } | 1417 } |
1416 | 1418 |
1417 | 1419 |
1418 void Simulator::VisitAddSubExtended(Instruction* instr) { | 1420 void Simulator::VisitAddSubExtended(Instruction* instr) { |
1419 Extend ext = static_cast<Extend>(instr->ExtendMode()); | 1421 Extend ext = static_cast<Extend>(instr->ExtendMode()); |
1420 unsigned left_shift = instr->ImmExtendShift(); | 1422 unsigned left_shift = instr->ImmExtendShift(); |
1421 if (instr->SixtyFourBits()) { | 1423 if (instr->SixtyFourBits()) { |
1422 int64_t op2 = ExtendValue(xreg(instr->Rm()), ext, left_shift); | 1424 int64_t op2 = ExtendValue(xreg(instr->Rm()), ext, left_shift); |
1423 AddSubHelper(instr, op2); | 1425 AddSubHelper(instr, op2); |
(...skipping 26 matching lines...) Expand all Loading... |
1450 op2 = (instr->Mask(NOT) == NOT) ? ~op2 : op2; | 1452 op2 = (instr->Mask(NOT) == NOT) ? ~op2 : op2; |
1451 LogicalHelper<int32_t>(instr, op2); | 1453 LogicalHelper<int32_t>(instr, op2); |
1452 } | 1454 } |
1453 } | 1455 } |
1454 | 1456 |
1455 | 1457 |
1456 void Simulator::VisitLogicalImmediate(Instruction* instr) { | 1458 void Simulator::VisitLogicalImmediate(Instruction* instr) { |
1457 if (instr->SixtyFourBits()) { | 1459 if (instr->SixtyFourBits()) { |
1458 LogicalHelper<int64_t>(instr, instr->ImmLogical()); | 1460 LogicalHelper<int64_t>(instr, instr->ImmLogical()); |
1459 } else { | 1461 } else { |
1460 LogicalHelper<int32_t>(instr, instr->ImmLogical()); | 1462 LogicalHelper<int32_t>(instr, static_cast<int32_t>(instr->ImmLogical())); |
1461 } | 1463 } |
1462 } | 1464 } |
1463 | 1465 |
1464 | 1466 |
1465 template<typename T> | 1467 template<typename T> |
1466 void Simulator::LogicalHelper(Instruction* instr, T op2) { | 1468 void Simulator::LogicalHelper(Instruction* instr, T op2) { |
1467 T op1 = reg<T>(instr->Rn()); | 1469 T op1 = reg<T>(instr->Rn()); |
1468 T result = 0; | 1470 T result = 0; |
1469 bool update_flags = false; | 1471 bool update_flags = false; |
1470 | 1472 |
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1872 MoveWideImmediateOp mov_op = | 1874 MoveWideImmediateOp mov_op = |
1873 static_cast<MoveWideImmediateOp>(instr->Mask(MoveWideImmediateMask)); | 1875 static_cast<MoveWideImmediateOp>(instr->Mask(MoveWideImmediateMask)); |
1874 int64_t new_xn_val = 0; | 1876 int64_t new_xn_val = 0; |
1875 | 1877 |
1876 bool is_64_bits = instr->SixtyFourBits() == 1; | 1878 bool is_64_bits = instr->SixtyFourBits() == 1; |
1877 // Shift is limited for W operations. | 1879 // Shift is limited for W operations. |
1878 DCHECK(is_64_bits || (instr->ShiftMoveWide() < 2)); | 1880 DCHECK(is_64_bits || (instr->ShiftMoveWide() < 2)); |
1879 | 1881 |
1880 // Get the shifted immediate. | 1882 // Get the shifted immediate. |
1881 int64_t shift = instr->ShiftMoveWide() * 16; | 1883 int64_t shift = instr->ShiftMoveWide() * 16; |
1882 int64_t shifted_imm16 = instr->ImmMoveWide() << shift; | 1884 int64_t shifted_imm16 = static_cast<int64_t>(instr->ImmMoveWide()) << shift; |
1883 | 1885 |
1884 // Compute the new value. | 1886 // Compute the new value. |
1885 switch (mov_op) { | 1887 switch (mov_op) { |
1886 case MOVN_w: | 1888 case MOVN_w: |
1887 case MOVN_x: { | 1889 case MOVN_x: { |
1888 new_xn_val = ~shifted_imm16; | 1890 new_xn_val = ~shifted_imm16; |
1889 if (!is_64_bits) new_xn_val &= kWRegMask; | 1891 if (!is_64_bits) new_xn_val &= kWRegMask; |
1890 break; | 1892 break; |
1891 } | 1893 } |
1892 case MOVK_w: | 1894 case MOVK_w: |
(...skipping 12 matching lines...) Expand all Loading... |
1905 default: | 1907 default: |
1906 UNREACHABLE(); | 1908 UNREACHABLE(); |
1907 } | 1909 } |
1908 | 1910 |
1909 // Update the destination register. | 1911 // Update the destination register. |
1910 set_xreg(instr->Rd(), new_xn_val); | 1912 set_xreg(instr->Rd(), new_xn_val); |
1911 } | 1913 } |
1912 | 1914 |
1913 | 1915 |
1914 void Simulator::VisitConditionalSelect(Instruction* instr) { | 1916 void Simulator::VisitConditionalSelect(Instruction* instr) { |
| 1917 uint64_t new_val = xreg(instr->Rn()); |
1915 if (ConditionFailed(static_cast<Condition>(instr->Condition()))) { | 1918 if (ConditionFailed(static_cast<Condition>(instr->Condition()))) { |
1916 uint64_t new_val = xreg(instr->Rm()); | 1919 new_val = xreg(instr->Rm()); |
1917 switch (instr->Mask(ConditionalSelectMask)) { | 1920 switch (instr->Mask(ConditionalSelectMask)) { |
1918 case CSEL_w: set_wreg(instr->Rd(), new_val); break; | 1921 case CSEL_w: |
1919 case CSEL_x: set_xreg(instr->Rd(), new_val); break; | 1922 case CSEL_x: |
1920 case CSINC_w: set_wreg(instr->Rd(), new_val + 1); break; | 1923 break; |
1921 case CSINC_x: set_xreg(instr->Rd(), new_val + 1); break; | 1924 case CSINC_w: |
1922 case CSINV_w: set_wreg(instr->Rd(), ~new_val); break; | 1925 case CSINC_x: |
1923 case CSINV_x: set_xreg(instr->Rd(), ~new_val); break; | 1926 new_val++; |
1924 case CSNEG_w: set_wreg(instr->Rd(), -new_val); break; | 1927 break; |
1925 case CSNEG_x: set_xreg(instr->Rd(), -new_val); break; | 1928 case CSINV_w: |
| 1929 case CSINV_x: |
| 1930 new_val = ~new_val; |
| 1931 break; |
| 1932 case CSNEG_w: |
| 1933 case CSNEG_x: |
| 1934 new_val = -new_val; |
| 1935 break; |
1926 default: UNIMPLEMENTED(); | 1936 default: UNIMPLEMENTED(); |
1927 } | 1937 } |
| 1938 } |
| 1939 if (instr->SixtyFourBits()) { |
| 1940 set_xreg(instr->Rd(), new_val); |
1928 } else { | 1941 } else { |
1929 if (instr->SixtyFourBits()) { | 1942 set_wreg(instr->Rd(), static_cast<uint32_t>(new_val)); |
1930 set_xreg(instr->Rd(), xreg(instr->Rn())); | |
1931 } else { | |
1932 set_wreg(instr->Rd(), wreg(instr->Rn())); | |
1933 } | |
1934 } | 1943 } |
1935 } | 1944 } |
1936 | 1945 |
1937 | 1946 |
1938 void Simulator::VisitDataProcessing1Source(Instruction* instr) { | 1947 void Simulator::VisitDataProcessing1Source(Instruction* instr) { |
1939 unsigned dst = instr->Rd(); | 1948 unsigned dst = instr->Rd(); |
1940 unsigned src = instr->Rn(); | 1949 unsigned src = instr->Rn(); |
1941 | 1950 |
1942 switch (instr->Mask(DataProcessing1SourceMask)) { | 1951 switch (instr->Mask(DataProcessing1SourceMask)) { |
1943 case RBIT_w: set_wreg(dst, ReverseBits(wreg(src), kWRegSizeInBits)); break; | 1952 case RBIT_w: |
1944 case RBIT_x: set_xreg(dst, ReverseBits(xreg(src), kXRegSizeInBits)); break; | 1953 set_wreg(dst, ReverseBits(wreg(src))); |
1945 case REV16_w: set_wreg(dst, ReverseBytes(wreg(src), Reverse16)); break; | 1954 break; |
1946 case REV16_x: set_xreg(dst, ReverseBytes(xreg(src), Reverse16)); break; | 1955 case RBIT_x: |
1947 case REV_w: set_wreg(dst, ReverseBytes(wreg(src), Reverse32)); break; | 1956 set_xreg(dst, ReverseBits(xreg(src))); |
1948 case REV32_x: set_xreg(dst, ReverseBytes(xreg(src), Reverse32)); break; | 1957 break; |
1949 case REV_x: set_xreg(dst, ReverseBytes(xreg(src), Reverse64)); break; | 1958 case REV16_w: |
| 1959 set_wreg(dst, ReverseBytes(wreg(src), 1)); |
| 1960 break; |
| 1961 case REV16_x: |
| 1962 set_xreg(dst, ReverseBytes(xreg(src), 1)); |
| 1963 break; |
| 1964 case REV_w: |
| 1965 set_wreg(dst, ReverseBytes(wreg(src), 2)); |
| 1966 break; |
| 1967 case REV32_x: |
| 1968 set_xreg(dst, ReverseBytes(xreg(src), 2)); |
| 1969 break; |
| 1970 case REV_x: |
| 1971 set_xreg(dst, ReverseBytes(xreg(src), 3)); |
| 1972 break; |
1950 case CLZ_w: set_wreg(dst, CountLeadingZeros(wreg(src), kWRegSizeInBits)); | 1973 case CLZ_w: set_wreg(dst, CountLeadingZeros(wreg(src), kWRegSizeInBits)); |
1951 break; | 1974 break; |
1952 case CLZ_x: set_xreg(dst, CountLeadingZeros(xreg(src), kXRegSizeInBits)); | 1975 case CLZ_x: set_xreg(dst, CountLeadingZeros(xreg(src), kXRegSizeInBits)); |
1953 break; | 1976 break; |
1954 case CLS_w: { | 1977 case CLS_w: { |
1955 set_wreg(dst, CountLeadingSignBits(wreg(src), kWRegSizeInBits)); | 1978 set_wreg(dst, CountLeadingSignBits(wreg(src), kWRegSizeInBits)); |
1956 break; | 1979 break; |
1957 } | 1980 } |
1958 case CLS_x: { | 1981 case CLS_x: { |
1959 set_xreg(dst, CountLeadingSignBits(xreg(src), kXRegSizeInBits)); | 1982 set_xreg(dst, CountLeadingSignBits(xreg(src), kXRegSizeInBits)); |
1960 break; | 1983 break; |
1961 } | 1984 } |
1962 default: UNIMPLEMENTED(); | 1985 default: UNIMPLEMENTED(); |
1963 } | 1986 } |
1964 } | 1987 } |
1965 | 1988 |
1966 | 1989 |
1967 uint64_t Simulator::ReverseBits(uint64_t value, unsigned num_bits) { | |
1968 DCHECK((num_bits == kWRegSizeInBits) || (num_bits == kXRegSizeInBits)); | |
1969 uint64_t result = 0; | |
1970 for (unsigned i = 0; i < num_bits; i++) { | |
1971 result = (result << 1) | (value & 1); | |
1972 value >>= 1; | |
1973 } | |
1974 return result; | |
1975 } | |
1976 | |
1977 | |
1978 uint64_t Simulator::ReverseBytes(uint64_t value, ReverseByteMode mode) { | |
1979 // Split the 64-bit value into an 8-bit array, where b[0] is the least | |
1980 // significant byte, and b[7] is the most significant. | |
1981 uint8_t bytes[8]; | |
1982 uint64_t mask = 0xff00000000000000UL; | |
1983 for (int i = 7; i >= 0; i--) { | |
1984 bytes[i] = (value & mask) >> (i * 8); | |
1985 mask >>= 8; | |
1986 } | |
1987 | |
1988 // Permutation tables for REV instructions. | |
1989 // permute_table[Reverse16] is used by REV16_x, REV16_w | |
1990 // permute_table[Reverse32] is used by REV32_x, REV_w | |
1991 // permute_table[Reverse64] is used by REV_x | |
1992 DCHECK((Reverse16 == 0) && (Reverse32 == 1) && (Reverse64 == 2)); | |
1993 static const uint8_t permute_table[3][8] = { {6, 7, 4, 5, 2, 3, 0, 1}, | |
1994 {4, 5, 6, 7, 0, 1, 2, 3}, | |
1995 {0, 1, 2, 3, 4, 5, 6, 7} }; | |
1996 uint64_t result = 0; | |
1997 for (int i = 0; i < 8; i++) { | |
1998 result <<= 8; | |
1999 result |= bytes[permute_table[mode][i]]; | |
2000 } | |
2001 return result; | |
2002 } | |
2003 | |
2004 | |
2005 template <typename T> | 1990 template <typename T> |
2006 void Simulator::DataProcessing2Source(Instruction* instr) { | 1991 void Simulator::DataProcessing2Source(Instruction* instr) { |
2007 Shift shift_op = NO_SHIFT; | 1992 Shift shift_op = NO_SHIFT; |
2008 T result = 0; | 1993 T result = 0; |
2009 switch (instr->Mask(DataProcessing2SourceMask)) { | 1994 switch (instr->Mask(DataProcessing2SourceMask)) { |
2010 case SDIV_w: | 1995 case SDIV_w: |
2011 case SDIV_x: { | 1996 case SDIV_x: { |
2012 T rn = reg<T>(instr->Rn()); | 1997 T rn = reg<T>(instr->Rn()); |
2013 T rm = reg<T>(instr->Rm()); | 1998 T rm = reg<T>(instr->Rm()); |
2014 if ((rn == std::numeric_limits<T>::min()) && (rm == -1)) { | 1999 if ((rn == std::numeric_limits<T>::min()) && (rm == -1)) { |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2114 case SMULH_x: | 2099 case SMULH_x: |
2115 DCHECK(instr->Ra() == kZeroRegCode); | 2100 DCHECK(instr->Ra() == kZeroRegCode); |
2116 result = MultiplyHighSigned(xreg(instr->Rn()), xreg(instr->Rm())); | 2101 result = MultiplyHighSigned(xreg(instr->Rn()), xreg(instr->Rm())); |
2117 break; | 2102 break; |
2118 default: UNIMPLEMENTED(); | 2103 default: UNIMPLEMENTED(); |
2119 } | 2104 } |
2120 | 2105 |
2121 if (instr->SixtyFourBits()) { | 2106 if (instr->SixtyFourBits()) { |
2122 set_xreg(instr->Rd(), result); | 2107 set_xreg(instr->Rd(), result); |
2123 } else { | 2108 } else { |
2124 set_wreg(instr->Rd(), result); | 2109 set_wreg(instr->Rd(), static_cast<int32_t>(result)); |
2125 } | 2110 } |
2126 } | 2111 } |
2127 | 2112 |
2128 | 2113 |
2129 template <typename T> | 2114 template <typename T> |
2130 void Simulator::BitfieldHelper(Instruction* instr) { | 2115 void Simulator::BitfieldHelper(Instruction* instr) { |
2131 typedef typename make_unsigned<T>::type unsignedT; | 2116 typedef typename make_unsigned<T>::type unsignedT; |
2132 T reg_size = sizeof(T) * 8; | 2117 T reg_size = sizeof(T) * 8; |
2133 T R = instr->ImmR(); | 2118 T R = instr->ImmR(); |
2134 T S = instr->ImmS(); | 2119 T S = instr->ImmS(); |
2135 T diff = S - R; | 2120 T diff = S - R; |
2136 T mask; | 2121 T mask; |
2137 if (diff >= 0) { | 2122 if (diff >= 0) { |
2138 mask = diff < reg_size - 1 ? (static_cast<T>(1) << (diff + 1)) - 1 | 2123 mask = diff < reg_size - 1 ? (static_cast<T>(1) << (diff + 1)) - 1 |
2139 : static_cast<T>(-1); | 2124 : static_cast<T>(-1); |
2140 } else { | 2125 } else { |
2141 mask = ((1L << (S + 1)) - 1); | 2126 uint64_t umask = ((1L << (S + 1)) - 1); |
2142 mask = (static_cast<uint64_t>(mask) >> R) | (mask << (reg_size - R)); | 2127 umask = (umask >> R) | (umask << (reg_size - R)); |
| 2128 mask = static_cast<T>(umask); |
2143 diff += reg_size; | 2129 diff += reg_size; |
2144 } | 2130 } |
2145 | 2131 |
2146 // inzero indicates if the extracted bitfield is inserted into the | 2132 // inzero indicates if the extracted bitfield is inserted into the |
2147 // destination register value or in zero. | 2133 // destination register value or in zero. |
2148 // If extend is true, extend the sign of the extracted bitfield. | 2134 // If extend is true, extend the sign of the extracted bitfield. |
2149 bool inzero = false; | 2135 bool inzero = false; |
2150 bool extend = false; | 2136 bool extend = false; |
2151 switch (instr->Mask(BitfieldMask)) { | 2137 switch (instr->Mask(BitfieldMask)) { |
2152 case BFM_x: | 2138 case BFM_x: |
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2556 // | 2542 // |
2557 // mantissa = (mantissa >> shift) + halfbit(adjusted); | 2543 // mantissa = (mantissa >> shift) + halfbit(adjusted); |
2558 | 2544 |
2559 static const int mantissa_offset = 0; | 2545 static const int mantissa_offset = 0; |
2560 static const int exponent_offset = mantissa_offset + mbits; | 2546 static const int exponent_offset = mantissa_offset + mbits; |
2561 static const int sign_offset = exponent_offset + ebits; | 2547 static const int sign_offset = exponent_offset + ebits; |
2562 STATIC_ASSERT(sign_offset == (sizeof(T) * kByteSize - 1)); | 2548 STATIC_ASSERT(sign_offset == (sizeof(T) * kByteSize - 1)); |
2563 | 2549 |
2564 // Bail out early for zero inputs. | 2550 // Bail out early for zero inputs. |
2565 if (mantissa == 0) { | 2551 if (mantissa == 0) { |
2566 return sign << sign_offset; | 2552 return static_cast<T>(sign << sign_offset); |
2567 } | 2553 } |
2568 | 2554 |
2569 // If all bits in the exponent are set, the value is infinite or NaN. | 2555 // If all bits in the exponent are set, the value is infinite or NaN. |
2570 // This is true for all binary IEEE-754 formats. | 2556 // This is true for all binary IEEE-754 formats. |
2571 static const int infinite_exponent = (1 << ebits) - 1; | 2557 static const int infinite_exponent = (1 << ebits) - 1; |
2572 static const int max_normal_exponent = infinite_exponent - 1; | 2558 static const int max_normal_exponent = infinite_exponent - 1; |
2573 | 2559 |
2574 // Apply the exponent bias to encode it for the result. Doing this early makes | 2560 // Apply the exponent bias to encode it for the result. Doing this early makes |
2575 // it easy to detect values that will be infinite or subnormal. | 2561 // it easy to detect values that will be infinite or subnormal. |
2576 exponent += max_normal_exponent >> 1; | 2562 exponent += max_normal_exponent >> 1; |
2577 | 2563 |
2578 if (exponent > max_normal_exponent) { | 2564 if (exponent > max_normal_exponent) { |
2579 // Overflow: The input is too large for the result type to represent. The | 2565 // Overflow: The input is too large for the result type to represent. The |
2580 // FPTieEven rounding mode handles overflows using infinities. | 2566 // FPTieEven rounding mode handles overflows using infinities. |
2581 exponent = infinite_exponent; | 2567 exponent = infinite_exponent; |
2582 mantissa = 0; | 2568 mantissa = 0; |
2583 return (sign << sign_offset) | | 2569 return static_cast<T>((sign << sign_offset) | |
2584 (exponent << exponent_offset) | | 2570 (exponent << exponent_offset) | |
2585 (mantissa << mantissa_offset); | 2571 (mantissa << mantissa_offset)); |
2586 } | 2572 } |
2587 | 2573 |
2588 // Calculate the shift required to move the top mantissa bit to the proper | 2574 // Calculate the shift required to move the top mantissa bit to the proper |
2589 // place in the destination type. | 2575 // place in the destination type. |
2590 const int highest_significant_bit = 63 - CountLeadingZeros(mantissa, 64); | 2576 const int highest_significant_bit = 63 - CountLeadingZeros(mantissa, 64); |
2591 int shift = highest_significant_bit - mbits; | 2577 int shift = highest_significant_bit - mbits; |
2592 | 2578 |
2593 if (exponent <= 0) { | 2579 if (exponent <= 0) { |
2594 // The output will be subnormal (before rounding). | 2580 // The output will be subnormal (before rounding). |
2595 | 2581 |
2596 // For subnormal outputs, the shift must be adjusted by the exponent. The +1 | 2582 // For subnormal outputs, the shift must be adjusted by the exponent. The +1 |
2597 // is necessary because the exponent of a subnormal value (encoded as 0) is | 2583 // is necessary because the exponent of a subnormal value (encoded as 0) is |
2598 // the same as the exponent of the smallest normal value (encoded as 1). | 2584 // the same as the exponent of the smallest normal value (encoded as 1). |
2599 shift += -exponent + 1; | 2585 shift += -exponent + 1; |
2600 | 2586 |
2601 // Handle inputs that would produce a zero output. | 2587 // Handle inputs that would produce a zero output. |
2602 // | 2588 // |
2603 // Shifts higher than highest_significant_bit+1 will always produce a zero | 2589 // Shifts higher than highest_significant_bit+1 will always produce a zero |
2604 // result. A shift of exactly highest_significant_bit+1 might produce a | 2590 // result. A shift of exactly highest_significant_bit+1 might produce a |
2605 // non-zero result after rounding. | 2591 // non-zero result after rounding. |
2606 if (shift > (highest_significant_bit + 1)) { | 2592 if (shift > (highest_significant_bit + 1)) { |
2607 // The result will always be +/-0.0. | 2593 // The result will always be +/-0.0. |
2608 return sign << sign_offset; | 2594 return static_cast<T>(sign << sign_offset); |
2609 } | 2595 } |
2610 | 2596 |
2611 // Properly encode the exponent for a subnormal output. | 2597 // Properly encode the exponent for a subnormal output. |
2612 exponent = 0; | 2598 exponent = 0; |
2613 } else { | 2599 } else { |
2614 // Clear the topmost mantissa bit, since this is not encoded in IEEE-754 | 2600 // Clear the topmost mantissa bit, since this is not encoded in IEEE-754 |
2615 // normal values. | 2601 // normal values. |
2616 mantissa &= ~(1UL << highest_significant_bit); | 2602 mantissa &= ~(1UL << highest_significant_bit); |
2617 } | 2603 } |
2618 | 2604 |
2619 if (shift > 0) { | 2605 if (shift > 0) { |
2620 // We have to shift the mantissa to the right. Some precision is lost, so we | 2606 // We have to shift the mantissa to the right. Some precision is lost, so we |
2621 // need to apply rounding. | 2607 // need to apply rounding. |
2622 uint64_t onebit_mantissa = (mantissa >> (shift)) & 1; | 2608 uint64_t onebit_mantissa = (mantissa >> (shift)) & 1; |
2623 uint64_t halfbit_mantissa = (mantissa >> (shift-1)) & 1; | 2609 uint64_t halfbit_mantissa = (mantissa >> (shift-1)) & 1; |
2624 uint64_t adjusted = mantissa - (halfbit_mantissa & ~onebit_mantissa); | 2610 uint64_t adjusted = mantissa - (halfbit_mantissa & ~onebit_mantissa); |
2625 T halfbit_adjusted = (adjusted >> (shift-1)) & 1; | 2611 T halfbit_adjusted = (adjusted >> (shift-1)) & 1; |
2626 | 2612 |
2627 T result = (sign << sign_offset) | | 2613 T result = |
2628 (exponent << exponent_offset) | | 2614 static_cast<T>((sign << sign_offset) | (exponent << exponent_offset) | |
2629 ((mantissa >> shift) << mantissa_offset); | 2615 ((mantissa >> shift) << mantissa_offset)); |
2630 | 2616 |
2631 // A very large mantissa can overflow during rounding. If this happens, the | 2617 // A very large mantissa can overflow during rounding. If this happens, the |
2632 // exponent should be incremented and the mantissa set to 1.0 (encoded as | 2618 // exponent should be incremented and the mantissa set to 1.0 (encoded as |
2633 // 0). Applying halfbit_adjusted after assembling the float has the nice | 2619 // 0). Applying halfbit_adjusted after assembling the float has the nice |
2634 // side-effect that this case is handled for free. | 2620 // side-effect that this case is handled for free. |
2635 // | 2621 // |
2636 // This also handles cases where a very large finite value overflows to | 2622 // This also handles cases where a very large finite value overflows to |
2637 // infinity, or where a very large subnormal value overflows to become | 2623 // infinity, or where a very large subnormal value overflows to become |
2638 // normal. | 2624 // normal. |
2639 return result + halfbit_adjusted; | 2625 return result + halfbit_adjusted; |
2640 } else { | 2626 } else { |
2641 // We have to shift the mantissa to the left (or not at all). The input | 2627 // We have to shift the mantissa to the left (or not at all). The input |
2642 // mantissa is exactly representable in the output mantissa, so apply no | 2628 // mantissa is exactly representable in the output mantissa, so apply no |
2643 // rounding correction. | 2629 // rounding correction. |
2644 return (sign << sign_offset) | | 2630 return static_cast<T>((sign << sign_offset) | |
2645 (exponent << exponent_offset) | | 2631 (exponent << exponent_offset) | |
2646 ((mantissa << -shift) << mantissa_offset); | 2632 ((mantissa << -shift) << mantissa_offset)); |
2647 } | 2633 } |
2648 } | 2634 } |
2649 | 2635 |
2650 | 2636 |
2651 // See FPRound for a description of this function. | 2637 // See FPRound for a description of this function. |
2652 static inline double FPRoundToDouble(int64_t sign, int64_t exponent, | 2638 static inline double FPRoundToDouble(int64_t sign, int64_t exponent, |
2653 uint64_t mantissa, FPRounding round_mode) { | 2639 uint64_t mantissa, FPRounding round_mode) { |
2654 int64_t bits = | 2640 int64_t bits = |
2655 FPRound<int64_t, kDoubleExponentBits, kDoubleMantissaBits>(sign, | 2641 FPRound<int64_t, kDoubleExponentBits, kDoubleMantissaBits>(sign, |
2656 exponent, | 2642 exponent, |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2831 if (fpcr().DN()) return kFP32DefaultNaN; | 2817 if (fpcr().DN()) return kFP32DefaultNaN; |
2832 | 2818 |
2833 // Convert NaNs as the processor would: | 2819 // Convert NaNs as the processor would: |
2834 // - The sign is propagated. | 2820 // - The sign is propagated. |
2835 // - The payload (mantissa) is transferred as much as possible, except | 2821 // - The payload (mantissa) is transferred as much as possible, except |
2836 // that the top bit is forced to '1', making the result a quiet NaN. | 2822 // that the top bit is forced to '1', making the result a quiet NaN. |
2837 uint64_t raw = double_to_rawbits(value); | 2823 uint64_t raw = double_to_rawbits(value); |
2838 | 2824 |
2839 uint32_t sign = raw >> 63; | 2825 uint32_t sign = raw >> 63; |
2840 uint32_t exponent = (1 << 8) - 1; | 2826 uint32_t exponent = (1 << 8) - 1; |
2841 uint32_t payload = unsigned_bitextract_64(50, 52 - 23, raw); | 2827 uint32_t payload = |
| 2828 static_cast<uint32_t>(unsigned_bitextract_64(50, 52 - 23, raw)); |
2842 payload |= (1 << 22); // Force a quiet NaN. | 2829 payload |= (1 << 22); // Force a quiet NaN. |
2843 | 2830 |
2844 return rawbits_to_float((sign << 31) | (exponent << 23) | payload); | 2831 return rawbits_to_float((sign << 31) | (exponent << 23) | payload); |
2845 } | 2832 } |
2846 | 2833 |
2847 case FP_ZERO: | 2834 case FP_ZERO: |
2848 case FP_INFINITE: { | 2835 case FP_INFINITE: { |
2849 // In a C++ cast, any value representable in the target type will be | 2836 // In a C++ cast, any value representable in the target type will be |
2850 // unchanged. This is always the case for +/-0.0 and infinities. | 2837 // unchanged. This is always the case for +/-0.0 and infinities. |
2851 return static_cast<float>(value); | 2838 return static_cast<float>(value); |
2852 } | 2839 } |
2853 | 2840 |
2854 case FP_NORMAL: | 2841 case FP_NORMAL: |
2855 case FP_SUBNORMAL: { | 2842 case FP_SUBNORMAL: { |
2856 // Convert double-to-float as the processor would, assuming that FPCR.FZ | 2843 // Convert double-to-float as the processor would, assuming that FPCR.FZ |
2857 // (flush-to-zero) is not set. | 2844 // (flush-to-zero) is not set. |
2858 uint64_t raw = double_to_rawbits(value); | 2845 uint64_t raw = double_to_rawbits(value); |
2859 // Extract the IEEE-754 double components. | 2846 // Extract the IEEE-754 double components. |
2860 uint32_t sign = raw >> 63; | 2847 uint32_t sign = raw >> 63; |
2861 // Extract the exponent and remove the IEEE-754 encoding bias. | 2848 // Extract the exponent and remove the IEEE-754 encoding bias. |
2862 int32_t exponent = unsigned_bitextract_64(62, 52, raw) - 1023; | 2849 int32_t exponent = |
| 2850 static_cast<int32_t>(unsigned_bitextract_64(62, 52, raw)) - 1023; |
2863 // Extract the mantissa and add the implicit '1' bit. | 2851 // Extract the mantissa and add the implicit '1' bit. |
2864 uint64_t mantissa = unsigned_bitextract_64(51, 0, raw); | 2852 uint64_t mantissa = unsigned_bitextract_64(51, 0, raw); |
2865 if (std::fpclassify(value) == FP_NORMAL) { | 2853 if (std::fpclassify(value) == FP_NORMAL) { |
2866 mantissa |= (1UL << 52); | 2854 mantissa |= (1UL << 52); |
2867 } | 2855 } |
2868 return FPRoundToFloat(sign, exponent, mantissa, round_mode); | 2856 return FPRoundToFloat(sign, exponent, mantissa, round_mode); |
2869 } | 2857 } |
2870 } | 2858 } |
2871 | 2859 |
2872 UNREACHABLE(); | 2860 UNREACHABLE(); |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3203 switch (instr->ImmSystemRegister()) { | 3191 switch (instr->ImmSystemRegister()) { |
3204 case NZCV: set_xreg(instr->Rt(), nzcv().RawValue()); break; | 3192 case NZCV: set_xreg(instr->Rt(), nzcv().RawValue()); break; |
3205 case FPCR: set_xreg(instr->Rt(), fpcr().RawValue()); break; | 3193 case FPCR: set_xreg(instr->Rt(), fpcr().RawValue()); break; |
3206 default: UNIMPLEMENTED(); | 3194 default: UNIMPLEMENTED(); |
3207 } | 3195 } |
3208 break; | 3196 break; |
3209 } | 3197 } |
3210 case MSR: { | 3198 case MSR: { |
3211 switch (instr->ImmSystemRegister()) { | 3199 switch (instr->ImmSystemRegister()) { |
3212 case NZCV: | 3200 case NZCV: |
3213 nzcv().SetRawValue(xreg(instr->Rt())); | 3201 nzcv().SetRawValue(wreg(instr->Rt())); |
3214 LogSystemRegister(NZCV); | 3202 LogSystemRegister(NZCV); |
3215 break; | 3203 break; |
3216 case FPCR: | 3204 case FPCR: |
3217 fpcr().SetRawValue(xreg(instr->Rt())); | 3205 fpcr().SetRawValue(wreg(instr->Rt())); |
3218 LogSystemRegister(FPCR); | 3206 LogSystemRegister(FPCR); |
3219 break; | 3207 break; |
3220 default: UNIMPLEMENTED(); | 3208 default: UNIMPLEMENTED(); |
3221 } | 3209 } |
3222 break; | 3210 break; |
3223 } | 3211 } |
3224 } | 3212 } |
3225 } else if (instr->Mask(SystemHintFMask) == SystemHintFixed) { | 3213 } else if (instr->Mask(SystemHintFMask) == SystemHintFixed) { |
3226 DCHECK(instr->Mask(SystemHintMask) == HINT); | 3214 DCHECK(instr->Mask(SystemHintMask) == HINT); |
3227 switch (instr->ImmHint()) { | 3215 switch (instr->ImmHint()) { |
(...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3831 | 3819 |
3832 delete[] format; | 3820 delete[] format; |
3833 } | 3821 } |
3834 | 3822 |
3835 | 3823 |
3836 #endif // USE_SIMULATOR | 3824 #endif // USE_SIMULATOR |
3837 | 3825 |
3838 } } // namespace v8::internal | 3826 } } // namespace v8::internal |
3839 | 3827 |
3840 #endif // V8_TARGET_ARCH_ARM64 | 3828 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |