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) 28extern "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