1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-15 10:17:20 +00:00

Implement xsetbv(), xsave() and xrstor() providing C access to the

similarly named CPU instructions.

Since our in-tree binutils gas is not aware of the instructions, and
I have to use the byte-sequence to encode them, hardcode the r/m operand
as (%rdi). This way, first argument of the pseudo-function is already
placed into proper register.

MFC after:	1 week
This commit is contained in:
Konstantin Belousov 2012-01-17 07:30:36 +00:00
parent 79937651ef
commit dd4f5d2437
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=230262

View File

@ -669,6 +669,41 @@ intr_restore(register_t rflags)
write_rflags(rflags);
}
static __inline void
xsetbv(uint32_t reg, uint64_t val)
{
uint32_t low, hi;
low = val;
hi = val >> 32;
__asm __volatile(".byte 0x0f,0x01,0xd1" : :
"c" (reg), "a" (low), "d" (hi));
}
static __inline void
xsave(char *addr, uint64_t mask)
{
uint32_t low, hi;
low = mask;
hi = mask >> 32;
/* xsave (%rdi) */
__asm __volatile(".byte 0x0f,0xae,0x27" : :
"a" (low), "d" (hi), "D" (addr) : "memory");
}
static __inline void
xrstor(char *addr, uint64_t mask)
{
uint32_t low, hi;
low = mask;
hi = mask >> 32;
/* xrstor (%rdi) */
__asm __volatile(".byte 0x0f,0xae,0x2f" : :
"a" (low), "d" (hi), "D" (addr));
}
#else /* !(__GNUCLIKE_ASM && __CC_SUPPORTS___INLINE) */
int breakpoint(void);
@ -733,6 +768,9 @@ u_int rgs(void);
void wbinvd(void);
void write_rflags(u_int rf);
void wrmsr(u_int msr, uint64_t newval);
void xsetbv(uint32_t reg, uint64_t val);
void xsave(char *addr, uint64_t mask);
void xrstor(char *addr, uint64_t mask);
#endif /* __GNUCLIKE_ASM && __CC_SUPPORTS___INLINE */