Date: Sun, 28 May 2006 20:06:26 +0800 From: David Xu <davidxu@freebsd.org> To: Bruce Evans <bde@zeta.org.au> Cc: cvs-src@freebsd.org, src-committers@freebsd.org, cvs-all@freebsd.org Subject: Re: cvs commit: src/sys/i386/isa npx.c Message-ID: <200605282006.26364.davidxu@freebsd.org> In-Reply-To: <20060528201544.L20679@delplex.bde.org> References: <200605280440.k4S4ej96064322@repoman.freebsd.org> <200605281741.52752.davidxu@freebsd.org> <20060528201544.L20679@delplex.bde.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Sunday 28 May 2006 19:15, Bruce Evans wrote: > Starting with a clean FP state like the old code does is safest, but POSIX > explicitly requires copying the environment, and bugs in the new code > result in half of the most dangerous part of the environment (the SSE > half of the exception flags) being copied anyway. > > Pending exceptions are not the only problem here. Pending exceptions > are an i387 thing. Most exceptions are non-pending ones for IEEE inexact. > > Bruce how about following patch ? Index: npx.c =================================================================== RCS file: /home/ncvs/src/sys/i386/isa/npx.c,v retrieving revision 1.168 diff -u -u -r1.168 npx.c --- npx.c 28 May 2006 04:40:45 -0000 1.168 +++ npx.c 28 May 2006 11:40:58 -0000 @@ -99,6 +99,7 @@ #define fxrstor(addr) __asm("fxrstor %0" : : "m" (*(addr))) #define fxsave(addr) __asm __volatile("fxsave %0" : "=m" (*(addr))) #define ldmxcsr(__csr) __asm __volatile("ldmxcsr %0" : : "m" (__csr)) +#define stmxcsr(addr) __asm __volatile("stmxcsr %0" : "=m" (*(addr))) #endif #define start_emulating() __asm("smsw %%ax; orb %0,%%al; lmsw %%ax" \ : : "n" (CR0_TS) : "ax") @@ -950,7 +951,8 @@ { union savefpu *state; u_int32_t mxcsr; - u_int32_t cw; + u_int16_t cw; + register_t s; if (!(td->td_pcb->pcb_flags & PCB_NPXINITDONE)) { newtd->td_pcb->pcb_flags &= ~PCB_NPXINITDONE; @@ -958,21 +960,40 @@ } state = &newtd->td_pcb->pcb_save; - /* get control word */ - if (npxgetregs(td, state)) - return; - if (cpu_fxsr) { - mxcsr = state->sv_xmm.sv_env.en_mxcsr; - cw = state->sv_xmm.sv_env.en_cw; + s = intr_disable(); + if (curthread == PCPU_GET(fpcurthread)) { +#ifdef CPU_ENABLE_SSE + if (cpu_fxsr) { + stmxcsr(&mxcsr); + fnstcw(&cw); + } + else +#endif + { + mxcsr = 0; + fnstcw(&cw); + } } else { - cw = state->sv_87.sv_env.en_cw; - mxcsr = 0; +#ifdef CPU_ENABLE_SSE + if (cpu_fxsr) { + mxcsr = td->td_pcb->pcb_save.sv_xmm.sv_env.en_mxcsr; + cw = td->td_pcb->pcb_save.sv_87.sv_env.en_cw; + } + else +#endif + { + mxcsr = 0; + cw = td->td_pcb->pcb_save.sv_87.sv_env.en_cw; + } } + intr_restore(s); bcopy(&npx_cleanstate, state, sizeof(*state)); +#ifdef CPU_ENABLE_SSE if (cpu_fxsr) { state->sv_xmm.sv_env.en_cw = cw; - state->sv_xmm.sv_env.en_mxcsr = mxcsr; + state->sv_xmm.sv_env.en_mxcsr = mxcsr & ~0x3F; } else +#endif state->sv_87.sv_env.en_cw = cw; newtd->td_pcb->pcb_flags |= PCB_NPXINITDONE; }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200605282006.26364.davidxu>