diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2004-02-21 22:55:21 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2004-02-21 22:55:21 +0000 |
commit | 417365bb0d3ebc5ebb03464554e35fb333ed7ff5 (patch) | |
tree | 7759238ef8875f8a0eeccc50b94acc08ec922af4 /lib/libpthread | |
parent | 1711ce4a9b0c09f2c139a422bd03f9dfd3a1023d (diff) |
if cpu has fxsr, use fxsave instead; ok marc
Diffstat (limited to 'lib/libpthread')
-rw-r--r-- | lib/libpthread/arch/i386/uthread_machdep.c | 50 | ||||
-rw-r--r-- | lib/libpthread/arch/i386/uthread_machdep.h | 6 |
2 files changed, 45 insertions, 11 deletions
diff --git a/lib/libpthread/arch/i386/uthread_machdep.c b/lib/libpthread/arch/i386/uthread_machdep.c index f516eebcbc0..c8d55941300 100644 --- a/lib/libpthread/arch/i386/uthread_machdep.c +++ b/lib/libpthread/arch/i386/uthread_machdep.c @@ -1,11 +1,13 @@ -/* $OpenBSD: uthread_machdep.c,v 1.3 2003/01/24 20:58:23 marc Exp $ */ +/* $OpenBSD: uthread_machdep.c,v 1.4 2004/02/21 22:55:20 deraadt Exp $ */ /* David Leonard, <d@csee.uq.edu.au>. Public domain. */ /* * Machine-dependent thread state functions for OpenBSD/i386. */ -#include <machine/param.h> +#include <sys/param.h> +#include <sys/sysctl.h> +#include <machine/cpu.h> #include <pthread.h> #include "pthread_private.h" @@ -31,6 +33,28 @@ struct frame { #define copyreg(reg, lval) \ __asm__("mov %%" #reg ", %0" : "=g"(lval)) +static int _thread_machdep_osfxsr(void); + +static int +_thread_machdep_osfxsr(void) +{ + int mib[] = { CTL_MACHDEP, CPU_OSFXSR }; + static int sse = -1; + size_t len; + int val; + + if (sse == -1) { + len = sizeof (val); + if (sysctl(mib, 2, &val, &len, NULL, 0) == -1) + return (0); + if (val) + sse = 1; + else + sse = 0; + } + return (sse); +} + /* * Given a stack and an entry function, initialise a state * structure that can be later switched to. @@ -65,23 +89,33 @@ _thread_machdep_init(struct _machdep_state* statep, void *base, int len, */ #define fldcw(addr) __asm("fldcw %0" : : "m" (*addr)) #define fnsave(addr) __asm("fnsave %0" : "=m" (*addr)) -#define frstor(addr) __asm("frstor %0" : : "m" (*addr)) +#define fninit() __asm("fninit") +#define frstor(addr) __asm("frstor %0" : : "m" (*addr)) +#define fxsave(addr) __asm("fxsave %0" : "=m" (*addr)) +#define fxrstor(addr) __asm("fxrstor %0" : : "m" (*addr)) #define fwait() __asm("fwait") void _thread_machdep_save_float_state(struct _machdep_state *ms) { - struct save87 *addr = &ms->fpreg; + union savefpu *addr = &ms->fpreg; - fnsave(addr); + if (_thread_machdep_osfxsr()) { + fxsave(&addr->sv_xmm); + fninit(); + } else + fnsave(&addr->sv_87); fwait(); } void _thread_machdep_restore_float_state(struct _machdep_state *ms) { - struct save87 *addr = &ms->fpreg; + union savefpu *addr = &ms->fpreg; - frstor(addr); + if (_thread_machdep_osfxsr()) + fxrstor(&addr->sv_xmm); + else + frstor(&addr->sv_87); + } - diff --git a/lib/libpthread/arch/i386/uthread_machdep.h b/lib/libpthread/arch/i386/uthread_machdep.h index f0f13ce7710..58b1425a75c 100644 --- a/lib/libpthread/arch/i386/uthread_machdep.h +++ b/lib/libpthread/arch/i386/uthread_machdep.h @@ -1,10 +1,10 @@ -/* $OpenBSD: uthread_machdep.h,v 1.8 2003/01/24 20:58:23 marc Exp $ */ +/* $OpenBSD: uthread_machdep.h,v 1.9 2004/02/21 22:55:20 deraadt Exp $ */ /* David Leonard, <d@csee.uq.edu.au>. Public domain. */ #include <machine/npx.h> struct _machdep_state { int esp; - struct save87 fpreg; + int pad[3]; + union savefpu fpreg; /* must be 128-bit aligned */ }; - |