| 1 | /* |
| 2 | * Copyright (C) 2015-2016 Apple Inc. All rights reserved. |
| 3 | * |
| 4 | * Redistribution and use in source and binary forms, with or without |
| 5 | * modification, are permitted provided that the following conditions |
| 6 | * are met: |
| 7 | * 1. Redistributions of source code must retain the above copyright |
| 8 | * notice, this list of conditions and the following disclaimer. |
| 9 | * 2. Redistributions in binary form must reproduce the above copyright |
| 10 | * notice, this list of conditions and the following disclaimer in the |
| 11 | * documentation and/or other materials provided with the distribution. |
| 12 | * |
| 13 | * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY |
| 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 15 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| 16 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR |
| 17 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| 18 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| 19 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| 20 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| 21 | * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 23 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 24 | */ |
| 25 | |
| 26 | #pragma once |
| 27 | |
| 28 | #include <cmath> |
| 29 | #include <wtf/Optional.h> |
| 30 | |
| 31 | namespace JSC { |
| 32 | |
| 33 | const int32_t maxExponentForIntegerMathPow = 1000; |
| 34 | double JIT_OPERATION operationMathPow(double x, double y) WTF_INTERNAL; |
| 35 | int32_t JIT_OPERATION operationToInt32(double) WTF_INTERNAL; |
| 36 | int32_t JIT_OPERATION operationToInt32SensibleSlow(double) WTF_INTERNAL; |
| 37 | |
| 38 | constexpr double maxSafeInteger() |
| 39 | { |
| 40 | // 2 ^ 53 - 1 |
| 41 | return 9007199254740991.0; |
| 42 | } |
| 43 | |
| 44 | constexpr double minSafeInteger() |
| 45 | { |
| 46 | // -(2 ^ 53 - 1) |
| 47 | return -9007199254740991.0; |
| 48 | } |
| 49 | |
| 50 | // This in the ToInt32 operation is defined in section 9.5 of the ECMA-262 spec. |
| 51 | // Note that this operation is identical to ToUInt32 other than to interpretation |
| 52 | // of the resulting bit-pattern (as such this method is also called to implement |
| 53 | // ToUInt32). |
| 54 | // |
| 55 | // The operation can be described as round towards zero, then select the 32 least |
| 56 | // bits of the resulting value in 2s-complement representation. |
| 57 | enum ToInt32Mode { |
| 58 | Generic, |
| 59 | AfterSensibleConversionAttempt, |
| 60 | }; |
| 61 | template<ToInt32Mode Mode> |
| 62 | ALWAYS_INLINE int32_t toInt32Internal(double number) |
| 63 | { |
| 64 | uint64_t bits = WTF::bitwise_cast<uint64_t>(number); |
| 65 | int32_t exp = (static_cast<int32_t>(bits >> 52) & 0x7ff) - 0x3ff; |
| 66 | |
| 67 | // If exponent < 0 there will be no bits to the left of the decimal point |
| 68 | // after rounding; if the exponent is > 83 then no bits of precision can be |
| 69 | // left in the low 32-bit range of the result (IEEE-754 doubles have 52 bits |
| 70 | // of fractional precision). |
| 71 | // Note this case handles 0, -0, and all infinite, NaN, & denormal value. |
| 72 | |
| 73 | // We need to check exp > 83 because: |
| 74 | // 1. exp may be used as a left shift value below in (exp - 52), and |
| 75 | // 2. Left shift amounts that exceed 31 results in undefined behavior. See: |
| 76 | // http://en.cppreference.com/w/cpp/language/operator_arithmetic#Bitwise_shift_operators |
| 77 | // |
| 78 | // Using an unsigned comparison here also gives us a exp < 0 check for free. |
| 79 | if (static_cast<uint32_t>(exp) > 83u) |
| 80 | return 0; |
| 81 | |
| 82 | // Select the appropriate 32-bits from the floating point mantissa. If the |
| 83 | // exponent is 52 then the bits we need to select are already aligned to the |
| 84 | // lowest bits of the 64-bit integer representation of the number, no need |
| 85 | // to shift. If the exponent is greater than 52 we need to shift the value |
| 86 | // left by (exp - 52), if the value is less than 52 we need to shift right |
| 87 | // accordingly. |
| 88 | uint32_t result = (exp > 52) |
| 89 | ? static_cast<uint32_t>(bits << (exp - 52)) |
| 90 | : static_cast<uint32_t>(bits >> (52 - exp)); |
| 91 | |
| 92 | // IEEE-754 double precision values are stored omitting an implicit 1 before |
| 93 | // the decimal point; we need to reinsert this now. We may also the shifted |
| 94 | // invalid bits into the result that are not a part of the mantissa (the sign |
| 95 | // and exponent bits from the floatingpoint representation); mask these out. |
| 96 | // Note that missingOne should be held as uint32_t since ((1 << 31) - 1) causes |
| 97 | // int32_t overflow. |
| 98 | if (Mode == ToInt32Mode::AfterSensibleConversionAttempt) { |
| 99 | if (exp == 31) { |
| 100 | // This is an optimization for when toInt32() is called in the slow path |
| 101 | // of a JIT operation. Currently, this optimization is only applicable for |
| 102 | // x86 ports. This optimization offers 5% performance improvement in |
| 103 | // kraken-crypto-pbkdf2. |
| 104 | // |
| 105 | // On x86, the fast path does a sensible double-to-int32 conversion, by |
| 106 | // first attempting to truncate the double value to int32 using the |
| 107 | // cvttsd2si_rr instruction. According to Intel's manual, cvttsd2si performs |
| 108 | // the following truncate operation: |
| 109 | // |
| 110 | // If src = NaN, +-Inf, or |(src)rz| > 0x7fffffff and (src)rz != 0x80000000, |
| 111 | // then the result becomes 0x80000000. Otherwise, the operation succeeds. |
| 112 | // |
| 113 | // Note that the ()rz notation means rounding towards zero. |
| 114 | // We'll call the slow case function only when the above cvttsd2si fails. The |
| 115 | // JIT code checks for fast path failure by checking if result == 0x80000000. |
| 116 | // Hence, the slow path will only see the following possible set of numbers: |
| 117 | // |
| 118 | // NaN, +-Inf, or |(src)rz| > 0x7fffffff. |
| 119 | // |
| 120 | // As a result, the exp of the double is always >= 31. We can take advantage |
| 121 | // of this by specifically checking for (exp == 31) and give the compiler a |
| 122 | // chance to constant fold the operations below. |
| 123 | const constexpr uint32_t missingOne = 1U << 31; |
| 124 | result &= missingOne - 1; |
| 125 | result += missingOne; |
| 126 | } |
| 127 | } else { |
| 128 | if (exp < 32) { |
| 129 | const uint32_t missingOne = 1U << exp; |
| 130 | result &= missingOne - 1; |
| 131 | result += missingOne; |
| 132 | } |
| 133 | } |
| 134 | |
| 135 | // If the input value was negative (we could test either 'number' or 'bits', |
| 136 | // but testing 'bits' is likely faster) invert the result appropriately. |
| 137 | return static_cast<int64_t>(bits) < 0 ? -static_cast<int32_t>(result) : static_cast<int32_t>(result); |
| 138 | } |
| 139 | |
| 140 | ALWAYS_INLINE int32_t toInt32(double number) |
| 141 | { |
| 142 | #if HAVE(FJCVTZS_INSTRUCTION) |
| 143 | int32_t result = 0; |
| 144 | __asm__ ("fjcvtzs %w0, %d1" : "=r" (result) : "w" (number) : "cc" ); |
| 145 | return result; |
| 146 | #else |
| 147 | return toInt32Internal<ToInt32Mode::Generic>(number); |
| 148 | #endif |
| 149 | } |
| 150 | |
| 151 | // This implements ToUInt32, defined in ECMA-262 9.6. |
| 152 | inline uint32_t toUInt32(double number) |
| 153 | { |
| 154 | // As commented in the spec, the operation of ToInt32 and ToUint32 only differ |
| 155 | // in how the result is interpreted; see NOTEs in sections 9.5 and 9.6. |
| 156 | return toInt32(number); |
| 157 | } |
| 158 | |
| 159 | inline Optional<double> safeReciprocalForDivByConst(double constant) |
| 160 | { |
| 161 | // No "weird" numbers (NaN, Denormal, etc). |
| 162 | if (!constant || !std::isnormal(constant)) |
| 163 | return WTF::nullopt; |
| 164 | |
| 165 | int exponent; |
| 166 | if (std::frexp(constant, &exponent) != 0.5) |
| 167 | return WTF::nullopt; |
| 168 | |
| 169 | // Note that frexp() returns the value divided by two |
| 170 | // so we to offset this exponent by one. |
| 171 | exponent -= 1; |
| 172 | |
| 173 | // A double exponent is between -1022 and 1023. |
| 174 | // Nothing we can do to invert 1023. |
| 175 | if (exponent == 1023) |
| 176 | return WTF::nullopt; |
| 177 | |
| 178 | double reciprocal = std::ldexp(1, -exponent); |
| 179 | ASSERT(std::isnormal(reciprocal)); |
| 180 | ASSERT(1. / constant == reciprocal); |
| 181 | ASSERT(constant == 1. / reciprocal); |
| 182 | ASSERT(1. == constant * reciprocal); |
| 183 | |
| 184 | return reciprocal; |
| 185 | } |
| 186 | |
| 187 | ALWAYS_INLINE bool canBeStrictInt32(double value) |
| 188 | { |
| 189 | // Note: while this behavior is undefined for NaN and inf, the subsequent statement will catch these cases. |
| 190 | const int32_t asInt32 = static_cast<int32_t>(value); |
| 191 | return !(asInt32 != value || (!asInt32 && std::signbit(value))); // true for -0.0 |
| 192 | } |
| 193 | |
| 194 | ALWAYS_INLINE bool canBeInt32(double value) |
| 195 | { |
| 196 | // Note: Strictly speaking this is an undefined behavior. |
| 197 | return static_cast<int32_t>(value) == value; |
| 198 | } |
| 199 | |
| 200 | extern "C" { |
| 201 | double JIT_OPERATION jsRound(double value) REFERENCED_FROM_ASM WTF_INTERNAL; |
| 202 | |
| 203 | // On Windows we need to wrap fmod; on other platforms we can call it directly. |
| 204 | // On ARMv7 we assert that all function pointers have to low bit set (point to thumb code). |
| 205 | #if CALLING_CONVENTION_IS_STDCALL || CPU(ARM_THUMB2) |
| 206 | double JIT_OPERATION jsMod(double x, double y) REFERENCED_FROM_ASM WTF_INTERNAL; |
| 207 | #else |
| 208 | #define jsMod fmod |
| 209 | #endif |
| 210 | } |
| 211 | |
| 212 | namespace Math { |
| 213 | |
| 214 | using std::sin; |
| 215 | using std::sinh; |
| 216 | using std::cos; |
| 217 | using std::cosh; |
| 218 | using std::tan; |
| 219 | using std::tanh; |
| 220 | using std::asin; |
| 221 | using std::asinh; |
| 222 | using std::acos; |
| 223 | using std::acosh; |
| 224 | using std::atan; |
| 225 | using std::atanh; |
| 226 | using std::log; |
| 227 | using std::log10; |
| 228 | using std::log2; |
| 229 | using std::cbrt; |
| 230 | using std::exp; |
| 231 | using std::expm1; |
| 232 | |
| 233 | double JIT_OPERATION log1p(double) WTF_INTERNAL; |
| 234 | |
| 235 | } // namespace Math |
| 236 | } // namespace JSC |
| 237 | |