10b57cec5SDimitry Andric /* ===-------- intrin.h ---------------------------------------------------===
20b57cec5SDimitry Andric *
30b57cec5SDimitry Andric * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric * See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric *
70b57cec5SDimitry Andric *===-----------------------------------------------------------------------===
80b57cec5SDimitry Andric */
90b57cec5SDimitry Andric
100b57cec5SDimitry Andric /* Only include this if we're compiling for the windows platform. */
110b57cec5SDimitry Andric #ifndef _MSC_VER
120b57cec5SDimitry Andric #include_next <intrin.h>
130b57cec5SDimitry Andric #else
140b57cec5SDimitry Andric
150b57cec5SDimitry Andric #ifndef __INTRIN_H
160b57cec5SDimitry Andric #define __INTRIN_H
170b57cec5SDimitry Andric
18*0fca6ea1SDimitry Andric #include <intrin0.h>
19*0fca6ea1SDimitry Andric
200b57cec5SDimitry Andric /* First include the standard intrinsics. */
21*0fca6ea1SDimitry Andric #if defined(__i386__) || (defined(__x86_64__) && !defined(__arm64ec__))
220b57cec5SDimitry Andric #include <x86intrin.h>
230b57cec5SDimitry Andric #endif
240b57cec5SDimitry Andric
250b57cec5SDimitry Andric #if defined(__arm__)
260b57cec5SDimitry Andric #include <armintr.h>
270b57cec5SDimitry Andric #endif
280b57cec5SDimitry Andric
29*0fca6ea1SDimitry Andric #if defined(__aarch64__) || defined(__arm64ec__)
300b57cec5SDimitry Andric #include <arm64intr.h>
310b57cec5SDimitry Andric #endif
320b57cec5SDimitry Andric
330b57cec5SDimitry Andric /* For the definition of jmp_buf. */
340b57cec5SDimitry Andric #if __STDC_HOSTED__
350b57cec5SDimitry Andric #include <setjmp.h>
360b57cec5SDimitry Andric #endif
370b57cec5SDimitry Andric
380b57cec5SDimitry Andric /* Define the default attributes for the functions in this file. */
390b57cec5SDimitry Andric #define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__))
400b57cec5SDimitry Andric
41480093f4SDimitry Andric #if __x86_64__
42480093f4SDimitry Andric #define __LPTRINT_TYPE__ __int64
43480093f4SDimitry Andric #else
44480093f4SDimitry Andric #define __LPTRINT_TYPE__ long
45480093f4SDimitry Andric #endif
46480093f4SDimitry Andric
470b57cec5SDimitry Andric #ifdef __cplusplus
480b57cec5SDimitry Andric extern "C" {
490b57cec5SDimitry Andric #endif
500b57cec5SDimitry Andric
510b57cec5SDimitry Andric #if defined(__MMX__)
520b57cec5SDimitry Andric /* And the random ones that aren't in those files. */
530b57cec5SDimitry Andric __m64 _m_from_float(float);
540b57cec5SDimitry Andric float _m_to_float(__m64);
550b57cec5SDimitry Andric #endif
560b57cec5SDimitry Andric
570b57cec5SDimitry Andric /* Other assorted instruction intrinsics. */
580b57cec5SDimitry Andric void __addfsbyte(unsigned long, unsigned char);
590b57cec5SDimitry Andric void __addfsdword(unsigned long, unsigned long);
600b57cec5SDimitry Andric void __addfsword(unsigned long, unsigned short);
610b57cec5SDimitry Andric void __code_seg(const char *);
620b57cec5SDimitry Andric void __cpuid(int[4], int);
630b57cec5SDimitry Andric void __cpuidex(int[4], int, int);
640b57cec5SDimitry Andric __int64 __emul(int, int);
650b57cec5SDimitry Andric unsigned __int64 __emulu(unsigned int, unsigned int);
660b57cec5SDimitry Andric unsigned int __getcallerseflags(void);
670b57cec5SDimitry Andric void __halt(void);
680b57cec5SDimitry Andric unsigned char __inbyte(unsigned short);
690b57cec5SDimitry Andric void __inbytestring(unsigned short, unsigned char *, unsigned long);
700b57cec5SDimitry Andric void __incfsbyte(unsigned long);
710b57cec5SDimitry Andric void __incfsdword(unsigned long);
720b57cec5SDimitry Andric void __incfsword(unsigned long);
730b57cec5SDimitry Andric unsigned long __indword(unsigned short);
740b57cec5SDimitry Andric void __indwordstring(unsigned short, unsigned long *, unsigned long);
750b57cec5SDimitry Andric void __int2c(void);
760b57cec5SDimitry Andric void __invlpg(void *);
770b57cec5SDimitry Andric unsigned short __inword(unsigned short);
780b57cec5SDimitry Andric void __inwordstring(unsigned short, unsigned short *, unsigned long);
790b57cec5SDimitry Andric void __lidt(void *);
800b57cec5SDimitry Andric unsigned __int64 __ll_lshift(unsigned __int64, int);
810b57cec5SDimitry Andric __int64 __ll_rshift(__int64, int);
820b57cec5SDimitry Andric void __movsb(unsigned char *, unsigned char const *, size_t);
830b57cec5SDimitry Andric void __movsd(unsigned long *, unsigned long const *, size_t);
840b57cec5SDimitry Andric void __movsw(unsigned short *, unsigned short const *, size_t);
850b57cec5SDimitry Andric void __nop(void);
860b57cec5SDimitry Andric void __nvreg_restore_fence(void);
870b57cec5SDimitry Andric void __nvreg_save_fence(void);
880b57cec5SDimitry Andric void __outbyte(unsigned short, unsigned char);
890b57cec5SDimitry Andric void __outbytestring(unsigned short, unsigned char *, unsigned long);
900b57cec5SDimitry Andric void __outdword(unsigned short, unsigned long);
910b57cec5SDimitry Andric void __outdwordstring(unsigned short, unsigned long *, unsigned long);
920b57cec5SDimitry Andric void __outword(unsigned short, unsigned short);
930b57cec5SDimitry Andric void __outwordstring(unsigned short, unsigned short *, unsigned long);
940b57cec5SDimitry Andric unsigned long __readcr0(void);
950b57cec5SDimitry Andric unsigned long __readcr2(void);
96480093f4SDimitry Andric unsigned __LPTRINT_TYPE__ __readcr3(void);
970b57cec5SDimitry Andric unsigned long __readcr4(void);
980b57cec5SDimitry Andric unsigned long __readcr8(void);
990b57cec5SDimitry Andric unsigned int __readdr(unsigned int);
1000b57cec5SDimitry Andric #ifdef __i386__
1010b57cec5SDimitry Andric unsigned char __readfsbyte(unsigned long);
1020b57cec5SDimitry Andric unsigned short __readfsword(unsigned long);
103349cc55cSDimitry Andric unsigned long __readfsdword(unsigned long);
104349cc55cSDimitry Andric unsigned __int64 __readfsqword(unsigned long);
1050b57cec5SDimitry Andric #endif
1060b57cec5SDimitry Andric unsigned __int64 __readmsr(unsigned long);
1070b57cec5SDimitry Andric unsigned __int64 __readpmc(unsigned long);
1080b57cec5SDimitry Andric unsigned long __segmentlimit(unsigned long);
1090b57cec5SDimitry Andric void __sidt(void *);
1100b57cec5SDimitry Andric void __stosb(unsigned char *, unsigned char, size_t);
1110b57cec5SDimitry Andric void __stosd(unsigned long *, unsigned long, size_t);
1120b57cec5SDimitry Andric void __stosw(unsigned short *, unsigned short, size_t);
1130b57cec5SDimitry Andric void __svm_clgi(void);
1140b57cec5SDimitry Andric void __svm_invlpga(void *, int);
1150b57cec5SDimitry Andric void __svm_skinit(int);
1160b57cec5SDimitry Andric void __svm_stgi(void);
1170b57cec5SDimitry Andric void __svm_vmload(size_t);
1180b57cec5SDimitry Andric void __svm_vmrun(size_t);
1190b57cec5SDimitry Andric void __svm_vmsave(size_t);
1200b57cec5SDimitry Andric void __ud2(void);
1210b57cec5SDimitry Andric unsigned __int64 __ull_rshift(unsigned __int64, int);
1220b57cec5SDimitry Andric void __vmx_off(void);
1230b57cec5SDimitry Andric void __vmx_vmptrst(unsigned __int64 *);
1240b57cec5SDimitry Andric void __wbinvd(void);
1250b57cec5SDimitry Andric void __writecr0(unsigned int);
126480093f4SDimitry Andric void __writecr3(unsigned __INTPTR_TYPE__);
1270b57cec5SDimitry Andric void __writecr4(unsigned int);
1280b57cec5SDimitry Andric void __writecr8(unsigned int);
1290b57cec5SDimitry Andric void __writedr(unsigned int, unsigned int);
1300b57cec5SDimitry Andric void __writefsbyte(unsigned long, unsigned char);
1310b57cec5SDimitry Andric void __writefsdword(unsigned long, unsigned long);
1320b57cec5SDimitry Andric void __writefsqword(unsigned long, unsigned __int64);
1330b57cec5SDimitry Andric void __writefsword(unsigned long, unsigned short);
1340b57cec5SDimitry Andric void __writemsr(unsigned long, unsigned __int64);
1350b57cec5SDimitry Andric void *_AddressOfReturnAddress(void);
1360b57cec5SDimitry Andric unsigned char _bittest(long const *, long);
1370b57cec5SDimitry Andric unsigned char _bittestandcomplement(long *, long);
1380b57cec5SDimitry Andric unsigned char _bittestandreset(long *, long);
1390b57cec5SDimitry Andric unsigned char _bittestandset(long *, long);
1400b57cec5SDimitry Andric void __cdecl _disable(void);
1410b57cec5SDimitry Andric void __cdecl _enable(void);
1420b57cec5SDimitry Andric long _InterlockedAddLargeStatistic(__int64 volatile *_Addend, long _Value);
1430b57cec5SDimitry Andric unsigned char _interlockedbittestandreset(long volatile *, long);
1440b57cec5SDimitry Andric unsigned char _interlockedbittestandset(long volatile *, long);
1450b57cec5SDimitry Andric void *_InterlockedCompareExchangePointer_HLEAcquire(void *volatile *, void *,
1460b57cec5SDimitry Andric void *);
1470b57cec5SDimitry Andric void *_InterlockedCompareExchangePointer_HLERelease(void *volatile *, void *,
1480b57cec5SDimitry Andric void *);
1490b57cec5SDimitry Andric long _InterlockedExchangeAdd_HLEAcquire(long volatile *, long);
1500b57cec5SDimitry Andric long _InterlockedExchangeAdd_HLERelease(long volatile *, long);
1510b57cec5SDimitry Andric __int64 _InterlockedExchangeAdd64_HLEAcquire(__int64 volatile *, __int64);
1520b57cec5SDimitry Andric __int64 _InterlockedExchangeAdd64_HLERelease(__int64 volatile *, __int64);
153349cc55cSDimitry Andric void _ReadBarrier(void);
1540b57cec5SDimitry Andric unsigned int _rorx_u32(unsigned int, const unsigned int);
1550b57cec5SDimitry Andric int _sarx_i32(int, unsigned int);
1560b57cec5SDimitry Andric #if __STDC_HOSTED__
1570b57cec5SDimitry Andric int __cdecl _setjmp(jmp_buf);
1580b57cec5SDimitry Andric #endif
1590b57cec5SDimitry Andric unsigned int _shlx_u32(unsigned int, unsigned int);
1600b57cec5SDimitry Andric unsigned int _shrx_u32(unsigned int, unsigned int);
1610b57cec5SDimitry Andric void _Store_HLERelease(long volatile *, long);
1620b57cec5SDimitry Andric void _Store64_HLERelease(__int64 volatile *, __int64);
1630b57cec5SDimitry Andric void _StorePointer_HLERelease(void *volatile *, void *);
164349cc55cSDimitry Andric void _WriteBarrier(void);
1650b57cec5SDimitry Andric unsigned __int32 xbegin(void);
1660b57cec5SDimitry Andric void _xend(void);
1670b57cec5SDimitry Andric
1680b57cec5SDimitry Andric /* These additional intrinsics are turned on in x64/amd64/x86_64 mode. */
169*0fca6ea1SDimitry Andric #if defined(__x86_64__) && !defined(__arm64ec__)
1700b57cec5SDimitry Andric void __addgsbyte(unsigned long, unsigned char);
1710b57cec5SDimitry Andric void __addgsdword(unsigned long, unsigned long);
1720b57cec5SDimitry Andric void __addgsqword(unsigned long, unsigned __int64);
1730b57cec5SDimitry Andric void __addgsword(unsigned long, unsigned short);
1740b57cec5SDimitry Andric void __faststorefence(void);
1750b57cec5SDimitry Andric void __incgsbyte(unsigned long);
1760b57cec5SDimitry Andric void __incgsdword(unsigned long);
1770b57cec5SDimitry Andric void __incgsqword(unsigned long);
1780b57cec5SDimitry Andric void __incgsword(unsigned long);
1790b57cec5SDimitry Andric void __movsq(unsigned long long *, unsigned long long const *, size_t);
1800b57cec5SDimitry Andric unsigned char __readgsbyte(unsigned long);
1810b57cec5SDimitry Andric unsigned long __readgsdword(unsigned long);
1820b57cec5SDimitry Andric unsigned __int64 __readgsqword(unsigned long);
1830b57cec5SDimitry Andric unsigned short __readgsword(unsigned long);
1840b57cec5SDimitry Andric void __stosq(unsigned __int64 *, unsigned __int64, size_t);
1850b57cec5SDimitry Andric unsigned char __vmx_on(unsigned __int64 *);
1860b57cec5SDimitry Andric unsigned char __vmx_vmclear(unsigned __int64 *);
1870b57cec5SDimitry Andric unsigned char __vmx_vmlaunch(void);
1880b57cec5SDimitry Andric unsigned char __vmx_vmptrld(unsigned __int64 *);
1890b57cec5SDimitry Andric unsigned char __vmx_vmread(size_t, size_t *);
1900b57cec5SDimitry Andric unsigned char __vmx_vmresume(void);
1910b57cec5SDimitry Andric unsigned char __vmx_vmwrite(size_t, size_t);
1920b57cec5SDimitry Andric void __writegsbyte(unsigned long, unsigned char);
1930b57cec5SDimitry Andric void __writegsdword(unsigned long, unsigned long);
1940b57cec5SDimitry Andric void __writegsqword(unsigned long, unsigned __int64);
1950b57cec5SDimitry Andric void __writegsword(unsigned long, unsigned short);
1960b57cec5SDimitry Andric unsigned char _bittest64(__int64 const *, __int64);
1970b57cec5SDimitry Andric unsigned char _bittestandcomplement64(__int64 *, __int64);
1980b57cec5SDimitry Andric unsigned char _bittestandreset64(__int64 *, __int64);
1990b57cec5SDimitry Andric unsigned char _bittestandset64(__int64 *, __int64);
2000b57cec5SDimitry Andric long _InterlockedAnd_np(long volatile *_Value, long _Mask);
2010b57cec5SDimitry Andric short _InterlockedAnd16_np(short volatile *_Value, short _Mask);
2020b57cec5SDimitry Andric __int64 _InterlockedAnd64_np(__int64 volatile *_Value, __int64 _Mask);
2030b57cec5SDimitry Andric char _InterlockedAnd8_np(char volatile *_Value, char _Mask);
2040b57cec5SDimitry Andric unsigned char _interlockedbittestandreset64(__int64 volatile *, __int64);
2050b57cec5SDimitry Andric unsigned char _interlockedbittestandset64(__int64 volatile *, __int64);
2060b57cec5SDimitry Andric long _InterlockedCompareExchange_np(long volatile *_Destination, long _Exchange,
2070b57cec5SDimitry Andric long _Comparand);
2080b57cec5SDimitry Andric unsigned char _InterlockedCompareExchange128_np(__int64 volatile *_Destination,
2090b57cec5SDimitry Andric __int64 _ExchangeHigh,
2100b57cec5SDimitry Andric __int64 _ExchangeLow,
2110b57cec5SDimitry Andric __int64 *_ComparandResult);
2120b57cec5SDimitry Andric short _InterlockedCompareExchange16_np(short volatile *_Destination,
2130b57cec5SDimitry Andric short _Exchange, short _Comparand);
2140b57cec5SDimitry Andric __int64 _InterlockedCompareExchange64_np(__int64 volatile *_Destination,
2150b57cec5SDimitry Andric __int64 _Exchange, __int64 _Comparand);
2160b57cec5SDimitry Andric void *_InterlockedCompareExchangePointer_np(void *volatile *_Destination,
2170b57cec5SDimitry Andric void *_Exchange, void *_Comparand);
2180b57cec5SDimitry Andric long _InterlockedOr_np(long volatile *_Value, long _Mask);
2190b57cec5SDimitry Andric short _InterlockedOr16_np(short volatile *_Value, short _Mask);
2200b57cec5SDimitry Andric __int64 _InterlockedOr64_np(__int64 volatile *_Value, __int64 _Mask);
2210b57cec5SDimitry Andric char _InterlockedOr8_np(char volatile *_Value, char _Mask);
2220b57cec5SDimitry Andric long _InterlockedXor_np(long volatile *_Value, long _Mask);
2230b57cec5SDimitry Andric short _InterlockedXor16_np(short volatile *_Value, short _Mask);
2240b57cec5SDimitry Andric __int64 _InterlockedXor64_np(__int64 volatile *_Value, __int64 _Mask);
2250b57cec5SDimitry Andric char _InterlockedXor8_np(char volatile *_Value, char _Mask);
2260b57cec5SDimitry Andric unsigned __int64 _rorx_u64(unsigned __int64, const unsigned int);
2270b57cec5SDimitry Andric __int64 _sarx_i64(__int64, unsigned int);
2280b57cec5SDimitry Andric unsigned __int64 _shlx_u64(unsigned __int64, unsigned int);
2290b57cec5SDimitry Andric unsigned __int64 _shrx_u64(unsigned __int64, unsigned int);
2300b57cec5SDimitry Andric __int64 __mulh(__int64, __int64);
2310b57cec5SDimitry Andric unsigned __int64 __umulh(unsigned __int64, unsigned __int64);
2320b57cec5SDimitry Andric __int64 _mul128(__int64, __int64, __int64 *);
2330b57cec5SDimitry Andric
2340b57cec5SDimitry Andric #endif /* __x86_64__ */
2350b57cec5SDimitry Andric
2360b57cec5SDimitry Andric /*----------------------------------------------------------------------------*\
2370b57cec5SDimitry Andric |* movs, stos
2380b57cec5SDimitry Andric \*----------------------------------------------------------------------------*/
239*0fca6ea1SDimitry Andric
240*0fca6ea1SDimitry Andric #if defined(__i386__) || (defined(__x86_64__) && !defined(__arm64ec__))
__movsb(unsigned char * __dst,unsigned char const * __src,size_t __n)241927c847dSDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS __movsb(unsigned char *__dst,
242927c847dSDimitry Andric unsigned char const *__src,
243927c847dSDimitry Andric size_t __n) {
244fe6060f1SDimitry Andric #if defined(__x86_64__)
245fe6060f1SDimitry Andric __asm__ __volatile__("rep movsb"
246fe6060f1SDimitry Andric : "+D"(__dst), "+S"(__src), "+c"(__n)
247fe6060f1SDimitry Andric :
248fe6060f1SDimitry Andric : "memory");
249fe6060f1SDimitry Andric #else
250349cc55cSDimitry Andric __asm__ __volatile__("xchg {%%esi, %1|%1, esi}\n"
251349cc55cSDimitry Andric "rep movsb\n"
252349cc55cSDimitry Andric "xchg {%%esi, %1|%1, esi}"
253fe6060f1SDimitry Andric : "+D"(__dst), "+r"(__src), "+c"(__n)
254fe6060f1SDimitry Andric :
255fe6060f1SDimitry Andric : "memory");
256fe6060f1SDimitry Andric #endif
2570b57cec5SDimitry Andric }
__movsd(unsigned long * __dst,unsigned long const * __src,size_t __n)258927c847dSDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS __movsd(unsigned long *__dst,
259927c847dSDimitry Andric unsigned long const *__src,
260927c847dSDimitry Andric size_t __n) {
261fe6060f1SDimitry Andric #if defined(__x86_64__)
262349cc55cSDimitry Andric __asm__ __volatile__("rep movs{l|d}"
263927c847dSDimitry Andric : "+D"(__dst), "+S"(__src), "+c"(__n)
264927c847dSDimitry Andric :
2650b57cec5SDimitry Andric : "memory");
266fe6060f1SDimitry Andric #else
267349cc55cSDimitry Andric __asm__ __volatile__("xchg {%%esi, %1|%1, esi}\n"
268349cc55cSDimitry Andric "rep movs{l|d}\n"
269349cc55cSDimitry Andric "xchg {%%esi, %1|%1, esi}"
270fe6060f1SDimitry Andric : "+D"(__dst), "+r"(__src), "+c"(__n)
271fe6060f1SDimitry Andric :
272fe6060f1SDimitry Andric : "memory");
273fe6060f1SDimitry Andric #endif
2740b57cec5SDimitry Andric }
__movsw(unsigned short * __dst,unsigned short const * __src,size_t __n)275927c847dSDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS __movsw(unsigned short *__dst,
276927c847dSDimitry Andric unsigned short const *__src,
277927c847dSDimitry Andric size_t __n) {
278fe6060f1SDimitry Andric #if defined(__x86_64__)
279927c847dSDimitry Andric __asm__ __volatile__("rep movsw"
280927c847dSDimitry Andric : "+D"(__dst), "+S"(__src), "+c"(__n)
281927c847dSDimitry Andric :
282927c847dSDimitry Andric : "memory");
283fe6060f1SDimitry Andric #else
284349cc55cSDimitry Andric __asm__ __volatile__("xchg {%%esi, %1|%1, esi}\n"
285349cc55cSDimitry Andric "rep movsw\n"
286349cc55cSDimitry Andric "xchg {%%esi, %1|%1, esi}"
287fe6060f1SDimitry Andric : "+D"(__dst), "+r"(__src), "+c"(__n)
288fe6060f1SDimitry Andric :
289fe6060f1SDimitry Andric : "memory");
290fe6060f1SDimitry Andric #endif
291927c847dSDimitry Andric }
__stosd(unsigned long * __dst,unsigned long __x,size_t __n)292927c847dSDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS __stosd(unsigned long *__dst,
293927c847dSDimitry Andric unsigned long __x,
294927c847dSDimitry Andric size_t __n) {
295349cc55cSDimitry Andric __asm__ __volatile__("rep stos{l|d}"
296927c847dSDimitry Andric : "+D"(__dst), "+c"(__n)
297927c847dSDimitry Andric : "a"(__x)
298927c847dSDimitry Andric : "memory");
299927c847dSDimitry Andric }
__stosw(unsigned short * __dst,unsigned short __x,size_t __n)300927c847dSDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS __stosw(unsigned short *__dst,
301927c847dSDimitry Andric unsigned short __x,
302927c847dSDimitry Andric size_t __n) {
303927c847dSDimitry Andric __asm__ __volatile__("rep stosw"
304927c847dSDimitry Andric : "+D"(__dst), "+c"(__n)
305927c847dSDimitry Andric : "a"(__x)
3060b57cec5SDimitry Andric : "memory");
3070b57cec5SDimitry Andric }
3080b57cec5SDimitry Andric #endif
309*0fca6ea1SDimitry Andric #if defined(__x86_64__) && !defined(__arm64ec__)
__movsq(unsigned long long * __dst,unsigned long long const * __src,size_t __n)310927c847dSDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS __movsq(
311927c847dSDimitry Andric unsigned long long *__dst, unsigned long long const *__src, size_t __n) {
312927c847dSDimitry Andric __asm__ __volatile__("rep movsq"
313927c847dSDimitry Andric : "+D"(__dst), "+S"(__src), "+c"(__n)
314927c847dSDimitry Andric :
315927c847dSDimitry Andric : "memory");
3160b57cec5SDimitry Andric }
__stosq(unsigned __int64 * __dst,unsigned __int64 __x,size_t __n)317927c847dSDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS __stosq(unsigned __int64 *__dst,
318927c847dSDimitry Andric unsigned __int64 __x,
319927c847dSDimitry Andric size_t __n) {
3200b57cec5SDimitry Andric __asm__ __volatile__("rep stosq" : "+D"(__dst), "+c"(__n) : "a"(__x)
3210b57cec5SDimitry Andric : "memory");
3220b57cec5SDimitry Andric }
3230b57cec5SDimitry Andric #endif
3240b57cec5SDimitry Andric
3250b57cec5SDimitry Andric /*----------------------------------------------------------------------------*\
3260b57cec5SDimitry Andric |* Misc
3270b57cec5SDimitry Andric \*----------------------------------------------------------------------------*/
328*0fca6ea1SDimitry Andric #if defined(__i386__) || (defined(__x86_64__) && !defined(__arm64ec__))
__halt(void)329927c847dSDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS __halt(void) {
3300b57cec5SDimitry Andric __asm__ volatile("hlt");
3310b57cec5SDimitry Andric }
332*0fca6ea1SDimitry Andric
__inbyte(unsigned short port)333*0fca6ea1SDimitry Andric static inline unsigned char __inbyte(unsigned short port) {
334*0fca6ea1SDimitry Andric unsigned char ret;
335*0fca6ea1SDimitry Andric __asm__ __volatile__("inb %w1, %b0" : "=a"(ret) : "Nd"(port));
336*0fca6ea1SDimitry Andric return ret;
337*0fca6ea1SDimitry Andric }
338*0fca6ea1SDimitry Andric
__inword(unsigned short port)339*0fca6ea1SDimitry Andric static inline unsigned short __inword(unsigned short port) {
340*0fca6ea1SDimitry Andric unsigned short ret;
341*0fca6ea1SDimitry Andric __asm__ __volatile__("inw %w1, %w0" : "=a"(ret) : "Nd"(port));
342*0fca6ea1SDimitry Andric return ret;
343*0fca6ea1SDimitry Andric }
344*0fca6ea1SDimitry Andric
__indword(unsigned short port)345*0fca6ea1SDimitry Andric static inline unsigned long __indword(unsigned short port) {
346*0fca6ea1SDimitry Andric unsigned long ret;
347*0fca6ea1SDimitry Andric __asm__ __volatile__("inl %w1, %k0" : "=a"(ret) : "Nd"(port));
348*0fca6ea1SDimitry Andric return ret;
349*0fca6ea1SDimitry Andric }
350*0fca6ea1SDimitry Andric
__outbyte(unsigned short port,unsigned char data)351*0fca6ea1SDimitry Andric static inline void __outbyte(unsigned short port, unsigned char data) {
352*0fca6ea1SDimitry Andric __asm__ __volatile__("outb %b0, %w1" : : "a"(data), "Nd"(port));
353*0fca6ea1SDimitry Andric }
354*0fca6ea1SDimitry Andric
__outword(unsigned short port,unsigned short data)355*0fca6ea1SDimitry Andric static inline void __outword(unsigned short port, unsigned short data) {
356*0fca6ea1SDimitry Andric __asm__ __volatile__("outw %w0, %w1" : : "a"(data), "Nd"(port));
357*0fca6ea1SDimitry Andric }
358*0fca6ea1SDimitry Andric
__outdword(unsigned short port,unsigned long data)359*0fca6ea1SDimitry Andric static inline void __outdword(unsigned short port, unsigned long data) {
360*0fca6ea1SDimitry Andric __asm__ __volatile__("outl %k0, %w1" : : "a"(data), "Nd"(port));
361*0fca6ea1SDimitry Andric }
3620b57cec5SDimitry Andric #endif
3630b57cec5SDimitry Andric
3640b57cec5SDimitry Andric #if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)
__nop(void)365927c847dSDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS __nop(void) {
3660b57cec5SDimitry Andric __asm__ volatile("nop");
3670b57cec5SDimitry Andric }
3680b57cec5SDimitry Andric #endif
3690b57cec5SDimitry Andric
3700b57cec5SDimitry Andric /*----------------------------------------------------------------------------*\
3710b57cec5SDimitry Andric |* MS AArch64 specific
3720b57cec5SDimitry Andric \*----------------------------------------------------------------------------*/
373*0fca6ea1SDimitry Andric #if defined(__aarch64__) || defined(__arm64ec__)
3740b57cec5SDimitry Andric unsigned __int64 __getReg(int);
3750b57cec5SDimitry Andric long _InterlockedAdd(long volatile *Addend, long Value);
376*0fca6ea1SDimitry Andric __int64 _InterlockedAdd64(__int64 volatile *Addend, __int64 Value);
3770b57cec5SDimitry Andric __int64 _ReadStatusReg(int);
3780b57cec5SDimitry Andric void _WriteStatusReg(int, __int64);
3790b57cec5SDimitry Andric
3800b57cec5SDimitry Andric unsigned short __cdecl _byteswap_ushort(unsigned short val);
3810b57cec5SDimitry Andric unsigned long __cdecl _byteswap_ulong (unsigned long val);
3820b57cec5SDimitry Andric unsigned __int64 __cdecl _byteswap_uint64(unsigned __int64 val);
3836e75b2fbSDimitry Andric
3846e75b2fbSDimitry Andric __int64 __mulh(__int64 __a, __int64 __b);
3856e75b2fbSDimitry Andric unsigned __int64 __umulh(unsigned __int64 __a, unsigned __int64 __b);
38681ad6265SDimitry Andric
38781ad6265SDimitry Andric void __break(int);
38881ad6265SDimitry Andric
38981ad6265SDimitry Andric void __writex18byte(unsigned long offset, unsigned char data);
39081ad6265SDimitry Andric void __writex18word(unsigned long offset, unsigned short data);
39181ad6265SDimitry Andric void __writex18dword(unsigned long offset, unsigned long data);
39281ad6265SDimitry Andric void __writex18qword(unsigned long offset, unsigned __int64 data);
39381ad6265SDimitry Andric
39481ad6265SDimitry Andric unsigned char __readx18byte(unsigned long offset);
39581ad6265SDimitry Andric unsigned short __readx18word(unsigned long offset);
39681ad6265SDimitry Andric unsigned long __readx18dword(unsigned long offset);
39781ad6265SDimitry Andric unsigned __int64 __readx18qword(unsigned long offset);
3985f757f3fSDimitry Andric
3995f757f3fSDimitry Andric double _CopyDoubleFromInt64(__int64);
4005f757f3fSDimitry Andric float _CopyFloatFromInt32(__int32);
4015f757f3fSDimitry Andric __int32 _CopyInt32FromFloat(float);
4025f757f3fSDimitry Andric __int64 _CopyInt64FromDouble(double);
4035f757f3fSDimitry Andric
4045f757f3fSDimitry Andric unsigned int _CountLeadingOnes(unsigned long);
4055f757f3fSDimitry Andric unsigned int _CountLeadingOnes64(unsigned __int64);
4065f757f3fSDimitry Andric unsigned int _CountLeadingSigns(long);
4075f757f3fSDimitry Andric unsigned int _CountLeadingSigns64(__int64);
4085f757f3fSDimitry Andric unsigned int _CountOneBits(unsigned long);
4095f757f3fSDimitry Andric unsigned int _CountOneBits64(unsigned __int64);
4105f757f3fSDimitry Andric
411*0fca6ea1SDimitry Andric unsigned int __hlt(unsigned int, ...);
412*0fca6ea1SDimitry Andric
413*0fca6ea1SDimitry Andric void __cdecl __prefetch(const void *);
414*0fca6ea1SDimitry Andric
4150b57cec5SDimitry Andric #endif
4160b57cec5SDimitry Andric
4170b57cec5SDimitry Andric /*----------------------------------------------------------------------------*\
4180b57cec5SDimitry Andric |* Privileged intrinsics
4190b57cec5SDimitry Andric \*----------------------------------------------------------------------------*/
420*0fca6ea1SDimitry Andric #if defined(__i386__) || (defined(__x86_64__) && !defined(__arm64ec__))
4210b57cec5SDimitry Andric static __inline__ unsigned __int64 __DEFAULT_FN_ATTRS
__readmsr(unsigned long __register)4220b57cec5SDimitry Andric __readmsr(unsigned long __register) {
4230b57cec5SDimitry Andric // Loads the contents of a 64-bit model specific register (MSR) specified in
4240b57cec5SDimitry Andric // the ECX register into registers EDX:EAX. The EDX register is loaded with
4250b57cec5SDimitry Andric // the high-order 32 bits of the MSR and the EAX register is loaded with the
4260b57cec5SDimitry Andric // low-order 32 bits. If less than 64 bits are implemented in the MSR being
4270b57cec5SDimitry Andric // read, the values returned to EDX:EAX in unimplemented bit locations are
4280b57cec5SDimitry Andric // undefined.
4290b57cec5SDimitry Andric unsigned long __edx;
4300b57cec5SDimitry Andric unsigned long __eax;
4310b57cec5SDimitry Andric __asm__ ("rdmsr" : "=d"(__edx), "=a"(__eax) : "c"(__register));
4320b57cec5SDimitry Andric return (((unsigned __int64)__edx) << 32) | (unsigned __int64)__eax;
4330b57cec5SDimitry Andric }
4340b57cec5SDimitry Andric
__readcr3(void)435927c847dSDimitry Andric static __inline__ unsigned __LPTRINT_TYPE__ __DEFAULT_FN_ATTRS __readcr3(void) {
436480093f4SDimitry Andric unsigned __LPTRINT_TYPE__ __cr3_val;
437349cc55cSDimitry Andric __asm__ __volatile__(
438349cc55cSDimitry Andric "mov {%%cr3, %0|%0, cr3}"
439349cc55cSDimitry Andric : "=r"(__cr3_val)
440349cc55cSDimitry Andric :
441349cc55cSDimitry Andric : "memory");
4420b57cec5SDimitry Andric return __cr3_val;
4430b57cec5SDimitry Andric }
4440b57cec5SDimitry Andric
4450b57cec5SDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS
__writecr3(unsigned __INTPTR_TYPE__ __cr3_val)446480093f4SDimitry Andric __writecr3(unsigned __INTPTR_TYPE__ __cr3_val) {
447349cc55cSDimitry Andric __asm__ ("mov {%0, %%cr3|cr3, %0}" : : "r"(__cr3_val) : "memory");
4480b57cec5SDimitry Andric }
449*0fca6ea1SDimitry Andric #endif
4500b57cec5SDimitry Andric
4510b57cec5SDimitry Andric #ifdef __cplusplus
4520b57cec5SDimitry Andric }
4530b57cec5SDimitry Andric #endif
4540b57cec5SDimitry Andric
455480093f4SDimitry Andric #undef __LPTRINT_TYPE__
456480093f4SDimitry Andric
4570b57cec5SDimitry Andric #undef __DEFAULT_FN_ATTRS
4580b57cec5SDimitry Andric
4590b57cec5SDimitry Andric #endif /* __INTRIN_H */
4600b57cec5SDimitry Andric #endif /* _MSC_VER */
461