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.
_addcarry_u32(unsigned char __cf,unsigned int __x,unsigned int __y,unsigned int * __p)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.
_subborrow_u32(unsigned char __cf,unsigned int __x,unsigned int __y,unsigned int * __p)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
_addcarry_u64(unsigned char __cf,unsigned long long __x,unsigned long long __y,unsigned long long * __p)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
_subborrow_u64(unsigned char __cf,unsigned long long __x,unsigned long long __y,unsigned long long * __p)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