OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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 #ifndef V8_BASE_BITS_H_ | 5 #ifndef V8_BASE_BITS_H_ |
6 #define V8_BASE_BITS_H_ | 6 #define V8_BASE_BITS_H_ |
7 | 7 |
8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 |
| 10 #include "src/base/base-export.h" |
9 #include "src/base/macros.h" | 11 #include "src/base/macros.h" |
10 #if V8_CC_MSVC | 12 #if V8_CC_MSVC |
11 #include <intrin.h> | 13 #include <intrin.h> |
12 #endif | 14 #endif |
13 #if V8_OS_WIN32 | 15 #if V8_OS_WIN32 |
14 #include "src/base/win32-headers.h" | 16 #include "src/base/win32-headers.h" |
15 #endif | 17 #endif |
16 | 18 |
17 namespace v8 { | 19 namespace v8 { |
18 namespace base { | 20 namespace base { |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 inline bool IsPowerOfTwo64(uint64_t value) { | 167 inline bool IsPowerOfTwo64(uint64_t value) { |
166 return value && !(value & (value - 1)); | 168 return value && !(value & (value - 1)); |
167 } | 169 } |
168 | 170 |
169 | 171 |
170 // RoundUpToPowerOfTwo32(value) returns the smallest power of two which is | 172 // RoundUpToPowerOfTwo32(value) returns the smallest power of two which is |
171 // greater than or equal to |value|. If you pass in a |value| that is already a | 173 // greater than or equal to |value|. If you pass in a |value| that is already a |
172 // power of two, it is returned as is. |value| must be less than or equal to | 174 // power of two, it is returned as is. |value| must be less than or equal to |
173 // 0x80000000u. Implementation is from "Hacker's Delight" by Henry S. Warren, | 175 // 0x80000000u. Implementation is from "Hacker's Delight" by Henry S. Warren, |
174 // Jr., figure 3-3, page 48, where the function is called clp2. | 176 // Jr., figure 3-3, page 48, where the function is called clp2. |
175 uint32_t RoundUpToPowerOfTwo32(uint32_t value); | 177 V8_BASE_EXPORT uint32_t RoundUpToPowerOfTwo32(uint32_t value); |
176 | |
177 | 178 |
178 // RoundDownToPowerOfTwo32(value) returns the greatest power of two which is | 179 // RoundDownToPowerOfTwo32(value) returns the greatest power of two which is |
179 // less than or equal to |value|. If you pass in a |value| that is already a | 180 // less than or equal to |value|. If you pass in a |value| that is already a |
180 // power of two, it is returned as is. | 181 // power of two, it is returned as is. |
181 inline uint32_t RoundDownToPowerOfTwo32(uint32_t value) { | 182 inline uint32_t RoundDownToPowerOfTwo32(uint32_t value) { |
182 if (value > 0x80000000u) return 0x80000000u; | 183 if (value > 0x80000000u) return 0x80000000u; |
183 uint32_t result = RoundUpToPowerOfTwo32(value); | 184 uint32_t result = RoundUpToPowerOfTwo32(value); |
184 if (result > value) result >>= 1; | 185 if (result > value) result >>= 1; |
185 return result; | 186 return result; |
186 } | 187 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 #else | 235 #else |
235 uint32_t res = static_cast<uint32_t>(lhs) - static_cast<uint32_t>(rhs); | 236 uint32_t res = static_cast<uint32_t>(lhs) - static_cast<uint32_t>(rhs); |
236 *val = bit_cast<int32_t>(res); | 237 *val = bit_cast<int32_t>(res); |
237 return ((res ^ lhs) & (res ^ ~rhs) & (1U << 31)) != 0; | 238 return ((res ^ lhs) & (res ^ ~rhs) & (1U << 31)) != 0; |
238 #endif | 239 #endif |
239 } | 240 } |
240 | 241 |
241 // SignedMulOverflow32(lhs,rhs,val) performs a signed multiplication of |lhs| | 242 // SignedMulOverflow32(lhs,rhs,val) performs a signed multiplication of |lhs| |
242 // and |rhs| and stores the result into the variable pointed to by |val| and | 243 // and |rhs| and stores the result into the variable pointed to by |val| and |
243 // returns true if the signed multiplication resulted in an overflow. | 244 // returns true if the signed multiplication resulted in an overflow. |
244 bool SignedMulOverflow32(int32_t lhs, int32_t rhs, int32_t* val); | 245 V8_BASE_EXPORT bool SignedMulOverflow32(int32_t lhs, int32_t rhs, int32_t* val); |
245 | 246 |
246 // SignedAddOverflow64(lhs,rhs,val) performs a signed summation of |lhs| and | 247 // SignedAddOverflow64(lhs,rhs,val) performs a signed summation of |lhs| and |
247 // |rhs| and stores the result into the variable pointed to by |val| and | 248 // |rhs| and stores the result into the variable pointed to by |val| and |
248 // returns true if the signed summation resulted in an overflow. | 249 // returns true if the signed summation resulted in an overflow. |
249 inline bool SignedAddOverflow64(int64_t lhs, int64_t rhs, int64_t* val) { | 250 inline bool SignedAddOverflow64(int64_t lhs, int64_t rhs, int64_t* val) { |
250 uint64_t res = static_cast<uint64_t>(lhs) + static_cast<uint64_t>(rhs); | 251 uint64_t res = static_cast<uint64_t>(lhs) + static_cast<uint64_t>(rhs); |
251 *val = bit_cast<int64_t>(res); | 252 *val = bit_cast<int64_t>(res); |
252 return ((res ^ lhs) & (res ^ rhs) & (1ULL << 63)) != 0; | 253 return ((res ^ lhs) & (res ^ rhs) & (1ULL << 63)) != 0; |
253 } | 254 } |
254 | 255 |
255 | 256 |
256 // SignedSubOverflow64(lhs,rhs,val) performs a signed subtraction of |lhs| and | 257 // SignedSubOverflow64(lhs,rhs,val) performs a signed subtraction of |lhs| and |
257 // |rhs| and stores the result into the variable pointed to by |val| and | 258 // |rhs| and stores the result into the variable pointed to by |val| and |
258 // returns true if the signed subtraction resulted in an overflow. | 259 // returns true if the signed subtraction resulted in an overflow. |
259 inline bool SignedSubOverflow64(int64_t lhs, int64_t rhs, int64_t* val) { | 260 inline bool SignedSubOverflow64(int64_t lhs, int64_t rhs, int64_t* val) { |
260 uint64_t res = static_cast<uint64_t>(lhs) - static_cast<uint64_t>(rhs); | 261 uint64_t res = static_cast<uint64_t>(lhs) - static_cast<uint64_t>(rhs); |
261 *val = bit_cast<int64_t>(res); | 262 *val = bit_cast<int64_t>(res); |
262 return ((res ^ lhs) & (res ^ ~rhs) & (1ULL << 63)) != 0; | 263 return ((res ^ lhs) & (res ^ ~rhs) & (1ULL << 63)) != 0; |
263 } | 264 } |
264 | 265 |
265 // SignedMulOverflow64(lhs,rhs,val) performs a signed multiplication of |lhs| | 266 // SignedMulOverflow64(lhs,rhs,val) performs a signed multiplication of |lhs| |
266 // and |rhs| and stores the result into the variable pointed to by |val| and | 267 // and |rhs| and stores the result into the variable pointed to by |val| and |
267 // returns true if the signed multiplication resulted in an overflow. | 268 // returns true if the signed multiplication resulted in an overflow. |
268 bool SignedMulOverflow64(int64_t lhs, int64_t rhs, int64_t* val); | 269 V8_BASE_EXPORT bool SignedMulOverflow64(int64_t lhs, int64_t rhs, int64_t* val); |
269 | 270 |
270 // SignedMulHigh32(lhs, rhs) multiplies two signed 32-bit values |lhs| and | 271 // SignedMulHigh32(lhs, rhs) multiplies two signed 32-bit values |lhs| and |
271 // |rhs|, extracts the most significant 32 bits of the result, and returns | 272 // |rhs|, extracts the most significant 32 bits of the result, and returns |
272 // those. | 273 // those. |
273 int32_t SignedMulHigh32(int32_t lhs, int32_t rhs); | 274 V8_BASE_EXPORT int32_t SignedMulHigh32(int32_t lhs, int32_t rhs); |
274 | |
275 | 275 |
276 // SignedMulHighAndAdd32(lhs, rhs, acc) multiplies two signed 32-bit values | 276 // SignedMulHighAndAdd32(lhs, rhs, acc) multiplies two signed 32-bit values |
277 // |lhs| and |rhs|, extracts the most significant 32 bits of the result, and | 277 // |lhs| and |rhs|, extracts the most significant 32 bits of the result, and |
278 // adds the accumulate value |acc|. | 278 // adds the accumulate value |acc|. |
279 int32_t SignedMulHighAndAdd32(int32_t lhs, int32_t rhs, int32_t acc); | 279 V8_BASE_EXPORT int32_t SignedMulHighAndAdd32(int32_t lhs, int32_t rhs, |
280 | 280 int32_t acc); |
281 | 281 |
282 // SignedDiv32(lhs, rhs) divides |lhs| by |rhs| and returns the quotient | 282 // SignedDiv32(lhs, rhs) divides |lhs| by |rhs| and returns the quotient |
283 // truncated to int32. If |rhs| is zero, then zero is returned. If |lhs| | 283 // truncated to int32. If |rhs| is zero, then zero is returned. If |lhs| |
284 // is minint and |rhs| is -1, it returns minint. | 284 // is minint and |rhs| is -1, it returns minint. |
285 int32_t SignedDiv32(int32_t lhs, int32_t rhs); | 285 V8_BASE_EXPORT int32_t SignedDiv32(int32_t lhs, int32_t rhs); |
286 | |
287 | 286 |
288 // SignedMod32(lhs, rhs) divides |lhs| by |rhs| and returns the remainder | 287 // SignedMod32(lhs, rhs) divides |lhs| by |rhs| and returns the remainder |
289 // truncated to int32. If either |rhs| is zero or |lhs| is minint and |rhs| | 288 // truncated to int32. If either |rhs| is zero or |lhs| is minint and |rhs| |
290 // is -1, it returns zero. | 289 // is -1, it returns zero. |
291 int32_t SignedMod32(int32_t lhs, int32_t rhs); | 290 V8_BASE_EXPORT int32_t SignedMod32(int32_t lhs, int32_t rhs); |
292 | |
293 | 291 |
294 // UnsignedAddOverflow32(lhs,rhs,val) performs an unsigned summation of |lhs| | 292 // UnsignedAddOverflow32(lhs,rhs,val) performs an unsigned summation of |lhs| |
295 // and |rhs| and stores the result into the variable pointed to by |val| and | 293 // and |rhs| and stores the result into the variable pointed to by |val| and |
296 // returns true if the unsigned summation resulted in an overflow. | 294 // returns true if the unsigned summation resulted in an overflow. |
297 inline bool UnsignedAddOverflow32(uint32_t lhs, uint32_t rhs, uint32_t* val) { | 295 inline bool UnsignedAddOverflow32(uint32_t lhs, uint32_t rhs, uint32_t* val) { |
298 #if V8_HAS_BUILTIN_SADD_OVERFLOW | 296 #if V8_HAS_BUILTIN_SADD_OVERFLOW |
299 return __builtin_uadd_overflow(lhs, rhs, val); | 297 return __builtin_uadd_overflow(lhs, rhs, val); |
300 #else | 298 #else |
301 *val = lhs + rhs; | 299 *val = lhs + rhs; |
302 return *val < (lhs | rhs); | 300 return *val < (lhs | rhs); |
303 #endif | 301 #endif |
304 } | 302 } |
305 | 303 |
306 | 304 |
307 // UnsignedDiv32(lhs, rhs) divides |lhs| by |rhs| and returns the quotient | 305 // UnsignedDiv32(lhs, rhs) divides |lhs| by |rhs| and returns the quotient |
308 // truncated to uint32. If |rhs| is zero, then zero is returned. | 306 // truncated to uint32. If |rhs| is zero, then zero is returned. |
309 inline uint32_t UnsignedDiv32(uint32_t lhs, uint32_t rhs) { | 307 inline uint32_t UnsignedDiv32(uint32_t lhs, uint32_t rhs) { |
310 return rhs ? lhs / rhs : 0u; | 308 return rhs ? lhs / rhs : 0u; |
311 } | 309 } |
312 | 310 |
313 | 311 |
314 // UnsignedMod32(lhs, rhs) divides |lhs| by |rhs| and returns the remainder | 312 // UnsignedMod32(lhs, rhs) divides |lhs| by |rhs| and returns the remainder |
315 // truncated to uint32. If |rhs| is zero, then zero is returned. | 313 // truncated to uint32. If |rhs| is zero, then zero is returned. |
316 inline uint32_t UnsignedMod32(uint32_t lhs, uint32_t rhs) { | 314 inline uint32_t UnsignedMod32(uint32_t lhs, uint32_t rhs) { |
317 return rhs ? lhs % rhs : 0u; | 315 return rhs ? lhs % rhs : 0u; |
318 } | 316 } |
319 | 317 |
320 | 318 |
321 // Clamp |value| on overflow and underflow conditions. | 319 // Clamp |value| on overflow and underflow conditions. |
322 int64_t FromCheckedNumeric(const internal::CheckedNumeric<int64_t> value); | 320 V8_BASE_EXPORT int64_t |
323 | 321 FromCheckedNumeric(const internal::CheckedNumeric<int64_t> value); |
324 | 322 |
325 // SignedSaturatedAdd64(lhs, rhs) adds |lhs| and |rhs|, | 323 // SignedSaturatedAdd64(lhs, rhs) adds |lhs| and |rhs|, |
326 // checks and returns the result. | 324 // checks and returns the result. |
327 int64_t SignedSaturatedAdd64(int64_t lhs, int64_t rhs); | 325 V8_BASE_EXPORT int64_t SignedSaturatedAdd64(int64_t lhs, int64_t rhs); |
328 | |
329 | 326 |
330 // SignedSaturatedSub64(lhs, rhs) substracts |lhs| by |rhs|, | 327 // SignedSaturatedSub64(lhs, rhs) substracts |lhs| by |rhs|, |
331 // checks and returns the result. | 328 // checks and returns the result. |
332 int64_t SignedSaturatedSub64(int64_t lhs, int64_t rhs); | 329 V8_BASE_EXPORT int64_t SignedSaturatedSub64(int64_t lhs, int64_t rhs); |
333 | |
334 | 330 |
335 } // namespace bits | 331 } // namespace bits |
336 } // namespace base | 332 } // namespace base |
337 } // namespace v8 | 333 } // namespace v8 |
338 | 334 |
339 #endif // V8_BASE_BITS_H_ | 335 #endif // V8_BASE_BITS_H_ |
OLD | NEW |