1*cb14a3feSDimitry Andric /*===---- adcintrin.h - ADC intrinsics -------------------------------------=== 2*cb14a3feSDimitry Andric * 3*cb14a3feSDimitry Andric * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*cb14a3feSDimitry Andric * See https://llvm.org/LICENSE.txt for license information. 5*cb14a3feSDimitry Andric * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*cb14a3feSDimitry Andric * 7*cb14a3feSDimitry Andric *===-----------------------------------------------------------------------=== 8*cb14a3feSDimitry Andric */ 9*cb14a3feSDimitry Andric 10*cb14a3feSDimitry Andric #ifndef __ADCINTRIN_H 11*cb14a3feSDimitry Andric #define __ADCINTRIN_H 12*cb14a3feSDimitry Andric 13*cb14a3feSDimitry Andric #if !defined(__i386__) && !defined(__x86_64__) 14*cb14a3feSDimitry Andric #error "This header is only meant to be used on x86 and x64 architecture" 15*cb14a3feSDimitry Andric #endif 16*cb14a3feSDimitry Andric 17*cb14a3feSDimitry Andric /* Define the default attributes for the functions in this file. */ 18*cb14a3feSDimitry Andric #define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__)) 19*cb14a3feSDimitry Andric 20*cb14a3feSDimitry Andric /* Use C++ inline semantics in C++, GNU inline for C mode. */ 21*cb14a3feSDimitry Andric #if defined(__cplusplus) 22*cb14a3feSDimitry Andric #define __INLINE __inline 23*cb14a3feSDimitry Andric #else 24*cb14a3feSDimitry Andric #define __INLINE static __inline 25*cb14a3feSDimitry Andric #endif 26*cb14a3feSDimitry Andric 27*cb14a3feSDimitry Andric #if defined(__cplusplus) 28*cb14a3feSDimitry Andric extern "C" { 29*cb14a3feSDimitry Andric #endif 30*cb14a3feSDimitry Andric 31*cb14a3feSDimitry Andric /// Adds unsigned 32-bit integers \a __x and \a __y, plus 0 or 1 as indicated 32*cb14a3feSDimitry Andric /// by the carry flag \a __cf. Stores the unsigned 32-bit sum in the memory 33*cb14a3feSDimitry Andric /// at \a __p, and returns the 8-bit carry-out (carry flag). 34*cb14a3feSDimitry Andric /// 35*cb14a3feSDimitry Andric /// \code{.operation} 36*cb14a3feSDimitry Andric /// temp := (__cf == 0) ? 0 : 1 37*cb14a3feSDimitry Andric /// Store32(__p, __x + __y + temp) 38*cb14a3feSDimitry Andric /// result := CF 39*cb14a3feSDimitry Andric /// \endcode 40*cb14a3feSDimitry Andric /// 41*cb14a3feSDimitry Andric /// \headerfile <immintrin.h> 42*cb14a3feSDimitry Andric /// 43*cb14a3feSDimitry Andric /// This intrinsic corresponds to the \c ADC instruction. 44*cb14a3feSDimitry Andric /// 45*cb14a3feSDimitry Andric /// \param __cf 46*cb14a3feSDimitry Andric /// The 8-bit unsigned carry flag; any non-zero value indicates carry. 47*cb14a3feSDimitry Andric /// \param __x 48*cb14a3feSDimitry Andric /// A 32-bit unsigned addend. 49*cb14a3feSDimitry Andric /// \param __y 50*cb14a3feSDimitry Andric /// A 32-bit unsigned addend. 51*cb14a3feSDimitry Andric /// \param __p 52*cb14a3feSDimitry Andric /// Pointer to memory for storing the sum. 53*cb14a3feSDimitry Andric /// \returns The 8-bit unsigned carry-out value. 54*cb14a3feSDimitry Andric __INLINE unsigned char __DEFAULT_FN_ATTRS _addcarry_u32(unsigned char __cf, 55*cb14a3feSDimitry Andric unsigned int __x, 56*cb14a3feSDimitry Andric unsigned int __y, 57*cb14a3feSDimitry Andric unsigned int *__p) { 58*cb14a3feSDimitry Andric return __builtin_ia32_addcarryx_u32(__cf, __x, __y, __p); 59*cb14a3feSDimitry Andric } 60*cb14a3feSDimitry Andric 61*cb14a3feSDimitry Andric /// Adds unsigned 32-bit integer \a __y to 0 or 1 as indicated by the carry 62*cb14a3feSDimitry Andric /// flag \a __cf, and subtracts the result from unsigned 32-bit integer 63*cb14a3feSDimitry Andric /// \a __x. Stores the unsigned 32-bit difference in the memory at \a __p, 64*cb14a3feSDimitry Andric /// and returns the 8-bit carry-out (carry or overflow flag). 65*cb14a3feSDimitry Andric /// 66*cb14a3feSDimitry Andric /// \code{.operation} 67*cb14a3feSDimitry Andric /// temp := (__cf == 0) ? 0 : 1 68*cb14a3feSDimitry Andric /// Store32(__p, __x - (__y + temp)) 69*cb14a3feSDimitry Andric /// result := CF 70*cb14a3feSDimitry Andric /// \endcode 71*cb14a3feSDimitry Andric /// 72*cb14a3feSDimitry Andric /// \headerfile <immintrin.h> 73*cb14a3feSDimitry Andric /// 74*cb14a3feSDimitry Andric /// This intrinsic corresponds to the \c SBB instruction. 75*cb14a3feSDimitry Andric /// 76*cb14a3feSDimitry Andric /// \param __cf 77*cb14a3feSDimitry Andric /// The 8-bit unsigned carry flag; any non-zero value indicates carry. 78*cb14a3feSDimitry Andric /// \param __x 79*cb14a3feSDimitry Andric /// The 32-bit unsigned minuend. 80*cb14a3feSDimitry Andric /// \param __y 81*cb14a3feSDimitry Andric /// The 32-bit unsigned subtrahend. 82*cb14a3feSDimitry Andric /// \param __p 83*cb14a3feSDimitry Andric /// Pointer to memory for storing the difference. 84*cb14a3feSDimitry Andric /// \returns The 8-bit unsigned carry-out value. 85*cb14a3feSDimitry Andric __INLINE unsigned char __DEFAULT_FN_ATTRS _subborrow_u32(unsigned char __cf, 86*cb14a3feSDimitry Andric unsigned int __x, 87*cb14a3feSDimitry Andric unsigned int __y, 88*cb14a3feSDimitry Andric unsigned int *__p) { 89*cb14a3feSDimitry Andric return __builtin_ia32_subborrow_u32(__cf, __x, __y, __p); 90*cb14a3feSDimitry Andric } 91*cb14a3feSDimitry Andric 92*cb14a3feSDimitry Andric #ifdef __x86_64__ 93*cb14a3feSDimitry Andric /// Adds unsigned 64-bit integers \a __x and \a __y, plus 0 or 1 as indicated 94*cb14a3feSDimitry Andric /// by the carry flag \a __cf. Stores the unsigned 64-bit sum in the memory 95*cb14a3feSDimitry Andric /// at \a __p, and returns the 8-bit carry-out (carry flag). 96*cb14a3feSDimitry Andric /// 97*cb14a3feSDimitry Andric /// \code{.operation} 98*cb14a3feSDimitry Andric /// temp := (__cf == 0) ? 0 : 1 99*cb14a3feSDimitry Andric /// Store64(__p, __x + __y + temp) 100*cb14a3feSDimitry Andric /// result := CF 101*cb14a3feSDimitry Andric /// \endcode 102*cb14a3feSDimitry Andric /// 103*cb14a3feSDimitry Andric /// \headerfile <immintrin.h> 104*cb14a3feSDimitry Andric /// 105*cb14a3feSDimitry Andric /// This intrinsic corresponds to the \c ADC instruction. 106*cb14a3feSDimitry Andric /// 107*cb14a3feSDimitry Andric /// \param __cf 108*cb14a3feSDimitry Andric /// The 8-bit unsigned carry flag; any non-zero value indicates carry. 109*cb14a3feSDimitry Andric /// \param __x 110*cb14a3feSDimitry Andric /// A 64-bit unsigned addend. 111*cb14a3feSDimitry Andric /// \param __y 112*cb14a3feSDimitry Andric /// A 64-bit unsigned addend. 113*cb14a3feSDimitry Andric /// \param __p 114*cb14a3feSDimitry Andric /// Pointer to memory for storing the sum. 115*cb14a3feSDimitry Andric /// \returns The 8-bit unsigned carry-out value. 116*cb14a3feSDimitry Andric __INLINE unsigned char __DEFAULT_FN_ATTRS 117*cb14a3feSDimitry Andric _addcarry_u64(unsigned char __cf, unsigned long long __x, 118*cb14a3feSDimitry Andric unsigned long long __y, unsigned long long *__p) { 119*cb14a3feSDimitry Andric return __builtin_ia32_addcarryx_u64(__cf, __x, __y, __p); 120*cb14a3feSDimitry Andric } 121*cb14a3feSDimitry Andric 122*cb14a3feSDimitry Andric /// Adds unsigned 64-bit integer \a __y to 0 or 1 as indicated by the carry 123*cb14a3feSDimitry Andric /// flag \a __cf, and subtracts the result from unsigned 64-bit integer 124*cb14a3feSDimitry Andric /// \a __x. Stores the unsigned 64-bit difference in the memory at \a __p, 125*cb14a3feSDimitry Andric /// and returns the 8-bit carry-out (carry or overflow flag). 126*cb14a3feSDimitry Andric /// 127*cb14a3feSDimitry Andric /// \code{.operation} 128*cb14a3feSDimitry Andric /// temp := (__cf == 0) ? 0 : 1 129*cb14a3feSDimitry Andric /// Store64(__p, __x - (__y + temp)) 130*cb14a3feSDimitry Andric /// result := CF 131*cb14a3feSDimitry Andric /// \endcode 132*cb14a3feSDimitry Andric /// 133*cb14a3feSDimitry Andric /// \headerfile <immintrin.h> 134*cb14a3feSDimitry Andric /// 135*cb14a3feSDimitry Andric /// This intrinsic corresponds to the \c ADC instruction. 136*cb14a3feSDimitry Andric /// 137*cb14a3feSDimitry Andric /// \param __cf 138*cb14a3feSDimitry Andric /// The 8-bit unsigned carry flag; any non-zero value indicates carry. 139*cb14a3feSDimitry Andric /// \param __x 140*cb14a3feSDimitry Andric /// The 64-bit unsigned minuend. 141*cb14a3feSDimitry Andric /// \param __y 142*cb14a3feSDimitry Andric /// The 64-bit unsigned subtrahend. 143*cb14a3feSDimitry Andric /// \param __p 144*cb14a3feSDimitry Andric /// Pointer to memory for storing the difference. 145*cb14a3feSDimitry Andric /// \returns The 8-bit unsigned carry-out value. 146*cb14a3feSDimitry Andric __INLINE unsigned char __DEFAULT_FN_ATTRS 147*cb14a3feSDimitry Andric _subborrow_u64(unsigned char __cf, unsigned long long __x, 148*cb14a3feSDimitry Andric unsigned long long __y, unsigned long long *__p) { 149*cb14a3feSDimitry Andric return __builtin_ia32_subborrow_u64(__cf, __x, __y, __p); 150*cb14a3feSDimitry Andric } 151*cb14a3feSDimitry Andric #endif 152*cb14a3feSDimitry Andric 153*cb14a3feSDimitry Andric #if defined(__cplusplus) 154*cb14a3feSDimitry Andric } 155*cb14a3feSDimitry Andric #endif 156*cb14a3feSDimitry Andric 157*cb14a3feSDimitry Andric #undef __INLINE 158*cb14a3feSDimitry Andric #undef __DEFAULT_FN_ATTRS 159*cb14a3feSDimitry Andric 160*cb14a3feSDimitry Andric #endif /* __ADCINTRIN_H */ 161