summaryrefslogtreecommitdiffstats
path: root/sys/i386/isa/npx.c
diff options
context:
space:
mode:
authordavidxu <davidxu@FreeBSD.org>2006-05-28 02:03:13 +0000
committerdavidxu <davidxu@FreeBSD.org>2006-05-28 02:03:13 +0000
commitbf6b4844d33a45b13bd4ffe69857c1b47fba93b4 (patch)
treea9d0c54100cd9435a1b34d1ae77128d74763952c /sys/i386/isa/npx.c
parentfecc90c6467c0c3892b79f81ed9501a4672c8815 (diff)
downloadFreeBSD-src-bf6b4844d33a45b13bd4ffe69857c1b47fba93b4.zip
FreeBSD-src-bf6b4844d33a45b13bd4ffe69857c1b47fba93b4.tar.gz
When creating a new thread, inherit floating-point environment from
current thread, this is required by POSIX pthread_create document.
Diffstat (limited to 'sys/i386/isa/npx.c')
-rw-r--r--sys/i386/isa/npx.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/sys/i386/isa/npx.c b/sys/i386/isa/npx.c
index bc39629..7b7f3a5 100644
--- a/sys/i386/isa/npx.c
+++ b/sys/i386/isa/npx.c
@@ -942,6 +942,36 @@ npxsetregs(td, addr)
curthread->td_pcb->pcb_flags |= PCB_NPXINITDONE;
}
+/*
+ * POSIX requires new thread to inherit floating-point environment.
+ */
+void
+npx_fork_thread(struct thread *td, struct thread *newtd)
+{
+ union savefpu *state;
+ u_int32_t mxcsr;
+ u_int32_t cw;
+
+ state = &newtd->td_pcb->pcb_save;
+ /* get control word */
+ if (npxgetregs(td, &newtd->td_pcb->pcb_save))
+ return;
+ if (cpu_fxsr) {
+ mxcsr = state->sv_xmm.sv_env.en_mxcsr;
+ cw = state->sv_xmm.sv_env.en_cw;
+ } else {
+ cw = state->sv_87.sv_env.en_cw;
+ mxcsr = 0;
+ }
+ bcopy(&npx_cleanstate, state, sizeof(*state));
+ if (cpu_fxsr) {
+ state->sv_xmm.sv_env.en_cw = cw;
+ state->sv_xmm.sv_env.en_mxcsr = mxcsr;
+ } else
+ state->sv_87.sv_env.en_cw = cw;
+ newtd->td_pcb->pcb_flags |= PCB_NPXINITDONE;
+}
+
static void
fpusave(addr)
union savefpu *addr;
OpenPOWER on IntegriCloud