annotate clang/lib/Headers/ia32intrin.h @ 176:de4ac79aef9d

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 17:13:11 +0900
parents 1d019706d866
children 2e18cbf3894f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 /* ===-------- ia32intrin.h ---------------------------------------------------===
anatofuz
parents:
diff changeset
2 *
anatofuz
parents:
diff changeset
3 * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
anatofuz
parents:
diff changeset
4 * See https://llvm.org/LICENSE.txt for license information.
anatofuz
parents:
diff changeset
5 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
anatofuz
parents:
diff changeset
6 *
anatofuz
parents:
diff changeset
7 *===-----------------------------------------------------------------------===
anatofuz
parents:
diff changeset
8 */
anatofuz
parents:
diff changeset
9
anatofuz
parents:
diff changeset
10 #ifndef __X86INTRIN_H
anatofuz
parents:
diff changeset
11 #error "Never use <ia32intrin.h> directly; include <x86intrin.h> instead."
anatofuz
parents:
diff changeset
12 #endif
anatofuz
parents:
diff changeset
13
anatofuz
parents:
diff changeset
14 #ifndef __IA32INTRIN_H
anatofuz
parents:
diff changeset
15 #define __IA32INTRIN_H
anatofuz
parents:
diff changeset
16
anatofuz
parents:
diff changeset
17 /** Find the first set bit starting from the lsb. Result is undefined if
anatofuz
parents:
diff changeset
18 * input is 0.
anatofuz
parents:
diff changeset
19 *
anatofuz
parents:
diff changeset
20 * \headerfile <x86intrin.h>
anatofuz
parents:
diff changeset
21 *
anatofuz
parents:
diff changeset
22 * This intrinsic corresponds to the <c> BSF </c> instruction or the
anatofuz
parents:
diff changeset
23 * <c> TZCNT </c> instruction.
anatofuz
parents:
diff changeset
24 *
anatofuz
parents:
diff changeset
25 * \param __A
anatofuz
parents:
diff changeset
26 * A 32-bit integer operand.
anatofuz
parents:
diff changeset
27 * \returns A 32-bit integer containing the bit number.
anatofuz
parents:
diff changeset
28 */
anatofuz
parents:
diff changeset
29 static __inline__ int __attribute__((__always_inline__, __nodebug__))
anatofuz
parents:
diff changeset
30 __bsfd(int __A) {
anatofuz
parents:
diff changeset
31 return __builtin_ctz(__A);
anatofuz
parents:
diff changeset
32 }
anatofuz
parents:
diff changeset
33
anatofuz
parents:
diff changeset
34 /** Find the first set bit starting from the msb. Result is undefined if
anatofuz
parents:
diff changeset
35 * input is 0.
anatofuz
parents:
diff changeset
36 *
anatofuz
parents:
diff changeset
37 * \headerfile <x86intrin.h>
anatofuz
parents:
diff changeset
38 *
anatofuz
parents:
diff changeset
39 * This intrinsic corresponds to the <c> BSR </c> instruction or the
anatofuz
parents:
diff changeset
40 * <c> LZCNT </c> instruction and an <c> XOR </c>.
anatofuz
parents:
diff changeset
41 *
anatofuz
parents:
diff changeset
42 * \param __A
anatofuz
parents:
diff changeset
43 * A 32-bit integer operand.
anatofuz
parents:
diff changeset
44 * \returns A 32-bit integer containing the bit number.
anatofuz
parents:
diff changeset
45 */
anatofuz
parents:
diff changeset
46 static __inline__ int __attribute__((__always_inline__, __nodebug__))
anatofuz
parents:
diff changeset
47 __bsrd(int __A) {
anatofuz
parents:
diff changeset
48 return 31 - __builtin_clz(__A);
anatofuz
parents:
diff changeset
49 }
anatofuz
parents:
diff changeset
50
anatofuz
parents:
diff changeset
51 /** Swaps the bytes in the input. Converting little endian to big endian or
anatofuz
parents:
diff changeset
52 * vice versa.
anatofuz
parents:
diff changeset
53 *
anatofuz
parents:
diff changeset
54 * \headerfile <x86intrin.h>
anatofuz
parents:
diff changeset
55 *
anatofuz
parents:
diff changeset
56 * This intrinsic corresponds to the <c> BSWAP </c> instruction.
anatofuz
parents:
diff changeset
57 *
anatofuz
parents:
diff changeset
58 * \param __A
anatofuz
parents:
diff changeset
59 * A 32-bit integer operand.
anatofuz
parents:
diff changeset
60 * \returns A 32-bit integer containing the swapped bytes.
anatofuz
parents:
diff changeset
61 */
anatofuz
parents:
diff changeset
62 static __inline__ int __attribute__((__always_inline__, __nodebug__))
anatofuz
parents:
diff changeset
63 __bswapd(int __A) {
anatofuz
parents:
diff changeset
64 return __builtin_bswap32(__A);
anatofuz
parents:
diff changeset
65 }
anatofuz
parents:
diff changeset
66
anatofuz
parents:
diff changeset
67 static __inline__ int __attribute__((__always_inline__, __nodebug__))
anatofuz
parents:
diff changeset
68 _bswap(int __A) {
anatofuz
parents:
diff changeset
69 return __builtin_bswap32(__A);
anatofuz
parents:
diff changeset
70 }
anatofuz
parents:
diff changeset
71
anatofuz
parents:
diff changeset
72 #define _bit_scan_forward(A) __bsfd((A))
anatofuz
parents:
diff changeset
73 #define _bit_scan_reverse(A) __bsrd((A))
anatofuz
parents:
diff changeset
74
anatofuz
parents:
diff changeset
75 #ifdef __x86_64__
anatofuz
parents:
diff changeset
76 /** Find the first set bit starting from the lsb. Result is undefined if
anatofuz
parents:
diff changeset
77 * input is 0.
anatofuz
parents:
diff changeset
78 *
anatofuz
parents:
diff changeset
79 * \headerfile <x86intrin.h>
anatofuz
parents:
diff changeset
80 *
anatofuz
parents:
diff changeset
81 * This intrinsic corresponds to the <c> BSF </c> instruction or the
anatofuz
parents:
diff changeset
82 * <c> TZCNT </c> instruction.
anatofuz
parents:
diff changeset
83 *
anatofuz
parents:
diff changeset
84 * \param __A
anatofuz
parents:
diff changeset
85 * A 64-bit integer operand.
anatofuz
parents:
diff changeset
86 * \returns A 32-bit integer containing the bit number.
anatofuz
parents:
diff changeset
87 */
anatofuz
parents:
diff changeset
88 static __inline__ int __attribute__((__always_inline__, __nodebug__))
anatofuz
parents:
diff changeset
89 __bsfq(long long __A) {
anatofuz
parents:
diff changeset
90 return __builtin_ctzll(__A);
anatofuz
parents:
diff changeset
91 }
anatofuz
parents:
diff changeset
92
anatofuz
parents:
diff changeset
93 /** Find the first set bit starting from the msb. Result is undefined if
anatofuz
parents:
diff changeset
94 * input is 0.
anatofuz
parents:
diff changeset
95 *
anatofuz
parents:
diff changeset
96 * \headerfile <x86intrin.h>
anatofuz
parents:
diff changeset
97 *
anatofuz
parents:
diff changeset
98 * This intrinsic corresponds to the <c> BSR </c> instruction or the
anatofuz
parents:
diff changeset
99 * <c> LZCNT </c> instruction and an <c> XOR </c>.
anatofuz
parents:
diff changeset
100 *
anatofuz
parents:
diff changeset
101 * \param __A
anatofuz
parents:
diff changeset
102 * A 64-bit integer operand.
anatofuz
parents:
diff changeset
103 * \returns A 32-bit integer containing the bit number.
anatofuz
parents:
diff changeset
104 */
anatofuz
parents:
diff changeset
105 static __inline__ int __attribute__((__always_inline__, __nodebug__))
anatofuz
parents:
diff changeset
106 __bsrq(long long __A) {
anatofuz
parents:
diff changeset
107 return 63 - __builtin_clzll(__A);
anatofuz
parents:
diff changeset
108 }
anatofuz
parents:
diff changeset
109
anatofuz
parents:
diff changeset
110 /** Swaps the bytes in the input. Converting little endian to big endian or
anatofuz
parents:
diff changeset
111 * vice versa.
anatofuz
parents:
diff changeset
112 *
anatofuz
parents:
diff changeset
113 * \headerfile <x86intrin.h>
anatofuz
parents:
diff changeset
114 *
anatofuz
parents:
diff changeset
115 * This intrinsic corresponds to the <c> BSWAP </c> instruction.
anatofuz
parents:
diff changeset
116 *
anatofuz
parents:
diff changeset
117 * \param __A
anatofuz
parents:
diff changeset
118 * A 64-bit integer operand.
anatofuz
parents:
diff changeset
119 * \returns A 64-bit integer containing the swapped bytes.
anatofuz
parents:
diff changeset
120 */
anatofuz
parents:
diff changeset
121 static __inline__ long long __attribute__((__always_inline__, __nodebug__))
anatofuz
parents:
diff changeset
122 __bswapq(long long __A) {
anatofuz
parents:
diff changeset
123 return __builtin_bswap64(__A);
anatofuz
parents:
diff changeset
124 }
anatofuz
parents:
diff changeset
125
anatofuz
parents:
diff changeset
126 #define _bswap64(A) __bswapq((A))
anatofuz
parents:
diff changeset
127 #endif
anatofuz
parents:
diff changeset
128
anatofuz
parents:
diff changeset
129 /** Counts the number of bits in the source operand having a value of 1.
anatofuz
parents:
diff changeset
130 *
anatofuz
parents:
diff changeset
131 * \headerfile <x86intrin.h>
anatofuz
parents:
diff changeset
132 *
anatofuz
parents:
diff changeset
133 * This intrinsic corresponds to the <c> POPCNT </c> instruction or a
anatofuz
parents:
diff changeset
134 * a sequence of arithmetic and logic ops to calculate it.
anatofuz
parents:
diff changeset
135 *
anatofuz
parents:
diff changeset
136 * \param __A
anatofuz
parents:
diff changeset
137 * An unsigned 32-bit integer operand.
anatofuz
parents:
diff changeset
138 * \returns A 32-bit integer containing the number of bits with value 1 in the
anatofuz
parents:
diff changeset
139 * source operand.
anatofuz
parents:
diff changeset
140 */
anatofuz
parents:
diff changeset
141 static __inline__ int __attribute__((__always_inline__, __nodebug__))
anatofuz
parents:
diff changeset
142 __popcntd(unsigned int __A)
anatofuz
parents:
diff changeset
143 {
anatofuz
parents:
diff changeset
144 return __builtin_popcount(__A);
anatofuz
parents:
diff changeset
145 }
anatofuz
parents:
diff changeset
146
anatofuz
parents:
diff changeset
147 #define _popcnt32(A) __popcntd((A))
anatofuz
parents:
diff changeset
148
anatofuz
parents:
diff changeset
149 #ifdef __x86_64__
anatofuz
parents:
diff changeset
150 /** Counts the number of bits in the source operand having a value of 1.
anatofuz
parents:
diff changeset
151 *
anatofuz
parents:
diff changeset
152 * \headerfile <x86intrin.h>
anatofuz
parents:
diff changeset
153 *
anatofuz
parents:
diff changeset
154 * This intrinsic corresponds to the <c> POPCNT </c> instruction or a
anatofuz
parents:
diff changeset
155 * a sequence of arithmetic and logic ops to calculate it.
anatofuz
parents:
diff changeset
156 *
anatofuz
parents:
diff changeset
157 * \param __A
anatofuz
parents:
diff changeset
158 * An unsigned 64-bit integer operand.
anatofuz
parents:
diff changeset
159 * \returns A 64-bit integer containing the number of bits with value 1 in the
anatofuz
parents:
diff changeset
160 * source operand.
anatofuz
parents:
diff changeset
161 */
anatofuz
parents:
diff changeset
162 static __inline__ long long __attribute__((__always_inline__, __nodebug__))
anatofuz
parents:
diff changeset
163 __popcntq(unsigned long long __A)
anatofuz
parents:
diff changeset
164 {
anatofuz
parents:
diff changeset
165 return __builtin_popcountll(__A);
anatofuz
parents:
diff changeset
166 }
anatofuz
parents:
diff changeset
167
anatofuz
parents:
diff changeset
168 #define _popcnt64(A) __popcntq((A))
anatofuz
parents:
diff changeset
169 #endif /* __x86_64__ */
anatofuz
parents:
diff changeset
170
anatofuz
parents:
diff changeset
171 #ifdef __x86_64__
anatofuz
parents:
diff changeset
172 static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
anatofuz
parents:
diff changeset
173 __readeflags(void)
anatofuz
parents:
diff changeset
174 {
anatofuz
parents:
diff changeset
175 return __builtin_ia32_readeflags_u64();
anatofuz
parents:
diff changeset
176 }
anatofuz
parents:
diff changeset
177
anatofuz
parents:
diff changeset
178 static __inline__ void __attribute__((__always_inline__, __nodebug__))
anatofuz
parents:
diff changeset
179 __writeeflags(unsigned long long __f)
anatofuz
parents:
diff changeset
180 {
anatofuz
parents:
diff changeset
181 __builtin_ia32_writeeflags_u64(__f);
anatofuz
parents:
diff changeset
182 }
anatofuz
parents:
diff changeset
183
anatofuz
parents:
diff changeset
184 #else /* !__x86_64__ */
anatofuz
parents:
diff changeset
185 static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
anatofuz
parents:
diff changeset
186 __readeflags(void)
anatofuz
parents:
diff changeset
187 {
anatofuz
parents:
diff changeset
188 return __builtin_ia32_readeflags_u32();
anatofuz
parents:
diff changeset
189 }
anatofuz
parents:
diff changeset
190
anatofuz
parents:
diff changeset
191 static __inline__ void __attribute__((__always_inline__, __nodebug__))
anatofuz
parents:
diff changeset
192 __writeeflags(unsigned int __f)
anatofuz
parents:
diff changeset
193 {
anatofuz
parents:
diff changeset
194 __builtin_ia32_writeeflags_u32(__f);
anatofuz
parents:
diff changeset
195 }
anatofuz
parents:
diff changeset
196 #endif /* !__x86_64__ */
anatofuz
parents:
diff changeset
197
anatofuz
parents:
diff changeset
198 /** Cast a 32-bit float value to a 32-bit unsigned integer value
anatofuz
parents:
diff changeset
199 *
anatofuz
parents:
diff changeset
200 * \headerfile <x86intrin.h>
anatofuz
parents:
diff changeset
201 * This intrinsic corresponds to the <c> VMOVD / MOVD </c> instruction in x86_64,
anatofuz
parents:
diff changeset
202 * and corresponds to the <c> VMOVL / MOVL </c> instruction in ia32.
anatofuz
parents:
diff changeset
203 *
anatofuz
parents:
diff changeset
204 * \param __A
anatofuz
parents:
diff changeset
205 * A 32-bit float value.
anatofuz
parents:
diff changeset
206 * \returns a 32-bit unsigned integer containing the converted value.
anatofuz
parents:
diff changeset
207 */
anatofuz
parents:
diff changeset
208 static __inline__ unsigned int __attribute__((__always_inline__))
anatofuz
parents:
diff changeset
209 _castf32_u32(float __A) {
anatofuz
parents:
diff changeset
210 unsigned int D;
anatofuz
parents:
diff changeset
211 __builtin_memcpy(&D, &__A, sizeof(__A));
anatofuz
parents:
diff changeset
212 return D;
anatofuz
parents:
diff changeset
213 }
anatofuz
parents:
diff changeset
214
anatofuz
parents:
diff changeset
215 /** Cast a 64-bit float value to a 64-bit unsigned integer value
anatofuz
parents:
diff changeset
216 *
anatofuz
parents:
diff changeset
217 * \headerfile <x86intrin.h>
anatofuz
parents:
diff changeset
218 * This intrinsic corresponds to the <c> VMOVQ / MOVQ </c> instruction in x86_64,
anatofuz
parents:
diff changeset
219 * and corresponds to the <c> VMOVL / MOVL </c> instruction in ia32.
anatofuz
parents:
diff changeset
220 *
anatofuz
parents:
diff changeset
221 * \param __A
anatofuz
parents:
diff changeset
222 * A 64-bit float value.
anatofuz
parents:
diff changeset
223 * \returns a 64-bit unsigned integer containing the converted value.
anatofuz
parents:
diff changeset
224 */
anatofuz
parents:
diff changeset
225 static __inline__ unsigned long long __attribute__((__always_inline__))
anatofuz
parents:
diff changeset
226 _castf64_u64(double __A) {
anatofuz
parents:
diff changeset
227 unsigned long long D;
anatofuz
parents:
diff changeset
228 __builtin_memcpy(&D, &__A, sizeof(__A));
anatofuz
parents:
diff changeset
229 return D;
anatofuz
parents:
diff changeset
230 }
anatofuz
parents:
diff changeset
231
anatofuz
parents:
diff changeset
232 /** Cast a 32-bit unsigned integer value to a 32-bit float value
anatofuz
parents:
diff changeset
233 *
anatofuz
parents:
diff changeset
234 * \headerfile <x86intrin.h>
anatofuz
parents:
diff changeset
235 * This intrinsic corresponds to the <c> VMOVQ / MOVQ </c> instruction in x86_64,
anatofuz
parents:
diff changeset
236 * and corresponds to the <c> FLDS </c> instruction in ia32.
anatofuz
parents:
diff changeset
237 *
anatofuz
parents:
diff changeset
238 * \param __A
anatofuz
parents:
diff changeset
239 * A 32-bit unsigned integer value.
anatofuz
parents:
diff changeset
240 * \returns a 32-bit float value containing the converted value.
anatofuz
parents:
diff changeset
241 */
anatofuz
parents:
diff changeset
242 static __inline__ float __attribute__((__always_inline__))
anatofuz
parents:
diff changeset
243 _castu32_f32(unsigned int __A) {
anatofuz
parents:
diff changeset
244 float D;
anatofuz
parents:
diff changeset
245 __builtin_memcpy(&D, &__A, sizeof(__A));
anatofuz
parents:
diff changeset
246 return D;
anatofuz
parents:
diff changeset
247 }
anatofuz
parents:
diff changeset
248
anatofuz
parents:
diff changeset
249 /** Cast a 64-bit unsigned integer value to a 64-bit float value
anatofuz
parents:
diff changeset
250 *
anatofuz
parents:
diff changeset
251 * \headerfile <x86intrin.h>
anatofuz
parents:
diff changeset
252 * This intrinsic corresponds to the <c> VMOVQ / MOVQ </c> instruction in x86_64,
anatofuz
parents:
diff changeset
253 * and corresponds to the <c> FLDL </c> instruction in ia32.
anatofuz
parents:
diff changeset
254 *
anatofuz
parents:
diff changeset
255 * \param __A
anatofuz
parents:
diff changeset
256 * A 64-bit unsigned integer value.
anatofuz
parents:
diff changeset
257 * \returns a 64-bit float value containing the converted value.
anatofuz
parents:
diff changeset
258 */
anatofuz
parents:
diff changeset
259 static __inline__ double __attribute__((__always_inline__))
anatofuz
parents:
diff changeset
260 _castu64_f64(unsigned long long __A) {
anatofuz
parents:
diff changeset
261 double D;
anatofuz
parents:
diff changeset
262 __builtin_memcpy(&D, &__A, sizeof(__A));
anatofuz
parents:
diff changeset
263 return D;
anatofuz
parents:
diff changeset
264 }
anatofuz
parents:
diff changeset
265
anatofuz
parents:
diff changeset
266 /** Adds the unsigned integer operand to the CRC-32C checksum of the
anatofuz
parents:
diff changeset
267 * unsigned char operand.
anatofuz
parents:
diff changeset
268 *
anatofuz
parents:
diff changeset
269 * \headerfile <x86intrin.h>
anatofuz
parents:
diff changeset
270 *
anatofuz
parents:
diff changeset
271 * This intrinsic corresponds to the <c> CRC32B </c> instruction.
anatofuz
parents:
diff changeset
272 *
anatofuz
parents:
diff changeset
273 * \param __C
anatofuz
parents:
diff changeset
274 * An unsigned integer operand to add to the CRC-32C checksum of operand
anatofuz
parents:
diff changeset
275 * \a __D.
anatofuz
parents:
diff changeset
276 * \param __D
anatofuz
parents:
diff changeset
277 * An unsigned 8-bit integer operand used to compute the CRC-32C checksum.
anatofuz
parents:
diff changeset
278 * \returns The result of adding operand \a __C to the CRC-32C checksum of
anatofuz
parents:
diff changeset
279 * operand \a __D.
anatofuz
parents:
diff changeset
280 */
anatofuz
parents:
diff changeset
281 static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__, __target__("sse4.2")))
anatofuz
parents:
diff changeset
282 __crc32b(unsigned int __C, unsigned char __D)
anatofuz
parents:
diff changeset
283 {
anatofuz
parents:
diff changeset
284 return __builtin_ia32_crc32qi(__C, __D);
anatofuz
parents:
diff changeset
285 }
anatofuz
parents:
diff changeset
286
anatofuz
parents:
diff changeset
287 /** Adds the unsigned integer operand to the CRC-32C checksum of the
anatofuz
parents:
diff changeset
288 * unsigned short operand.
anatofuz
parents:
diff changeset
289 *
anatofuz
parents:
diff changeset
290 * \headerfile <x86intrin.h>
anatofuz
parents:
diff changeset
291 *
anatofuz
parents:
diff changeset
292 * This intrinsic corresponds to the <c> CRC32W </c> instruction.
anatofuz
parents:
diff changeset
293 *
anatofuz
parents:
diff changeset
294 * \param __C
anatofuz
parents:
diff changeset
295 * An unsigned integer operand to add to the CRC-32C checksum of operand
anatofuz
parents:
diff changeset
296 * \a __D.
anatofuz
parents:
diff changeset
297 * \param __D
anatofuz
parents:
diff changeset
298 * An unsigned 16-bit integer operand used to compute the CRC-32C checksum.
anatofuz
parents:
diff changeset
299 * \returns The result of adding operand \a __C to the CRC-32C checksum of
anatofuz
parents:
diff changeset
300 * operand \a __D.
anatofuz
parents:
diff changeset
301 */
anatofuz
parents:
diff changeset
302 static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__, __target__("sse4.2")))
anatofuz
parents:
diff changeset
303 __crc32w(unsigned int __C, unsigned short __D)
anatofuz
parents:
diff changeset
304 {
anatofuz
parents:
diff changeset
305 return __builtin_ia32_crc32hi(__C, __D);
anatofuz
parents:
diff changeset
306 }
anatofuz
parents:
diff changeset
307
anatofuz
parents:
diff changeset
308 /** Adds the unsigned integer operand to the CRC-32C checksum of the
anatofuz
parents:
diff changeset
309 * second unsigned integer operand.
anatofuz
parents:
diff changeset
310 *
anatofuz
parents:
diff changeset
311 * \headerfile <x86intrin.h>
anatofuz
parents:
diff changeset
312 *
anatofuz
parents:
diff changeset
313 * This intrinsic corresponds to the <c> CRC32D </c> instruction.
anatofuz
parents:
diff changeset
314 *
anatofuz
parents:
diff changeset
315 * \param __C
anatofuz
parents:
diff changeset
316 * An unsigned integer operand to add to the CRC-32C checksum of operand
anatofuz
parents:
diff changeset
317 * \a __D.
anatofuz
parents:
diff changeset
318 * \param __D
anatofuz
parents:
diff changeset
319 * An unsigned 32-bit integer operand used to compute the CRC-32C checksum.
anatofuz
parents:
diff changeset
320 * \returns The result of adding operand \a __C to the CRC-32C checksum of
anatofuz
parents:
diff changeset
321 * operand \a __D.
anatofuz
parents:
diff changeset
322 */
anatofuz
parents:
diff changeset
323 static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__, __target__("sse4.2")))
anatofuz
parents:
diff changeset
324 __crc32d(unsigned int __C, unsigned int __D)
anatofuz
parents:
diff changeset
325 {
anatofuz
parents:
diff changeset
326 return __builtin_ia32_crc32si(__C, __D);
anatofuz
parents:
diff changeset
327 }
anatofuz
parents:
diff changeset
328
anatofuz
parents:
diff changeset
329 #ifdef __x86_64__
anatofuz
parents:
diff changeset
330 /** Adds the unsigned integer operand to the CRC-32C checksum of the
anatofuz
parents:
diff changeset
331 * unsigned 64-bit integer operand.
anatofuz
parents:
diff changeset
332 *
anatofuz
parents:
diff changeset
333 * \headerfile <x86intrin.h>
anatofuz
parents:
diff changeset
334 *
anatofuz
parents:
diff changeset
335 * This intrinsic corresponds to the <c> CRC32Q </c> instruction.
anatofuz
parents:
diff changeset
336 *
anatofuz
parents:
diff changeset
337 * \param __C
anatofuz
parents:
diff changeset
338 * An unsigned integer operand to add to the CRC-32C checksum of operand
anatofuz
parents:
diff changeset
339 * \a __D.
anatofuz
parents:
diff changeset
340 * \param __D
anatofuz
parents:
diff changeset
341 * An unsigned 64-bit integer operand used to compute the CRC-32C checksum.
anatofuz
parents:
diff changeset
342 * \returns The result of adding operand \a __C to the CRC-32C checksum of
anatofuz
parents:
diff changeset
343 * operand \a __D.
anatofuz
parents:
diff changeset
344 */
anatofuz
parents:
diff changeset
345 static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__, __target__("sse4.2")))
anatofuz
parents:
diff changeset
346 __crc32q(unsigned long long __C, unsigned long long __D)
anatofuz
parents:
diff changeset
347 {
anatofuz
parents:
diff changeset
348 return __builtin_ia32_crc32di(__C, __D);
anatofuz
parents:
diff changeset
349 }
anatofuz
parents:
diff changeset
350 #endif /* __x86_64__ */
anatofuz
parents:
diff changeset
351
anatofuz
parents:
diff changeset
352 static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
anatofuz
parents:
diff changeset
353 __rdpmc(int __A) {
anatofuz
parents:
diff changeset
354 return __builtin_ia32_rdpmc(__A);
anatofuz
parents:
diff changeset
355 }
anatofuz
parents:
diff changeset
356
anatofuz
parents:
diff changeset
357 /* __rdtscp */
anatofuz
parents:
diff changeset
358 static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
anatofuz
parents:
diff changeset
359 __rdtscp(unsigned int *__A) {
anatofuz
parents:
diff changeset
360 return __builtin_ia32_rdtscp(__A);
anatofuz
parents:
diff changeset
361 }
anatofuz
parents:
diff changeset
362
anatofuz
parents:
diff changeset
363 #define _rdtsc() __rdtsc()
anatofuz
parents:
diff changeset
364
anatofuz
parents:
diff changeset
365 #define _rdpmc(A) __rdpmc(A)
anatofuz
parents:
diff changeset
366
anatofuz
parents:
diff changeset
367 static __inline__ void __attribute__((__always_inline__, __nodebug__))
anatofuz
parents:
diff changeset
368 _wbinvd(void) {
anatofuz
parents:
diff changeset
369 __builtin_ia32_wbinvd();
anatofuz
parents:
diff changeset
370 }
anatofuz
parents:
diff changeset
371
anatofuz
parents:
diff changeset
372 static __inline__ unsigned char __attribute__((__always_inline__, __nodebug__))
anatofuz
parents:
diff changeset
373 __rolb(unsigned char __X, int __C) {
anatofuz
parents:
diff changeset
374 return __builtin_rotateleft8(__X, __C);
anatofuz
parents:
diff changeset
375 }
anatofuz
parents:
diff changeset
376
anatofuz
parents:
diff changeset
377 static __inline__ unsigned char __attribute__((__always_inline__, __nodebug__))
anatofuz
parents:
diff changeset
378 __rorb(unsigned char __X, int __C) {
anatofuz
parents:
diff changeset
379 return __builtin_rotateright8(__X, __C);
anatofuz
parents:
diff changeset
380 }
anatofuz
parents:
diff changeset
381
anatofuz
parents:
diff changeset
382 static __inline__ unsigned short __attribute__((__always_inline__, __nodebug__))
anatofuz
parents:
diff changeset
383 __rolw(unsigned short __X, int __C) {
anatofuz
parents:
diff changeset
384 return __builtin_rotateleft16(__X, __C);
anatofuz
parents:
diff changeset
385 }
anatofuz
parents:
diff changeset
386
anatofuz
parents:
diff changeset
387 static __inline__ unsigned short __attribute__((__always_inline__, __nodebug__))
anatofuz
parents:
diff changeset
388 __rorw(unsigned short __X, int __C) {
anatofuz
parents:
diff changeset
389 return __builtin_rotateright16(__X, __C);
anatofuz
parents:
diff changeset
390 }
anatofuz
parents:
diff changeset
391
anatofuz
parents:
diff changeset
392 static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
anatofuz
parents:
diff changeset
393 __rold(unsigned int __X, int __C) {
anatofuz
parents:
diff changeset
394 return __builtin_rotateleft32(__X, __C);
anatofuz
parents:
diff changeset
395 }
anatofuz
parents:
diff changeset
396
anatofuz
parents:
diff changeset
397 static __inline__ unsigned int __attribute__((__always_inline__, __nodebug__))
anatofuz
parents:
diff changeset
398 __rord(unsigned int __X, int __C) {
anatofuz
parents:
diff changeset
399 return __builtin_rotateright32(__X, __C);
anatofuz
parents:
diff changeset
400 }
anatofuz
parents:
diff changeset
401
anatofuz
parents:
diff changeset
402 #ifdef __x86_64__
anatofuz
parents:
diff changeset
403 static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
anatofuz
parents:
diff changeset
404 __rolq(unsigned long long __X, int __C) {
anatofuz
parents:
diff changeset
405 return __builtin_rotateleft64(__X, __C);
anatofuz
parents:
diff changeset
406 }
anatofuz
parents:
diff changeset
407
anatofuz
parents:
diff changeset
408 static __inline__ unsigned long long __attribute__((__always_inline__, __nodebug__))
anatofuz
parents:
diff changeset
409 __rorq(unsigned long long __X, int __C) {
anatofuz
parents:
diff changeset
410 return __builtin_rotateright64(__X, __C);
anatofuz
parents:
diff changeset
411 }
anatofuz
parents:
diff changeset
412 #endif /* __x86_64__ */
anatofuz
parents:
diff changeset
413
anatofuz
parents:
diff changeset
414 #ifndef _MSC_VER
anatofuz
parents:
diff changeset
415 /* These are already provided as builtins for MSVC. */
anatofuz
parents:
diff changeset
416 /* Select the correct function based on the size of long. */
anatofuz
parents:
diff changeset
417 #ifdef __LP64__
anatofuz
parents:
diff changeset
418 #define _lrotl(a,b) __rolq((a), (b))
anatofuz
parents:
diff changeset
419 #define _lrotr(a,b) __rorq((a), (b))
anatofuz
parents:
diff changeset
420 #else
anatofuz
parents:
diff changeset
421 #define _lrotl(a,b) __rold((a), (b))
anatofuz
parents:
diff changeset
422 #define _lrotr(a,b) __rord((a), (b))
anatofuz
parents:
diff changeset
423 #endif
anatofuz
parents:
diff changeset
424 #define _rotl(a,b) __rold((a), (b))
anatofuz
parents:
diff changeset
425 #define _rotr(a,b) __rord((a), (b))
anatofuz
parents:
diff changeset
426 #endif // _MSC_VER
anatofuz
parents:
diff changeset
427
anatofuz
parents:
diff changeset
428 /* These are not builtins so need to be provided in all modes. */
anatofuz
parents:
diff changeset
429 #define _rotwl(a,b) __rolw((a), (b))
anatofuz
parents:
diff changeset
430 #define _rotwr(a,b) __rorw((a), (b))
anatofuz
parents:
diff changeset
431
anatofuz
parents:
diff changeset
432 #endif /* __IA32INTRIN_H */