asm.h revision ec1eca74badc326cb04c0d139286e5a2ce99da63
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * innotek Portable Runtime - Assembly Functions.
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * Copyright (C) 2006-2007 innotek GmbH
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * available from http://www.virtualbox.org. This file is free software;
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * you can redistribute it and/or modify it under the terms of the GNU
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * General Public License as published by the Free Software Foundation,
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * distribution. VirtualBox OSE is distributed in the hope that it will
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * be useful, but WITHOUT ANY WARRANTY of any kind.
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync/** @todo #include <iprt/param.h> for PAGE_SIZE. */
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync/** @def RT_INLINE_ASM_USES_INTRIN
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * Defined as 1 if we're using a _MSC_VER 1400.
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * Otherwise defined as 0.
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsync /* Emit the intrinsics at all optimization levels. */
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync/** @defgroup grp_asm ASM - Assembly Routines
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * @ingroup grp_rt
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync/** @def RT_INLINE_ASM_EXTERNAL
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * Defined as 1 if the compiler does not support inline assembly.
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * The ASM* functions will then be implemented in an external .asm file.
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * @remark At the present time it's unconfirmed whether or not Microsoft skipped
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * inline assmebly in their AMD64 compiler.
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync/** @def RT_INLINE_ASM_GNU_STYLE
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync * Defined as 1 if the compiler understand GNU style inline assembly.
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync/** @todo find a more proper place for this structure? */
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsynctypedef struct RTIDTR
852e87ceabd0234ac0f9e71537c11d08e35f736cvboxsync /** Size of the IDT. */
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync /** Address of the IDT. */
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsynctypedef struct RTGDTR
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync /** Size of the GDT. */
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync /** Address of the GDT. */
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync/** @def ASMReturnAddress
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * Gets the return address of the current (or calling if you like) function or method.
b3109af8dcc2a3da7f424aa05a4e84a64bf1c43fvboxsync# define ASMReturnAddress() __builtin_return_address(0)
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * Gets the content of the IDTR CPU register.
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync * @param pIdtr Where to store the IDTR contents.
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * Sets the content of the IDTR CPU register.
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * @param pIdtr Where to load the IDTR contents from
9edbe160de7266b3b5d54ccf2f07ed95f9f40c6bvboxsync * Gets the content of the GDTR CPU register.
9edbe160de7266b3b5d54ccf2f07ed95f9f40c6bvboxsync * @param pGdtr Where to store the GDTR contents.
951d1da36c2120dd8bf59a3b57800f8429dcd387vboxsync * Get the cs register.
9edbe160de7266b3b5d54ccf2f07ed95f9f40c6bvboxsync * @returns cs.
0780b79e94db3b60fb4a3057df7c64ba8b1cb75dvboxsync __asm__ __volatile__("movw %%cs, %0\n\t" : "=r" (SelCS));
9edbe160de7266b3b5d54ccf2f07ed95f9f40c6bvboxsync * Get the DS register.
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * @returns DS.
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync __asm__ __volatile__("movw %%ds, %0\n\t" : "=r" (SelDS));
4aafb1203580a5c145a7bdae57ebf69a36fa4f01vboxsync * Get the ES register.
4aafb1203580a5c145a7bdae57ebf69a36fa4f01vboxsync * @returns ES.
852e87ceabd0234ac0f9e71537c11d08e35f736cvboxsync __asm__ __volatile__("movw %%es, %0\n\t" : "=r" (SelES));
0f77dc54d7ec617480988ccdfcd080f480e79698vboxsync * Get the FS register.
0f77dc54d7ec617480988ccdfcd080f480e79698vboxsync * @returns FS.
0f77dc54d7ec617480988ccdfcd080f480e79698vboxsync __asm__ __volatile__("movw %%fs, %0\n\t" : "=r" (SelFS));
76cb9831bbeaff3bb30068363e35660a776736c4vboxsync * Get the GS register.
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync * @returns GS.
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync __asm__ __volatile__("movw %%gs, %0\n\t" : "=r" (SelGS));
0f77dc54d7ec617480988ccdfcd080f480e79698vboxsync * Get the SS register.
852e87ceabd0234ac0f9e71537c11d08e35f736cvboxsync * @returns SS.
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync __asm__ __volatile__("movw %%ss, %0\n\t" : "=r" (SelSS));
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * Get the TR register.
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * @returns TR.
10f0e3bfdb61e7bae30a1a1d9c17659a908c3d37vboxsync __asm__ __volatile__("str %w0\n\t" : "=r" (SelTR));
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * Get the [RE]FLAGS register.
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * @returns [RE]FLAGS.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync "popq %0\n\t"
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync "popl %0\n\t"
10f0e3bfdb61e7bae30a1a1d9c17659a908c3d37vboxsync * Set the [RE]FLAGS register.
10f0e3bfdb61e7bae30a1a1d9c17659a908c3d37vboxsync * @param uFlags The new [RE]FLAGS value.
10f0e3bfdb61e7bae30a1a1d9c17659a908c3d37vboxsync "popfq\n\t"
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync "popfl\n\t"
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * Gets the content of the CPU timestamp counter register.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * @returns TSC.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync __asm__ __volatile__ ("rdtsc\n\t" : "=a" (u.s.Lo), "=d" (u.s.Hi));
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync return u.u;
10f0e3bfdb61e7bae30a1a1d9c17659a908c3d37vboxsync * Performs the cpuid instruction returning all registers.
10f0e3bfdb61e7bae30a1a1d9c17659a908c3d37vboxsync * @param uOperator CPUID operation (eax).
10f0e3bfdb61e7bae30a1a1d9c17659a908c3d37vboxsync * @param pvEAX Where to store eax.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * @param pvEBX Where to store ebx.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * @param pvECX Where to store ecx.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * @param pvEDX Where to store edx.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * @remark We're using void pointers to ease the use of special bitfield structures and such.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsyncDECLASM(void) ASMCpuId(uint32_t uOperator, void *pvEAX, void *pvEBX, void *pvECX, void *pvEDX);
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsyncDECLINLINE(void) ASMCpuId(uint32_t uOperator, void *pvEAX, void *pvEBX, void *pvECX, void *pvEDX)
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync "cpuid\n\t"
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync "xchgl %%ebx, %1\n\t"
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * Performs the cpuid instruction returning ecx and edx.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * @param uOperator CPUID operation (eax).
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * @param pvECX Where to store ecx.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * @param pvEDX Where to store edx.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * @remark We're using void pointers to ease the use of special bitfield structures and such.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsyncDECLASM(void) ASMCpuId_ECX_EDX(uint32_t uOperator, void *pvECX, void *pvEDX);
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsyncDECLINLINE(void) ASMCpuId_ECX_EDX(uint32_t uOperator, void *pvECX, void *pvEDX)
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync ASMCpuId(uOperator, &uOperator, &uEBX, pvECX, pvEDX);
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * Performs the cpuid instruction returning edx.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * @param uOperator CPUID operation (eax).
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * @returns EDX after cpuid operation.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsyncDECLINLINE(uint32_t) ASMCpuId_EDX(uint32_t uOperator)
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync# elif (defined(PIC) || defined(RT_OS_DARWIN)) && defined(__i386__) /* darwin: PIC by default. */
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync "cpuid\n\t"
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync "pop %%ebx\n\t"
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * Performs the cpuid instruction returning ecx.
0f77dc54d7ec617480988ccdfcd080f480e79698vboxsync * @param uOperator CPUID operation (eax).
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * @returns ECX after cpuid operation.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsyncDECLINLINE(uint32_t) ASMCpuId_ECX(uint32_t uOperator)
619824b60d668e6e43f385ef78cf06e13d43aab6vboxsync# elif (defined(PIC) || defined(RT_OS_DARWIN)) && defined(__i386__) /* darwin: 4.0.1 compiler option / bug? */
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync "cpuid\n\t"
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync "pop %%ebx\n\t"
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync * Checks if the current CPU supports CPUID.
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync * @returns true if CPUID is supported.
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync return true; /* ASSUME that all amd64 compatible CPUs have cpuid. */
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync#else /* !RT_ARCH_AMD64 */
951d1da36c2120dd8bf59a3b57800f8429dcd387vboxsync bool fRet = false;
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync "pop %1\n\t"
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync "mov %1, %2\n\t"
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync "xorl $0x200000, %1\n\t"
951d1da36c2120dd8bf59a3b57800f8429dcd387vboxsync "push %1\n\t"
951d1da36c2120dd8bf59a3b57800f8429dcd387vboxsync "pushf\n\t"
951d1da36c2120dd8bf59a3b57800f8429dcd387vboxsync "pop %1\n\t"
951d1da36c2120dd8bf59a3b57800f8429dcd387vboxsync "cmpl %1, %2\n\t"
951d1da36c2120dd8bf59a3b57800f8429dcd387vboxsync "setne %0\n\t"
951d1da36c2120dd8bf59a3b57800f8429dcd387vboxsync "push %2\n\t"
852e87ceabd0234ac0f9e71537c11d08e35f736cvboxsync#endif /* !RT_ARCH_AMD64 */
852e87ceabd0234ac0f9e71537c11d08e35f736cvboxsync * Gets the APIC ID of the current CPU.
4aafb1203580a5c145a7bdae57ebf69a36fa4f01vboxsync * @returns the APIC ID.
4aafb1203580a5c145a7bdae57ebf69a36fa4f01vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync# elif (defined(PIC) || defined(RT_OS_DARWIN)) && defined(__i386__)
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync "cpuid\n\t"
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync "xchgl %%ebx,%1\n\t"
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * @returns cr0.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * Sets the CR0 register.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * @param uCR0 The new CR0 value.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync __asm__ __volatile__("movq %0, %%cr0\n\t" :: "r" (uCR0));
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync __asm__ __volatile__("movl %0, %%cr0\n\t" :: "r" (uCR0));
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * @returns cr2.
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
affcf9ad9ceb4b20938f02dd7cd284b4aaf6b5bbvboxsync * Sets the CR2 register.
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * @param uCR2 The new CR0 value.
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync __asm__ __volatile__("movq %0, %%cr2\n\t" :: "r" (uCR2));
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync __asm__ __volatile__("movl %0, %%cr2\n\t" :: "r" (uCR2));
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * @returns cr3.
951d1da36c2120dd8bf59a3b57800f8429dcd387vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * Sets the CR3 register.
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * @param uCR3 New CR3 value.
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync __asm__ __volatile__ ("movq %0, %%cr3\n\t" : : "r" (uCR3));
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync __asm__ __volatile__ ("movl %0, %%cr3\n\t" : : "r" (uCR3));
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * Reloads the CR3 register.
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync "movq %0, %%cr3\n\t"
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync : "=r" (u));
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync "movl %0, %%cr3\n\t"
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync : "=r" (u));
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * @returns cr4.
f0ed7ab5e7f8d2f73b5aa08e46eb3a04cbb31cb2vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync /*mov eax, cr4*/
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * Sets the CR4 register.
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync * @param uCR4 New CR4 value.
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync __asm__ __volatile__ ("movq %0, %%cr4\n\t" : : "r" (uCR4));
ae41886ba231ade1b868dd32ff24ee49813ebbabvboxsync __asm__ __volatile__ ("movl %0, %%cr4\n\t" : : "r" (uCR4));
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * @returns cr8.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * @remark The lock prefix hack for access from non-64-bit modes is NOT used and 0 is returned.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync# else /* !RT_ARCH_AMD64 */
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync# endif /* !RT_ARCH_AMD64 */
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync * Enables interrupts (EFLAGS.IF).
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
b377a71756cce9f39d25b561f72bfa33ce8a39devboxsync * Disables interrupts (!EFLAGS.IF).
0f77dc54d7ec617480988ccdfcd080f480e79698vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * Disables interrupts and returns previous xFLAGS.
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync "popq %0\n\t"
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync "popl %0\n\t"
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync# elif RT_INLINE_ASM_USES_INTRIN && !defined(RT_ARCH_X86)
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * Reads a machine specific register.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * @returns Register content.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * @param uRegister Register to read.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
0f77dc54d7ec617480988ccdfcd080f480e79698vboxsync return u.u;
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * Writes a machine specific register.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * @returns Register content.
852e87ceabd0234ac0f9e71537c11d08e35f736cvboxsync * @param uRegister Register to write to.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * @param u64Val Value to write.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsyncDECLASM(void) ASMWrMsr(uint32_t uRegister, uint64_t u64Val);
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsyncDECLINLINE(void) ASMWrMsr(uint32_t uRegister, uint64_t u64Val)
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * Reads low part of a machine specific register.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * @returns Register content.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * @param uRegister Register to read.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsyncDECLINLINE(uint32_t) ASMRdMsr_Low(uint32_t uRegister)
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync * Reads high part of a machine specific register.
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync * @returns Register content.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * @param uRegister Register to read.
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsyncDECLASM(uint32_t) ASMRdMsr_High(uint32_t uRegister);
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsyncDECLINLINE(uint32_t) ASMRdMsr_High(uint32_t uRegister)
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync * Gets dr7.
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync * @returns dr7.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * Gets dr6.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * @returns dr6.
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync * Reads and clears DR6.
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync * @returns DR6.
25c97a3e3ce2710f95faa6d181486df26b518e74vboxsync RTCCUINTREG uNewValue = 0xffff0ff0; /* 31-16 and 4-11 are 1's, 12 and 63-31 are zero. */
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync "movq %1, %%dr6\n\t"
0f77dc54d7ec617480988ccdfcd080f480e79698vboxsync "movl %1, %%dr6\n\t"
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync mov ecx, 0ffff0ff0h; /* 31-16 and 4-11 are 1's, 12 and 63-31 are zero. */
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync mov ecx, 0ffff0ff0h; /* 31-16 and 4-11 are 1's, 12 is zero. */
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync * Compiler memory barrier.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * Ensure that the compiler does not use any cached (register/tmp stack) memory
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * values or any outstanding writes when returning from this function.
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync * This function must be used if non-volatile data is modified by a
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * device or the VMM. Typical cases are port access, MMIO access,
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync * trapping instruction, etc.
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync# define ASMCompilerBarrier() do { __asm__ __volatile__ ("" : : : "memory"); } while (0)
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync# define ASMCompilerBarrier() do { _ReadWriteBarrier(); } while (0)
7e3ff7c4e45ee1f8eb46a1aba9d2d8816d337c4avboxsync#else /* 2003 should have _ReadWriteBarrier() but I guess we're at 2002 level then... */
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync * Writes a 8-bit unsigned integer to an I/O port.
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync * @param Port I/O port to read from.
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync * @param u8 8-bit integer to write.
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
0cde281779e97ead3181bbd3b628451fa2b1efe1vboxsyncDECLINLINE(void) ASMOutU8(RTIOPORT Port, uint8_t u8)
4b65b0b7127fe2f685bb5c3319f803a16b84ee6cvboxsync * Gets a 8-bit unsigned integer from an I/O port.
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync * @returns 8-bit integer.
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync * @param Port I/O port to read from.
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync * Writes a 16-bit unsigned integer to an I/O port.
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync * @param Port I/O port to read from.
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync * @param u16 16-bit integer to write.
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsync#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
bc0c1e33e433d1276ea1606ace81f61594ee3838vboxsyncDECLASM(void) ASMOutU16(RTIOPORT Port, uint16_t u16);
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsyncDECLINLINE(void) ASMOutU16(RTIOPORT Port, uint16_t u16)
return u16;
return u32;
# ifdef RT_ARCH_AMD64
return u8;
#ifdef _MSC_VER
# ifdef RT_ARCH_AMD64
return u16;
# ifdef RT_ARCH_AMD64
return u32;
# if defined(RT_ARCH_AMD64)
return u64;
#ifdef RT_ARCH_AMD64
return u128Ret.u;
return u128;
# ifdef RT_ARCH_AMD64
return u64;
switch (sizeof(*(pu))) { \
DECLASM(bool) ASMAtomicCmpXchgU32(volatile uint32_t *pu32, const uint32_t u32New, const uint32_t u32Old);
DECLINLINE(bool) ASMAtomicCmpXchgU32(volatile uint32_t *pu32, const uint32_t u32New, const uint32_t u32Old)
return (bool)u32Ret;
# ifdef RT_ARCH_AMD64
# ifdef RT_ARCH_AMD64
return !!u32Ret;
DECLINLINE(bool) ASMAtomicCmpXchgS32(volatile int32_t *pi32, const int32_t i32New, const int32_t i32Old)
DECLASM(bool) ASMAtomicCmpXchgU64(volatile uint64_t *pu64, const uint64_t u64New, const uint64_t u64Old);
DECLINLINE(bool) ASMAtomicCmpXchgU64(volatile uint64_t *pu64, const uint64_t u64New, const uint64_t u64Old)
return (bool)u64Ret;
bool fRet;
return fRet;
return (bool)u32Ret;
return !!u32Ret;
DECLINLINE(bool) ASMAtomicCmpXchgS64(volatile int64_t *pi64, const int64_t i64, const int64_t i64Old)
switch (sizeof(*(pu))) { \
case 4: (fRc) = ASMAtomicCmpXchgU32((volatile uint32_t *)(void *)(pu), (uint32_t)(uNew), (uint32_t)(uOld)); \
case 8: (fRc) = ASMAtomicCmpXchgU64((volatile uint64_t *)(void *)(pu), (uint64_t)(uNew), (uint64_t)(uOld)); \
(fRc) = false; \
# ifdef RT_ARCH_AMD64
return u32;
# ifdef RT_ARCH_AMD64
return u32;
# ifdef RT_ARCH_AMD64
# ifdef RT_ARCH_AMD64
# ifdef RT_ARCH_AMD64
# ifdef RT_ARCH_AMD64
# ifdef RT_ARCH_AMD64
# ifdef RT_ARCH_AMD64
# ifdef RT_ARCH_AMD64
# ifdef RT_ARCH_AMD64
return (void *)pb;
return NULL;
# ifdef RT_ARCH_AMD64
return u64;
# ifdef RT_ARCH_AMD64
return i64;
# ifdef RT_ARCH_AMD64
return u32;
# ifdef RT_ARCH_AMD64
return i32;
# ifdef RT_ARCH_AMD64
return u64Result;
edx = u64Lo.hi = (u64A.lo * u32B).hi */
eax = u64A.hi */
return u64Result;
RTUINT64U u;
# ifdef RT_ARCH_AMD64
return u8;
# ifndef __L4ENV__
# ifdef RT_ARCH_AMD64
# ifdef RT_ARCH_AMD64
# ifdef RT_ARCH_AMD64
# ifdef RT_ARCH_AMD64
# ifdef RT_ARCH_AMD64
# ifdef RT_ARCH_AMD64
# ifdef RT_ARCH_AMD64
return rc.f;
# ifdef RT_ARCH_AMD64
return rc.f;
# ifdef RT_ARCH_AMD64
return rc.f;
# ifdef RT_ARCH_AMD64
return rc.f;
# ifdef RT_ARCH_AMD64
return rc.f;
# ifdef RT_ARCH_AMD64
return rc.f;
# ifdef RT_ARCH_AMD64
return rc.f;
pu32++;
if (cBits)
# ifdef RT_ARCH_AMD64
# ifdef RT_ARCH_AMD64
# ifdef RT_ARCH_AMD64
done:
return iBit;
if (iBit)
unsigned long ulBit = 0;
done:
if (iBit >= 0)
if (iBit >= 0)
if (iBit >= 0)
return iBit;
if (cBits)
# ifdef RT_ARCH_AMD64
# ifdef RT_ARCH_AMD64
# ifdef RT_ARCH_AMD64
done:
return iBit;
if (iBit)
unsigned long ulBit = 0;
done:
if (iBit >= 0)
if (iBit >= 0)
if (iBit >= 0)
return iBit;
unsigned long iBit;
iBit++;
iBit = 0;
done:
return iBit;
unsigned long iBit;
iBit++;
iBit = 0;
done:
return iBit;
return u32;