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