1*bdd1243dSDimitry Andric /*===----------------------- raointintrin.h - RAOINT ------------------------===
2*bdd1243dSDimitry Andric *
3*bdd1243dSDimitry Andric * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*bdd1243dSDimitry Andric * See https://llvm.org/LICENSE.txt for license information.
5*bdd1243dSDimitry Andric * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*bdd1243dSDimitry Andric *
7*bdd1243dSDimitry Andric *===-----------------------------------------------------------------------===
8*bdd1243dSDimitry Andric */
9*bdd1243dSDimitry Andric
10*bdd1243dSDimitry Andric #ifndef __X86GPRINTRIN_H
11*bdd1243dSDimitry Andric #error "Never use <raointintrin.h> directly; include <x86gprintrin.h> instead."
12*bdd1243dSDimitry Andric #endif // __X86GPRINTRIN_H
13*bdd1243dSDimitry Andric
14*bdd1243dSDimitry Andric #ifndef __RAOINTINTRIN_H
15*bdd1243dSDimitry Andric #define __RAOINTINTRIN_H
16*bdd1243dSDimitry Andric
17*bdd1243dSDimitry Andric #define __DEFAULT_FN_ATTRS \
18*bdd1243dSDimitry Andric __attribute__((__always_inline__, __nodebug__, __target__("raoint")))
19*bdd1243dSDimitry Andric
20*bdd1243dSDimitry Andric /// Atomically add a 32-bit value at memory operand \a __A and a 32-bit \a __B,
21*bdd1243dSDimitry Andric /// and store the result to the same memory location.
22*bdd1243dSDimitry Andric ///
23*bdd1243dSDimitry Andric /// This intrinsic should be used for contention or weak ordering. It may
24*bdd1243dSDimitry Andric /// result in bad performance for hot data used by single thread only.
25*bdd1243dSDimitry Andric ///
26*bdd1243dSDimitry Andric /// \headerfile <x86intrin.h>
27*bdd1243dSDimitry Andric ///
28*bdd1243dSDimitry Andric /// This intrinsic corresponds to the \c AADD instruction.
29*bdd1243dSDimitry Andric ///
30*bdd1243dSDimitry Andric /// \param __A
31*bdd1243dSDimitry Andric /// A pointer to a 32-bit memory location.
32*bdd1243dSDimitry Andric /// \param __B
33*bdd1243dSDimitry Andric /// A 32-bit integer value.
34*bdd1243dSDimitry Andric ///
35*bdd1243dSDimitry Andric /// \code{.operation}
36*bdd1243dSDimitry Andric /// MEM[__A+31:__A] := MEM[__A+31:__A] + __B[31:0]
37*bdd1243dSDimitry Andric /// \endcode
_aadd_i32(int * __A,int __B)38*bdd1243dSDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS _aadd_i32(int *__A, int __B) {
39*bdd1243dSDimitry Andric __builtin_ia32_aadd32((int *)__A, __B);
40*bdd1243dSDimitry Andric }
41*bdd1243dSDimitry Andric
42*bdd1243dSDimitry Andric /// Atomically and a 32-bit value at memory operand \a __A and a 32-bit \a __B,
43*bdd1243dSDimitry Andric /// and store the result to the same memory location.
44*bdd1243dSDimitry Andric ///
45*bdd1243dSDimitry Andric /// This intrinsic should be used for contention or weak ordering. It may
46*bdd1243dSDimitry Andric /// result in bad performance for hot data used by single thread only.
47*bdd1243dSDimitry Andric ///
48*bdd1243dSDimitry Andric /// \headerfile <x86intrin.h>
49*bdd1243dSDimitry Andric ///
50*bdd1243dSDimitry Andric /// This intrinsic corresponds to the \c AAND instruction.
51*bdd1243dSDimitry Andric ///
52*bdd1243dSDimitry Andric /// \param __A
53*bdd1243dSDimitry Andric /// A pointer to a 32-bit memory location.
54*bdd1243dSDimitry Andric /// \param __B
55*bdd1243dSDimitry Andric /// A 32-bit integer value.
56*bdd1243dSDimitry Andric ///
57*bdd1243dSDimitry Andric /// \code{.operation}
58*bdd1243dSDimitry Andric /// MEM[__A+31:__A] := MEM[__A+31:__A] AND __B[31:0]
59*bdd1243dSDimitry Andric /// \endcode
_aand_i32(int * __A,int __B)60*bdd1243dSDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS _aand_i32(int *__A, int __B) {
61*bdd1243dSDimitry Andric __builtin_ia32_aand32((int *)__A, __B);
62*bdd1243dSDimitry Andric }
63*bdd1243dSDimitry Andric
64*bdd1243dSDimitry Andric /// Atomically or a 32-bit value at memory operand \a __A and a 32-bit \a __B,
65*bdd1243dSDimitry Andric /// and store the result to the same memory location.
66*bdd1243dSDimitry Andric ///
67*bdd1243dSDimitry Andric /// This intrinsic should be used for contention or weak ordering. It may
68*bdd1243dSDimitry Andric /// result in bad performance for hot data used by single thread only.
69*bdd1243dSDimitry Andric ///
70*bdd1243dSDimitry Andric /// \headerfile <x86intrin.h>
71*bdd1243dSDimitry Andric ///
72*bdd1243dSDimitry Andric /// This intrinsic corresponds to the \c AOR instruction.
73*bdd1243dSDimitry Andric ///
74*bdd1243dSDimitry Andric /// \param __A
75*bdd1243dSDimitry Andric /// A pointer to a 32-bit memory location.
76*bdd1243dSDimitry Andric /// \param __B
77*bdd1243dSDimitry Andric /// A 32-bit integer value.
78*bdd1243dSDimitry Andric ///
79*bdd1243dSDimitry Andric /// \code{.operation}
80*bdd1243dSDimitry Andric /// MEM[__A+31:__A] := MEM[__A+31:__A] OR __B[31:0]
81*bdd1243dSDimitry Andric /// \endcode
_aor_i32(int * __A,int __B)82*bdd1243dSDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS _aor_i32(int *__A, int __B) {
83*bdd1243dSDimitry Andric __builtin_ia32_aor32((int *)__A, __B);
84*bdd1243dSDimitry Andric }
85*bdd1243dSDimitry Andric
86*bdd1243dSDimitry Andric /// Atomically xor a 32-bit value at memory operand \a __A and a 32-bit \a __B,
87*bdd1243dSDimitry Andric /// and store the result to the same memory location.
88*bdd1243dSDimitry Andric ///
89*bdd1243dSDimitry Andric /// This intrinsic should be used for contention or weak ordering. It may
90*bdd1243dSDimitry Andric /// result in bad performance for hot data used by single thread only.
91*bdd1243dSDimitry Andric ///
92*bdd1243dSDimitry Andric /// \headerfile <x86intrin.h>
93*bdd1243dSDimitry Andric ///
94*bdd1243dSDimitry Andric /// This intrinsic corresponds to the \c AXOR instruction.
95*bdd1243dSDimitry Andric ///
96*bdd1243dSDimitry Andric /// \param __A
97*bdd1243dSDimitry Andric /// A pointer to a 32-bit memory location.
98*bdd1243dSDimitry Andric /// \param __B
99*bdd1243dSDimitry Andric /// A 32-bit integer value.
100*bdd1243dSDimitry Andric ///
101*bdd1243dSDimitry Andric /// \code{.operation}
102*bdd1243dSDimitry Andric /// MEM[__A+31:__A] := MEM[__A+31:__A] XOR __B[31:0]
103*bdd1243dSDimitry Andric /// \endcode
_axor_i32(int * __A,int __B)104*bdd1243dSDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS _axor_i32(int *__A, int __B) {
105*bdd1243dSDimitry Andric __builtin_ia32_axor32((int *)__A, __B);
106*bdd1243dSDimitry Andric }
107*bdd1243dSDimitry Andric
108*bdd1243dSDimitry Andric #ifdef __x86_64__
109*bdd1243dSDimitry Andric /// Atomically add a 64-bit value at memory operand \a __A and a 64-bit \a __B,
110*bdd1243dSDimitry Andric /// and store the result to the same memory location.
111*bdd1243dSDimitry Andric ///
112*bdd1243dSDimitry Andric /// This intrinsic should be used for contention or weak ordering. It may
113*bdd1243dSDimitry Andric /// result in bad performance for hot data used by single thread only.
114*bdd1243dSDimitry Andric ///
115*bdd1243dSDimitry Andric /// \headerfile <x86intrin.h>
116*bdd1243dSDimitry Andric ///
117*bdd1243dSDimitry Andric /// This intrinsic corresponds to the \c AADD instruction.
118*bdd1243dSDimitry Andric ///
119*bdd1243dSDimitry Andric /// \param __A
120*bdd1243dSDimitry Andric /// A pointer to a 64-bit memory location.
121*bdd1243dSDimitry Andric /// \param __B
122*bdd1243dSDimitry Andric /// A 64-bit integer value.
123*bdd1243dSDimitry Andric ///
124*bdd1243dSDimitry Andric /// \code{.operation}
125*bdd1243dSDimitry Andric /// MEM[__A+63:__A] := MEM[__A+63:__A] + __B[63:0]
126*bdd1243dSDimitry Andric /// \endcode
_aadd_i64(long long * __A,long long __B)127*bdd1243dSDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS _aadd_i64(long long *__A,
128*bdd1243dSDimitry Andric long long __B) {
129*bdd1243dSDimitry Andric __builtin_ia32_aadd64((long long *)__A, __B);
130*bdd1243dSDimitry Andric }
131*bdd1243dSDimitry Andric
132*bdd1243dSDimitry Andric /// Atomically and a 64-bit value at memory operand \a __A and a 64-bit \a __B,
133*bdd1243dSDimitry Andric /// and store the result to the same memory location.
134*bdd1243dSDimitry Andric ///
135*bdd1243dSDimitry Andric /// This intrinsic should be used for contention or weak ordering. It may
136*bdd1243dSDimitry Andric /// result in bad performance for hot data used by single thread only.
137*bdd1243dSDimitry Andric ///
138*bdd1243dSDimitry Andric /// \headerfile <x86intrin.h>
139*bdd1243dSDimitry Andric ///
140*bdd1243dSDimitry Andric /// This intrinsic corresponds to the \c AAND instruction.
141*bdd1243dSDimitry Andric ///
142*bdd1243dSDimitry Andric /// \param __A
143*bdd1243dSDimitry Andric /// A pointer to a 64-bit memory location.
144*bdd1243dSDimitry Andric /// \param __B
145*bdd1243dSDimitry Andric /// A 64-bit integer value.
146*bdd1243dSDimitry Andric ///
147*bdd1243dSDimitry Andric /// \code{.operation}
148*bdd1243dSDimitry Andric /// MEM[__A+63:__A] := MEM[__A+63:__A] AND __B[63:0]
149*bdd1243dSDimitry Andric /// \endcode
_aand_i64(long long * __A,long long __B)150*bdd1243dSDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS _aand_i64(long long *__A,
151*bdd1243dSDimitry Andric long long __B) {
152*bdd1243dSDimitry Andric __builtin_ia32_aand64((long long *)__A, __B);
153*bdd1243dSDimitry Andric }
154*bdd1243dSDimitry Andric
155*bdd1243dSDimitry Andric /// Atomically or a 64-bit value at memory operand \a __A and a 64-bit \a __B,
156*bdd1243dSDimitry Andric /// and store the result to the same memory location.
157*bdd1243dSDimitry Andric ///
158*bdd1243dSDimitry Andric /// This intrinsic should be used for contention or weak ordering. It may
159*bdd1243dSDimitry Andric /// result in bad performance for hot data used by single thread only.
160*bdd1243dSDimitry Andric ///
161*bdd1243dSDimitry Andric /// \headerfile <x86intrin.h>
162*bdd1243dSDimitry Andric ///
163*bdd1243dSDimitry Andric /// This intrinsic corresponds to the \c AOR instruction.
164*bdd1243dSDimitry Andric ///
165*bdd1243dSDimitry Andric /// \param __A
166*bdd1243dSDimitry Andric /// A pointer to a 64-bit memory location.
167*bdd1243dSDimitry Andric /// \param __B
168*bdd1243dSDimitry Andric /// A 64-bit integer value.
169*bdd1243dSDimitry Andric ///
170*bdd1243dSDimitry Andric /// \code{.operation}
171*bdd1243dSDimitry Andric /// MEM[__A+63:__A] := MEM[__A+63:__A] OR __B[63:0]
172*bdd1243dSDimitry Andric /// \endcode
_aor_i64(long long * __A,long long __B)173*bdd1243dSDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS _aor_i64(long long *__A,
174*bdd1243dSDimitry Andric long long __B) {
175*bdd1243dSDimitry Andric __builtin_ia32_aor64((long long *)__A, __B);
176*bdd1243dSDimitry Andric }
177*bdd1243dSDimitry Andric
178*bdd1243dSDimitry Andric /// Atomically xor a 64-bit value at memory operand \a __A and a 64-bit \a __B,
179*bdd1243dSDimitry Andric /// and store the result to the same memory location.
180*bdd1243dSDimitry Andric ///
181*bdd1243dSDimitry Andric /// This intrinsic should be used for contention or weak ordering. It may
182*bdd1243dSDimitry Andric /// result in bad performance for hot data used by single thread only.
183*bdd1243dSDimitry Andric ///
184*bdd1243dSDimitry Andric /// \headerfile <x86intrin.h>
185*bdd1243dSDimitry Andric ///
186*bdd1243dSDimitry Andric /// This intrinsic corresponds to the \c AXOR instruction.
187*bdd1243dSDimitry Andric ///
188*bdd1243dSDimitry Andric /// \param __A
189*bdd1243dSDimitry Andric /// A pointer to a 64-bit memory location.
190*bdd1243dSDimitry Andric /// \param __B
191*bdd1243dSDimitry Andric /// A 64-bit integer value.
192*bdd1243dSDimitry Andric ///
193*bdd1243dSDimitry Andric /// \code{.operation}
194*bdd1243dSDimitry Andric /// MEM[__A+63:__A] := MEM[__A+63:__A] XOR __B[63:0]
195*bdd1243dSDimitry Andric /// \endcode
_axor_i64(long long * __A,long long __B)196*bdd1243dSDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS _axor_i64(long long *__A,
197*bdd1243dSDimitry Andric long long __B) {
198*bdd1243dSDimitry Andric __builtin_ia32_axor64((long long *)__A, __B);
199*bdd1243dSDimitry Andric }
200*bdd1243dSDimitry Andric #endif // __x86_64__
201*bdd1243dSDimitry Andric
202*bdd1243dSDimitry Andric #undef __DEFAULT_FN_ATTRS
203*bdd1243dSDimitry Andric #endif // __RAOINTINTRIN_H
204