diff options
author | davidxu <davidxu@FreeBSD.org> | 2006-05-28 02:03:13 +0000 |
---|---|---|
committer | davidxu <davidxu@FreeBSD.org> | 2006-05-28 02:03:13 +0000 |
commit | bf6b4844d33a45b13bd4ffe69857c1b47fba93b4 (patch) | |
tree | a9d0c54100cd9435a1b34d1ae77128d74763952c /sys/i386/isa/npx.c | |
parent | fecc90c6467c0c3892b79f81ed9501a4672c8815 (diff) | |
download | FreeBSD-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.c | 30 |
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; |