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