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

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

Issue 1131573006: ARM64: Enable shorten-64-to-32 warning (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 7 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/arm64/simulator-arm64.h ('k') | src/arm64/utils-arm64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/arm64/simulator-arm64.h ('k') | src/arm64/utils-arm64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698