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;
 }
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/cvs-all
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to