Author: jhb
Date: Thu Jul  5 18:19:35 2012
New Revision: 238142
URL: http://svn.freebsd.org/changeset/base/238142

Log:
  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

Modified:
  head/sys/amd64/amd64/fpu.c
  head/sys/amd64/include/cpufunc.h

Modified: head/sys/amd64/amd64/fpu.c
==============================================================================
--- head/sys/amd64/amd64/fpu.c  Thu Jul  5 17:02:20 2012        (r238141)
+++ head/sys/amd64/amd64/fpu.c  Thu Jul  5 18:19:35 2012        (r238142)
@@ -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);
        }
 
        /*

Modified: head/sys/amd64/include/cpufunc.h
==============================================================================
--- head/sys/amd64/include/cpufunc.h    Thu Jul  5 17:02:20 2012        
(r238141)
+++ head/sys/amd64/include/cpufunc.h    Thu Jul  5 18:19:35 2012        
(r238142)
@@ -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)
  */
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to