blob: a42a1ee5e30047ef5802955453304b608eef6f7e [file] [log] [blame]
Logan Chien969aea62018-12-05 18:40:57 +08001/* ===-------- intrin.h ---------------------------------------------------===
2 *
Logan Chiendf4f7662019-09-04 16:45:23 -07003 * 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
Logan Chien969aea62018-12-05 18:40:57 +08006 *
7 *===-----------------------------------------------------------------------===
8 */
9
10/* Only include this if we're compiling for the windows platform. */
11#ifndef _MSC_VER
12#include_next <intrin.h>
13#else
14
15#ifndef __INTRIN_H
16#define __INTRIN_H
17
18/* First include the standard intrinsics. */
19#if defined(__i386__) || defined(__x86_64__)
20#include <x86intrin.h>
21#endif
22
23#if defined(__arm__)
24#include <armintr.h>
25#endif
26
27#if defined(__aarch64__)
28#include <arm64intr.h>
29#endif
30
31/* For the definition of jmp_buf. */
32#if __STDC_HOSTED__
33#include <setjmp.h>
34#endif
35
36/* Define the default attributes for the functions in this file. */
37#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__))
38
Sasha Smundak746b0222020-02-25 09:19:04 -080039#if __x86_64__
40#define __LPTRINT_TYPE__ __int64
41#else
42#define __LPTRINT_TYPE__ long
43#endif
44
Logan Chien969aea62018-12-05 18:40:57 +080045#ifdef __cplusplus
46extern "C" {
47#endif
48
49#if defined(__MMX__)
50/* And the random ones that aren't in those files. */
51__m64 _m_from_float(float);
52float _m_to_float(__m64);
53#endif
54
55/* Other assorted instruction intrinsics. */
56void __addfsbyte(unsigned long, unsigned char);
57void __addfsdword(unsigned long, unsigned long);
58void __addfsword(unsigned long, unsigned short);
59void __code_seg(const char *);
60static __inline__
61void __cpuid(int[4], int);
62static __inline__
63void __cpuidex(int[4], int, int);
64static __inline__
65__int64 __emul(int, int);
66static __inline__
67unsigned __int64 __emulu(unsigned int, unsigned int);
68unsigned int __getcallerseflags(void);
69static __inline__
70void __halt(void);
71unsigned char __inbyte(unsigned short);
72void __inbytestring(unsigned short, unsigned char *, unsigned long);
73void __incfsbyte(unsigned long);
74void __incfsdword(unsigned long);
75void __incfsword(unsigned long);
76unsigned long __indword(unsigned short);
77void __indwordstring(unsigned short, unsigned long *, unsigned long);
78void __int2c(void);
79void __invlpg(void *);
80unsigned short __inword(unsigned short);
81void __inwordstring(unsigned short, unsigned short *, unsigned long);
82void __lidt(void *);
83unsigned __int64 __ll_lshift(unsigned __int64, int);
84__int64 __ll_rshift(__int64, int);
Logan Chien969aea62018-12-05 18:40:57 +080085static __inline__
86void __movsb(unsigned char *, unsigned char const *, size_t);
87static __inline__
88void __movsd(unsigned long *, unsigned long const *, size_t);
89static __inline__
90void __movsw(unsigned short *, unsigned short const *, size_t);
91static __inline__
92void __nop(void);
93void __nvreg_restore_fence(void);
94void __nvreg_save_fence(void);
95void __outbyte(unsigned short, unsigned char);
96void __outbytestring(unsigned short, unsigned char *, unsigned long);
97void __outdword(unsigned short, unsigned long);
98void __outdwordstring(unsigned short, unsigned long *, unsigned long);
99void __outword(unsigned short, unsigned short);
100void __outwordstring(unsigned short, unsigned short *, unsigned long);
101unsigned long __readcr0(void);
102unsigned long __readcr2(void);
Sasha Smundak746b0222020-02-25 09:19:04 -0800103unsigned __LPTRINT_TYPE__ __readcr3(void);
Logan Chien969aea62018-12-05 18:40:57 +0800104unsigned long __readcr4(void);
105unsigned long __readcr8(void);
106unsigned int __readdr(unsigned int);
107#ifdef __i386__
108static __inline__
109unsigned char __readfsbyte(unsigned long);
110static __inline__
111unsigned __int64 __readfsqword(unsigned long);
112static __inline__
113unsigned short __readfsword(unsigned long);
114#endif
115static __inline__
116unsigned __int64 __readmsr(unsigned long);
117unsigned __int64 __readpmc(unsigned long);
118unsigned long __segmentlimit(unsigned long);
119void __sidt(void *);
120static __inline__
121void __stosb(unsigned char *, unsigned char, size_t);
122static __inline__
123void __stosd(unsigned long *, unsigned long, size_t);
124static __inline__
125void __stosw(unsigned short *, unsigned short, size_t);
126void __svm_clgi(void);
127void __svm_invlpga(void *, int);
128void __svm_skinit(int);
129void __svm_stgi(void);
130void __svm_vmload(size_t);
131void __svm_vmrun(size_t);
132void __svm_vmsave(size_t);
133void __ud2(void);
134unsigned __int64 __ull_rshift(unsigned __int64, int);
135void __vmx_off(void);
136void __vmx_vmptrst(unsigned __int64 *);
137void __wbinvd(void);
138void __writecr0(unsigned int);
139static __inline__
Sasha Smundak746b0222020-02-25 09:19:04 -0800140void __writecr3(unsigned __INTPTR_TYPE__);
Logan Chien969aea62018-12-05 18:40:57 +0800141void __writecr4(unsigned int);
142void __writecr8(unsigned int);
143void __writedr(unsigned int, unsigned int);
144void __writefsbyte(unsigned long, unsigned char);
145void __writefsdword(unsigned long, unsigned long);
146void __writefsqword(unsigned long, unsigned __int64);
147void __writefsword(unsigned long, unsigned short);
148void __writemsr(unsigned long, unsigned __int64);
149static __inline__
150void *_AddressOfReturnAddress(void);
151static __inline__
152unsigned char _BitScanForward(unsigned long *_Index, unsigned long _Mask);
153static __inline__
154unsigned char _BitScanReverse(unsigned long *_Index, unsigned long _Mask);
155unsigned char _bittest(long const *, long);
156unsigned char _bittestandcomplement(long *, long);
157unsigned char _bittestandreset(long *, long);
158unsigned char _bittestandset(long *, long);
159void __cdecl _disable(void);
160void __cdecl _enable(void);
161long _InterlockedAddLargeStatistic(__int64 volatile *_Addend, long _Value);
162unsigned char _interlockedbittestandreset(long volatile *, long);
163unsigned char _interlockedbittestandset(long volatile *, long);
164void *_InterlockedCompareExchangePointer_HLEAcquire(void *volatile *, void *,
165 void *);
166void *_InterlockedCompareExchangePointer_HLERelease(void *volatile *, void *,
167 void *);
168long _InterlockedExchangeAdd_HLEAcquire(long volatile *, long);
169long _InterlockedExchangeAdd_HLERelease(long volatile *, long);
170__int64 _InterlockedExchangeAdd64_HLEAcquire(__int64 volatile *, __int64);
171__int64 _InterlockedExchangeAdd64_HLERelease(__int64 volatile *, __int64);
Logan Chien969aea62018-12-05 18:40:57 +0800172static __inline__ void
173__attribute__((__deprecated__("use other intrinsics or C++11 atomics instead")))
174_ReadBarrier(void);
175static __inline__ void
176__attribute__((__deprecated__("use other intrinsics or C++11 atomics instead")))
177_ReadWriteBarrier(void);
178unsigned int _rorx_u32(unsigned int, const unsigned int);
179int _sarx_i32(int, unsigned int);
180#if __STDC_HOSTED__
181int __cdecl _setjmp(jmp_buf);
182#endif
183unsigned int _shlx_u32(unsigned int, unsigned int);
184unsigned int _shrx_u32(unsigned int, unsigned int);
185void _Store_HLERelease(long volatile *, long);
186void _Store64_HLERelease(__int64 volatile *, __int64);
187void _StorePointer_HLERelease(void *volatile *, void *);
188static __inline__ void
189__attribute__((__deprecated__("use other intrinsics or C++11 atomics instead")))
190_WriteBarrier(void);
191unsigned __int32 xbegin(void);
192void _xend(void);
Logan Chien969aea62018-12-05 18:40:57 +0800193
194/* These additional intrinsics are turned on in x64/amd64/x86_64 mode. */
195#ifdef __x86_64__
196void __addgsbyte(unsigned long, unsigned char);
197void __addgsdword(unsigned long, unsigned long);
198void __addgsqword(unsigned long, unsigned __int64);
199void __addgsword(unsigned long, unsigned short);
200static __inline__
201void __faststorefence(void);
202void __incgsbyte(unsigned long);
203void __incgsdword(unsigned long);
204void __incgsqword(unsigned long);
205void __incgsword(unsigned long);
Logan Chien969aea62018-12-05 18:40:57 +0800206static __inline__
207void __movsq(unsigned long long *, unsigned long long const *, size_t);
208static __inline__
209unsigned char __readgsbyte(unsigned long);
210static __inline__
211unsigned long __readgsdword(unsigned long);
212static __inline__
213unsigned __int64 __readgsqword(unsigned long);
214unsigned short __readgsword(unsigned long);
215unsigned __int64 __shiftleft128(unsigned __int64 _LowPart,
216 unsigned __int64 _HighPart,
217 unsigned char _Shift);
218unsigned __int64 __shiftright128(unsigned __int64 _LowPart,
219 unsigned __int64 _HighPart,
220 unsigned char _Shift);
221static __inline__
222void __stosq(unsigned __int64 *, unsigned __int64, size_t);
223unsigned char __vmx_on(unsigned __int64 *);
224unsigned char __vmx_vmclear(unsigned __int64 *);
225unsigned char __vmx_vmlaunch(void);
226unsigned char __vmx_vmptrld(unsigned __int64 *);
227unsigned char __vmx_vmread(size_t, size_t *);
228unsigned char __vmx_vmresume(void);
229unsigned char __vmx_vmwrite(size_t, size_t);
230void __writegsbyte(unsigned long, unsigned char);
231void __writegsdword(unsigned long, unsigned long);
232void __writegsqword(unsigned long, unsigned __int64);
233void __writegsword(unsigned long, unsigned short);
234unsigned char _bittest64(__int64 const *, __int64);
235unsigned char _bittestandcomplement64(__int64 *, __int64);
236unsigned char _bittestandreset64(__int64 *, __int64);
237unsigned char _bittestandset64(__int64 *, __int64);
238long _InterlockedAnd_np(long volatile *_Value, long _Mask);
239short _InterlockedAnd16_np(short volatile *_Value, short _Mask);
240__int64 _InterlockedAnd64_np(__int64 volatile *_Value, __int64 _Mask);
241char _InterlockedAnd8_np(char volatile *_Value, char _Mask);
242unsigned char _interlockedbittestandreset64(__int64 volatile *, __int64);
243unsigned char _interlockedbittestandset64(__int64 volatile *, __int64);
244long _InterlockedCompareExchange_np(long volatile *_Destination, long _Exchange,
245 long _Comparand);
Logan Chien969aea62018-12-05 18:40:57 +0800246unsigned char _InterlockedCompareExchange128_np(__int64 volatile *_Destination,
247 __int64 _ExchangeHigh,
248 __int64 _ExchangeLow,
249 __int64 *_ComparandResult);
250short _InterlockedCompareExchange16_np(short volatile *_Destination,
251 short _Exchange, short _Comparand);
252__int64 _InterlockedCompareExchange64_np(__int64 volatile *_Destination,
253 __int64 _Exchange, __int64 _Comparand);
254void *_InterlockedCompareExchangePointer_np(void *volatile *_Destination,
255 void *_Exchange, void *_Comparand);
256long _InterlockedOr_np(long volatile *_Value, long _Mask);
257short _InterlockedOr16_np(short volatile *_Value, short _Mask);
258__int64 _InterlockedOr64_np(__int64 volatile *_Value, __int64 _Mask);
259char _InterlockedOr8_np(char volatile *_Value, char _Mask);
260long _InterlockedXor_np(long volatile *_Value, long _Mask);
261short _InterlockedXor16_np(short volatile *_Value, short _Mask);
262__int64 _InterlockedXor64_np(__int64 volatile *_Value, __int64 _Mask);
263char _InterlockedXor8_np(char volatile *_Value, char _Mask);
264unsigned __int64 _rorx_u64(unsigned __int64, const unsigned int);
265__int64 _sarx_i64(__int64, unsigned int);
266unsigned __int64 _shlx_u64(unsigned __int64, unsigned int);
267unsigned __int64 _shrx_u64(unsigned __int64, unsigned int);
268static __inline__
269__int64 __mulh(__int64, __int64);
270static __inline__
271unsigned __int64 __umulh(unsigned __int64, unsigned __int64);
272static __inline__
273__int64 _mul128(__int64, __int64, __int64*);
274static __inline__
275unsigned __int64 _umul128(unsigned __int64,
276 unsigned __int64,
277 unsigned __int64*);
278
279#endif /* __x86_64__ */
280
281#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
282
283static __inline__
284unsigned char _BitScanForward64(unsigned long *_Index, unsigned __int64 _Mask);
285static __inline__
286unsigned char _BitScanReverse64(unsigned long *_Index, unsigned __int64 _Mask);
287
Sasha Smundak0fc590b2020-10-07 08:11:59 -0700288#endif
289
290#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
Logan Chien969aea62018-12-05 18:40:57 +0800291static __inline__
292__int64 _InterlockedDecrement64(__int64 volatile *_Addend);
293static __inline__
294__int64 _InterlockedExchange64(__int64 volatile *_Target, __int64 _Value);
295static __inline__
296__int64 _InterlockedExchangeAdd64(__int64 volatile *_Addend, __int64 _Value);
297static __inline__
298__int64 _InterlockedExchangeSub64(__int64 volatile *_Subend, __int64 _Value);
299static __inline__
300__int64 _InterlockedIncrement64(__int64 volatile *_Addend);
301static __inline__
302__int64 _InterlockedOr64(__int64 volatile *_Value, __int64 _Mask);
303static __inline__
304__int64 _InterlockedXor64(__int64 volatile *_Value, __int64 _Mask);
305static __inline__
306__int64 _InterlockedAnd64(__int64 volatile *_Value, __int64 _Mask);
307
308#endif
309
310/*----------------------------------------------------------------------------*\
311|* Interlocked Exchange Add
312\*----------------------------------------------------------------------------*/
313#if defined(__arm__) || defined(__aarch64__)
314char _InterlockedExchangeAdd8_acq(char volatile *_Addend, char _Value);
315char _InterlockedExchangeAdd8_nf(char volatile *_Addend, char _Value);
316char _InterlockedExchangeAdd8_rel(char volatile *_Addend, char _Value);
317short _InterlockedExchangeAdd16_acq(short volatile *_Addend, short _Value);
318short _InterlockedExchangeAdd16_nf(short volatile *_Addend, short _Value);
319short _InterlockedExchangeAdd16_rel(short volatile *_Addend, short _Value);
320long _InterlockedExchangeAdd_acq(long volatile *_Addend, long _Value);
321long _InterlockedExchangeAdd_nf(long volatile *_Addend, long _Value);
322long _InterlockedExchangeAdd_rel(long volatile *_Addend, long _Value);
323__int64 _InterlockedExchangeAdd64_acq(__int64 volatile *_Addend, __int64 _Value);
324__int64 _InterlockedExchangeAdd64_nf(__int64 volatile *_Addend, __int64 _Value);
325__int64 _InterlockedExchangeAdd64_rel(__int64 volatile *_Addend, __int64 _Value);
326#endif
327/*----------------------------------------------------------------------------*\
328|* Interlocked Increment
329\*----------------------------------------------------------------------------*/
330#if defined(__arm__) || defined(__aarch64__)
331short _InterlockedIncrement16_acq(short volatile *_Value);
332short _InterlockedIncrement16_nf(short volatile *_Value);
333short _InterlockedIncrement16_rel(short volatile *_Value);
334long _InterlockedIncrement_acq(long volatile *_Value);
335long _InterlockedIncrement_nf(long volatile *_Value);
336long _InterlockedIncrement_rel(long volatile *_Value);
337__int64 _InterlockedIncrement64_acq(__int64 volatile *_Value);
338__int64 _InterlockedIncrement64_nf(__int64 volatile *_Value);
339__int64 _InterlockedIncrement64_rel(__int64 volatile *_Value);
340#endif
341/*----------------------------------------------------------------------------*\
342|* Interlocked Decrement
343\*----------------------------------------------------------------------------*/
344#if defined(__arm__) || defined(__aarch64__)
345short _InterlockedDecrement16_acq(short volatile *_Value);
346short _InterlockedDecrement16_nf(short volatile *_Value);
347short _InterlockedDecrement16_rel(short volatile *_Value);
348long _InterlockedDecrement_acq(long volatile *_Value);
349long _InterlockedDecrement_nf(long volatile *_Value);
350long _InterlockedDecrement_rel(long volatile *_Value);
351__int64 _InterlockedDecrement64_acq(__int64 volatile *_Value);
352__int64 _InterlockedDecrement64_nf(__int64 volatile *_Value);
353__int64 _InterlockedDecrement64_rel(__int64 volatile *_Value);
354#endif
355/*----------------------------------------------------------------------------*\
356|* Interlocked And
357\*----------------------------------------------------------------------------*/
358#if defined(__arm__) || defined(__aarch64__)
359char _InterlockedAnd8_acq(char volatile *_Value, char _Mask);
360char _InterlockedAnd8_nf(char volatile *_Value, char _Mask);
361char _InterlockedAnd8_rel(char volatile *_Value, char _Mask);
362short _InterlockedAnd16_acq(short volatile *_Value, short _Mask);
363short _InterlockedAnd16_nf(short volatile *_Value, short _Mask);
364short _InterlockedAnd16_rel(short volatile *_Value, short _Mask);
365long _InterlockedAnd_acq(long volatile *_Value, long _Mask);
366long _InterlockedAnd_nf(long volatile *_Value, long _Mask);
367long _InterlockedAnd_rel(long volatile *_Value, long _Mask);
368__int64 _InterlockedAnd64_acq(__int64 volatile *_Value, __int64 _Mask);
369__int64 _InterlockedAnd64_nf(__int64 volatile *_Value, __int64 _Mask);
370__int64 _InterlockedAnd64_rel(__int64 volatile *_Value, __int64 _Mask);
371#endif
372/*----------------------------------------------------------------------------*\
373|* Bit Counting and Testing
374\*----------------------------------------------------------------------------*/
375#if defined(__arm__) || defined(__aarch64__)
376unsigned char _interlockedbittestandset_acq(long volatile *_BitBase,
377 long _BitPos);
378unsigned char _interlockedbittestandset_nf(long volatile *_BitBase,
379 long _BitPos);
380unsigned char _interlockedbittestandset_rel(long volatile *_BitBase,
381 long _BitPos);
382unsigned char _interlockedbittestandreset_acq(long volatile *_BitBase,
383 long _BitPos);
384unsigned char _interlockedbittestandreset_nf(long volatile *_BitBase,
385 long _BitPos);
386unsigned char _interlockedbittestandreset_rel(long volatile *_BitBase,
387 long _BitPos);
388#endif
389/*----------------------------------------------------------------------------*\
390|* Interlocked Or
391\*----------------------------------------------------------------------------*/
392#if defined(__arm__) || defined(__aarch64__)
393char _InterlockedOr8_acq(char volatile *_Value, char _Mask);
394char _InterlockedOr8_nf(char volatile *_Value, char _Mask);
395char _InterlockedOr8_rel(char volatile *_Value, char _Mask);
396short _InterlockedOr16_acq(short volatile *_Value, short _Mask);
397short _InterlockedOr16_nf(short volatile *_Value, short _Mask);
398short _InterlockedOr16_rel(short volatile *_Value, short _Mask);
399long _InterlockedOr_acq(long volatile *_Value, long _Mask);
400long _InterlockedOr_nf(long volatile *_Value, long _Mask);
401long _InterlockedOr_rel(long volatile *_Value, long _Mask);
402__int64 _InterlockedOr64_acq(__int64 volatile *_Value, __int64 _Mask);
403__int64 _InterlockedOr64_nf(__int64 volatile *_Value, __int64 _Mask);
404__int64 _InterlockedOr64_rel(__int64 volatile *_Value, __int64 _Mask);
405#endif
406/*----------------------------------------------------------------------------*\
407|* Interlocked Xor
408\*----------------------------------------------------------------------------*/
409#if defined(__arm__) || defined(__aarch64__)
410char _InterlockedXor8_acq(char volatile *_Value, char _Mask);
411char _InterlockedXor8_nf(char volatile *_Value, char _Mask);
412char _InterlockedXor8_rel(char volatile *_Value, char _Mask);
413short _InterlockedXor16_acq(short volatile *_Value, short _Mask);
414short _InterlockedXor16_nf(short volatile *_Value, short _Mask);
415short _InterlockedXor16_rel(short volatile *_Value, short _Mask);
416long _InterlockedXor_acq(long volatile *_Value, long _Mask);
417long _InterlockedXor_nf(long volatile *_Value, long _Mask);
418long _InterlockedXor_rel(long volatile *_Value, long _Mask);
419__int64 _InterlockedXor64_acq(__int64 volatile *_Value, __int64 _Mask);
420__int64 _InterlockedXor64_nf(__int64 volatile *_Value, __int64 _Mask);
421__int64 _InterlockedXor64_rel(__int64 volatile *_Value, __int64 _Mask);
422#endif
423/*----------------------------------------------------------------------------*\
424|* Interlocked Exchange
425\*----------------------------------------------------------------------------*/
426#if defined(__arm__) || defined(__aarch64__)
427char _InterlockedExchange8_acq(char volatile *_Target, char _Value);
428char _InterlockedExchange8_nf(char volatile *_Target, char _Value);
429char _InterlockedExchange8_rel(char volatile *_Target, char _Value);
430short _InterlockedExchange16_acq(short volatile *_Target, short _Value);
431short _InterlockedExchange16_nf(short volatile *_Target, short _Value);
432short _InterlockedExchange16_rel(short volatile *_Target, short _Value);
433long _InterlockedExchange_acq(long volatile *_Target, long _Value);
434long _InterlockedExchange_nf(long volatile *_Target, long _Value);
435long _InterlockedExchange_rel(long volatile *_Target, long _Value);
436__int64 _InterlockedExchange64_acq(__int64 volatile *_Target, __int64 _Value);
437__int64 _InterlockedExchange64_nf(__int64 volatile *_Target, __int64 _Value);
438__int64 _InterlockedExchange64_rel(__int64 volatile *_Target, __int64 _Value);
439#endif
440/*----------------------------------------------------------------------------*\
441|* Interlocked Compare Exchange
442\*----------------------------------------------------------------------------*/
443#if defined(__arm__) || defined(__aarch64__)
444char _InterlockedCompareExchange8_acq(char volatile *_Destination,
445 char _Exchange, char _Comparand);
446char _InterlockedCompareExchange8_nf(char volatile *_Destination,
447 char _Exchange, char _Comparand);
448char _InterlockedCompareExchange8_rel(char volatile *_Destination,
449 char _Exchange, char _Comparand);
450short _InterlockedCompareExchange16_acq(short volatile *_Destination,
451 short _Exchange, short _Comparand);
452short _InterlockedCompareExchange16_nf(short volatile *_Destination,
453 short _Exchange, short _Comparand);
454short _InterlockedCompareExchange16_rel(short volatile *_Destination,
455 short _Exchange, short _Comparand);
456long _InterlockedCompareExchange_acq(long volatile *_Destination,
457 long _Exchange, long _Comparand);
458long _InterlockedCompareExchange_nf(long volatile *_Destination,
459 long _Exchange, long _Comparand);
460long _InterlockedCompareExchange_rel(long volatile *_Destination,
461 long _Exchange, long _Comparand);
462__int64 _InterlockedCompareExchange64_acq(__int64 volatile *_Destination,
463 __int64 _Exchange, __int64 _Comparand);
464__int64 _InterlockedCompareExchange64_nf(__int64 volatile *_Destination,
465 __int64 _Exchange, __int64 _Comparand);
466__int64 _InterlockedCompareExchange64_rel(__int64 volatile *_Destination,
467 __int64 _Exchange, __int64 _Comparand);
468#endif
Pirama Arumuga Nainar986b8802021-06-03 16:00:34 -0700469#if defined(__x86_64__) || defined(__aarch64__)
470unsigned char _InterlockedCompareExchange128(__int64 volatile *_Destination,
471 __int64 _ExchangeHigh,
472 __int64 _ExchangeLow,
473 __int64 *_ComparandResult);
474#endif
475#if defined(__aarch64__)
476unsigned char _InterlockedCompareExchange128_acq(__int64 volatile *_Destination,
477 __int64 _ExchangeHigh,
478 __int64 _ExchangeLow,
479 __int64 *_ComparandResult);
480unsigned char _InterlockedCompareExchange128_nf(__int64 volatile *_Destination,
481 __int64 _ExchangeHigh,
482 __int64 _ExchangeLow,
483 __int64 *_ComparandResult);
484unsigned char _InterlockedCompareExchange128_rel(__int64 volatile *_Destination,
485 __int64 _ExchangeHigh,
486 __int64 _ExchangeLow,
487 __int64 *_ComparandResult);
488#endif
Logan Chien969aea62018-12-05 18:40:57 +0800489
490/*----------------------------------------------------------------------------*\
491|* movs, stos
492\*----------------------------------------------------------------------------*/
493#if defined(__i386__) || defined(__x86_64__)
494static __inline__ void __DEFAULT_FN_ATTRS
495__movsb(unsigned char *__dst, unsigned char const *__src, size_t __n) {
496 __asm__ __volatile__("rep movsb" : "+D"(__dst), "+S"(__src), "+c"(__n)
497 : : "memory");
498}
499static __inline__ void __DEFAULT_FN_ATTRS
500__movsd(unsigned long *__dst, unsigned long const *__src, size_t __n) {
501 __asm__ __volatile__("rep movsl" : "+D"(__dst), "+S"(__src), "+c"(__n)
502 : : "memory");
503}
504static __inline__ void __DEFAULT_FN_ATTRS
505__movsw(unsigned short *__dst, unsigned short const *__src, size_t __n) {
506 __asm__ __volatile__("rep movsw" : "+D"(__dst), "+S"(__src), "+c"(__n)
507 : : "memory");
508}
509static __inline__ void __DEFAULT_FN_ATTRS
510__stosd(unsigned long *__dst, unsigned long __x, size_t __n) {
511 __asm__ __volatile__("rep stosl" : "+D"(__dst), "+c"(__n) : "a"(__x)
512 : "memory");
513}
514static __inline__ void __DEFAULT_FN_ATTRS
515__stosw(unsigned short *__dst, unsigned short __x, size_t __n) {
516 __asm__ __volatile__("rep stosw" : "+D"(__dst), "+c"(__n) : "a"(__x)
517 : "memory");
518}
519#endif
520#ifdef __x86_64__
521static __inline__ void __DEFAULT_FN_ATTRS
522__movsq(unsigned long long *__dst, unsigned long long const *__src, size_t __n) {
523 __asm__ __volatile__("rep movsq" : "+D"(__dst), "+S"(__src), "+c"(__n)
524 : : "memory");
525}
526static __inline__ void __DEFAULT_FN_ATTRS
527__stosq(unsigned __int64 *__dst, unsigned __int64 __x, size_t __n) {
528 __asm__ __volatile__("rep stosq" : "+D"(__dst), "+c"(__n) : "a"(__x)
529 : "memory");
530}
531#endif
532
533/*----------------------------------------------------------------------------*\
534|* Misc
535\*----------------------------------------------------------------------------*/
536#if defined(__i386__) || defined(__x86_64__)
Pirama Arumuga Nainar7e1f8392021-08-16 17:30:48 -0700537#if defined(__i386__)
538#define __cpuid_count(__leaf, __count, __eax, __ebx, __ecx, __edx) \
539 __asm("cpuid" \
540 : "=a"(__eax), "=b"(__ebx), "=c"(__ecx), "=d"(__edx) \
541 : "0"(__leaf), "2"(__count))
542#else
543/* x86-64 uses %rbx as the base register, so preserve it. */
544#define __cpuid_count(__leaf, __count, __eax, __ebx, __ecx, __edx) \
545 __asm("xchgq %%rbx,%q1\n" \
546 "cpuid\n" \
547 "xchgq %%rbx,%q1" \
548 : "=a"(__eax), "=r"(__ebx), "=c"(__ecx), "=d"(__edx) \
549 : "0"(__leaf), "2"(__count))
550#endif
551static __inline__ void __DEFAULT_FN_ATTRS __cpuid(int __info[4], int __level) {
552 __cpuid_count(__level, 0, __info[0], __info[1], __info[2], __info[3]);
Logan Chien969aea62018-12-05 18:40:57 +0800553}
Pirama Arumuga Nainar7e1f8392021-08-16 17:30:48 -0700554static __inline__ void __DEFAULT_FN_ATTRS __cpuidex(int __info[4], int __level,
555 int __ecx) {
556 __cpuid_count(__level, __ecx, __info[0], __info[1], __info[2], __info[3]);
Logan Chien969aea62018-12-05 18:40:57 +0800557}
Pirama Arumuga Nainar7e1f8392021-08-16 17:30:48 -0700558static __inline__ void __DEFAULT_FN_ATTRS __halt(void) {
559 __asm__ volatile("hlt");
Logan Chien969aea62018-12-05 18:40:57 +0800560}
Logan Chiendbcf4122019-03-21 10:50:25 +0800561#endif
562
563#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)
Pirama Arumuga Nainar7e1f8392021-08-16 17:30:48 -0700564static __inline__ void __DEFAULT_FN_ATTRS __nop(void) {
565 __asm__ volatile("nop");
Logan Chien969aea62018-12-05 18:40:57 +0800566}
567#endif
568
569/*----------------------------------------------------------------------------*\
570|* MS AArch64 specific
571\*----------------------------------------------------------------------------*/
572#if defined(__aarch64__)
573unsigned __int64 __getReg(int);
574long _InterlockedAdd(long volatile *Addend, long Value);
Logan Chiendbcf4122019-03-21 10:50:25 +0800575__int64 _ReadStatusReg(int);
576void _WriteStatusReg(int, __int64);
577
578unsigned short __cdecl _byteswap_ushort(unsigned short val);
579unsigned long __cdecl _byteswap_ulong (unsigned long val);
580unsigned __int64 __cdecl _byteswap_uint64(unsigned __int64 val);
Logan Chien969aea62018-12-05 18:40:57 +0800581#endif
582
583/*----------------------------------------------------------------------------*\
584|* Privileged intrinsics
585\*----------------------------------------------------------------------------*/
586#if defined(__i386__) || defined(__x86_64__)
587static __inline__ unsigned __int64 __DEFAULT_FN_ATTRS
588__readmsr(unsigned long __register) {
589 // Loads the contents of a 64-bit model specific register (MSR) specified in
590 // the ECX register into registers EDX:EAX. The EDX register is loaded with
591 // the high-order 32 bits of the MSR and the EAX register is loaded with the
592 // low-order 32 bits. If less than 64 bits are implemented in the MSR being
593 // read, the values returned to EDX:EAX in unimplemented bit locations are
594 // undefined.
595 unsigned long __edx;
596 unsigned long __eax;
597 __asm__ ("rdmsr" : "=d"(__edx), "=a"(__eax) : "c"(__register));
598 return (((unsigned __int64)__edx) << 32) | (unsigned __int64)__eax;
599}
Sasha Smundak746b0222020-02-25 09:19:04 -0800600#endif
Logan Chien969aea62018-12-05 18:40:57 +0800601
Sasha Smundak746b0222020-02-25 09:19:04 -0800602static __inline__ unsigned __LPTRINT_TYPE__ __DEFAULT_FN_ATTRS
Logan Chien969aea62018-12-05 18:40:57 +0800603__readcr3(void) {
Sasha Smundak746b0222020-02-25 09:19:04 -0800604 unsigned __LPTRINT_TYPE__ __cr3_val;
605 __asm__ __volatile__ ("mov %%cr3, %0" : "=r"(__cr3_val) : : "memory");
Logan Chien969aea62018-12-05 18:40:57 +0800606 return __cr3_val;
607}
608
609static __inline__ void __DEFAULT_FN_ATTRS
Sasha Smundak746b0222020-02-25 09:19:04 -0800610__writecr3(unsigned __INTPTR_TYPE__ __cr3_val) {
611 __asm__ ("mov %0, %%cr3" : : "r"(__cr3_val) : "memory");
Logan Chien969aea62018-12-05 18:40:57 +0800612}
Logan Chien969aea62018-12-05 18:40:57 +0800613
614#ifdef __cplusplus
615}
616#endif
617
Sasha Smundak746b0222020-02-25 09:19:04 -0800618#undef __LPTRINT_TYPE__
619
Logan Chien969aea62018-12-05 18:40:57 +0800620#undef __DEFAULT_FN_ATTRS
621
622#endif /* __INTRIN_H */
623#endif /* _MSC_VER */