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 |