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