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 | |