mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-28 20:41:52 -06:00
qemu/host-utils: Add wrappers for carry builtins
These builtins came in clang 3.8, but are not present in gcc through version 11. Even in clang the optimization is only ideal on x86_64, but never worse than the hand-coding that we currently do. Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
cec07c0b61
commit
1ec8070e58
1 changed files with 50 additions and 0 deletions
|
@ -26,6 +26,7 @@
|
||||||
#ifndef HOST_UTILS_H
|
#ifndef HOST_UTILS_H
|
||||||
#define HOST_UTILS_H
|
#define HOST_UTILS_H
|
||||||
|
|
||||||
|
#include "qemu/compiler.h"
|
||||||
#include "qemu/bswap.h"
|
#include "qemu/bswap.h"
|
||||||
|
|
||||||
#ifdef CONFIG_INT128
|
#ifdef CONFIG_INT128
|
||||||
|
@ -581,6 +582,55 @@ static inline bool umul64_overflow(uint64_t x, uint64_t y, uint64_t *ret)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* uadd64_carry - addition with carry-in and carry-out
|
||||||
|
* @x, @y: addends
|
||||||
|
* @pcarry: in-out carry value
|
||||||
|
*
|
||||||
|
* Computes @x + @y + *@pcarry, placing the carry-out back
|
||||||
|
* into *@pcarry and returning the 64-bit sum.
|
||||||
|
*/
|
||||||
|
static inline uint64_t uadd64_carry(uint64_t x, uint64_t y, bool *pcarry)
|
||||||
|
{
|
||||||
|
#if __has_builtin(__builtin_addcll)
|
||||||
|
unsigned long long c = *pcarry;
|
||||||
|
x = __builtin_addcll(x, y, c, &c);
|
||||||
|
*pcarry = c & 1;
|
||||||
|
return x;
|
||||||
|
#else
|
||||||
|
bool c = *pcarry;
|
||||||
|
/* This is clang's internal expansion of __builtin_addc. */
|
||||||
|
c = uadd64_overflow(x, c, &x);
|
||||||
|
c |= uadd64_overflow(x, y, &x);
|
||||||
|
*pcarry = c;
|
||||||
|
return x;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* usub64_borrow - subtraction with borrow-in and borrow-out
|
||||||
|
* @x, @y: addends
|
||||||
|
* @pborrow: in-out borrow value
|
||||||
|
*
|
||||||
|
* Computes @x - @y - *@pborrow, placing the borrow-out back
|
||||||
|
* into *@pborrow and returning the 64-bit sum.
|
||||||
|
*/
|
||||||
|
static inline uint64_t usub64_borrow(uint64_t x, uint64_t y, bool *pborrow)
|
||||||
|
{
|
||||||
|
#if __has_builtin(__builtin_subcll)
|
||||||
|
unsigned long long b = *pborrow;
|
||||||
|
x = __builtin_subcll(x, y, b, &b);
|
||||||
|
*pborrow = b & 1;
|
||||||
|
return x;
|
||||||
|
#else
|
||||||
|
bool b = *pborrow;
|
||||||
|
b = usub64_overflow(x, b, &x);
|
||||||
|
b |= usub64_overflow(x, y, &x);
|
||||||
|
*pborrow = b;
|
||||||
|
return x;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/* Host type specific sizes of these routines. */
|
/* Host type specific sizes of these routines. */
|
||||||
|
|
||||||
#if ULONG_MAX == UINT32_MAX
|
#if ULONG_MAX == UINT32_MAX
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue