]>
git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - ubuntu/vbox/include/iprt/asm-amd64-x86.h
4f9d647bf7eafab15ab0d55beb626b59eae528d2
2 * IPRT - AMD64 and x86 Specific Assembly Functions.
6 * Copyright (C) 2006-2016 Oracle Corporation
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
26 #ifndef ___iprt_asm_amd64_x86_h
27 #define ___iprt_asm_amd64_x86_h
29 #include <iprt/types.h>
30 #include <iprt/assert.h>
31 #if !defined(RT_ARCH_AMD64) && !defined(RT_ARCH_X86)
32 # error "Not on AMD64 or x86"
35 #if defined(_MSC_VER) && RT_INLINE_ASM_USES_INTRIN
36 # pragma warning(push)
37 # pragma warning(disable:4668) /* Several incorrect __cplusplus uses. */
38 # pragma warning(disable:4255) /* Incorrect __slwpcb prototype. */
41 /* Emit the intrinsics at all optimization levels. */
42 # pragma intrinsic(_ReadWriteBarrier)
43 # pragma intrinsic(__cpuid)
44 # pragma intrinsic(_enable)
45 # pragma intrinsic(_disable)
46 # pragma intrinsic(__rdtsc)
47 # pragma intrinsic(__readmsr)
48 # pragma intrinsic(__writemsr)
49 # pragma intrinsic(__outbyte)
50 # pragma intrinsic(__outbytestring)
51 # pragma intrinsic(__outword)
52 # pragma intrinsic(__outwordstring)
53 # pragma intrinsic(__outdword)
54 # pragma intrinsic(__outdwordstring)
55 # pragma intrinsic(__inbyte)
56 # pragma intrinsic(__inbytestring)
57 # pragma intrinsic(__inword)
58 # pragma intrinsic(__inwordstring)
59 # pragma intrinsic(__indword)
60 # pragma intrinsic(__indwordstring)
61 # pragma intrinsic(__invlpg)
62 # pragma intrinsic(__wbinvd)
63 # pragma intrinsic(__readcr0)
64 # pragma intrinsic(__readcr2)
65 # pragma intrinsic(__readcr3)
66 # pragma intrinsic(__readcr4)
67 # pragma intrinsic(__writecr0)
68 # pragma intrinsic(__writecr3)
69 # pragma intrinsic(__writecr4)
70 # pragma intrinsic(__readdr)
71 # pragma intrinsic(__writedr)
73 # pragma intrinsic(__readcr8)
74 # pragma intrinsic(__writecr8)
76 # if RT_INLINE_ASM_USES_INTRIN >= 14
77 # pragma intrinsic(__halt)
79 # if RT_INLINE_ASM_USES_INTRIN >= 15
80 # pragma intrinsic(__readeflags)
81 # pragma intrinsic(__writeeflags)
82 # pragma intrinsic(__rdtscp)
88 * Include #pragma aux definitions for Watcom C/C++.
90 #if defined(__WATCOMC__) && ARCH_BITS == 16
91 # include "asm-amd64-x86-watcom-16.h"
92 #elif defined(__WATCOMC__) && ARCH_BITS == 32
93 # include "asm-amd64-x86-watcom-32.h"
97 /** @defgroup grp_rt_asm_amd64_x86 AMD64 and x86 Specific ASM Routines
102 /** @todo find a more proper place for these structures? */
106 typedef struct RTIDTR
108 /** Size of the IDT. */
110 /** Address of the IDT. */
121 typedef struct RTIDTRALIGNEDINT
123 /** Alignment padding. */
124 uint16_t au16Padding
[ARCH_BITS
== 64 ? 3 : 1];
125 /** The IDTR structure. */
130 /** Wrapped RTIDTR for preventing misalignment exceptions. */
131 typedef union RTIDTRALIGNED
133 /** Try make sure this structure has optimal alignment. */
134 uint64_t auAlignmentHack
[ARCH_BITS
== 64 ? 2 : 1];
135 /** Aligned structure. */
138 AssertCompileSize(RTIDTRALIGNED
, ((ARCH_BITS
== 64) + 1) * 8);
139 /** Pointer to a an RTIDTR alignment wrapper. */
140 typedef RTIDTRALIGNED
*PRIDTRALIGNED
;
145 typedef struct RTGDTR
147 /** Size of the GDT. */
149 /** Address of the GDT. */
160 typedef struct RTGDTRALIGNEDINT
162 /** Alignment padding. */
163 uint16_t au16Padding
[ARCH_BITS
== 64 ? 3 : 1];
164 /** The GDTR structure. */
169 /** Wrapped RTGDTR for preventing misalignment exceptions. */
170 typedef union RTGDTRALIGNED
172 /** Try make sure this structure has optimal alignment. */
173 uint64_t auAlignmentHack
[ARCH_BITS
== 64 ? 2 : 1];
174 /** Aligned structure. */
177 AssertCompileSize(RTIDTRALIGNED
, ((ARCH_BITS
== 64) + 1) * 8);
178 /** Pointer to a an RTGDTR alignment wrapper. */
179 typedef RTGDTRALIGNED
*PRGDTRALIGNED
;
183 * Gets the content of the IDTR CPU register.
184 * @param pIdtr Where to store the IDTR contents.
186 #if RT_INLINE_ASM_EXTERNAL
187 DECLASM(void) ASMGetIDTR(PRTIDTR pIdtr
);
189 DECLINLINE(void) ASMGetIDTR(PRTIDTR pIdtr
)
191 # if RT_INLINE_ASM_GNU_STYLE
192 __asm__
__volatile__("sidt %0" : "=m" (*pIdtr
));
196 # ifdef RT_ARCH_AMD64
210 * Gets the content of the IDTR.LIMIT CPU register.
211 * @returns IDTR limit.
213 #if RT_INLINE_ASM_EXTERNAL
214 DECLASM(uint16_t) ASMGetIdtrLimit(void);
216 DECLINLINE(uint16_t) ASMGetIdtrLimit(void)
218 RTIDTRALIGNED TmpIdtr
;
219 # if RT_INLINE_ASM_GNU_STYLE
220 __asm__
__volatile__("sidt %0" : "=m" (TmpIdtr
.s
.Idtr
));
224 sidt
[TmpIdtr
.s
.Idtr
]
227 return TmpIdtr
.s
.Idtr
.cbIdt
;
233 * Sets the content of the IDTR CPU register.
234 * @param pIdtr Where to load the IDTR contents from
236 #if RT_INLINE_ASM_EXTERNAL
237 DECLASM(void) ASMSetIDTR(const RTIDTR
*pIdtr
);
239 DECLINLINE(void) ASMSetIDTR(const RTIDTR
*pIdtr
)
241 # if RT_INLINE_ASM_GNU_STYLE
242 __asm__
__volatile__("lidt %0" : : "m" (*pIdtr
));
246 # ifdef RT_ARCH_AMD64
260 * Gets the content of the GDTR CPU register.
261 * @param pGdtr Where to store the GDTR contents.
263 #if RT_INLINE_ASM_EXTERNAL
264 DECLASM(void) ASMGetGDTR(PRTGDTR pGdtr
);
266 DECLINLINE(void) ASMGetGDTR(PRTGDTR pGdtr
)
268 # if RT_INLINE_ASM_GNU_STYLE
269 __asm__
__volatile__("sgdt %0" : "=m" (*pGdtr
));
273 # ifdef RT_ARCH_AMD64
287 * Sets the content of the GDTR CPU register.
288 * @param pGdtr Where to load the GDTR contents from
290 #if RT_INLINE_ASM_EXTERNAL
291 DECLASM(void) ASMSetGDTR(const RTGDTR
*pGdtr
);
293 DECLINLINE(void) ASMSetGDTR(const RTGDTR
*pGdtr
)
295 # if RT_INLINE_ASM_GNU_STYLE
296 __asm__
__volatile__("lgdt %0" : : "m" (*pGdtr
));
300 # ifdef RT_ARCH_AMD64
315 * Get the cs register.
318 #if RT_INLINE_ASM_EXTERNAL
319 DECLASM(RTSEL
) ASMGetCS(void);
321 DECLINLINE(RTSEL
) ASMGetCS(void)
324 # if RT_INLINE_ASM_GNU_STYLE
325 __asm__
__volatile__("movw %%cs, %0\n\t" : "=r" (SelCS
));
339 * Get the DS register.
342 #if RT_INLINE_ASM_EXTERNAL
343 DECLASM(RTSEL
) ASMGetDS(void);
345 DECLINLINE(RTSEL
) ASMGetDS(void)
348 # if RT_INLINE_ASM_GNU_STYLE
349 __asm__
__volatile__("movw %%ds, %0\n\t" : "=r" (SelDS
));
363 * Get the ES register.
366 #if RT_INLINE_ASM_EXTERNAL
367 DECLASM(RTSEL
) ASMGetES(void);
369 DECLINLINE(RTSEL
) ASMGetES(void)
372 # if RT_INLINE_ASM_GNU_STYLE
373 __asm__
__volatile__("movw %%es, %0\n\t" : "=r" (SelES
));
387 * Get the FS register.
390 #if RT_INLINE_ASM_EXTERNAL
391 DECLASM(RTSEL
) ASMGetFS(void);
393 DECLINLINE(RTSEL
) ASMGetFS(void)
396 # if RT_INLINE_ASM_GNU_STYLE
397 __asm__
__volatile__("movw %%fs, %0\n\t" : "=r" (SelFS
));
411 * Get the GS register.
414 #if RT_INLINE_ASM_EXTERNAL
415 DECLASM(RTSEL
) ASMGetGS(void);
417 DECLINLINE(RTSEL
) ASMGetGS(void)
420 # if RT_INLINE_ASM_GNU_STYLE
421 __asm__
__volatile__("movw %%gs, %0\n\t" : "=r" (SelGS
));
435 * Get the SS register.
438 #if RT_INLINE_ASM_EXTERNAL
439 DECLASM(RTSEL
) ASMGetSS(void);
441 DECLINLINE(RTSEL
) ASMGetSS(void)
444 # if RT_INLINE_ASM_GNU_STYLE
445 __asm__
__volatile__("movw %%ss, %0\n\t" : "=r" (SelSS
));
459 * Get the TR register.
462 #if RT_INLINE_ASM_EXTERNAL
463 DECLASM(RTSEL
) ASMGetTR(void);
465 DECLINLINE(RTSEL
) ASMGetTR(void)
468 # if RT_INLINE_ASM_GNU_STYLE
469 __asm__
__volatile__("str %w0\n\t" : "=r" (SelTR
));
483 * Get the LDTR register.
486 #if RT_INLINE_ASM_EXTERNAL
487 DECLASM(RTSEL
) ASMGetLDTR(void);
489 DECLINLINE(RTSEL
) ASMGetLDTR(void)
492 # if RT_INLINE_ASM_GNU_STYLE
493 __asm__
__volatile__("sldt %w0\n\t" : "=r" (SelLDTR
));
507 * Get the access rights for the segment selector.
509 * @returns The access rights on success or UINT32_MAX on failure.
510 * @param uSel The selector value.
512 * @remarks Using UINT32_MAX for failure is chosen because valid access rights
513 * always have bits 0:7 as 0 (on both Intel & AMD).
515 #if RT_INLINE_ASM_EXTERNAL
516 DECLASM(uint32_t) ASMGetSegAttr(uint32_t uSel
);
518 DECLINLINE(uint32_t) ASMGetSegAttr(uint32_t uSel
)
521 /* LAR only accesses 16-bit of the source operand, but eax for the
522 destination operand is required for getting the full 32-bit access rights. */
523 # if RT_INLINE_ASM_GNU_STYLE
524 __asm__
__volatile__("lar %1, %%eax\n\t"
526 "movl $0xffffffff, %%eax\n\t"
548 * Get the [RE]FLAGS register.
549 * @returns [RE]FLAGS.
551 #if RT_INLINE_ASM_EXTERNAL && RT_INLINE_ASM_USES_INTRIN < 15
552 DECLASM(RTCCUINTREG
) ASMGetFlags(void);
554 DECLINLINE(RTCCUINTREG
) ASMGetFlags(void)
557 # if RT_INLINE_ASM_GNU_STYLE
558 # ifdef RT_ARCH_AMD64
559 __asm__
__volatile__("pushfq\n\t"
563 __asm__
__volatile__("pushfl\n\t"
567 # elif RT_INLINE_ASM_USES_INTRIN >= 15
568 uFlags
= __readeflags();
572 # ifdef RT_ARCH_AMD64
587 * Set the [RE]FLAGS register.
588 * @param uFlags The new [RE]FLAGS value.
590 #if RT_INLINE_ASM_EXTERNAL && RT_INLINE_ASM_USES_INTRIN < 15
591 DECLASM(void) ASMSetFlags(RTCCUINTREG uFlags
);
593 DECLINLINE(void) ASMSetFlags(RTCCUINTREG uFlags
)
595 # if RT_INLINE_ASM_GNU_STYLE
596 # ifdef RT_ARCH_AMD64
597 __asm__
__volatile__("pushq %0\n\t"
601 __asm__
__volatile__("pushl %0\n\t"
605 # elif RT_INLINE_ASM_USES_INTRIN >= 15
606 __writeeflags(uFlags
);
610 # ifdef RT_ARCH_AMD64
624 * Modifies the [RE]FLAGS register.
625 * @returns Original value.
626 * @param fAndEfl Flags to keep (applied first).
627 * @param fOrEfl Flags to be set.
629 #if RT_INLINE_ASM_EXTERNAL && RT_INLINE_ASM_USES_INTRIN < 15
630 DECLASM(RTCCUINTREG
) ASMChangeFlags(RTCCUINTREG fAndEfl
, RTCCUINTREG fOrEfl
);
632 DECLINLINE(RTCCUINTREG
) ASMChangeFlags(RTCCUINTREG fAndEfl
, RTCCUINTREG fOrEfl
)
635 # if RT_INLINE_ASM_GNU_STYLE
636 # ifdef RT_ARCH_AMD64
637 __asm__
__volatile__("pushfq\n\t"
638 "movq (%%rsp), %0\n\t"
641 "mov %1, (%%rsp)\n\t"
648 __asm__
__volatile__("pushfl\n\t"
649 "movl (%%esp), %0\n\t"
650 "andl %1, (%%esp)\n\t"
651 "orl %2, (%%esp)\n\t"
657 # elif RT_INLINE_ASM_USES_INTRIN >= 15
658 fOldEfl
= __readeflags();
659 __writeeflags((fOldEfl
& fAndEfl
) | fOrEfl
);
663 # ifdef RT_ARCH_AMD64
692 * Modifies the [RE]FLAGS register by ORing in one or more flags.
693 * @returns Original value.
694 * @param fOrEfl The flags to be set (ORed in).
696 #if RT_INLINE_ASM_EXTERNAL && RT_INLINE_ASM_USES_INTRIN < 15
697 DECLASM(RTCCUINTREG
) ASMAddFlags(RTCCUINTREG fOrEfl
);
699 DECLINLINE(RTCCUINTREG
) ASMAddFlags(RTCCUINTREG fOrEfl
)
702 # if RT_INLINE_ASM_GNU_STYLE
703 # ifdef RT_ARCH_AMD64
704 __asm__
__volatile__("pushfq\n\t"
705 "movq (%%rsp), %0\n\t"
706 "orq %1, (%%rsp)\n\t"
711 __asm__
__volatile__("pushfl\n\t"
712 "movl (%%esp), %0\n\t"
713 "orl %1, (%%esp)\n\t"
718 # elif RT_INLINE_ASM_USES_INTRIN >= 15
719 fOldEfl
= __readeflags();
720 __writeeflags(fOldEfl
| fOrEfl
);
724 # ifdef RT_ARCH_AMD64
747 * Modifies the [RE]FLAGS register by AND'ing out one or more flags.
748 * @returns Original value.
749 * @param fAndEfl The flags to keep.
751 #if RT_INLINE_ASM_EXTERNAL && RT_INLINE_ASM_USES_INTRIN < 15
752 DECLASM(RTCCUINTREG
) ASMClearFlags(RTCCUINTREG fAndEfl
);
754 DECLINLINE(RTCCUINTREG
) ASMClearFlags(RTCCUINTREG fAndEfl
)
757 # if RT_INLINE_ASM_GNU_STYLE
758 # ifdef RT_ARCH_AMD64
759 __asm__
__volatile__("pushfq\n\t"
760 "movq (%%rsp), %0\n\t"
761 "andq %1, (%%rsp)\n\t"
766 __asm__
__volatile__("pushfl\n\t"
767 "movl (%%esp), %0\n\t"
768 "andl %1, (%%esp)\n\t"
773 # elif RT_INLINE_ASM_USES_INTRIN >= 15
774 fOldEfl
= __readeflags();
775 __writeeflags(fOldEfl
& fAndEfl
);
779 # ifdef RT_ARCH_AMD64
802 * Gets the content of the CPU timestamp counter register.
806 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
807 DECLASM(uint64_t) ASMReadTSC(void);
809 DECLINLINE(uint64_t) ASMReadTSC(void)
812 # if RT_INLINE_ASM_GNU_STYLE
813 __asm__
__volatile__("rdtsc\n\t" : "=a" (u
.s
.Lo
), "=d" (u
.s
.Hi
));
815 # if RT_INLINE_ASM_USES_INTRIN
832 * Gets the content of the CPU timestamp counter register and the
833 * assoicated AUX value.
836 * @param puAux Where to store the AUX value.
838 #if RT_INLINE_ASM_EXTERNAL && RT_INLINE_ASM_USES_INTRIN < 15
839 DECLASM(uint64_t) ASMReadTscWithAux(uint32_t *puAux
);
841 DECLINLINE(uint64_t) ASMReadTscWithAux(uint32_t *puAux
)
844 # if RT_INLINE_ASM_GNU_STYLE
845 /* rdtscp is not supported by ancient linux build VM of course :-( */
846 /*__asm__ __volatile__("rdtscp\n\t" : "=a" (u.s.Lo), "=d" (u.s.Hi), "=c" (*puAux)); */
847 __asm__
__volatile__(".byte 0x0f,0x01,0xf9\n\t" : "=a" (u
.s
.Lo
), "=d" (u
.s
.Hi
), "=c" (*puAux
));
849 # if RT_INLINE_ASM_USES_INTRIN >= 15
850 u
.u
= __rdtscp(puAux
);
868 * Performs the cpuid instruction returning all registers.
870 * @param uOperator CPUID operation (eax).
871 * @param pvEAX Where to store eax.
872 * @param pvEBX Where to store ebx.
873 * @param pvECX Where to store ecx.
874 * @param pvEDX Where to store edx.
875 * @remark We're using void pointers to ease the use of special bitfield structures and such.
877 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
878 DECLASM(void) ASMCpuId(uint32_t uOperator
, void *pvEAX
, void *pvEBX
, void *pvECX
, void *pvEDX
);
880 DECLINLINE(void) ASMCpuId(uint32_t uOperator
, void *pvEAX
, void *pvEBX
, void *pvECX
, void *pvEDX
)
882 # if RT_INLINE_ASM_GNU_STYLE
883 # ifdef RT_ARCH_AMD64
884 RTCCUINTREG uRAX
, uRBX
, uRCX
, uRDX
;
885 __asm__
__volatile__ ("cpuid\n\t"
890 : "0" (uOperator
), "2" (0));
891 *(uint32_t *)pvEAX
= (uint32_t)uRAX
;
892 *(uint32_t *)pvEBX
= (uint32_t)uRBX
;
893 *(uint32_t *)pvECX
= (uint32_t)uRCX
;
894 *(uint32_t *)pvEDX
= (uint32_t)uRDX
;
896 __asm__
__volatile__ ("xchgl %%ebx, %1\n\t"
898 "xchgl %%ebx, %1\n\t"
899 : "=a" (*(uint32_t *)pvEAX
),
900 "=r" (*(uint32_t *)pvEBX
),
901 "=c" (*(uint32_t *)pvECX
),
902 "=d" (*(uint32_t *)pvEDX
)
903 : "0" (uOperator
), "2" (0));
906 # elif RT_INLINE_ASM_USES_INTRIN
908 __cpuid(aInfo
, uOperator
);
909 *(uint32_t *)pvEAX
= aInfo
[0];
910 *(uint32_t *)pvEBX
= aInfo
[1];
911 *(uint32_t *)pvECX
= aInfo
[2];
912 *(uint32_t *)pvEDX
= aInfo
[3];
930 *(uint32_t *)pvEAX
= uEAX
;
931 *(uint32_t *)pvEBX
= uEBX
;
932 *(uint32_t *)pvECX
= uECX
;
933 *(uint32_t *)pvEDX
= uEDX
;
940 * Performs the CPUID instruction with EAX and ECX input returning ALL output
943 * @param uOperator CPUID operation (eax).
944 * @param uIdxECX ecx index
945 * @param pvEAX Where to store eax.
946 * @param pvEBX Where to store ebx.
947 * @param pvECX Where to store ecx.
948 * @param pvEDX Where to store edx.
949 * @remark We're using void pointers to ease the use of special bitfield structures and such.
951 #if RT_INLINE_ASM_EXTERNAL || RT_INLINE_ASM_USES_INTRIN
952 DECLASM(void) ASMCpuId_Idx_ECX(uint32_t uOperator
, uint32_t uIdxECX
, void *pvEAX
, void *pvEBX
, void *pvECX
, void *pvEDX
);
954 DECLINLINE(void) ASMCpuId_Idx_ECX(uint32_t uOperator
, uint32_t uIdxECX
, void *pvEAX
, void *pvEBX
, void *pvECX
, void *pvEDX
)
956 # if RT_INLINE_ASM_GNU_STYLE
957 # ifdef RT_ARCH_AMD64
958 RTCCUINTREG uRAX
, uRBX
, uRCX
, uRDX
;
966 *(uint32_t *)pvEAX
= (uint32_t)uRAX
;
967 *(uint32_t *)pvEBX
= (uint32_t)uRBX
;
968 *(uint32_t *)pvECX
= (uint32_t)uRCX
;
969 *(uint32_t *)pvEDX
= (uint32_t)uRDX
;
971 __asm__ ("xchgl %%ebx, %1\n\t"
973 "xchgl %%ebx, %1\n\t"
974 : "=a" (*(uint32_t *)pvEAX
),
975 "=r" (*(uint32_t *)pvEBX
),
976 "=c" (*(uint32_t *)pvECX
),
977 "=d" (*(uint32_t *)pvEDX
)
982 # elif RT_INLINE_ASM_USES_INTRIN
984 __cpuidex(aInfo
, uOperator
, uIdxECX
);
985 *(uint32_t *)pvEAX
= aInfo
[0];
986 *(uint32_t *)pvEBX
= aInfo
[1];
987 *(uint32_t *)pvECX
= aInfo
[2];
988 *(uint32_t *)pvEDX
= aInfo
[3];
1007 *(uint32_t *)pvEAX
= uEAX
;
1008 *(uint32_t *)pvEBX
= uEBX
;
1009 *(uint32_t *)pvECX
= uECX
;
1010 *(uint32_t *)pvEDX
= uEDX
;
1017 * CPUID variant that initializes all 4 registers before the CPUID instruction.
1019 * @returns The EAX result value.
1020 * @param uOperator CPUID operation (eax).
1021 * @param uInitEBX The value to assign EBX prior to the CPUID instruction.
1022 * @param uInitECX The value to assign ECX prior to the CPUID instruction.
1023 * @param uInitEDX The value to assign EDX prior to the CPUID instruction.
1024 * @param pvEAX Where to store eax. Optional.
1025 * @param pvEBX Where to store ebx. Optional.
1026 * @param pvECX Where to store ecx. Optional.
1027 * @param pvEDX Where to store edx. Optional.
1029 DECLASM(uint32_t) ASMCpuIdExSlow(uint32_t uOperator
, uint32_t uInitEBX
, uint32_t uInitECX
, uint32_t uInitEDX
,
1030 void *pvEAX
, void *pvEBX
, void *pvECX
, void *pvEDX
);
1034 * Performs the cpuid instruction returning ecx and edx.
1036 * @param uOperator CPUID operation (eax).
1037 * @param pvECX Where to store ecx.
1038 * @param pvEDX Where to store edx.
1039 * @remark We're using void pointers to ease the use of special bitfield structures and such.
1041 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
1042 DECLASM(void) ASMCpuId_ECX_EDX(uint32_t uOperator
, void *pvECX
, void *pvEDX
);
1044 DECLINLINE(void) ASMCpuId_ECX_EDX(uint32_t uOperator
, void *pvECX
, void *pvEDX
)
1047 ASMCpuId(uOperator
, &uOperator
, &uEBX
, pvECX
, pvEDX
);
1053 * Performs the cpuid instruction returning eax.
1055 * @param uOperator CPUID operation (eax).
1056 * @returns EAX after cpuid operation.
1058 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
1059 DECLASM(uint32_t) ASMCpuId_EAX(uint32_t uOperator
);
1061 DECLINLINE(uint32_t) ASMCpuId_EAX(uint32_t uOperator
)
1064 # if RT_INLINE_ASM_GNU_STYLE
1065 # ifdef RT_ARCH_AMD64
1069 : "rbx", "rcx", "rdx");
1070 # elif (defined(PIC) || defined(__PIC__)) && defined(__i386__)
1071 __asm__ ("push %%ebx\n\t"
1081 : "edx", "ecx", "ebx");
1084 # elif RT_INLINE_ASM_USES_INTRIN
1086 __cpuid(aInfo
, uOperator
);
1093 mov eax
, [uOperator
]
1099 return (uint32_t)xAX
;
1105 * Performs the cpuid instruction returning ebx.
1107 * @param uOperator CPUID operation (eax).
1108 * @returns EBX after cpuid operation.
1110 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
1111 DECLASM(uint32_t) ASMCpuId_EBX(uint32_t uOperator
);
1113 DECLINLINE(uint32_t) ASMCpuId_EBX(uint32_t uOperator
)
1116 # if RT_INLINE_ASM_GNU_STYLE
1117 # ifdef RT_ARCH_AMD64
1124 # elif (defined(PIC) || defined(__PIC__)) && defined(__i386__)
1125 __asm__ ("push %%ebx\n\t"
1127 "mov %%ebx, %%edx\n\t"
1141 # elif RT_INLINE_ASM_USES_INTRIN
1143 __cpuid(aInfo
, uOperator
);
1150 mov eax
, [uOperator
]
1156 return (uint32_t)xBX
;
1162 * Performs the cpuid instruction returning ecx.
1164 * @param uOperator CPUID operation (eax).
1165 * @returns ECX after cpuid operation.
1167 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
1168 DECLASM(uint32_t) ASMCpuId_ECX(uint32_t uOperator
);
1170 DECLINLINE(uint32_t) ASMCpuId_ECX(uint32_t uOperator
)
1173 # if RT_INLINE_ASM_GNU_STYLE
1174 # ifdef RT_ARCH_AMD64
1181 # elif (defined(PIC) || defined(__PIC__)) && defined(__i386__)
1182 __asm__ ("push %%ebx\n\t"
1198 # elif RT_INLINE_ASM_USES_INTRIN
1200 __cpuid(aInfo
, uOperator
);
1207 mov eax
, [uOperator
]
1213 return (uint32_t)xCX
;
1219 * Performs the cpuid instruction returning edx.
1221 * @param uOperator CPUID operation (eax).
1222 * @returns EDX after cpuid operation.
1224 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
1225 DECLASM(uint32_t) ASMCpuId_EDX(uint32_t uOperator
);
1227 DECLINLINE(uint32_t) ASMCpuId_EDX(uint32_t uOperator
)
1230 # if RT_INLINE_ASM_GNU_STYLE
1231 # ifdef RT_ARCH_AMD64
1238 # elif (defined(PIC) || defined(__PIC__)) && defined(__i386__)
1239 __asm__ ("push %%ebx\n\t"
1254 # elif RT_INLINE_ASM_USES_INTRIN
1256 __cpuid(aInfo
, uOperator
);
1263 mov eax
, [uOperator
]
1269 return (uint32_t)xDX
;
1275 * Checks if the current CPU supports CPUID.
1277 * @returns true if CPUID is supported.
1280 DECLASM(bool) ASMHasCpuId(void);
1282 DECLINLINE(bool) ASMHasCpuId(void)
1284 # ifdef RT_ARCH_AMD64
1285 return true; /* ASSUME that all amd64 compatible CPUs have cpuid. */
1286 # else /* !RT_ARCH_AMD64 */
1288 # if RT_INLINE_ASM_GNU_STYLE
1291 __asm__ ("pushf\n\t"
1294 "xorl $0x200000, %1\n\t"
1303 : "=m" (fRet
), "=r" (u1
), "=r" (u2
));
1322 # endif /* !RT_ARCH_AMD64 */
1328 * Gets the APIC ID of the current CPU.
1330 * @returns the APIC ID.
1332 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
1333 DECLASM(uint8_t) ASMGetApicId(void);
1335 DECLINLINE(uint8_t) ASMGetApicId(void)
1338 # if RT_INLINE_ASM_GNU_STYLE
1339 # ifdef RT_ARCH_AMD64
1341 __asm__
__volatile__ ("cpuid"
1346 # elif (defined(PIC) || defined(__PIC__)) && defined(__i386__)
1348 __asm__
__volatile__ ("mov %%ebx,%1\n\t"
1350 "xchgl %%ebx,%1\n\t"
1357 __asm__
__volatile__ ("cpuid"
1364 # elif RT_INLINE_ASM_USES_INTRIN
1379 return (uint8_t)(xBX
>> 24);
1385 * Tests if it a genuine Intel CPU based on the ASMCpuId(0) output.
1387 * @returns true/false.
1388 * @param uEBX EBX return from ASMCpuId(0)
1389 * @param uECX ECX return from ASMCpuId(0)
1390 * @param uEDX EDX return from ASMCpuId(0)
1392 DECLINLINE(bool) ASMIsIntelCpuEx(uint32_t uEBX
, uint32_t uECX
, uint32_t uEDX
)
1394 return uEBX
== UINT32_C(0x756e6547)
1395 && uECX
== UINT32_C(0x6c65746e)
1396 && uEDX
== UINT32_C(0x49656e69);
1401 * Tests if this is a genuine Intel CPU.
1403 * @returns true/false.
1404 * @remarks ASSUMES that cpuid is supported by the CPU.
1406 DECLINLINE(bool) ASMIsIntelCpu(void)
1408 uint32_t uEAX
, uEBX
, uECX
, uEDX
;
1409 ASMCpuId(0, &uEAX
, &uEBX
, &uECX
, &uEDX
);
1410 return ASMIsIntelCpuEx(uEBX
, uECX
, uEDX
);
1415 * Tests if it an authentic AMD CPU based on the ASMCpuId(0) output.
1417 * @returns true/false.
1418 * @param uEBX EBX return from ASMCpuId(0)
1419 * @param uECX ECX return from ASMCpuId(0)
1420 * @param uEDX EDX return from ASMCpuId(0)
1422 DECLINLINE(bool) ASMIsAmdCpuEx(uint32_t uEBX
, uint32_t uECX
, uint32_t uEDX
)
1424 return uEBX
== UINT32_C(0x68747541)
1425 && uECX
== UINT32_C(0x444d4163)
1426 && uEDX
== UINT32_C(0x69746e65);
1431 * Tests if this is an authentic AMD CPU.
1433 * @returns true/false.
1434 * @remarks ASSUMES that cpuid is supported by the CPU.
1436 DECLINLINE(bool) ASMIsAmdCpu(void)
1438 uint32_t uEAX
, uEBX
, uECX
, uEDX
;
1439 ASMCpuId(0, &uEAX
, &uEBX
, &uECX
, &uEDX
);
1440 return ASMIsAmdCpuEx(uEBX
, uECX
, uEDX
);
1445 * Tests if it a centaur hauling VIA CPU based on the ASMCpuId(0) output.
1447 * @returns true/false.
1448 * @param uEBX EBX return from ASMCpuId(0).
1449 * @param uECX ECX return from ASMCpuId(0).
1450 * @param uEDX EDX return from ASMCpuId(0).
1452 DECLINLINE(bool) ASMIsViaCentaurCpuEx(uint32_t uEBX
, uint32_t uECX
, uint32_t uEDX
)
1454 return uEBX
== UINT32_C(0x746e6543)
1455 && uECX
== UINT32_C(0x736c7561)
1456 && uEDX
== UINT32_C(0x48727561);
1461 * Tests if this is a centaur hauling VIA CPU.
1463 * @returns true/false.
1464 * @remarks ASSUMES that cpuid is supported by the CPU.
1466 DECLINLINE(bool) ASMIsViaCentaurCpu(void)
1468 uint32_t uEAX
, uEBX
, uECX
, uEDX
;
1469 ASMCpuId(0, &uEAX
, &uEBX
, &uECX
, &uEDX
);
1470 return ASMIsViaCentaurCpuEx(uEBX
, uECX
, uEDX
);
1475 * Checks whether ASMCpuId_EAX(0x00000000) indicates a valid range.
1478 * @returns true/false.
1479 * @param uEAX The EAX value of CPUID leaf 0x00000000.
1481 * @note This only succeeds if there are at least two leaves in the range.
1482 * @remarks The upper range limit is just some half reasonable value we've
1483 * picked out of thin air.
1485 DECLINLINE(bool) ASMIsValidStdRange(uint32_t uEAX
)
1487 return uEAX
>= UINT32_C(0x00000001) && uEAX
<= UINT32_C(0x000fffff);
1492 * Checks whether ASMCpuId_EAX(0x80000000) indicates a valid range.
1494 * This only succeeds if there are at least two leaves in the range.
1496 * @returns true/false.
1497 * @param uEAX The EAX value of CPUID leaf 0x80000000.
1499 * @note This only succeeds if there are at least two leaves in the range.
1500 * @remarks The upper range limit is just some half reasonable value we've
1501 * picked out of thin air.
1503 DECLINLINE(bool) ASMIsValidExtRange(uint32_t uEAX
)
1505 return uEAX
>= UINT32_C(0x80000001) && uEAX
<= UINT32_C(0x800fffff);
1510 * Extracts the CPU family from ASMCpuId(1) or ASMCpuId(0x80000001)
1513 * @param uEAX EAX return from ASMCpuId(1) or ASMCpuId(0x80000001).
1515 DECLINLINE(uint32_t) ASMGetCpuFamily(uint32_t uEAX
)
1517 return ((uEAX
>> 8) & 0xf) == 0xf
1518 ? ((uEAX
>> 20) & 0x7f) + 0xf
1519 : ((uEAX
>> 8) & 0xf);
1524 * Extracts the CPU model from ASMCpuId(1) or ASMCpuId(0x80000001), Intel variant.
1527 * @param uEAX EAX from ASMCpuId(1) or ASMCpuId(0x80000001).
1529 DECLINLINE(uint32_t) ASMGetCpuModelIntel(uint32_t uEAX
)
1531 return ((uEAX
>> 8) & 0xf) == 0xf || (((uEAX
>> 8) & 0xf) == 0x6) /* family! */
1532 ? ((uEAX
>> 4) & 0xf) | ((uEAX
>> 12) & 0xf0)
1533 : ((uEAX
>> 4) & 0xf);
1538 * Extracts the CPU model from ASMCpuId(1) or ASMCpuId(0x80000001), AMD variant.
1541 * @param uEAX EAX from ASMCpuId(1) or ASMCpuId(0x80000001).
1543 DECLINLINE(uint32_t) ASMGetCpuModelAMD(uint32_t uEAX
)
1545 return ((uEAX
>> 8) & 0xf) == 0xf
1546 ? ((uEAX
>> 4) & 0xf) | ((uEAX
>> 12) & 0xf0)
1547 : ((uEAX
>> 4) & 0xf);
1552 * Extracts the CPU model from ASMCpuId(1) or ASMCpuId(0x80000001)
1555 * @param uEAX EAX from ASMCpuId(1) or ASMCpuId(0x80000001).
1556 * @param fIntel Whether it's an intel CPU. Use ASMIsIntelCpuEx() or ASMIsIntelCpu().
1558 DECLINLINE(uint32_t) ASMGetCpuModel(uint32_t uEAX
, bool fIntel
)
1560 return ((uEAX
>> 8) & 0xf) == 0xf || (((uEAX
>> 8) & 0xf) == 0x6 && fIntel
) /* family! */
1561 ? ((uEAX
>> 4) & 0xf) | ((uEAX
>> 12) & 0xf0)
1562 : ((uEAX
>> 4) & 0xf);
1567 * Extracts the CPU stepping from ASMCpuId(1) or ASMCpuId(0x80000001)
1570 * @param uEAX EAX from ASMCpuId(1) or ASMCpuId(0x80000001).
1572 DECLINLINE(uint32_t) ASMGetCpuStepping(uint32_t uEAX
)
1582 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
1583 DECLASM(RTCCUINTXREG
) ASMGetCR0(void);
1585 DECLINLINE(RTCCUINTXREG
) ASMGetCR0(void)
1588 # if RT_INLINE_ASM_USES_INTRIN
1591 # elif RT_INLINE_ASM_GNU_STYLE
1592 # ifdef RT_ARCH_AMD64
1593 __asm__
__volatile__("movq %%cr0, %0\t\n" : "=r" (uCR0
));
1595 __asm__
__volatile__("movl %%cr0, %0\t\n" : "=r" (uCR0
));
1600 # ifdef RT_ARCH_AMD64
1615 * Sets the CR0 register.
1616 * @param uCR0 The new CR0 value.
1618 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
1619 DECLASM(void) ASMSetCR0(RTCCUINTXREG uCR0
);
1621 DECLINLINE(void) ASMSetCR0(RTCCUINTXREG uCR0
)
1623 # if RT_INLINE_ASM_USES_INTRIN
1626 # elif RT_INLINE_ASM_GNU_STYLE
1627 # ifdef RT_ARCH_AMD64
1628 __asm__
__volatile__("movq %0, %%cr0\n\t" :: "r" (uCR0
));
1630 __asm__
__volatile__("movl %0, %%cr0\n\t" :: "r" (uCR0
));
1635 # ifdef RT_ARCH_AMD64
1652 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
1653 DECLASM(RTCCUINTXREG
) ASMGetCR2(void);
1655 DECLINLINE(RTCCUINTXREG
) ASMGetCR2(void)
1658 # if RT_INLINE_ASM_USES_INTRIN
1661 # elif RT_INLINE_ASM_GNU_STYLE
1662 # ifdef RT_ARCH_AMD64
1663 __asm__
__volatile__("movq %%cr2, %0\t\n" : "=r" (uCR2
));
1665 __asm__
__volatile__("movl %%cr2, %0\t\n" : "=r" (uCR2
));
1670 # ifdef RT_ARCH_AMD64
1685 * Sets the CR2 register.
1686 * @param uCR2 The new CR0 value.
1688 #if RT_INLINE_ASM_EXTERNAL
1689 DECLASM(void) ASMSetCR2(RTCCUINTXREG uCR2
);
1691 DECLINLINE(void) ASMSetCR2(RTCCUINTXREG uCR2
)
1693 # if RT_INLINE_ASM_GNU_STYLE
1694 # ifdef RT_ARCH_AMD64
1695 __asm__
__volatile__("movq %0, %%cr2\n\t" :: "r" (uCR2
));
1697 __asm__
__volatile__("movl %0, %%cr2\n\t" :: "r" (uCR2
));
1702 # ifdef RT_ARCH_AMD64
1719 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
1720 DECLASM(RTCCUINTXREG
) ASMGetCR3(void);
1722 DECLINLINE(RTCCUINTXREG
) ASMGetCR3(void)
1725 # if RT_INLINE_ASM_USES_INTRIN
1728 # elif RT_INLINE_ASM_GNU_STYLE
1729 # ifdef RT_ARCH_AMD64
1730 __asm__
__volatile__("movq %%cr3, %0\t\n" : "=r" (uCR3
));
1732 __asm__
__volatile__("movl %%cr3, %0\t\n" : "=r" (uCR3
));
1737 # ifdef RT_ARCH_AMD64
1752 * Sets the CR3 register.
1754 * @param uCR3 New CR3 value.
1756 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
1757 DECLASM(void) ASMSetCR3(RTCCUINTXREG uCR3
);
1759 DECLINLINE(void) ASMSetCR3(RTCCUINTXREG uCR3
)
1761 # if RT_INLINE_ASM_USES_INTRIN
1764 # elif RT_INLINE_ASM_GNU_STYLE
1765 # ifdef RT_ARCH_AMD64
1766 __asm__
__volatile__("movq %0, %%cr3\n\t" : : "r" (uCR3
));
1768 __asm__
__volatile__("movl %0, %%cr3\n\t" : : "r" (uCR3
));
1773 # ifdef RT_ARCH_AMD64
1787 * Reloads the CR3 register.
1789 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
1790 DECLASM(void) ASMReloadCR3(void);
1792 DECLINLINE(void) ASMReloadCR3(void)
1794 # if RT_INLINE_ASM_USES_INTRIN
1795 __writecr3(__readcr3());
1797 # elif RT_INLINE_ASM_GNU_STYLE
1799 # ifdef RT_ARCH_AMD64
1800 __asm__
__volatile__("movq %%cr3, %0\n\t"
1801 "movq %0, %%cr3\n\t"
1804 __asm__
__volatile__("movl %%cr3, %0\n\t"
1805 "movl %0, %%cr3\n\t"
1811 # ifdef RT_ARCH_AMD64
1828 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
1829 DECLASM(RTCCUINTXREG
) ASMGetCR4(void);
1831 DECLINLINE(RTCCUINTXREG
) ASMGetCR4(void)
1834 # if RT_INLINE_ASM_USES_INTRIN
1837 # elif RT_INLINE_ASM_GNU_STYLE
1838 # ifdef RT_ARCH_AMD64
1839 __asm__
__volatile__("movq %%cr4, %0\t\n" : "=r" (uCR4
));
1841 __asm__
__volatile__("movl %%cr4, %0\t\n" : "=r" (uCR4
));
1846 # ifdef RT_ARCH_AMD64
1850 push eax
/* just in case */
1866 * Sets the CR4 register.
1868 * @param uCR4 New CR4 value.
1870 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
1871 DECLASM(void) ASMSetCR4(RTCCUINTXREG uCR4
);
1873 DECLINLINE(void) ASMSetCR4(RTCCUINTXREG uCR4
)
1875 # if RT_INLINE_ASM_USES_INTRIN
1878 # elif RT_INLINE_ASM_GNU_STYLE
1879 # ifdef RT_ARCH_AMD64
1880 __asm__
__volatile__("movq %0, %%cr4\n\t" : : "r" (uCR4
));
1882 __asm__
__volatile__("movl %0, %%cr4\n\t" : : "r" (uCR4
));
1887 # ifdef RT_ARCH_AMD64
1894 _emit
0xE0 /* mov cr4, eax */
1905 * @remark The lock prefix hack for access from non-64-bit modes is NOT used and 0 is returned.
1907 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
1908 DECLASM(RTCCUINTXREG
) ASMGetCR8(void);
1910 DECLINLINE(RTCCUINTXREG
) ASMGetCR8(void)
1912 # ifdef RT_ARCH_AMD64
1914 # if RT_INLINE_ASM_USES_INTRIN
1917 # elif RT_INLINE_ASM_GNU_STYLE
1918 __asm__
__volatile__("movq %%cr8, %0\t\n" : "=r" (uCR8
));
1927 # else /* !RT_ARCH_AMD64 */
1929 # endif /* !RT_ARCH_AMD64 */
1935 * Get XCR0 (eXtended feature Control Register 0).
1938 DECLASM(uint64_t) ASMGetXcr0(void);
1941 * Sets the XCR0 register.
1942 * @param uXcr0 The new XCR0 value.
1944 DECLASM(void) ASMSetXcr0(uint64_t uXcr0
);
1946 struct X86XSAVEAREA
;
1948 * Save extended CPU state.
1949 * @param pXStateArea Where to save the state.
1950 * @param fComponents Which state components to save.
1952 DECLASM(void) ASMXSave(struct X86XSAVEAREA
*pXStateArea
, uint64_t fComponents
);
1955 * Loads extended CPU state.
1956 * @param pXStateArea Where to load the state from.
1957 * @param fComponents Which state components to load.
1959 DECLASM(void) ASMXRstor(struct X86XSAVEAREA
const *pXStateArea
, uint64_t fComponents
);
1963 * Enables interrupts (EFLAGS.IF).
1965 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
1966 DECLASM(void) ASMIntEnable(void);
1968 DECLINLINE(void) ASMIntEnable(void)
1970 # if RT_INLINE_ASM_GNU_STYLE
1972 # elif RT_INLINE_ASM_USES_INTRIN
1982 * Disables interrupts (!EFLAGS.IF).
1984 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
1985 DECLASM(void) ASMIntDisable(void);
1987 DECLINLINE(void) ASMIntDisable(void)
1989 # if RT_INLINE_ASM_GNU_STYLE
1991 # elif RT_INLINE_ASM_USES_INTRIN
2001 * Disables interrupts and returns previous xFLAGS.
2003 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
2004 DECLASM(RTCCUINTREG
) ASMIntDisableFlags(void);
2006 DECLINLINE(RTCCUINTREG
) ASMIntDisableFlags(void)
2009 # if RT_INLINE_ASM_GNU_STYLE
2010 # ifdef RT_ARCH_AMD64
2011 __asm__
__volatile__("pushfq\n\t"
2016 __asm__
__volatile__("pushfl\n\t"
2021 # elif RT_INLINE_ASM_USES_INTRIN && !defined(RT_ARCH_X86)
2022 xFlags
= ASMGetFlags();
2037 * Are interrupts enabled?
2039 * @returns true / false.
2041 DECLINLINE(bool) ASMIntAreEnabled(void)
2043 RTCCUINTREG uFlags
= ASMGetFlags();
2044 return uFlags
& 0x200 /* X86_EFL_IF */ ? true : false;
2049 * Halts the CPU until interrupted.
2051 #if RT_INLINE_ASM_EXTERNAL && RT_INLINE_ASM_USES_INTRIN < 14
2052 DECLASM(void) ASMHalt(void);
2054 DECLINLINE(void) ASMHalt(void)
2056 # if RT_INLINE_ASM_GNU_STYLE
2057 __asm__
__volatile__("hlt\n\t");
2058 # elif RT_INLINE_ASM_USES_INTRIN
2070 * Reads a machine specific register.
2072 * @returns Register content.
2073 * @param uRegister Register to read.
2075 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
2076 DECLASM(uint64_t) ASMRdMsr(uint32_t uRegister
);
2078 DECLINLINE(uint64_t) ASMRdMsr(uint32_t uRegister
)
2081 # if RT_INLINE_ASM_GNU_STYLE
2082 __asm__
__volatile__("rdmsr\n\t"
2087 # elif RT_INLINE_ASM_USES_INTRIN
2088 u
.u
= __readmsr(uRegister
);
2093 mov ecx
, [uRegister
]
2106 * Writes a machine specific register.
2108 * @returns Register content.
2109 * @param uRegister Register to write to.
2110 * @param u64Val Value to write.
2112 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
2113 DECLASM(void) ASMWrMsr(uint32_t uRegister
, uint64_t u64Val
);
2115 DECLINLINE(void) ASMWrMsr(uint32_t uRegister
, uint64_t u64Val
)
2120 # if RT_INLINE_ASM_GNU_STYLE
2121 __asm__
__volatile__("wrmsr\n\t"
2126 # elif RT_INLINE_ASM_USES_INTRIN
2127 __writemsr(uRegister
, u
.u
);
2132 mov ecx
, [uRegister
]
2143 * Reads a machine specific register, extended version (for AMD).
2145 * @returns Register content.
2146 * @param uRegister Register to read.
2147 * @param uXDI RDI/EDI value.
2149 #if RT_INLINE_ASM_EXTERNAL
2150 DECLASM(uint64_t) ASMRdMsrEx(uint32_t uRegister
, RTCCUINTXREG uXDI
);
2152 DECLINLINE(uint64_t) ASMRdMsrEx(uint32_t uRegister
, RTCCUINTXREG uXDI
)
2155 # if RT_INLINE_ASM_GNU_STYLE
2156 __asm__
__volatile__("rdmsr\n\t"
2165 mov ecx
, [uRegister
]
2180 * Writes a machine specific register, extended version (for AMD).
2182 * @returns Register content.
2183 * @param uRegister Register to write to.
2184 * @param uXDI RDI/EDI value.
2185 * @param u64Val Value to write.
2187 #if RT_INLINE_ASM_EXTERNAL
2188 DECLASM(void) ASMWrMsrEx(uint32_t uRegister
, RTCCUINTXREG uXDI
, uint64_t u64Val
);
2190 DECLINLINE(void) ASMWrMsrEx(uint32_t uRegister
, RTCCUINTXREG uXDI
, uint64_t u64Val
)
2195 # if RT_INLINE_ASM_GNU_STYLE
2196 __asm__
__volatile__("wrmsr\n\t"
2205 mov ecx
, [uRegister
]
2219 * Reads low part of a machine specific register.
2221 * @returns Register content.
2222 * @param uRegister Register to read.
2224 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
2225 DECLASM(uint32_t) ASMRdMsr_Low(uint32_t uRegister
);
2227 DECLINLINE(uint32_t) ASMRdMsr_Low(uint32_t uRegister
)
2230 # if RT_INLINE_ASM_GNU_STYLE
2231 __asm__
__volatile__("rdmsr\n\t"
2236 # elif RT_INLINE_ASM_USES_INTRIN
2237 u32
= (uint32_t)__readmsr(uRegister
);
2242 mov ecx
, [uRegister
]
2254 * Reads high part of a machine specific register.
2256 * @returns Register content.
2257 * @param uRegister Register to read.
2259 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
2260 DECLASM(uint32_t) ASMRdMsr_High(uint32_t uRegister
);
2262 DECLINLINE(uint32_t) ASMRdMsr_High(uint32_t uRegister
)
2265 # if RT_INLINE_ASM_GNU_STYLE
2266 __asm__
__volatile__("rdmsr\n\t"
2271 # elif RT_INLINE_ASM_USES_INTRIN
2272 u32
= (uint32_t)(__readmsr(uRegister
) >> 32);
2277 mov ecx
, [uRegister
]
2293 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
2294 DECLASM(RTCCUINTXREG
) ASMGetDR0(void);
2296 DECLINLINE(RTCCUINTXREG
) ASMGetDR0(void)
2299 # if RT_INLINE_ASM_USES_INTRIN
2301 # elif RT_INLINE_ASM_GNU_STYLE
2302 # ifdef RT_ARCH_AMD64
2303 __asm__
__volatile__("movq %%dr0, %0\n\t" : "=r" (uDR0
));
2305 __asm__
__volatile__("movl %%dr0, %0\n\t" : "=r" (uDR0
));
2310 # ifdef RT_ARCH_AMD64
2329 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
2330 DECLASM(RTCCUINTXREG
) ASMGetDR1(void);
2332 DECLINLINE(RTCCUINTXREG
) ASMGetDR1(void)
2335 # if RT_INLINE_ASM_USES_INTRIN
2337 # elif RT_INLINE_ASM_GNU_STYLE
2338 # ifdef RT_ARCH_AMD64
2339 __asm__
__volatile__("movq %%dr1, %0\n\t" : "=r" (uDR1
));
2341 __asm__
__volatile__("movl %%dr1, %0\n\t" : "=r" (uDR1
));
2346 # ifdef RT_ARCH_AMD64
2365 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
2366 DECLASM(RTCCUINTXREG
) ASMGetDR2(void);
2368 DECLINLINE(RTCCUINTXREG
) ASMGetDR2(void)
2371 # if RT_INLINE_ASM_USES_INTRIN
2373 # elif RT_INLINE_ASM_GNU_STYLE
2374 # ifdef RT_ARCH_AMD64
2375 __asm__
__volatile__("movq %%dr2, %0\n\t" : "=r" (uDR2
));
2377 __asm__
__volatile__("movl %%dr2, %0\n\t" : "=r" (uDR2
));
2382 # ifdef RT_ARCH_AMD64
2401 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
2402 DECLASM(RTCCUINTXREG
) ASMGetDR3(void);
2404 DECLINLINE(RTCCUINTXREG
) ASMGetDR3(void)
2407 # if RT_INLINE_ASM_USES_INTRIN
2409 # elif RT_INLINE_ASM_GNU_STYLE
2410 # ifdef RT_ARCH_AMD64
2411 __asm__
__volatile__("movq %%dr3, %0\n\t" : "=r" (uDR3
));
2413 __asm__
__volatile__("movl %%dr3, %0\n\t" : "=r" (uDR3
));
2418 # ifdef RT_ARCH_AMD64
2437 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
2438 DECLASM(RTCCUINTXREG
) ASMGetDR6(void);
2440 DECLINLINE(RTCCUINTXREG
) ASMGetDR6(void)
2443 # if RT_INLINE_ASM_USES_INTRIN
2445 # elif RT_INLINE_ASM_GNU_STYLE
2446 # ifdef RT_ARCH_AMD64
2447 __asm__
__volatile__("movq %%dr6, %0\n\t" : "=r" (uDR6
));
2449 __asm__
__volatile__("movl %%dr6, %0\n\t" : "=r" (uDR6
));
2454 # ifdef RT_ARCH_AMD64
2469 * Reads and clears DR6.
2473 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
2474 DECLASM(RTCCUINTXREG
) ASMGetAndClearDR6(void);
2476 DECLINLINE(RTCCUINTXREG
) ASMGetAndClearDR6(void)
2479 # if RT_INLINE_ASM_USES_INTRIN
2481 __writedr(6, 0xffff0ff0U
); /* 31-16 and 4-11 are 1's, 12 and 63-31 are zero. */
2482 # elif RT_INLINE_ASM_GNU_STYLE
2483 RTCCUINTXREG uNewValue
= 0xffff0ff0U
;/* 31-16 and 4-11 are 1's, 12 and 63-31 are zero. */
2484 # ifdef RT_ARCH_AMD64
2485 __asm__
__volatile__("movq %%dr6, %0\n\t"
2486 "movq %1, %%dr6\n\t"
2490 __asm__
__volatile__("movl %%dr6, %0\n\t"
2491 "movl %1, %%dr6\n\t"
2498 # ifdef RT_ARCH_AMD64
2502 mov ecx
, 0ffff0ff0h
; /* 31-16 and 4-11 are 1's, 12 and 63-31 are zero. */
2507 mov ecx
, 0ffff0ff0h
; /* 31-16 and 4-11 are 1's, 12 is zero. */
2522 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
2523 DECLASM(RTCCUINTXREG
) ASMGetDR7(void);
2525 DECLINLINE(RTCCUINTXREG
) ASMGetDR7(void)
2528 # if RT_INLINE_ASM_USES_INTRIN
2530 # elif RT_INLINE_ASM_GNU_STYLE
2531 # ifdef RT_ARCH_AMD64
2532 __asm__
__volatile__("movq %%dr7, %0\n\t" : "=r" (uDR7
));
2534 __asm__
__volatile__("movl %%dr7, %0\n\t" : "=r" (uDR7
));
2539 # ifdef RT_ARCH_AMD64
2556 * @param uDRVal Debug register value to write
2558 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
2559 DECLASM(void) ASMSetDR0(RTCCUINTXREG uDRVal
);
2561 DECLINLINE(void) ASMSetDR0(RTCCUINTXREG uDRVal
)
2563 # if RT_INLINE_ASM_USES_INTRIN
2564 __writedr(0, uDRVal
);
2565 # elif RT_INLINE_ASM_GNU_STYLE
2566 # ifdef RT_ARCH_AMD64
2567 __asm__
__volatile__("movq %0, %%dr0\n\t" : : "r" (uDRVal
));
2569 __asm__
__volatile__("movl %0, %%dr0\n\t" : : "r" (uDRVal
));
2574 # ifdef RT_ARCH_AMD64
2590 * @param uDRVal Debug register value to write
2592 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
2593 DECLASM(void) ASMSetDR1(RTCCUINTXREG uDRVal
);
2595 DECLINLINE(void) ASMSetDR1(RTCCUINTXREG uDRVal
)
2597 # if RT_INLINE_ASM_USES_INTRIN
2598 __writedr(1, uDRVal
);
2599 # elif RT_INLINE_ASM_GNU_STYLE
2600 # ifdef RT_ARCH_AMD64
2601 __asm__
__volatile__("movq %0, %%dr1\n\t" : : "r" (uDRVal
));
2603 __asm__
__volatile__("movl %0, %%dr1\n\t" : : "r" (uDRVal
));
2608 # ifdef RT_ARCH_AMD64
2624 * @param uDRVal Debug register value to write
2626 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
2627 DECLASM(void) ASMSetDR2(RTCCUINTXREG uDRVal
);
2629 DECLINLINE(void) ASMSetDR2(RTCCUINTXREG uDRVal
)
2631 # if RT_INLINE_ASM_USES_INTRIN
2632 __writedr(2, uDRVal
);
2633 # elif RT_INLINE_ASM_GNU_STYLE
2634 # ifdef RT_ARCH_AMD64
2635 __asm__
__volatile__("movq %0, %%dr2\n\t" : : "r" (uDRVal
));
2637 __asm__
__volatile__("movl %0, %%dr2\n\t" : : "r" (uDRVal
));
2642 # ifdef RT_ARCH_AMD64
2658 * @param uDRVal Debug register value to write
2660 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
2661 DECLASM(void) ASMSetDR3(RTCCUINTXREG uDRVal
);
2663 DECLINLINE(void) ASMSetDR3(RTCCUINTXREG uDRVal
)
2665 # if RT_INLINE_ASM_USES_INTRIN
2666 __writedr(3, uDRVal
);
2667 # elif RT_INLINE_ASM_GNU_STYLE
2668 # ifdef RT_ARCH_AMD64
2669 __asm__
__volatile__("movq %0, %%dr3\n\t" : : "r" (uDRVal
));
2671 __asm__
__volatile__("movl %0, %%dr3\n\t" : : "r" (uDRVal
));
2676 # ifdef RT_ARCH_AMD64
2692 * @param uDRVal Debug register value to write
2694 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
2695 DECLASM(void) ASMSetDR6(RTCCUINTXREG uDRVal
);
2697 DECLINLINE(void) ASMSetDR6(RTCCUINTXREG uDRVal
)
2699 # if RT_INLINE_ASM_USES_INTRIN
2700 __writedr(6, uDRVal
);
2701 # elif RT_INLINE_ASM_GNU_STYLE
2702 # ifdef RT_ARCH_AMD64
2703 __asm__
__volatile__("movq %0, %%dr6\n\t" : : "r" (uDRVal
));
2705 __asm__
__volatile__("movl %0, %%dr6\n\t" : : "r" (uDRVal
));
2710 # ifdef RT_ARCH_AMD64
2726 * @param uDRVal Debug register value to write
2728 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
2729 DECLASM(void) ASMSetDR7(RTCCUINTXREG uDRVal
);
2731 DECLINLINE(void) ASMSetDR7(RTCCUINTXREG uDRVal
)
2733 # if RT_INLINE_ASM_USES_INTRIN
2734 __writedr(7, uDRVal
);
2735 # elif RT_INLINE_ASM_GNU_STYLE
2736 # ifdef RT_ARCH_AMD64
2737 __asm__
__volatile__("movq %0, %%dr7\n\t" : : "r" (uDRVal
));
2739 __asm__
__volatile__("movl %0, %%dr7\n\t" : : "r" (uDRVal
));
2744 # ifdef RT_ARCH_AMD64
2758 * Writes a 8-bit unsigned integer to an I/O port, ordered.
2760 * @param Port I/O port to write to.
2761 * @param u8 8-bit integer to write.
2763 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
2764 DECLASM(void) ASMOutU8(RTIOPORT Port
, uint8_t u8
);
2766 DECLINLINE(void) ASMOutU8(RTIOPORT Port
, uint8_t u8
)
2768 # if RT_INLINE_ASM_GNU_STYLE
2769 __asm__
__volatile__("outb %b1, %w0\n\t"
2773 # elif RT_INLINE_ASM_USES_INTRIN
2774 __outbyte(Port
, u8
);
2789 * Reads a 8-bit unsigned integer from an I/O port, ordered.
2791 * @returns 8-bit integer.
2792 * @param Port I/O port to read from.
2794 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
2795 DECLASM(uint8_t) ASMInU8(RTIOPORT Port
);
2797 DECLINLINE(uint8_t) ASMInU8(RTIOPORT Port
)
2800 # if RT_INLINE_ASM_GNU_STYLE
2801 __asm__
__volatile__("inb %w1, %b0\n\t"
2805 # elif RT_INLINE_ASM_USES_INTRIN
2806 u8
= __inbyte(Port
);
2822 * Writes a 16-bit unsigned integer to an I/O port, ordered.
2824 * @param Port I/O port to write to.
2825 * @param u16 16-bit integer to write.
2827 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
2828 DECLASM(void) ASMOutU16(RTIOPORT Port
, uint16_t u16
);
2830 DECLINLINE(void) ASMOutU16(RTIOPORT Port
, uint16_t u16
)
2832 # if RT_INLINE_ASM_GNU_STYLE
2833 __asm__
__volatile__("outw %w1, %w0\n\t"
2837 # elif RT_INLINE_ASM_USES_INTRIN
2838 __outword(Port
, u16
);
2853 * Reads a 16-bit unsigned integer from an I/O port, ordered.
2855 * @returns 16-bit integer.
2856 * @param Port I/O port to read from.
2858 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
2859 DECLASM(uint16_t) ASMInU16(RTIOPORT Port
);
2861 DECLINLINE(uint16_t) ASMInU16(RTIOPORT Port
)
2864 # if RT_INLINE_ASM_GNU_STYLE
2865 __asm__
__volatile__("inw %w1, %w0\n\t"
2869 # elif RT_INLINE_ASM_USES_INTRIN
2870 u16
= __inword(Port
);
2886 * Writes a 32-bit unsigned integer to an I/O port, ordered.
2888 * @param Port I/O port to write to.
2889 * @param u32 32-bit integer to write.
2891 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
2892 DECLASM(void) ASMOutU32(RTIOPORT Port
, uint32_t u32
);
2894 DECLINLINE(void) ASMOutU32(RTIOPORT Port
, uint32_t u32
)
2896 # if RT_INLINE_ASM_GNU_STYLE
2897 __asm__
__volatile__("outl %1, %w0\n\t"
2901 # elif RT_INLINE_ASM_USES_INTRIN
2902 __outdword(Port
, u32
);
2917 * Reads a 32-bit unsigned integer from an I/O port, ordered.
2919 * @returns 32-bit integer.
2920 * @param Port I/O port to read from.
2922 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
2923 DECLASM(uint32_t) ASMInU32(RTIOPORT Port
);
2925 DECLINLINE(uint32_t) ASMInU32(RTIOPORT Port
)
2928 # if RT_INLINE_ASM_GNU_STYLE
2929 __asm__
__volatile__("inl %w1, %0\n\t"
2933 # elif RT_INLINE_ASM_USES_INTRIN
2934 u32
= __indword(Port
);
2950 * Writes a string of 8-bit unsigned integer items to an I/O port, ordered.
2952 * @param Port I/O port to write to.
2953 * @param pau8 Pointer to the string buffer.
2954 * @param c The number of items to write.
2956 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
2957 DECLASM(void) ASMOutStrU8(RTIOPORT Port
, uint8_t const *pau8
, size_t c
);
2959 DECLINLINE(void) ASMOutStrU8(RTIOPORT Port
, uint8_t const *pau8
, size_t c
)
2961 # if RT_INLINE_ASM_GNU_STYLE
2962 __asm__
__volatile__("rep; outsb\n\t"
2967 # elif RT_INLINE_ASM_USES_INTRIN
2968 __outbytestring(Port
, (unsigned char *)pau8
, (unsigned long)c
);
2986 * Reads a string of 8-bit unsigned integer items from an I/O port, ordered.
2988 * @param Port I/O port to read from.
2989 * @param pau8 Pointer to the string buffer (output).
2990 * @param c The number of items to read.
2992 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
2993 DECLASM(void) ASMInStrU8(RTIOPORT Port
, uint8_t *pau8
, size_t c
);
2995 DECLINLINE(void) ASMInStrU8(RTIOPORT Port
, uint8_t *pau8
, size_t c
)
2997 # if RT_INLINE_ASM_GNU_STYLE
2998 __asm__
__volatile__("rep; insb\n\t"
3003 # elif RT_INLINE_ASM_USES_INTRIN
3004 __inbytestring(Port
, pau8
, (unsigned long)c
);
3022 * Writes a string of 16-bit unsigned integer items to an I/O port, ordered.
3024 * @param Port I/O port to write to.
3025 * @param pau16 Pointer to the string buffer.
3026 * @param c The number of items to write.
3028 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
3029 DECLASM(void) ASMOutStrU16(RTIOPORT Port
, uint16_t const *pau16
, size_t c
);
3031 DECLINLINE(void) ASMOutStrU16(RTIOPORT Port
, uint16_t const *pau16
, size_t c
)
3033 # if RT_INLINE_ASM_GNU_STYLE
3034 __asm__
__volatile__("rep; outsw\n\t"
3039 # elif RT_INLINE_ASM_USES_INTRIN
3040 __outwordstring(Port
, (unsigned short *)pau16
, (unsigned long)c
);
3058 * Reads a string of 16-bit unsigned integer items from an I/O port, ordered.
3060 * @param Port I/O port to read from.
3061 * @param pau16 Pointer to the string buffer (output).
3062 * @param c The number of items to read.
3064 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
3065 DECLASM(void) ASMInStrU16(RTIOPORT Port
, uint16_t *pau16
, size_t c
);
3067 DECLINLINE(void) ASMInStrU16(RTIOPORT Port
, uint16_t *pau16
, size_t c
)
3069 # if RT_INLINE_ASM_GNU_STYLE
3070 __asm__
__volatile__("rep; insw\n\t"
3075 # elif RT_INLINE_ASM_USES_INTRIN
3076 __inwordstring(Port
, pau16
, (unsigned long)c
);
3094 * Writes a string of 32-bit unsigned integer items to an I/O port, ordered.
3096 * @param Port I/O port to write to.
3097 * @param pau32 Pointer to the string buffer.
3098 * @param c The number of items to write.
3100 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
3101 DECLASM(void) ASMOutStrU32(RTIOPORT Port
, uint32_t const *pau32
, size_t c
);
3103 DECLINLINE(void) ASMOutStrU32(RTIOPORT Port
, uint32_t const *pau32
, size_t c
)
3105 # if RT_INLINE_ASM_GNU_STYLE
3106 __asm__
__volatile__("rep; outsl\n\t"
3111 # elif RT_INLINE_ASM_USES_INTRIN
3112 __outdwordstring(Port
, (unsigned long *)pau32
, (unsigned long)c
);
3130 * Reads a string of 32-bit unsigned integer items from an I/O port, ordered.
3132 * @param Port I/O port to read from.
3133 * @param pau32 Pointer to the string buffer (output).
3134 * @param c The number of items to read.
3136 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
3137 DECLASM(void) ASMInStrU32(RTIOPORT Port
, uint32_t *pau32
, size_t c
);
3139 DECLINLINE(void) ASMInStrU32(RTIOPORT Port
, uint32_t *pau32
, size_t c
)
3141 # if RT_INLINE_ASM_GNU_STYLE
3142 __asm__
__volatile__("rep; insl\n\t"
3147 # elif RT_INLINE_ASM_USES_INTRIN
3148 __indwordstring(Port
, (unsigned long *)pau32
, (unsigned long)c
);
3168 * @param uPtr Address of the page to invalidate.
3170 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
3171 DECLASM(void) ASMInvalidatePage(RTCCUINTXREG uPtr
);
3173 DECLINLINE(void) ASMInvalidatePage(RTCCUINTXREG uPtr
)
3175 # if RT_INLINE_ASM_USES_INTRIN
3176 __invlpg((void *)uPtr
);
3178 # elif RT_INLINE_ASM_GNU_STYLE
3179 __asm__
__volatile__("invlpg %0\n\t"
3180 : : "m" (*(uint8_t *)(uintptr_t)uPtr
));
3184 # ifdef RT_ARCH_AMD64
3198 * Write back the internal caches and invalidate them.
3200 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
3201 DECLASM(void) ASMWriteBackAndInvalidateCaches(void);
3203 DECLINLINE(void) ASMWriteBackAndInvalidateCaches(void)
3205 # if RT_INLINE_ASM_USES_INTRIN
3208 # elif RT_INLINE_ASM_GNU_STYLE
3209 __asm__
__volatile__("wbinvd");
3221 * Invalidate internal and (perhaps) external caches without first
3222 * flushing dirty cache lines. Use with extreme care.
3224 #if RT_INLINE_ASM_EXTERNAL
3225 DECLASM(void) ASMInvalidateInternalCaches(void);
3227 DECLINLINE(void) ASMInvalidateInternalCaches(void)
3229 # if RT_INLINE_ASM_GNU_STYLE
3230 __asm__
__volatile__("invd");
3242 * Memory load/store fence, waits for any pending writes and reads to complete.
3243 * Requires the X86_CPUID_FEATURE_EDX_SSE2 CPUID bit set.
3245 DECLINLINE(void) ASMMemoryFenceSSE2(void)
3247 #if RT_INLINE_ASM_GNU_STYLE
3248 __asm__
__volatile__ (".byte 0x0f,0xae,0xf0\n\t");
3249 #elif RT_INLINE_ASM_USES_INTRIN
3263 * Memory store fence, waits for any writes to complete.
3264 * Requires the X86_CPUID_FEATURE_EDX_SSE CPUID bit set.
3266 DECLINLINE(void) ASMWriteFenceSSE(void)
3268 #if RT_INLINE_ASM_GNU_STYLE
3269 __asm__
__volatile__ (".byte 0x0f,0xae,0xf8\n\t");
3270 #elif RT_INLINE_ASM_USES_INTRIN
3284 * Memory load fence, waits for any pending reads to complete.
3285 * Requires the X86_CPUID_FEATURE_EDX_SSE2 CPUID bit set.
3287 DECLINLINE(void) ASMReadFenceSSE2(void)
3289 #if RT_INLINE_ASM_GNU_STYLE
3290 __asm__
__volatile__ (".byte 0x0f,0xae,0xe8\n\t");
3291 #elif RT_INLINE_ASM_USES_INTRIN
3303 #if !defined(_MSC_VER) || !defined(RT_ARCH_AMD64)
3306 * Clear the AC bit in the EFLAGS register.
3307 * Requires the X86_CPUID_STEXT_FEATURE_EBX_SMAP CPUID bit set.
3308 * Requires to be executed in R0.
3310 DECLINLINE(void) ASMClearAC(void)
3312 #if RT_INLINE_ASM_GNU_STYLE
3313 __asm__
__volatile__ (".byte 0x0f,0x01,0xca\n\t");
3326 * Set the AC bit in the EFLAGS register.
3327 * Requires the X86_CPUID_STEXT_FEATURE_EBX_SMAP CPUID bit set.
3328 * Requires to be executed in R0.
3330 DECLINLINE(void) ASMSetAC(void)
3332 #if RT_INLINE_ASM_GNU_STYLE
3333 __asm__
__volatile__ (".byte 0x0f,0x01,0xcb\n\t");
3344 #endif /* !_MSC_VER) || !RT_ARCH_AMD64 */