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