Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 4 Jul 2012 13:15:54 GMT
From:      John Baldwin <jhb@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 213890 for review
Message-ID:  <201207041315.q64DFsup016323@skunkworks.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@213890?ac=10

Change 213890 by jhb@jhb_ralph on 2012/07/04 13:15:40

	- Add rxcr() and load_xcr() wrappers around xgetbv/xsetbv.
	- Use the actual instructions for xsave and xrstor.

Affected files ...

.. //depot/projects/smpng/sys/amd64/amd64/fpu.c#23 edit
.. //depot/projects/smpng/sys/amd64/include/cpufunc.h#25 edit

Differences ...

==== //depot/projects/smpng/sys/amd64/amd64/fpu.c#23 (text+ko) ====

@@ -85,9 +85,7 @@
 
 	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,22 +95,10 @@
 
 	low = mask;
 	hi = mask >> 32;
-	/* xsave (%rdi) */
-	__asm __volatile(".byte	0x0f,0xae,0x27" : :
-	    "a" (low), "d" (hi), "D" (addr) : "memory");
+	__asm __volatile("xsave %0" : "=m" (*addr) : "a" (low), "d" (hi) :
+	    "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));
-}
-
 #else	/* !(__GNUCLIKE_ASM && !lint) */
 
 void	fldcw(u_short cw);
@@ -127,7 +113,6 @@
 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 @@
 
 	if (use_xsave) {
 		load_cr4(rcr4() | CR4_XSAVE);
-		xsetbv(XCR0, xsave_mask);
+		load_xcr(XCR0, xsave_mask);
 	}
 
 	/*

==== //depot/projects/smpng/sys/amd64/include/cpufunc.h#25 (text+ko) ====

@@ -411,6 +411,25 @@
 	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, hi;
+
+	low = val;
+	hi = val >> 32;
+	__asm __volatile("xsetbv" : : "c" (reg), "a" (low), "d" (hi));
+}
+
 /*
  * Global TLB flush (except for thise for pages marked PG_G)
  */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201207041315.q64DFsup016323>