1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-02-04 17:15:50 +00:00

Now that our assembler supports the xsave family of instructions, use them

natively rather than hand-assembled versions.  For xgetbv/xsetbv, add a
wrapper API to deal with xcr* registers: rxcr() and load_xcr().

Reviewed by:	kib
MFC after:	1 month
This commit is contained in:
John Baldwin 2012-07-05 18:19:35 +00:00
parent 9597393516
commit 7574a595f2
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=238142
2 changed files with 23 additions and 19 deletions

View File

@ -85,9 +85,7 @@ xrstor(char *addr, uint64_t mask)
low = mask;
hi = mask >> 32;
/* xrstor (%rdi) */
__asm __volatile(".byte 0x0f,0xae,0x2f" : :
"a" (low), "d" (hi), "D" (addr));
__asm __volatile("xrstor %0" : : "m" (*addr), "a" (low), "d" (hi));
}
static __inline void
@ -97,20 +95,8 @@ xsave(char *addr, uint64_t mask)
low = mask;
hi = mask >> 32;
/* xsave (%rdi) */
__asm __volatile(".byte 0x0f,0xae,0x27" : :
"a" (low), "d" (hi), "D" (addr) : "memory");
}
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));
__asm __volatile("xsave %0" : "=m" (*addr) : "a" (low), "d" (hi) :
"memory");
}
#else /* !(__GNUCLIKE_ASM && !lint) */
@ -127,7 +113,6 @@ void start_emulating(void);
void stop_emulating(void);
void xrstor(char *addr, uint64_t mask);
void xsave(char *addr, uint64_t mask);
void xsetbv(uint32_t reg, uint64_t val);
#endif /* __GNUCLIKE_ASM && !lint */
@ -238,7 +223,7 @@ fpuinit(void)
if (use_xsave) {
load_cr4(rcr4() | CR4_XSAVE);
xsetbv(XCR0, xsave_mask);
load_xcr(XCR0, xsave_mask);
}
/*

View File

@ -418,6 +418,25 @@ rcr4(void)
return (data);
}
static __inline u_long
rxcr(u_int reg)
{
u_int low, high;
__asm __volatile("xgetbv" : "=a" (low), "=d" (high) : "c" (reg));
return (low | ((uint64_t)high << 32));
}
static __inline void
load_xcr(u_int reg, u_long val)
{
u_int low, high;
low = val;
high = val >> 32;
__asm __volatile("xsetbv" : : "c" (reg), "a" (low), "d" (high));
}
/*
* Global TLB flush (except for thise for pages marked PG_G)
*/