https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110304
Bug ID: 110304
Summary: __builtin_adcs missing and you miss the point of
builtin_adcb
Product: gcc
Version: unknown
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: unlvsur at live dot com
Target Milestone: ---
https://github.com/gcc-mirror/gcc/commit/2b4e0415ad664cdb3ce87d1f7eee5ca26911a05b#
This does not include __builtin_adcb, __builtin_adcs and __builtin_subcb,
__builtin_subcs
"
While the design of these builtins in clang is questionable,
rather than being say
unsigned __builtin_addc (unsigned, unsigned, bool, bool *)
"
You miss the point of the point when it falls back to architectures like mips,
wasm, riscv or loongarch where they do not provide flags at all:
template<::std::unsigned_integral T>
inline constexpr T add_carry(T a,T b,T carryin,T& carryout) noexcept
{
[[assume(carryin==0||carryin==1)]];
a+=b;
carryout=a<b;
a+=carryin;
carryout+=a<carryin;
return a;
}
template<::std::unsigned_integral T>
inline constexpr T sub_carry(T a,T b,T carryin,T& carryout) noexcept
{
[[assume(carryin==0||carryin==1)]];
a-=b;
carryout=b<a;
a-=carryin;
carryout+=carryin<a;
return a;
}
Mine is much faster than your __builtin_uadd_overflow on these architectures.
#define __builtin_addc(a,b,carry_in,carry_out) \
({ unsigned _s; \
unsigned _c1 = __builtin_uadd_overflow (a, b, &_s); \
unsigned _c2 = __builtin_uadd_overflow (_s, carry_in, &_s); \
*(carry_out) = (_c1 | _c2); \
_s; })