svn commit: r345562 - in head/sys: amd64/amd64 i386/i386
Conrad Meyer
cem at FreeBSD.org
Tue Mar 26 22:45:43 UTC 2019
Author: cem
Date: Tue Mar 26 22:45:41 2019
New Revision: 345562
URL: https://svnweb.freebsd.org/changeset/base/345562
Log:
x86: Use XSAVEOPT for fpusave(), when available
Remove redundant npxsave_core definition while here.
Suggested by: Anton Rang
Reviewed by: kib, Anton Rang <rang AT acm.org>
Sponsored by: Dell EMC Isilon
Differential Revision: https://reviews.freebsd.org/D19665
Modified:
head/sys/amd64/amd64/fpu.c
head/sys/i386/i386/npx.c
Modified: head/sys/amd64/amd64/fpu.c
==============================================================================
--- head/sys/amd64/amd64/fpu.c Tue Mar 26 22:34:07 2019 (r345561)
+++ head/sys/amd64/amd64/fpu.c Tue Mar 26 22:45:41 2019 (r345562)
@@ -100,6 +100,17 @@ xsave(char *addr, uint64_t mask)
"memory");
}
+static __inline void
+xsaveopt(char *addr, uint64_t mask)
+{
+ uint32_t low, hi;
+
+ low = mask;
+ hi = mask >> 32;
+ __asm __volatile("xsaveopt %0" : "=m" (*addr) : "a" (low), "d" (hi) :
+ "memory");
+}
+
#else /* !(__GNUCLIKE_ASM && !lint) */
void fldcw(u_short cw);
@@ -113,6 +124,7 @@ void ldmxcsr(u_int csr);
void stmxcsr(u_int *csr);
void xrstor(char *addr, uint64_t mask);
void xsave(char *addr, uint64_t mask);
+void xsaveopt(char *addr, uint64_t mask);
#endif /* __GNUCLIKE_ASM && !lint */
@@ -158,6 +170,13 @@ struct xsave_area_elm_descr {
} *xsave_area_desc;
static void
+fpusave_xsaveopt(void *addr)
+{
+
+ xsaveopt((char *)addr, xsave_mask);
+}
+
+static void
fpusave_xsave(void *addr)
{
@@ -201,7 +220,10 @@ DEFINE_IFUNC(, void, fpusave, (void *), static)
{
init_xsave();
- return (use_xsave ? fpusave_xsave : fpusave_fxsave);
+ if (use_xsave)
+ return ((cpu_stdext_feature & CPUID_EXTSTATE_XSAVEOPT) != 0 ?
+ fpusave_xsaveopt : fpusave_xsave);
+ return (fpusave_fxsave);
}
DEFINE_IFUNC(, void, fpurestore, (void *), static)
@@ -356,7 +378,7 @@ fpuinitstate(void *arg __unused)
saveintr = intr_disable();
stop_emulating();
- fpusave(fpu_initialstate);
+ fpusave_fxsave(fpu_initialstate);
if (fpu_initialstate->sv_env.en_mxcsr_mask)
cpu_mxcsr_mask = fpu_initialstate->sv_env.en_mxcsr_mask;
else
Modified: head/sys/i386/i386/npx.c
==============================================================================
--- head/sys/i386/i386/npx.c Tue Mar 26 22:34:07 2019 (r345561)
+++ head/sys/i386/i386/npx.c Tue Mar 26 22:45:41 2019 (r345562)
@@ -313,7 +313,7 @@ cleanup:
}
static void
-npxsave_xsaveopt(union savefpu *addr)
+fpusave_xsaveopt(union savefpu *addr)
{
xsaveopt((char *)addr, xsave_mask);
@@ -352,29 +352,18 @@ init_xsave(void)
TUNABLE_INT_FETCH("hw.use_xsave", &use_xsave);
}
-DEFINE_IFUNC(, void, npxsave_core, (union savefpu *), static)
+DEFINE_IFUNC(, void, fpusave, (union savefpu *), static)
{
init_xsave();
if (use_xsave)
return ((cpu_stdext_feature & CPUID_EXTSTATE_XSAVEOPT) != 0 ?
- npxsave_xsaveopt : fpusave_xsave);
+ fpusave_xsaveopt : fpusave_xsave);
if (cpu_fxsr)
return (fpusave_fxsave);
return (fpusave_fnsave);
}
-DEFINE_IFUNC(, void, fpusave, (union savefpu *), static)
-{
-
- init_xsave();
- if (use_xsave)
- return (fpusave_xsave);
- if (cpu_fxsr)
- return (fpusave_fxsave);
- return (fpusave_fnsave);
-}
-
/*
* Enable XSAVE if supported and allowed by user.
* Calculate the xsave_mask.
@@ -494,7 +483,10 @@ npxinitstate(void *arg __unused)
saveintr = intr_disable();
stop_emulating();
- fpusave(npx_initialstate);
+ if (cpu_fxsr)
+ fpusave_fxsave(npx_initialstate);
+ else
+ fpusave_fnsave(npx_initialstate);
if (cpu_fxsr) {
if (npx_initialstate->sv_xmm.sv_env.en_mxcsr_mask)
cpu_mxcsr_mask =
@@ -922,7 +914,7 @@ npxsave(union savefpu *addr)
{
stop_emulating();
- npxsave_core(addr);
+ fpusave(addr);
}
void npxswitch(struct thread *td, struct pcb *pcb);
More information about the svn-src-head
mailing list