blob: e82e6239af9a481c996a996bffee2944bf3faf6d [file] [log] [blame]
ths05f778c2007-10-27 13:05:54 +00001/*
2 * Utility compute operations used by translated code.
3 *
4 * Copyright (c) 2007 Thiemo Seufer
5 * Copyright (c) 2007 Jocelyn Mayer
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 */
Markus Armbruster175de522016-06-29 15:29:06 +020025
Paolo Bonzinicb9c3772012-12-06 12:15:58 +010026#ifndef HOST_UTILS_H
Markus Armbruster175de522016-06-29 15:29:06 +020027#define HOST_UTILS_H
ths05f778c2007-10-27 13:05:54 +000028
Richard Henderson1ec80702020-11-13 03:22:23 +000029#include "qemu/compiler.h"
Richard Henderson652a4b72015-09-14 13:00:34 -070030#include "qemu/bswap.h"
thscebdff72008-06-05 22:55:54 +000031
Richard Hendersonf5401662013-02-16 12:46:59 -080032#ifdef CONFIG_INT128
Blue Swirlfacd2852009-08-16 08:03:26 +000033static inline void mulu64(uint64_t *plow, uint64_t *phigh,
34 uint64_t a, uint64_t b)
j_mayer7a51ad82007-11-04 02:24:58 +000035{
Richard Hendersonf5401662013-02-16 12:46:59 -080036 __uint128_t r = (__uint128_t)a * b;
37 *plow = r;
38 *phigh = r >> 64;
j_mayer7a51ad82007-11-04 02:24:58 +000039}
Richard Hendersonf5401662013-02-16 12:46:59 -080040
Blue Swirlfacd2852009-08-16 08:03:26 +000041static inline void muls64(uint64_t *plow, uint64_t *phigh,
42 int64_t a, int64_t b)
j_mayer7a51ad82007-11-04 02:24:58 +000043{
Richard Hendersonf5401662013-02-16 12:46:59 -080044 __int128_t r = (__int128_t)a * b;
45 *plow = r;
46 *phigh = r >> 64;
j_mayer7a51ad82007-11-04 02:24:58 +000047}
Tom Musta98d1eb22014-01-07 10:05:51 -060048
Peter Maydell49caffe2015-08-19 16:20:20 +010049/* compute with 96 bit intermediate result: (a*b)/c */
50static inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
51{
52 return (__int128_t)a * b / c;
53}
54
Luis Pires9276a312021-10-25 16:11:36 -030055static inline void divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor)
Tom Musta98d1eb22014-01-07 10:05:51 -060056{
Luis Pires9276a312021-10-25 16:11:36 -030057 __uint128_t dividend = ((__uint128_t)*phigh << 64) | *plow;
58 __uint128_t result = dividend / divisor;
59 *plow = result;
60 *phigh = dividend % divisor;
Tom Musta98d1eb22014-01-07 10:05:51 -060061}
Tom Mustae44259b2014-01-07 10:05:52 -060062
Luis Pires9276a312021-10-25 16:11:36 -030063static inline void divs128(int64_t *plow, int64_t *phigh, int64_t divisor)
Tom Mustae44259b2014-01-07 10:05:52 -060064{
Luis Pires9276a312021-10-25 16:11:36 -030065 __int128_t dividend = ((__int128_t)*phigh << 64) | (uint64_t)*plow;
66 __int128_t result = dividend / divisor;
67 *plow = result;
68 *phigh = dividend % divisor;
Tom Mustae44259b2014-01-07 10:05:52 -060069}
j_mayer7a51ad82007-11-04 02:24:58 +000070#else
Lijun Pandb7b62e2020-07-01 18:43:44 -050071void muls64(uint64_t *plow, uint64_t *phigh, int64_t a, int64_t b);
72void mulu64(uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b);
Luis Pires9276a312021-10-25 16:11:36 -030073void divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor);
74void divs128(int64_t *plow, int64_t *phigh, int64_t divisor);
Peter Maydell49caffe2015-08-19 16:20:20 +010075
76static inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
77{
78 union {
79 uint64_t ll;
80 struct {
81#ifdef HOST_WORDS_BIGENDIAN
82 uint32_t high, low;
83#else
84 uint32_t low, high;
85#endif
86 } l;
87 } u, res;
88 uint64_t rl, rh;
89
90 u.ll = a;
91 rl = (uint64_t)u.l.low * (uint64_t)b;
92 rh = (uint64_t)u.l.high * (uint64_t)b;
93 rh += (rl >> 32);
94 res.l.high = rh / c;
95 res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
96 return res.ll;
97}
j_mayer7a51ad82007-11-04 02:24:58 +000098#endif
99
Richard Henderson72d81152013-02-13 17:47:35 -0800100/**
101 * clz32 - count leading zeros in a 32-bit value.
102 * @val: The value to search
103 *
104 * Returns 32 if the value is zero. Note that the GCC builtin is
105 * undefined if the value is zero.
106 */
Blue Swirlfacd2852009-08-16 08:03:26 +0000107static inline int clz32(uint32_t val)
ths05f778c2007-10-27 13:05:54 +0000108{
Richard Henderson72d81152013-02-13 17:47:35 -0800109 return val ? __builtin_clz(val) : 32;
ths05f778c2007-10-27 13:05:54 +0000110}
111
Richard Henderson72d81152013-02-13 17:47:35 -0800112/**
113 * clo32 - count leading ones in a 32-bit value.
114 * @val: The value to search
115 *
116 * Returns 32 if the value is -1.
117 */
Blue Swirlfacd2852009-08-16 08:03:26 +0000118static inline int clo32(uint32_t val)
ths05f778c2007-10-27 13:05:54 +0000119{
120 return clz32(~val);
121}
122
Richard Henderson72d81152013-02-13 17:47:35 -0800123/**
124 * clz64 - count leading zeros in a 64-bit value.
125 * @val: The value to search
126 *
127 * Returns 64 if the value is zero. Note that the GCC builtin is
128 * undefined if the value is zero.
129 */
Blue Swirlfacd2852009-08-16 08:03:26 +0000130static inline int clz64(uint64_t val)
ths05f778c2007-10-27 13:05:54 +0000131{
Richard Henderson72d81152013-02-13 17:47:35 -0800132 return val ? __builtin_clzll(val) : 64;
ths05f778c2007-10-27 13:05:54 +0000133}
134
Richard Henderson72d81152013-02-13 17:47:35 -0800135/**
136 * clo64 - count leading ones in a 64-bit value.
137 * @val: The value to search
138 *
139 * Returns 64 if the value is -1.
140 */
Blue Swirlfacd2852009-08-16 08:03:26 +0000141static inline int clo64(uint64_t val)
ths05f778c2007-10-27 13:05:54 +0000142{
143 return clz64(~val);
144}
j_mayerb9ef45f2007-10-28 12:52:38 +0000145
Richard Henderson72d81152013-02-13 17:47:35 -0800146/**
147 * ctz32 - count trailing zeros in a 32-bit value.
148 * @val: The value to search
149 *
150 * Returns 32 if the value is zero. Note that the GCC builtin is
151 * undefined if the value is zero.
152 */
Blue Swirlfacd2852009-08-16 08:03:26 +0000153static inline int ctz32(uint32_t val)
j_mayerb9ef45f2007-10-28 12:52:38 +0000154{
Richard Henderson72d81152013-02-13 17:47:35 -0800155 return val ? __builtin_ctz(val) : 32;
balrogc8906842008-11-12 17:18:41 +0000156}
157
Richard Henderson72d81152013-02-13 17:47:35 -0800158/**
159 * cto32 - count trailing ones in a 32-bit value.
160 * @val: The value to search
161 *
162 * Returns 32 if the value is -1.
163 */
Blue Swirlfacd2852009-08-16 08:03:26 +0000164static inline int cto32(uint32_t val)
balrogc8906842008-11-12 17:18:41 +0000165{
j_mayerb9ef45f2007-10-28 12:52:38 +0000166 return ctz32(~val);
167}
168
Richard Henderson72d81152013-02-13 17:47:35 -0800169/**
170 * ctz64 - count trailing zeros in a 64-bit value.
171 * @val: The value to search
172 *
173 * Returns 64 if the value is zero. Note that the GCC builtin is
174 * undefined if the value is zero.
175 */
Blue Swirlfacd2852009-08-16 08:03:26 +0000176static inline int ctz64(uint64_t val)
j_mayerb9ef45f2007-10-28 12:52:38 +0000177{
Richard Henderson72d81152013-02-13 17:47:35 -0800178 return val ? __builtin_ctzll(val) : 64;
j_mayerb9ef45f2007-10-28 12:52:38 +0000179}
180
Richard Henderson72d81152013-02-13 17:47:35 -0800181/**
Dr. David Alan Gilbert1c884ab2014-02-12 17:14:33 +0000182 * cto64 - count trailing ones in a 64-bit value.
Richard Henderson72d81152013-02-13 17:47:35 -0800183 * @val: The value to search
184 *
185 * Returns 64 if the value is -1.
186 */
Blue Swirlfacd2852009-08-16 08:03:26 +0000187static inline int cto64(uint64_t val)
j_mayerb9ef45f2007-10-28 12:52:38 +0000188{
189 return ctz64(~val);
190}
191
Richard Henderson72d81152013-02-13 17:47:35 -0800192/**
Claudio Fontanaafd3fe42013-12-17 19:42:35 +0000193 * clrsb32 - count leading redundant sign bits in a 32-bit value.
194 * @val: The value to search
195 *
196 * Returns the number of bits following the sign bit that are equal to it.
197 * No special cases; output range is [0-31].
198 */
199static inline int clrsb32(uint32_t val)
200{
Thomas Huthf773b422018-12-03 14:33:12 +0100201#if __has_builtin(__builtin_clrsb) || !defined(__clang__)
Claudio Fontanaafd3fe42013-12-17 19:42:35 +0000202 return __builtin_clrsb(val);
203#else
204 return clz32(val ^ ((int32_t)val >> 1)) - 1;
205#endif
206}
207
208/**
209 * clrsb64 - count leading redundant sign bits in a 64-bit value.
210 * @val: The value to search
211 *
212 * Returns the number of bits following the sign bit that are equal to it.
213 * No special cases; output range is [0-63].
214 */
215static inline int clrsb64(uint64_t val)
216{
Thomas Huthf773b422018-12-03 14:33:12 +0100217#if __has_builtin(__builtin_clrsbll) || !defined(__clang__)
Claudio Fontanaafd3fe42013-12-17 19:42:35 +0000218 return __builtin_clrsbll(val);
219#else
220 return clz64(val ^ ((int64_t)val >> 1)) - 1;
221#endif
222}
223
224/**
Richard Henderson72d81152013-02-13 17:47:35 -0800225 * ctpop8 - count the population of one bits in an 8-bit value.
226 * @val: The value to search
227 */
Blue Swirlfacd2852009-08-16 08:03:26 +0000228static inline int ctpop8(uint8_t val)
j_mayerb9ef45f2007-10-28 12:52:38 +0000229{
Richard Henderson72d81152013-02-13 17:47:35 -0800230 return __builtin_popcount(val);
j_mayerb9ef45f2007-10-28 12:52:38 +0000231}
232
Richard Henderson72d81152013-02-13 17:47:35 -0800233/**
234 * ctpop16 - count the population of one bits in a 16-bit value.
235 * @val: The value to search
236 */
Blue Swirlfacd2852009-08-16 08:03:26 +0000237static inline int ctpop16(uint16_t val)
j_mayerb9ef45f2007-10-28 12:52:38 +0000238{
Richard Henderson72d81152013-02-13 17:47:35 -0800239 return __builtin_popcount(val);
j_mayerb9ef45f2007-10-28 12:52:38 +0000240}
241
Richard Henderson72d81152013-02-13 17:47:35 -0800242/**
243 * ctpop32 - count the population of one bits in a 32-bit value.
244 * @val: The value to search
245 */
Blue Swirlfacd2852009-08-16 08:03:26 +0000246static inline int ctpop32(uint32_t val)
j_mayerb9ef45f2007-10-28 12:52:38 +0000247{
aurel327d019982008-10-12 00:53:08 +0000248 return __builtin_popcount(val);
j_mayerb9ef45f2007-10-28 12:52:38 +0000249}
250
Richard Henderson72d81152013-02-13 17:47:35 -0800251/**
252 * ctpop64 - count the population of one bits in a 64-bit value.
253 * @val: The value to search
254 */
Blue Swirlfacd2852009-08-16 08:03:26 +0000255static inline int ctpop64(uint64_t val)
j_mayerb9ef45f2007-10-28 12:52:38 +0000256{
aurel327d019982008-10-12 00:53:08 +0000257 return __builtin_popcountll(val);
ths3800af92007-12-18 01:58:05 +0000258}
Paolo Bonzinicb9c3772012-12-06 12:15:58 +0100259
Richard Henderson652a4b72015-09-14 13:00:34 -0700260/**
261 * revbit8 - reverse the bits in an 8-bit value.
262 * @x: The value to modify.
263 */
264static inline uint8_t revbit8(uint8_t x)
265{
Richard Henderson5140d6b2020-11-06 10:59:36 -0800266#if __has_builtin(__builtin_bitreverse8)
267 return __builtin_bitreverse8(x);
268#else
Richard Henderson652a4b72015-09-14 13:00:34 -0700269 /* Assign the correct nibble position. */
270 x = ((x & 0xf0) >> 4)
271 | ((x & 0x0f) << 4);
272 /* Assign the correct bit position. */
273 x = ((x & 0x88) >> 3)
274 | ((x & 0x44) >> 1)
275 | ((x & 0x22) << 1)
276 | ((x & 0x11) << 3);
277 return x;
Richard Henderson5140d6b2020-11-06 10:59:36 -0800278#endif
Richard Henderson652a4b72015-09-14 13:00:34 -0700279}
280
281/**
282 * revbit16 - reverse the bits in a 16-bit value.
283 * @x: The value to modify.
284 */
285static inline uint16_t revbit16(uint16_t x)
286{
Richard Henderson5140d6b2020-11-06 10:59:36 -0800287#if __has_builtin(__builtin_bitreverse16)
288 return __builtin_bitreverse16(x);
289#else
Richard Henderson652a4b72015-09-14 13:00:34 -0700290 /* Assign the correct byte position. */
291 x = bswap16(x);
292 /* Assign the correct nibble position. */
293 x = ((x & 0xf0f0) >> 4)
294 | ((x & 0x0f0f) << 4);
295 /* Assign the correct bit position. */
296 x = ((x & 0x8888) >> 3)
297 | ((x & 0x4444) >> 1)
298 | ((x & 0x2222) << 1)
299 | ((x & 0x1111) << 3);
300 return x;
Richard Henderson5140d6b2020-11-06 10:59:36 -0800301#endif
Richard Henderson652a4b72015-09-14 13:00:34 -0700302}
303
304/**
305 * revbit32 - reverse the bits in a 32-bit value.
306 * @x: The value to modify.
307 */
308static inline uint32_t revbit32(uint32_t x)
309{
Richard Henderson5140d6b2020-11-06 10:59:36 -0800310#if __has_builtin(__builtin_bitreverse32)
311 return __builtin_bitreverse32(x);
312#else
Richard Henderson652a4b72015-09-14 13:00:34 -0700313 /* Assign the correct byte position. */
314 x = bswap32(x);
315 /* Assign the correct nibble position. */
316 x = ((x & 0xf0f0f0f0u) >> 4)
317 | ((x & 0x0f0f0f0fu) << 4);
318 /* Assign the correct bit position. */
319 x = ((x & 0x88888888u) >> 3)
320 | ((x & 0x44444444u) >> 1)
321 | ((x & 0x22222222u) << 1)
322 | ((x & 0x11111111u) << 3);
323 return x;
Richard Henderson5140d6b2020-11-06 10:59:36 -0800324#endif
Richard Henderson652a4b72015-09-14 13:00:34 -0700325}
326
327/**
328 * revbit64 - reverse the bits in a 64-bit value.
329 * @x: The value to modify.
330 */
331static inline uint64_t revbit64(uint64_t x)
332{
Richard Henderson5140d6b2020-11-06 10:59:36 -0800333#if __has_builtin(__builtin_bitreverse64)
334 return __builtin_bitreverse64(x);
335#else
Richard Henderson652a4b72015-09-14 13:00:34 -0700336 /* Assign the correct byte position. */
337 x = bswap64(x);
338 /* Assign the correct nibble position. */
339 x = ((x & 0xf0f0f0f0f0f0f0f0ull) >> 4)
340 | ((x & 0x0f0f0f0f0f0f0f0full) << 4);
341 /* Assign the correct bit position. */
342 x = ((x & 0x8888888888888888ull) >> 3)
343 | ((x & 0x4444444444444444ull) >> 1)
344 | ((x & 0x2222222222222222ull) << 1)
345 | ((x & 0x1111111111111111ull) << 3);
346 return x;
Richard Henderson5140d6b2020-11-06 10:59:36 -0800347#endif
Richard Henderson652a4b72015-09-14 13:00:34 -0700348}
349
Richard Hendersoncec07c02020-11-06 17:42:36 -0800350/**
Luis Piresd03bba02021-09-10 08:26:05 -0300351 * Return the absolute value of a 64-bit integer as an unsigned 64-bit value
352 */
353static inline uint64_t uabs64(int64_t v)
354{
355 return v < 0 ? -v : v;
356}
357
358/**
Richard Hendersoncec07c02020-11-06 17:42:36 -0800359 * sadd32_overflow - addition with overflow indication
360 * @x, @y: addends
361 * @ret: Output for sum
362 *
363 * Computes *@ret = @x + @y, and returns true if and only if that
364 * value has been truncated.
365 */
366static inline bool sadd32_overflow(int32_t x, int32_t y, int32_t *ret)
367{
368#if __has_builtin(__builtin_add_overflow) || __GNUC__ >= 5
369 return __builtin_add_overflow(x, y, ret);
370#else
371 *ret = x + y;
372 return ((*ret ^ x) & ~(x ^ y)) < 0;
373#endif
374}
375
376/**
377 * sadd64_overflow - addition with overflow indication
378 * @x, @y: addends
379 * @ret: Output for sum
380 *
381 * Computes *@ret = @x + @y, and returns true if and only if that
382 * value has been truncated.
383 */
384static inline bool sadd64_overflow(int64_t x, int64_t y, int64_t *ret)
385{
386#if __has_builtin(__builtin_add_overflow) || __GNUC__ >= 5
387 return __builtin_add_overflow(x, y, ret);
388#else
389 *ret = x + y;
390 return ((*ret ^ x) & ~(x ^ y)) < 0;
391#endif
392}
393
394/**
395 * uadd32_overflow - addition with overflow indication
396 * @x, @y: addends
397 * @ret: Output for sum
398 *
399 * Computes *@ret = @x + @y, and returns true if and only if that
400 * value has been truncated.
401 */
402static inline bool uadd32_overflow(uint32_t x, uint32_t y, uint32_t *ret)
403{
404#if __has_builtin(__builtin_add_overflow) || __GNUC__ >= 5
405 return __builtin_add_overflow(x, y, ret);
406#else
407 *ret = x + y;
408 return *ret < x;
409#endif
410}
411
412/**
413 * uadd64_overflow - addition with overflow indication
414 * @x, @y: addends
415 * @ret: Output for sum
416 *
417 * Computes *@ret = @x + @y, and returns true if and only if that
418 * value has been truncated.
419 */
420static inline bool uadd64_overflow(uint64_t x, uint64_t y, uint64_t *ret)
421{
422#if __has_builtin(__builtin_add_overflow) || __GNUC__ >= 5
423 return __builtin_add_overflow(x, y, ret);
424#else
425 *ret = x + y;
426 return *ret < x;
427#endif
428}
429
430/**
431 * ssub32_overflow - subtraction with overflow indication
432 * @x: Minuend
433 * @y: Subtrahend
434 * @ret: Output for difference
435 *
436 * Computes *@ret = @x - @y, and returns true if and only if that
437 * value has been truncated.
438 */
439static inline bool ssub32_overflow(int32_t x, int32_t y, int32_t *ret)
440{
441#if __has_builtin(__builtin_sub_overflow) || __GNUC__ >= 5
442 return __builtin_sub_overflow(x, y, ret);
443#else
444 *ret = x - y;
445 return ((*ret ^ x) & (x ^ y)) < 0;
446#endif
447}
448
449/**
450 * ssub64_overflow - subtraction with overflow indication
451 * @x: Minuend
452 * @y: Subtrahend
453 * @ret: Output for sum
454 *
455 * Computes *@ret = @x - @y, and returns true if and only if that
456 * value has been truncated.
457 */
458static inline bool ssub64_overflow(int64_t x, int64_t y, int64_t *ret)
459{
460#if __has_builtin(__builtin_sub_overflow) || __GNUC__ >= 5
461 return __builtin_sub_overflow(x, y, ret);
462#else
463 *ret = x - y;
464 return ((*ret ^ x) & (x ^ y)) < 0;
465#endif
466}
467
468/**
469 * usub32_overflow - subtraction with overflow indication
470 * @x: Minuend
471 * @y: Subtrahend
472 * @ret: Output for sum
473 *
474 * Computes *@ret = @x - @y, and returns true if and only if that
475 * value has been truncated.
476 */
477static inline bool usub32_overflow(uint32_t x, uint32_t y, uint32_t *ret)
478{
479#if __has_builtin(__builtin_sub_overflow) || __GNUC__ >= 5
480 return __builtin_sub_overflow(x, y, ret);
481#else
482 *ret = x - y;
483 return x < y;
484#endif
485}
486
487/**
488 * usub64_overflow - subtraction with overflow indication
489 * @x: Minuend
490 * @y: Subtrahend
491 * @ret: Output for sum
492 *
493 * Computes *@ret = @x - @y, and returns true if and only if that
494 * value has been truncated.
495 */
496static inline bool usub64_overflow(uint64_t x, uint64_t y, uint64_t *ret)
497{
498#if __has_builtin(__builtin_sub_overflow) || __GNUC__ >= 5
499 return __builtin_sub_overflow(x, y, ret);
500#else
501 *ret = x - y;
502 return x < y;
503#endif
504}
505
506/**
507 * smul32_overflow - multiplication with overflow indication
508 * @x, @y: Input multipliers
509 * @ret: Output for product
510 *
511 * Computes *@ret = @x * @y, and returns true if and only if that
512 * value has been truncated.
513 */
514static inline bool smul32_overflow(int32_t x, int32_t y, int32_t *ret)
515{
516#if __has_builtin(__builtin_mul_overflow) || __GNUC__ >= 5
517 return __builtin_mul_overflow(x, y, ret);
518#else
519 int64_t z = (int64_t)x * y;
520 *ret = z;
521 return *ret != z;
522#endif
523}
524
525/**
526 * smul64_overflow - multiplication with overflow indication
527 * @x, @y: Input multipliers
528 * @ret: Output for product
529 *
530 * Computes *@ret = @x * @y, and returns true if and only if that
531 * value has been truncated.
532 */
533static inline bool smul64_overflow(int64_t x, int64_t y, int64_t *ret)
534{
535#if __has_builtin(__builtin_mul_overflow) || __GNUC__ >= 5
536 return __builtin_mul_overflow(x, y, ret);
537#else
538 uint64_t hi, lo;
539 muls64(&lo, &hi, x, y);
540 *ret = lo;
541 return hi != ((int64_t)lo >> 63);
542#endif
543}
544
545/**
546 * umul32_overflow - multiplication with overflow indication
547 * @x, @y: Input multipliers
548 * @ret: Output for product
549 *
550 * Computes *@ret = @x * @y, and returns true if and only if that
551 * value has been truncated.
552 */
553static inline bool umul32_overflow(uint32_t x, uint32_t y, uint32_t *ret)
554{
555#if __has_builtin(__builtin_mul_overflow) || __GNUC__ >= 5
556 return __builtin_mul_overflow(x, y, ret);
557#else
558 uint64_t z = (uint64_t)x * y;
559 *ret = z;
560 return z > UINT32_MAX;
561#endif
562}
563
564/**
565 * umul64_overflow - multiplication with overflow indication
566 * @x, @y: Input multipliers
567 * @ret: Output for product
568 *
569 * Computes *@ret = @x * @y, and returns true if and only if that
570 * value has been truncated.
571 */
572static inline bool umul64_overflow(uint64_t x, uint64_t y, uint64_t *ret)
573{
574#if __has_builtin(__builtin_mul_overflow) || __GNUC__ >= 5
575 return __builtin_mul_overflow(x, y, ret);
576#else
577 uint64_t hi;
578 mulu64(ret, &hi, x, y);
579 return hi != 0;
580#endif
581}
582
Richard Henderson1ec80702020-11-13 03:22:23 +0000583/**
584 * uadd64_carry - addition with carry-in and carry-out
585 * @x, @y: addends
586 * @pcarry: in-out carry value
587 *
588 * Computes @x + @y + *@pcarry, placing the carry-out back
589 * into *@pcarry and returning the 64-bit sum.
590 */
591static inline uint64_t uadd64_carry(uint64_t x, uint64_t y, bool *pcarry)
592{
593#if __has_builtin(__builtin_addcll)
594 unsigned long long c = *pcarry;
595 x = __builtin_addcll(x, y, c, &c);
596 *pcarry = c & 1;
597 return x;
598#else
599 bool c = *pcarry;
600 /* This is clang's internal expansion of __builtin_addc. */
601 c = uadd64_overflow(x, c, &x);
602 c |= uadd64_overflow(x, y, &x);
603 *pcarry = c;
604 return x;
605#endif
606}
607
608/**
609 * usub64_borrow - subtraction with borrow-in and borrow-out
610 * @x, @y: addends
611 * @pborrow: in-out borrow value
612 *
613 * Computes @x - @y - *@pborrow, placing the borrow-out back
614 * into *@pborrow and returning the 64-bit sum.
615 */
616static inline uint64_t usub64_borrow(uint64_t x, uint64_t y, bool *pborrow)
617{
618#if __has_builtin(__builtin_subcll)
619 unsigned long long b = *pborrow;
620 x = __builtin_subcll(x, y, b, &b);
621 *pborrow = b & 1;
622 return x;
623#else
624 bool b = *pborrow;
625 b = usub64_overflow(x, b, &x);
626 b |= usub64_overflow(x, y, &x);
627 *pborrow = b;
628 return x;
629#endif
630}
631
Richard Henderson01654372013-02-13 17:47:34 -0800632/* Host type specific sizes of these routines. */
633
634#if ULONG_MAX == UINT32_MAX
635# define clzl clz32
636# define ctzl ctz32
637# define clol clo32
638# define ctol cto32
639# define ctpopl ctpop32
Richard Henderson652a4b72015-09-14 13:00:34 -0700640# define revbitl revbit32
Richard Henderson01654372013-02-13 17:47:34 -0800641#elif ULONG_MAX == UINT64_MAX
642# define clzl clz64
643# define ctzl ctz64
644# define clol clo64
645# define ctol cto64
646# define ctpopl ctpop64
Richard Henderson652a4b72015-09-14 13:00:34 -0700647# define revbitl revbit64
Richard Henderson01654372013-02-13 17:47:34 -0800648#else
649# error Unknown sizeof long
650#endif
651
Peter Maydell8f1ed5f2015-07-24 13:33:12 +0100652static inline bool is_power_of_2(uint64_t value)
653{
654 if (!value) {
Eric Blakee52eeb42016-05-31 12:33:31 -0600655 return false;
Peter Maydell8f1ed5f2015-07-24 13:33:12 +0100656 }
657
658 return !(value & (value - 1));
659}
660
Markus Armbruster43c64a02017-07-27 11:46:15 +0200661/**
662 * Return @value rounded down to the nearest power of two or zero.
663 */
664static inline uint64_t pow2floor(uint64_t value)
Peter Maydell8f1ed5f2015-07-24 13:33:12 +0100665{
Markus Armbruster43c64a02017-07-27 11:46:15 +0200666 if (!value) {
667 /* Avoid undefined shift by 64 */
668 return 0;
Peter Maydell8f1ed5f2015-07-24 13:33:12 +0100669 }
Markus Armbruster43c64a02017-07-27 11:46:15 +0200670 return 0x8000000000000000ull >> clz64(value);
Peter Maydell8f1ed5f2015-07-24 13:33:12 +0100671}
672
Markus Armbruster362aaf12017-07-27 11:46:16 +0200673/*
674 * Return @value rounded up to the nearest power of two modulo 2^64.
675 * This is *zero* for @value > 2^63, so be careful.
676 */
Peter Maydell8f1ed5f2015-07-24 13:33:12 +0100677static inline uint64_t pow2ceil(uint64_t value)
678{
Markus Armbruster362aaf12017-07-27 11:46:16 +0200679 int n = clz64(value - 1);
Peter Maydell8f1ed5f2015-07-24 13:33:12 +0100680
Markus Armbruster362aaf12017-07-27 11:46:16 +0200681 if (!n) {
682 /*
683 * @value - 1 has no leading zeroes, thus @value - 1 >= 2^63
684 * Therefore, either @value == 0 or @value > 2^63.
685 * If it's 0, return 1, else return 0.
686 */
687 return !value;
Peter Maydell8f1ed5f2015-07-24 13:33:12 +0100688 }
Markus Armbruster362aaf12017-07-27 11:46:16 +0200689 return 0x8000000000000000ull >> (n - 1);
Peter Maydell8f1ed5f2015-07-24 13:33:12 +0100690}
691
Yuval Shaia37e626c2018-01-14 11:01:43 +0200692static inline uint32_t pow2roundup32(uint32_t x)
693{
694 x |= (x >> 1);
695 x |= (x >> 2);
696 x |= (x >> 4);
697 x |= (x >> 8);
698 x |= (x >> 16);
699 return x + 1;
700}
701
Jose Ricardo Zivianif539fbe2017-01-10 00:10:09 -0200702/**
703 * urshift - 128-bit Unsigned Right Shift.
704 * @plow: in/out - lower 64-bit integer.
705 * @phigh: in/out - higher 64-bit integer.
706 * @shift: in - bytes to shift, between 0 and 127.
707 *
708 * Result is zero-extended and stored in plow/phigh, which are
709 * input/output variables. Shift values outside the range will
710 * be mod to 128. In other words, the caller is responsible to
711 * verify/assert both the shift range and plow/phigh pointers.
712 */
713void urshift(uint64_t *plow, uint64_t *phigh, int32_t shift);
714
715/**
716 * ulshift - 128-bit Unsigned Left Shift.
717 * @plow: in/out - lower 64-bit integer.
718 * @phigh: in/out - higher 64-bit integer.
719 * @shift: in - bytes to shift, between 0 and 127.
720 * @overflow: out - true if any 1-bit is shifted out.
721 *
722 * Result is zero-extended and stored in plow/phigh, which are
723 * input/output variables. Shift values outside the range will
724 * be mod to 128. In other words, the caller is responsible to
725 * verify/assert both the shift range and plow/phigh pointers.
726 */
727void ulshift(uint64_t *plow, uint64_t *phigh, int32_t shift, bool *overflow);
728
Paolo Bonzinicb9c3772012-12-06 12:15:58 +0100729#endif