From 01cf3702717619365bfc8c89f9a0fe9671fc2cd3 Mon Sep 17 00:00:00 2001 From: jhb Date: Thu, 5 Jul 2012 18:19:35 +0000 Subject: 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 --- sys/amd64/amd64/fpu.c | 23 ++++------------------- sys/amd64/include/cpufunc.h | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 19 deletions(-) (limited to 'sys/amd64') diff --git a/sys/amd64/amd64/fpu.c b/sys/amd64/amd64/fpu.c index 55299c8..77e11bc 100644 --- a/sys/amd64/amd64/fpu.c +++ b/sys/amd64/amd64/fpu.c @@ -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); } /* diff --git a/sys/amd64/include/cpufunc.h b/sys/amd64/include/cpufunc.h index 927d00f..829efc1 100644 --- a/sys/amd64/include/cpufunc.h +++ b/sys/amd64/include/cpufunc.h @@ -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) */ -- cgit v1.1