v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
bits.h
Go to the documentation of this file.
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
3// found in the LICENSE file.
4
5#ifndef V8_BASE_BITS_H_
6#define V8_BASE_BITS_H_
7
8#include <stdint.h>
9#include <type_traits>
10
12#include "src/base/macros.h"
13#if V8_CC_MSVC
14#include <intrin.h>
15#endif
16#if V8_OS_WIN32
18#endif
19
20namespace v8 {
21namespace base {
22namespace bits {
23
24// CountPopulation(value) returns the number of bits set in |value|.
25template <typename T>
26constexpr inline unsigned CountPopulation(T value)
27 requires(std::is_unsigned<T>::value && sizeof(T) <= 8)
28{
29 static_assert(sizeof(T) <= 8);
30#if V8_HAS_BUILTIN_POPCOUNT
31 return sizeof(T) == 8 ? __builtin_popcountll(static_cast<uint64_t>(value))
32 : __builtin_popcount(static_cast<uint32_t>(value));
33#else
34 // Fall back to divide-and-conquer popcount (see "Hacker's Delight" by Henry
35 // S. Warren, Jr.), chapter 5-1.
36 constexpr uint64_t mask[] = {0x5555555555555555, 0x3333333333333333,
37 0x0f0f0f0f0f0f0f0f};
38 // Start with 64 buckets of 1 bits, holding values from [0,1].
39 value = ((value >> 1) & mask[0]) + (value & mask[0]);
40 // Having 32 buckets of 2 bits, holding values from [0,2] now.
41 value = ((value >> 2) & mask[1]) + (value & mask[1]);
42 // Having 16 buckets of 4 bits, holding values from [0,4] now.
43 value = ((value >> 4) & mask[2]) + (value & mask[2]);
44 // Having 8 buckets of 8 bits, holding values from [0,8] now.
45 // From this point on, the buckets are bigger than the number of bits
46 // required to hold the values, and the buckets are bigger the maximum
47 // result, so there's no need to mask value anymore, since there's no
48 // more risk of overflow between buckets.
49 if (sizeof(T) > 1) value = (value >> (sizeof(T) > 1 ? 8 : 0)) + value;
50 // Having 4 buckets of 16 bits, holding values from [0,16] now.
51 if (sizeof(T) > 2) value = (value >> (sizeof(T) > 2 ? 16 : 0)) + value;
52 // Having 2 buckets of 32 bits, holding values from [0,32] now.
53 if (sizeof(T) > 4) value = (value >> (sizeof(T) > 4 ? 32 : 0)) + value;
54 // Having 1 buckets of 64 bits, holding values from [0,64] now.
55 return static_cast<unsigned>(value & 0xff);
56#endif
57}
58
59// ReverseBits(value) returns |value| in reverse bit order.
60template <typename T>
61T ReverseBits(T value) {
62 static_assert((sizeof(value) == 1) || (sizeof(value) == 2) ||
63 (sizeof(value) == 4) || (sizeof(value) == 8));
64 T result = 0;
65 for (unsigned i = 0; i < (sizeof(value) * 8); i++) {
66 result = (result << 1) | (value & 1);
67 value >>= 1;
68 }
69 return result;
70}
71
72// ReverseBytes(value) returns |value| in reverse byte order.
73template <typename T>
74T ReverseBytes(T value) {
75 static_assert((sizeof(value) == 1) || (sizeof(value) == 2) ||
76 (sizeof(value) == 4) || (sizeof(value) == 8));
77 T result = 0;
78 for (unsigned i = 0; i < sizeof(value); i++) {
79 result = (result << 8) | (value & 0xff);
80 value >>= 8;
81 }
82 return result;
83}
84
85template <class T>
86inline constexpr std::make_unsigned_t<T> Unsigned(T value) {
87 static_assert(std::is_signed_v<T>);
88 return static_cast<std::make_unsigned_t<T>>(value);
89}
90template <class T>
91inline constexpr std::make_signed_t<T> Signed(T value) {
92 static_assert(std::is_unsigned_v<T>);
93 return static_cast<std::make_signed_t<T>>(value);
94}
95
96// CountLeadingZeros(value) returns the number of zero bits following the most
97// significant 1 bit in |value| if |value| is non-zero, otherwise it returns
98// {sizeof(T) * 8}.
99template <typename T, unsigned bits = sizeof(T) * 8>
100inline constexpr unsigned CountLeadingZeros(T value)
101 requires(std::is_unsigned<T>::value && sizeof(T) <= 8)
102{
103 static_assert(bits > 0, "invalid instantiation");
104#if V8_HAS_BUILTIN_CLZ
105 return value == 0
106 ? bits
107 : bits == 64
108 ? __builtin_clzll(static_cast<uint64_t>(value))
109 : __builtin_clz(static_cast<uint32_t>(value)) - (32 - bits);
110#else
111 // Binary search algorithm taken from "Hacker's Delight" (by Henry S. Warren,
112 // Jr.), figures 5-11 and 5-12.
113 if (bits == 1) return static_cast<unsigned>(value) ^ 1;
114 T upper_half = value >> (bits / 2);
115 T next_value = upper_half != 0 ? upper_half : value;
116 unsigned add = upper_half != 0 ? 0 : bits / 2;
117 constexpr unsigned next_bits = bits == 1 ? 1 : bits / 2;
118 return CountLeadingZeros<T, next_bits>(next_value) + add;
119#endif
120}
121
122inline constexpr unsigned CountLeadingZeros32(uint32_t value) {
123 return CountLeadingZeros(value);
124}
125inline constexpr unsigned CountLeadingZeros64(uint64_t value) {
126 return CountLeadingZeros(value);
127}
128
129// The number of leading zeros for a positive number,
130// the number of leading ones for a negative number.
131template <class T>
132constexpr unsigned CountLeadingSignBits(T value) {
133 static_assert(std::is_signed_v<T>);
134 return value < 0 ? CountLeadingZeros(~Unsigned(value))
135 : CountLeadingZeros(Unsigned(value));
136}
137
138// CountTrailingZeros(value) returns the number of zero bits preceding the
139// least significant 1 bit in |value| if |value| is non-zero, otherwise it
140// returns {sizeof(T) * 8}.
141// See CountTrailingZerosNonZero for an optimized version for the case that
142// |value| is guaranteed to be non-zero.
143template <typename T, unsigned bits = sizeof(T) * 8>
144inline constexpr unsigned CountTrailingZeros(T value)
145 requires(std::is_integral<T>::value && sizeof(T) <= 8)
146{
147#if V8_HAS_BUILTIN_CTZ
148 return value == 0 ? bits
149 : bits == 64 ? __builtin_ctzll(static_cast<uint64_t>(value))
150 : __builtin_ctz(static_cast<uint32_t>(value));
151#else
152 // Fall back to popcount (see "Hacker's Delight" by Henry S. Warren, Jr.),
153 // chapter 5-4. On x64, since is faster than counting in a loop and faster
154 // than doing binary search.
155 using U = typename std::make_unsigned<T>::type;
156 U u = value;
157 return CountPopulation(static_cast<U>(~u & (u - 1u)));
158#endif
159}
160
161inline constexpr unsigned CountTrailingZeros32(uint32_t value) {
162 return CountTrailingZeros(value);
163}
164inline constexpr unsigned CountTrailingZeros64(uint64_t value) {
165 return CountTrailingZeros(value);
166}
167
168// CountTrailingZerosNonZero(value) returns the number of zero bits preceding
169// the least significant 1 bit in |value| if |value| is non-zero, otherwise the
170// behavior is undefined.
171// See CountTrailingZeros for an alternative version that allows |value| == 0.
172template <typename T, unsigned bits = sizeof(T) * 8>
173inline constexpr unsigned CountTrailingZerosNonZero(T value)
174 requires(std::is_integral<T>::value && sizeof(T) <= 8)
175{
176 DCHECK_NE(0, value);
177#if V8_HAS_BUILTIN_CTZ
178 return bits == 64 ? __builtin_ctzll(static_cast<uint64_t>(value))
179 : __builtin_ctz(static_cast<uint32_t>(value));
180#else
181 return CountTrailingZeros<T, bits>(value);
182#endif
183}
184
185// Returns true iff |value| is a power of 2.
186template <typename T>
187constexpr inline bool IsPowerOfTwo(T value)
188 requires(std::is_integral<T>::value || std::is_enum<T>::value)
189{
190 return value > 0 && (value & (value - 1)) == 0;
191}
192
193// Identical to {CountTrailingZeros}, but only works for powers of 2.
194template <typename T>
195inline constexpr int WhichPowerOfTwo(T value)
196 requires std::is_integral<T>::value
197{
198 DCHECK(IsPowerOfTwo(value));
199#if V8_HAS_BUILTIN_CTZ
200 static_assert(sizeof(T) <= 8);
201 return sizeof(T) == 8 ? __builtin_ctzll(static_cast<uint64_t>(value))
202 : __builtin_ctz(static_cast<uint32_t>(value));
203#else
204 // Fall back to popcount (see "Hacker's Delight" by Henry S. Warren, Jr.),
205 // chapter 5-4. On x64, since is faster than counting in a loop and faster
206 // than doing binary search.
207 using U = typename std::make_unsigned<T>::type;
208 U u = value;
209 return CountPopulation(static_cast<U>(u - 1));
210#endif
211}
212
213// RoundUpToPowerOfTwo32(value) returns the smallest power of two which is
214// greater than or equal to |value|. If you pass in a |value| that is already a
215// power of two, it is returned as is. |value| must be less than or equal to
216// 0x80000000u. Uses computation based on leading zeros if we have compiler
217// support for that. Falls back to the implementation from "Hacker's Delight" by
218// Henry S. Warren, Jr., figure 3-3, page 48, where the function is called clp2.
219V8_BASE_EXPORT constexpr uint32_t RoundUpToPowerOfTwo32(uint32_t value) {
220 DCHECK_LE(value, uint32_t{1} << 31);
221 if (value) --value;
222// Use computation based on leading zeros if we have compiler support for that.
223#if V8_HAS_BUILTIN_CLZ || V8_CC_MSVC
224 return 1u << (32 - CountLeadingZeros(value));
225#else
226 value |= value >> 1;
227 value |= value >> 2;
228 value |= value >> 4;
229 value |= value >> 8;
230 value |= value >> 16;
231 return value + 1;
232#endif
233}
234// Same for 64 bit integers. |value| must be <= 2^63
235V8_BASE_EXPORT constexpr uint64_t RoundUpToPowerOfTwo64(uint64_t value) {
236 DCHECK_LE(value, uint64_t{1} << 63);
237 if (value) --value;
238// Use computation based on leading zeros if we have compiler support for that.
239#if V8_HAS_BUILTIN_CLZ
240 return uint64_t{1} << (64 - CountLeadingZeros(value));
241#else
242 value |= value >> 1;
243 value |= value >> 2;
244 value |= value >> 4;
245 value |= value >> 8;
246 value |= value >> 16;
247 value |= value >> 32;
248 return value + 1;
249#endif
250}
251// Same for size_t integers.
252inline constexpr size_t RoundUpToPowerOfTwo(size_t value) {
253 if (sizeof(size_t) == sizeof(uint64_t)) {
254 return RoundUpToPowerOfTwo64(value);
255 } else {
256 // Without windows.h included this line triggers a truncation warning on
257 // 64-bit builds. Presumably windows.h disables the relevant warning.
258 return RoundUpToPowerOfTwo32(static_cast<uint32_t>(value));
259 }
260}
261
262// RoundDownToPowerOfTwo32(value) returns the greatest power of two which is
263// less than or equal to |value|. If you pass in a |value| that is already a
264// power of two, it is returned as is.
265inline uint32_t RoundDownToPowerOfTwo32(uint32_t value) {
266 if (value > 0x80000000u) return 0x80000000u;
267 uint32_t result = RoundUpToPowerOfTwo32(value);
268 if (result > value) result >>= 1;
269 return result;
270}
271
272
273// Precondition: 0 <= shift < 32
274inline constexpr uint32_t RotateRight32(uint32_t value, uint32_t shift) {
275 return (value >> shift) | (value << ((32 - shift) & 31));
276}
277
278// Precondition: 0 <= shift < 32
279inline constexpr uint32_t RotateLeft32(uint32_t value, uint32_t shift) {
280 return (value << shift) | (value >> ((32 - shift) & 31));
281}
282
283// Precondition: 0 <= shift < 64
284inline constexpr uint64_t RotateRight64(uint64_t value, uint64_t shift) {
285 return (value >> shift) | (value << ((64 - shift) & 63));
286}
287
288// Precondition: 0 <= shift < 64
289inline constexpr uint64_t RotateLeft64(uint64_t value, uint64_t shift) {
290 return (value << shift) | (value >> ((64 - shift) & 63));
291}
292
293// SignedAddOverflow32(lhs,rhs,val) performs a signed summation of |lhs| and
294// |rhs| and stores the result into the variable pointed to by |val| and
295// returns true if the signed summation resulted in an overflow.
296inline bool SignedAddOverflow32(int32_t lhs, int32_t rhs, int32_t* val) {
297#if V8_HAS_BUILTIN_SADD_OVERFLOW
298 return __builtin_sadd_overflow(lhs, rhs, val);
299#else
300 uint32_t res = static_cast<uint32_t>(lhs) + static_cast<uint32_t>(rhs);
301 *val = base::bit_cast<int32_t>(res);
302 return ((res ^ lhs) & (res ^ rhs) & (1U << 31)) != 0;
303#endif
304}
305
306
307// SignedSubOverflow32(lhs,rhs,val) performs a signed subtraction of |lhs| and
308// |rhs| and stores the result into the variable pointed to by |val| and
309// returns true if the signed subtraction resulted in an overflow.
310inline bool SignedSubOverflow32(int32_t lhs, int32_t rhs, int32_t* val) {
311#if V8_HAS_BUILTIN_SSUB_OVERFLOW
312 return __builtin_ssub_overflow(lhs, rhs, val);
313#else
314 uint32_t res = static_cast<uint32_t>(lhs) - static_cast<uint32_t>(rhs);
315 *val = base::bit_cast<int32_t>(res);
316 return ((res ^ lhs) & (res ^ ~rhs) & (1U << 31)) != 0;
317#endif
318}
319
320// SignedMulOverflow32(lhs,rhs,val) performs a signed multiplication of |lhs|
321// and |rhs| and stores the result into the variable pointed to by |val| and
322// returns true if the signed multiplication resulted in an overflow.
323inline bool SignedMulOverflow32(int32_t lhs, int32_t rhs, int32_t* val) {
324#if V8_HAS_BUILTIN_SMUL_OVERFLOW
325 return __builtin_smul_overflow(lhs, rhs, val);
326#else
327 // Compute the result as {int64_t}, then check for overflow.
328 int64_t result = int64_t{lhs} * int64_t{rhs};
329 *val = static_cast<int32_t>(result);
330 using limits = std::numeric_limits<int32_t>;
331 return result < limits::min() || result > limits::max();
332#endif
333}
334
335// SignedAddOverflow64(lhs,rhs,val) performs a signed summation of |lhs| and
336// |rhs| and stores the result into the variable pointed to by |val| and
337// returns true if the signed summation resulted in an overflow.
338inline bool SignedAddOverflow64(int64_t lhs, int64_t rhs, int64_t* val) {
339#if V8_HAS_BUILTIN_ADD_OVERFLOW
340 return __builtin_add_overflow(lhs, rhs, val);
341#else
342 uint64_t res = static_cast<uint64_t>(lhs) + static_cast<uint64_t>(rhs);
343 *val = base::bit_cast<int64_t>(res);
344 return ((res ^ lhs) & (res ^ rhs) & (1ULL << 63)) != 0;
345#endif
346}
347
348
349// SignedSubOverflow64(lhs,rhs,val) performs a signed subtraction of |lhs| and
350// |rhs| and stores the result into the variable pointed to by |val| and
351// returns true if the signed subtraction resulted in an overflow.
352inline bool SignedSubOverflow64(int64_t lhs, int64_t rhs, int64_t* val) {
353#if V8_HAS_BUILTIN_SUB_OVERFLOW
354 return __builtin_sub_overflow(lhs, rhs, val);
355#else
356 uint64_t res = static_cast<uint64_t>(lhs) - static_cast<uint64_t>(rhs);
357 *val = base::bit_cast<int64_t>(res);
358 return ((res ^ lhs) & (res ^ ~rhs) & (1ULL << 63)) != 0;
359#endif
360}
361
362// SignedMulOverflow64(lhs,rhs,val) performs a signed multiplication of |lhs|
363// and |rhs| and stores the result into the variable pointed to by |val| and
364// returns true if the signed multiplication resulted in an overflow.
365inline bool SignedMulOverflow64(int64_t lhs, int64_t rhs, int64_t* val) {
366#if V8_HAS_BUILTIN_MUL_OVERFLOW
367 return __builtin_mul_overflow(lhs, rhs, val);
368#else
369 int64_t res = base::bit_cast<int64_t>(static_cast<uint64_t>(lhs) *
370 static_cast<uint64_t>(rhs));
371 *val = res;
372
373 // Check for INT64_MIN / -1 as it's undefined behaviour and could cause
374 // hardware exceptions.
375 if ((res == INT64_MIN && lhs == -1)) {
376 return true;
377 }
378
379 return lhs != 0 && (res / lhs) != rhs;
380#endif
381}
382
383// SignedMulHigh32(lhs, rhs) multiplies two signed 32-bit values |lhs| and
384// |rhs|, extracts the most significant 32 bits of the result, and returns
385// those.
386V8_BASE_EXPORT int32_t SignedMulHigh32(int32_t lhs, int32_t rhs);
387
388// UnsignedMulHigh32(lhs, rhs) multiplies two unsigned 32-bit values |lhs| and
389// |rhs|, extracts the most significant 32 bits of the result, and returns
390// those.
391V8_BASE_EXPORT uint32_t UnsignedMulHigh32(uint32_t lhs, uint32_t rhs);
392
393// SignedMulHigh64(lhs, rhs) multiplies two signed 64-bit values |lhs| and
394// |rhs|, extracts the most significant 64 bits of the result, and returns
395// those.
396V8_BASE_EXPORT int64_t SignedMulHigh64(int64_t lhs, int64_t rhs);
397
398// UnsignedMulHigh64(lhs, rhs) multiplies two unsigned 64-bit values |lhs| and
399// |rhs|, extracts the most significant 64 bits of the result, and returns
400// those.
401V8_BASE_EXPORT uint64_t UnsignedMulHigh64(uint64_t lhs, uint64_t rhs);
402
403// SignedMulHighAndAdd32(lhs, rhs, acc) multiplies two signed 32-bit values
404// |lhs| and |rhs|, extracts the most significant 32 bits of the result, and
405// adds the accumulate value |acc|.
406V8_BASE_EXPORT int32_t SignedMulHighAndAdd32(int32_t lhs, int32_t rhs,
407 int32_t acc);
408
409// SignedDiv32(lhs, rhs) divides |lhs| by |rhs| and returns the quotient
410// truncated to int32. If |rhs| is zero, then zero is returned. If |lhs|
411// is minint and |rhs| is -1, it returns minint.
412V8_BASE_EXPORT int32_t SignedDiv32(int32_t lhs, int32_t rhs);
413
414// SignedDiv64(lhs, rhs) divides |lhs| by |rhs| and returns the quotient
415// truncated to int64. If |rhs| is zero, then zero is returned. If |lhs|
416// is minint and |rhs| is -1, it returns minint.
417V8_BASE_EXPORT int64_t SignedDiv64(int64_t lhs, int64_t rhs);
418
419// SignedMod32(lhs, rhs) divides |lhs| by |rhs| and returns the remainder
420// truncated to int32. If either |rhs| is zero or |lhs| is minint and |rhs|
421// is -1, it returns zero.
422V8_BASE_EXPORT int32_t SignedMod32(int32_t lhs, int32_t rhs);
423
424// SignedMod64(lhs, rhs) divides |lhs| by |rhs| and returns the remainder
425// truncated to int64. If either |rhs| is zero or |lhs| is minint and |rhs|
426// is -1, it returns zero.
427V8_BASE_EXPORT int64_t SignedMod64(int64_t lhs, int64_t rhs);
428
429// UnsignedAddOverflow32(lhs,rhs,val) performs an unsigned summation of |lhs|
430// and |rhs| and stores the result into the variable pointed to by |val| and
431// returns true if the unsigned summation resulted in an overflow.
432inline bool UnsignedAddOverflow32(uint32_t lhs, uint32_t rhs, uint32_t* val) {
433#if V8_HAS_BUILTIN_SADD_OVERFLOW
434 return __builtin_uadd_overflow(lhs, rhs, val);
435#else
436 *val = lhs + rhs;
437 return *val < (lhs | rhs);
438#endif
439}
440
441
442// UnsignedDiv32(lhs, rhs) divides |lhs| by |rhs| and returns the quotient
443// truncated to uint32. If |rhs| is zero, then zero is returned.
444inline uint32_t UnsignedDiv32(uint32_t lhs, uint32_t rhs) {
445 return rhs ? lhs / rhs : 0u;
446}
447
448// UnsignedDiv64(lhs, rhs) divides |lhs| by |rhs| and returns the quotient
449// truncated to uint64. If |rhs| is zero, then zero is returned.
450inline uint64_t UnsignedDiv64(uint64_t lhs, uint64_t rhs) {
451 return rhs ? lhs / rhs : 0u;
452}
453
454// UnsignedMod32(lhs, rhs) divides |lhs| by |rhs| and returns the remainder
455// truncated to uint32. If |rhs| is zero, then zero is returned.
456inline uint32_t UnsignedMod32(uint32_t lhs, uint32_t rhs) {
457 return rhs ? lhs % rhs : 0u;
458}
459
460// UnsignedMod64(lhs, rhs) divides |lhs| by |rhs| and returns the remainder
461// truncated to uint64. If |rhs| is zero, then zero is returned.
462inline uint64_t UnsignedMod64(uint64_t lhs, uint64_t rhs) {
463 return rhs ? lhs % rhs : 0u;
464}
465
466// Wraparound integer arithmetic without undefined behavior.
467
468inline int32_t WraparoundAdd32(int32_t lhs, int32_t rhs) {
469 return static_cast<int32_t>(static_cast<uint32_t>(lhs) +
470 static_cast<uint32_t>(rhs));
471}
472
473inline int32_t WraparoundNeg32(int32_t x) {
474 return static_cast<int32_t>(-static_cast<uint32_t>(x));
475}
476
477// SignedSaturatedAdd64(lhs, rhs) adds |lhs| and |rhs|,
478// checks and returns the result.
479V8_BASE_EXPORT int64_t SignedSaturatedAdd64(int64_t lhs, int64_t rhs);
480
481// SignedSaturatedSub64(lhs, rhs) subtracts |lhs| by |rhs|,
482// checks and returns the result.
483V8_BASE_EXPORT int64_t SignedSaturatedSub64(int64_t lhs, int64_t rhs);
484
485template <class T>
486V8_BASE_EXPORT constexpr int BitWidth(T x) {
487 return std::numeric_limits<T>::digits - CountLeadingZeros(x);
488}
489
490} // namespace bits
491} // namespace base
492} // namespace v8
493
494#endif // V8_BASE_BITS_H_
#define V8_BASE_EXPORT
Definition base-export.h:26
#define T
ZoneVector< RpoNumber > & result
int x
uint32_t const mask
constexpr unsigned CountLeadingZeros(T value)
Definition bits.h:100
int32_t SignedMulHighAndAdd32(int32_t lhs, int32_t rhs, int32_t acc)
Definition bits.cc:62
bool SignedAddOverflow64(int64_t lhs, int64_t rhs, int64_t *val)
Definition bits.h:338
constexpr uint64_t RotateRight64(uint64_t value, uint64_t shift)
Definition bits.h:284
V8_BASE_EXPORT constexpr uint64_t RoundUpToPowerOfTwo64(uint64_t value)
Definition bits.h:235
int32_t SignedMulHigh32(int32_t lhs, int32_t rhs)
Definition bits.cc:15
constexpr uint32_t RotateLeft32(uint32_t value, uint32_t shift)
Definition bits.h:279
constexpr unsigned CountTrailingZeros64(uint64_t value)
Definition bits.h:164
uint32_t RoundDownToPowerOfTwo32(uint32_t value)
Definition bits.h:265
constexpr unsigned CountTrailingZeros32(uint32_t value)
Definition bits.h:161
int32_t SignedDiv32(int32_t lhs, int32_t rhs)
Definition bits.cc:69
constexpr unsigned CountLeadingZeros64(uint64_t value)
Definition bits.h:125
int64_t SignedDiv64(int64_t lhs, int64_t rhs)
Definition bits.cc:75
bool SignedSubOverflow64(int64_t lhs, int64_t rhs, int64_t *val)
Definition bits.h:352
constexpr unsigned CountTrailingZeros(T value)
Definition bits.h:144
constexpr unsigned CountPopulation(T value)
Definition bits.h:26
uint32_t UnsignedMulHigh32(uint32_t lhs, uint32_t rhs)
Definition bits.cc:56
int64_t SignedMulHigh64(int64_t u, int64_t v)
Definition bits.cc:24
constexpr bool IsPowerOfTwo(T value)
Definition bits.h:187
constexpr std::make_signed_t< T > Signed(T value)
Definition bits.h:91
int32_t WraparoundNeg32(int32_t x)
Definition bits.h:473
uint32_t UnsignedDiv32(uint32_t lhs, uint32_t rhs)
Definition bits.h:444
T ReverseBytes(T value)
Definition bits.h:74
uint32_t UnsignedMod32(uint32_t lhs, uint32_t rhs)
Definition bits.h:456
constexpr uint64_t RotateLeft64(uint64_t value, uint64_t shift)
Definition bits.h:289
constexpr uint32_t RotateRight32(uint32_t value, uint32_t shift)
Definition bits.h:274
V8_BASE_EXPORT constexpr int BitWidth(T x)
Definition bits.h:486
constexpr std::make_unsigned_t< T > Unsigned(T value)
Definition bits.h:86
constexpr unsigned CountLeadingZeros32(uint32_t value)
Definition bits.h:122
T ReverseBits(T value)
Definition bits.h:61
constexpr unsigned CountLeadingSignBits(T value)
Definition bits.h:132
int64_t SignedMod64(int64_t lhs, int64_t rhs)
Definition bits.cc:86
uint64_t UnsignedDiv64(uint64_t lhs, uint64_t rhs)
Definition bits.h:450
bool UnsignedAddOverflow32(uint32_t lhs, uint32_t rhs, uint32_t *val)
Definition bits.h:432
int32_t WraparoundAdd32(int32_t lhs, int32_t rhs)
Definition bits.h:468
bool SignedAddOverflow32(int32_t lhs, int32_t rhs, int32_t *val)
Definition bits.h:296
uint64_t UnsignedMod64(uint64_t lhs, uint64_t rhs)
Definition bits.h:462
constexpr unsigned CountTrailingZerosNonZero(T value)
Definition bits.h:173
int32_t SignedMod32(int32_t lhs, int32_t rhs)
Definition bits.cc:81
int64_t SignedSaturatedSub64(int64_t lhs, int64_t rhs)
Definition bits.cc:100
bool SignedSubOverflow32(int32_t lhs, int32_t rhs, int32_t *val)
Definition bits.h:310
bool SignedMulOverflow32(int32_t lhs, int32_t rhs, int32_t *val)
Definition bits.h:323
uint64_t UnsignedMulHigh64(uint64_t u, uint64_t v)
Definition bits.cc:41
V8_BASE_EXPORT constexpr uint32_t RoundUpToPowerOfTwo32(uint32_t value)
Definition bits.h:219
bool SignedMulOverflow64(int64_t lhs, int64_t rhs, int64_t *val)
Definition bits.h:365
constexpr size_t RoundUpToPowerOfTwo(size_t value)
Definition bits.h:252
int64_t SignedSaturatedAdd64(int64_t lhs, int64_t rhs)
Definition bits.cc:91
constexpr int WhichPowerOfTwo(T value)
Definition bits.h:195
V8_INLINE Dest bit_cast(Source const &source)
Definition macros.h:95
#define DCHECK_LE(v1, v2)
Definition logging.h:490
#define DCHECK_NE(v1, v2)
Definition logging.h:486
#define DCHECK(condition)
Definition logging.h:482
std::unique_ptr< ValueMirror > value