In <[EMAIL PROTECTED]>, Bruce Evans wrote: 
> >Guessing from LINT's comments, you had to leave out npx and include
> >one of the emulators, but -current's config refuses to config a kernel
> >file without npx support.
> 
> This was broken by adding "mandatory" to the npx line in file.i386.
> 
> >I also tried to add "disable" to npx's config line, which compiles and
> >runs ok, but still uses the hardware FPU (timing and exception test). 
> 
> This may be because npx0 now attaches to nexus, but "disable" only works
> for isa devices.  It's annoying that userconfig doesn't support displaying
> or changing npx0.  BTW, PCI devices are no longer displayed by userconfig.

The following diff makes FPU and FPU emulators selectable from
userconfig. npx0 is still mandatory, but it gets an additional flag
bit 0x08, which requests the hardware FPU to be ignored and an
emulator to be used if one is compiled in. If none is compiled into
the kernel, a warning is printed and the hardware FPU is used.

The diff also contains the FPE trapcode stuff, which is now found to
run with GPL_MATH_EMUL (although actualy computing of error codes
isn't done in this case) and not to make things worse for (non-GPL)
MATH_EMUL.

I plan to commit this, unless someone objets (the impressive-looking
trapcode table is only 127 bytes in size, to pre-comment on one
issue).

Martin
-- 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Martin Cracauer <[EMAIL PROTECTED]> http://www.cons.org/cracauer/
  Tel.: (private) +4940 5221829 Fax.: (private) +4940 5228536
Index: i386/conf/LINT
===================================================================
RCS file: /home/CVS-FreeBSD/src/sys/i386/conf/LINT,v
retrieving revision 1.617
diff -c -r1.617 LINT
*** LINT        1999/07/09 04:29:56     1.617
--- LINT        1999/07/22 22:16:32
***************
*** 956,973 ****
  options       SC_NO_SYSMOUSE
  
  #
! # The Numeric Processing eXtension driver.  This should be configured if
! # your machine has a math co-processor, unless the coprocessor is very
! # buggy. If it is not configured then you *must* configure math emulation
! # (see above).  If both npx0 and emulation are configured, then only npx0
! # is used (provided it works).
  device                npx0    at nexus? port IO_NPX flags 0x0 irq 13
  
  #
  # `flags' for npx0:
! #     0x01    don't use the npx registers to optimize bcopy
! #     0x02    don't use the npx registers to optimize bzero
  #     0x04    don't use the npx registers to optimize copyin or copyout.
  # The npx registers are normally used to optimize copying and zeroing when
  # all of the following conditions are satisfied:
  #     I586_CPU is an option
--- 956,975 ----
  options       SC_NO_SYSMOUSE
  
  #
! # The Numeric Processing eXtension driver. In addition to this, you
! # may configure a math emulator (see above). If your machine has a
! # hardware FPU and the kernel configuration includes the npx device
! # *and* a math emulator compiled into the kernel, the hardware FPU
! # will be used, unless it is found to be broken or unless "flags" to
! # npx0 includes "0x08", which requests preference for the emulator.
  device                npx0    at nexus? port IO_NPX flags 0x0 irq 13
  
  #
  # `flags' for npx0:
! #     0x01    don't use the npx registers to optimize bcopy.
! #     0x02    don't use the npx registers to optimize bzero.
  #     0x04    don't use the npx registers to optimize copyin or copyout.
+ #     0x08    use emulator even if hardware FPU is available.
  # The npx registers are normally used to optimize copying and zeroing when
  # all of the following conditions are satisfied:
  #     I586_CPU is an option
***************
*** 978,983 ****
--- 980,988 ----
  # The flags can be used to control cases where it doesn't work or is slower.
  # Setting them at boot time using userconfig works right (the optimizations
  # are not used until later in the bootstrap when npx0 is attached).
+ # Flag 0x08 does not imply any settings of the other flags, you may run
+ # with FPU preference set to emulator, but still using the i586 optimized
+ # memory routines.
  #
  
  #
***************
*** 1149,1154 ****
--- 1154,1160 ----
  #             higher priority console).  This replaces the COMCONSOLE option.
  #     0x40    reserve this unit for low level console operations.  Do not
  #             access the device in any normal way.
+ #     0x80    use this port for serial line gdb support in ddb.
  #
  # PnP `flags' (set via userconfig using pnp x flags y)
  #     0x1     disable probing of this device.  Used to prevent your modem
Index: i386/i386/trap.c
===================================================================
RCS file: /home/CVS-FreeBSD/src/sys/i386/i386/trap.c,v
retrieving revision 1.139
diff -c -r1.139 trap.c
*** trap.c      1999/06/18 14:32:16     1.139
--- trap.c      1999/07/22 19:13:55
***************
*** 360,366 ****
                        break;
  
                case T_DIVIDE:          /* integer divide fault */
!                       ucode = FPE_INTDIV_TRAP;
                        i = SIGFPE;
                        break;
  
--- 360,366 ----
                        break;
  
                case T_DIVIDE:          /* integer divide fault */
!                       ucode = FPE_INTDIV;
                        i = SIGFPE;
                        break;
  
***************
*** 382,393 ****
  #endif /* NISA > 0 */
  
                case T_OFLOW:           /* integer overflow fault */
!                       ucode = FPE_INTOVF_TRAP;
                        i = SIGFPE;
                        break;
  
                case T_BOUND:           /* bounds check fault */
!                       ucode = FPE_SUBRNG_TRAP;
                        i = SIGFPE;
                        break;
  
--- 382,393 ----
  #endif /* NISA > 0 */
  
                case T_OFLOW:           /* integer overflow fault */
!                       ucode = FPE_INTOVF;
                        i = SIGFPE;
                        break;
  
                case T_BOUND:           /* bounds check fault */
!                       ucode = FPE_FLTSUB;
                        i = SIGFPE;
                        break;
  
Index: i386/i386/userconfig.c
===================================================================
RCS file: /home/CVS-FreeBSD/src/sys/i386/i386/userconfig.c,v
retrieving revision 1.148
diff -c -r1.148 userconfig.c
*** userconfig.c        1999/07/09 04:29:54     1.148
--- userconfig.c        1999/07/22 19:52:10
***************
*** 458,464 ****
  
  {"apm",         "Advanced Power Management",          FLG_FIXED,      CLS_MISC},
  {"labpc",       "National Instruments Lab-PC/Lab-PC+",        0,              
CLS_MISC},
! {"npx",               "Math coprocessor",                     FLG_INVISIBLE,  
CLS_MISC},
  {"lkm",               "Loadable PCI driver support",          FLG_INVISIBLE,  
CLS_MISC},
  {"vga",               "Catchall PCI VGA driver",              FLG_INVISIBLE,  
CLS_MISC},
  {"chip",        "PCI chipset support",                        FLG_INVISIBLE,  
CLS_MISC},
--- 458,464 ----
  
  {"apm",         "Advanced Power Management",          FLG_FIXED,      CLS_MISC},
  {"labpc",       "National Instruments Lab-PC/Lab-PC+",        0,              
CLS_MISC},
! {"npx",               "Math coprocessor",                     FLG_IMMUTABLE,  
CLS_MISC},
  {"lkm",               "Loadable PCI driver support",          FLG_INVISIBLE,  
CLS_MISC},
  {"vga",               "Catchall PCI VGA driver",              FLG_INVISIBLE,  
CLS_MISC},
  {"chip",        "PCI chipset support",                        FLG_INVISIBLE,  
CLS_MISC},
Index: i386/include/ieeefp.h
===================================================================
RCS file: /home/CVS-FreeBSD/src/sys/i386/include/ieeefp.h,v
retrieving revision 1.5
diff -c -r1.5 ieeefp.h
*** ieeefp.h    1997/02/22 09:34:41     1.5
--- ieeefp.h    1999/07/22 19:13:55
***************
*** 72,77 ****
--- 72,78 ----
  #define FP_X_OFL      0x08    /* overflow */
  #define FP_X_UFL      0x10    /* underflow */
  #define FP_X_IMP      0x20    /* (im)precision */
+ #define FP_X_STK      0x40    /* stack fault */
  
  /*
   * FP registers
Index: i386/include/trap.h
===================================================================
RCS file: /home/CVS-FreeBSD/src/sys/i386/include/trap.h,v
retrieving revision 1.7
diff -c -r1.7 trap.h
*** trap.h      1997/02/22 09:35:19     1.7
--- trap.h      1999/07/22 19:13:55
***************
*** 76,88 ****
  #define           ILL_ALIGN_FAULT     T_ALIGNFLT
  #define           ILL_FPOP_FAULT      T_FPOPFLT       /* coprocessor operand fault */
  
! /* codes for SIGFPE/ARITHTRAP */
  #define           FPE_INTOVF_TRAP     0x1     /* integer overflow */
  #define           FPE_INTDIV_TRAP     0x2     /* integer divide by zero */
  #define           FPE_FLTDIV_TRAP     0x3     /* floating/decimal divide by zero */
  #define           FPE_FLTOVF_TRAP     0x4     /* floating overflow */
  #define           FPE_FLTUND_TRAP     0x5     /* floating underflow */
! #define           FPE_FPU_NP_TRAP     0x6     /* floating point unit not present */
  #define           FPE_SUBRNG_TRAP     0x7     /* subrange out of bounds */
  
  /* codes for SIGBUS */
--- 76,104 ----
  #define           ILL_ALIGN_FAULT     T_ALIGNFLT
  #define           ILL_FPOP_FAULT      T_FPOPFLT       /* coprocessor operand fault */
  
! /* 
!  * codes for SIGFPE/ARITHTRAP 
!  *
!  */
! /* portable macros */
! #define FPE_INTDIV    1       /* integer divide by zero */
! #define FPE_INTOVF    2       /* integer overflow */
! #define FPE_FLTDIV    3       /* floating point divide by zero */
! #define FPE_FLTOVF    4       /* floating point overflow */
! #define FPE_FLTUND    5       /* floating point underflow */
! #define FPE_FLTRES    6       /* floating point inexact result */
! #define FPE_FLTINV    7       /* invalid floating point operation */
! #define FPE_FLTSUB    8       /* subscript out of range */
! 
! /* old FreeBSD macros, deprecated */
  #define           FPE_INTOVF_TRAP     0x1     /* integer overflow */
  #define           FPE_INTDIV_TRAP     0x2     /* integer divide by zero */
  #define           FPE_FLTDIV_TRAP     0x3     /* floating/decimal divide by zero */
  #define           FPE_FLTOVF_TRAP     0x4     /* floating overflow */
  #define           FPE_FLTUND_TRAP     0x5     /* floating underflow */
! #define           FPE_FPU_NP_TRAP     0x6     /* floating point unit not present 
!                                        * - won't happen in practice
!                                        */
  #define           FPE_SUBRNG_TRAP     0x7     /* subrange out of bounds */
  
  /* codes for SIGBUS */
Index: i386/isa/npx.c
===================================================================
RCS file: /home/CVS-FreeBSD/src/sys/i386/isa/npx.c,v
retrieving revision 1.73
diff -c -r1.73 npx.c
*** npx.c       1999/05/15 17:58:58     1.73
--- npx.c       1999/07/22 22:14:19
***************
*** 86,91 ****
--- 86,92 ----
  #define       NPX_DISABLE_I586_OPTIMIZED_BCOPY        (1 << 0)
  #define       NPX_DISABLE_I586_OPTIMIZED_BZERO        (1 << 1)
  #define       NPX_DISABLE_I586_OPTIMIZED_COPYIO       (1 << 2)
+ #define       NPX_PREFER_EMULATOR                     (1 << 3)
  
  #ifdef        __GNUC__
  
***************
*** 396,429 ****
  npx_attach(dev)
        device_t dev;
  {
- #ifdef I586_CPU
        int flags;
! #endif
  
        device_print_prettyname(dev);
        if (npx_irq13) {
                printf("using IRQ 13 interface\n");
        } else {
-               if (npx_ex16)
-                       printf("INT 16 interface\n");
  #if defined(MATH_EMULATE) || defined(GPL_MATH_EMULATE)
!               else if (npx_exists) {
                        printf("error reporting broken; using 387 emulator\n");
                        hw_float = npx_exists = 0;
                } else
                        printf("387 emulator\n");
  #else
!               else
!                       printf("no 387 emulator in kernel!\n");
  #endif
        }
        npxinit(__INITIAL_NPXCW__);
  
  #ifdef I586_CPU
!       if (resource_int_value("npx", 0, "flags", &flags) != 0)
!               flags = 0;
! 
!       if (cpu_class == CPUCLASS_586 && npx_ex16 &&
            timezero("i586_bzero()", i586_bzero) <
            timezero("bzero()", bzero) * 4 / 5) {
                if (!(flags & NPX_DISABLE_I586_OPTIMIZED_BCOPY)) {
--- 397,440 ----
  npx_attach(dev)
        device_t dev;
  {
        int flags;
! 
!       if (resource_int_value("npx", 0, "flags", &flags) != 0)
!               flags = 0;
  
        device_print_prettyname(dev);
        if (npx_irq13) {
                printf("using IRQ 13 interface\n");
        } else {
  #if defined(MATH_EMULATE) || defined(GPL_MATH_EMULATE)
!               if (npx_ex16) {
!                       if (!(flags & NPX_PREFER_EMULATOR))
!                               printf("INT 16 interface\n");
!                       else {
!                               printf("FPU exists, but flags request "
!                                   "emulator\n");
!                               hw_float = npx_exists = 0;
!                       }
!               } else if (npx_exists) {
                        printf("error reporting broken; using 387 emulator\n");
                        hw_float = npx_exists = 0;
                } else
                        printf("387 emulator\n");
  #else
!               if (npx_ex16) {
!                       printf("INT 16 interface\n");
!                       if (flags & NPX_PREFER_EMULATOR) {
!                               printf("emulator requested, but none compiled "
!                                   "into kernel, using FPU\n");
!                       }
!               } else
!                       printf("no 387 emulator in kernel and no FPU!\n");
  #endif
        }
        npxinit(__INITIAL_NPXCW__);
  
  #ifdef I586_CPU
!       if (cpu_class == CPUCLASS_586 && npx_ex16 && npx_exists &&
            timezero("i586_bzero()", i586_bzero) <
            timezero("bzero()", bzero) * 4 / 5) {
                if (!(flags & NPX_DISABLE_I586_OPTIMIZED_BCOPY)) {
***************
*** 494,513 ****
  #endif
  }
  
  /*
   * Preserve the FP status word, clear FP exceptions, then generate a SIGFPE.
   *
   * Clearing exceptions is necessary mainly to avoid IRQ13 bugs.  We now
   * depend on longjmp() restoring a usable state.  Restoring the state
   * or examining it might fail if we didn't clear exceptions.
-  *
-  * XXX there is no standard way to tell SIGFPE handlers about the error
-  * state.  The old interface:
-  *
-  *    void handler(int sig, int code, struct sigcontext *scp);
   *
!  * is broken because it is non-ANSI and because the FP state is not in
!  * struct sigcontext.
   *
   * XXX the FP state is not preserved across signal handlers.  So signal
   * handlers cannot afford to do FP unless they preserve the state or
--- 505,693 ----
  #endif
  }
  
+ /* 
+  * The following mechanism is used to ensure that the FPE_... value
+  * that is passed as a trapcode to the signal handler of the user
+  * process does not have more than one bit set.
+  * 
+  * Multiple bits may be set if the user process modifies the control
+  * word while a status word bit is already set. While this is a sign
+  * of bad coding, we have no choise than to narrow them down to one
+  * bit, since we must not send a trapcode that is not exactly one of
+  * the FPE_ macros.
+  *
+  * The mechanism has a static table with 127 entries. Each combination
+  * of the 7 FPU status word exception bits directly translates to a
+  * position in this table, where a single FPE_... value is stored.
+  * This FPE_... value stored there is considered the "most important"
+  * of the exception bits and will be sent as the signal code. The
+  * precedence of the bits is based upon Intel Document "Numerical
+  * Applications", Chapter "Special Computational Situations".
+  *
+  * The macro to choose one of these values does these steps: 1) Throw
+  * away status word bits that cannot be masked. 2) Throw away the bits
+  * currently masked in the control word, assuming the user isn't
+  * interested in them anymore. 3) Reinsert status word bit 7 (stack
+  * fault) if it is set, which cannot be masked but must be presered.
+  * 4) Use the remaining bits to point into the trapcode table.
+  *
+  * The 6 maskable bits in order of their preference, as stated in the
+  * above referenced Intel manual:
+  * 1  Invalid operation (FP_X_INV)
+  * 1a   Stack underflow
+  * 1b   Stack overflow
+  * 1c   Operand of unsupported format
+  * 1d   SNaN operand.
+  * 2  QNaN operand (not an exception, irrelavant here)
+  * 3  Any other invalid-operation not mentioned above or zero divide
+  *      (FP_X_INV, FP_X_DZ)
+  * 4  Denormal operand (FP_X_DNML)
+  * 5  Numeric over/underflow (FP_X_OFL, FP_X_UFL)
+  * 6  Inexact result (FP_X_IMP) */
+ 
+ static char fpetable[128] = {
+       0,
+       FPE_FLTINV, /*  1 - INV */
+       FPE_FLTUND, /*  2 - DNML */
+       FPE_FLTINV, /*  3 - INV | DNML */
+       FPE_FLTDIV, /*  4 - DZ */
+       FPE_FLTINV, /*  5 - INV | DZ */
+       FPE_FLTDIV, /*  6 - DNML | DZ */
+       FPE_FLTINV, /*  7 - INV | DNML | DZ */
+       FPE_FLTOVF, /*  8 - OFL */
+       FPE_FLTINV, /*  9 - INV | OFL */
+       FPE_FLTUND, /*  A - DNML | OFL */
+       FPE_FLTINV, /*  B - INV | DNML | OFL */
+       FPE_FLTDIV, /*  C - DZ | OFL */
+       FPE_FLTINV, /*  D - INV | DZ | OFL */
+       FPE_FLTDIV, /*  E - DNML | DZ | OFL */
+       FPE_FLTINV, /*  F - INV | DNML | DZ | OFL */
+       FPE_FLTUND, /* 10 - UFL */
+       FPE_FLTINV, /* 11 - INV | UFL */
+       FPE_FLTUND, /* 12 - DNML | UFL */
+       FPE_FLTINV, /* 13 - INV | DNML | UFL */
+       FPE_FLTDIV, /* 14 - DZ | UFL */
+       FPE_FLTINV, /* 15 - INV | DZ | UFL */
+       FPE_FLTDIV, /* 16 - DNML | DZ | UFL */
+       FPE_FLTINV, /* 17 - INV | DNML | DZ | UFL */
+       FPE_FLTOVF, /* 18 - OFL | UFL */
+       FPE_FLTINV, /* 19 - INV | OFL | UFL */
+       FPE_FLTUND, /* 1A - DNML | OFL | UFL */
+       FPE_FLTINV, /* 1B - INV | DNML | OFL | UFL */
+       FPE_FLTDIV, /* 1C - DZ | OFL | UFL */
+       FPE_FLTINV, /* 1D - INV | DZ | OFL | UFL */
+       FPE_FLTDIV, /* 1E - DNML | DZ | OFL | UFL */
+       FPE_FLTINV, /* 1F - INV | DNML | DZ | OFL | UFL */
+       FPE_FLTRES, /* 20 - IMP */
+       FPE_FLTINV, /* 21 - INV | IMP */
+       FPE_FLTUND, /* 22 - DNML | IMP */
+       FPE_FLTINV, /* 23 - INV | DNML | IMP */
+       FPE_FLTDIV, /* 24 - DZ | IMP */
+       FPE_FLTINV, /* 25 - INV | DZ | IMP */
+       FPE_FLTDIV, /* 26 - DNML | DZ | IMP */
+       FPE_FLTINV, /* 27 - INV | DNML | DZ | IMP */
+       FPE_FLTOVF, /* 28 - OFL | IMP */
+       FPE_FLTINV, /* 29 - INV | OFL | IMP */
+       FPE_FLTUND, /* 2A - DNML | OFL | IMP */
+       FPE_FLTINV, /* 2B - INV | DNML | OFL | IMP */
+       FPE_FLTDIV, /* 2C - DZ | OFL | IMP */
+       FPE_FLTINV, /* 2D - INV | DZ | OFL | IMP */
+       FPE_FLTDIV, /* 2E - DNML | DZ | OFL | IMP */
+       FPE_FLTINV, /* 2F - INV | DNML | DZ | OFL | IMP */
+       FPE_FLTUND, /* 30 - UFL | IMP */
+       FPE_FLTINV, /* 31 - INV | UFL | IMP */
+       FPE_FLTUND, /* 32 - DNML | UFL | IMP */
+       FPE_FLTINV, /* 33 - INV | DNML | UFL | IMP */
+       FPE_FLTDIV, /* 34 - DZ | UFL | IMP */
+       FPE_FLTINV, /* 35 - INV | DZ | UFL | IMP */
+       FPE_FLTDIV, /* 36 - DNML | DZ | UFL | IMP */
+       FPE_FLTINV, /* 37 - INV | DNML | DZ | UFL | IMP */
+       FPE_FLTOVF, /* 38 - OFL | UFL | IMP */
+       FPE_FLTINV, /* 39 - INV | OFL | UFL | IMP */
+       FPE_FLTUND, /* 3A - DNML | OFL | UFL | IMP */
+       FPE_FLTINV, /* 3B - INV | DNML | OFL | UFL | IMP */
+       FPE_FLTDIV, /* 3C - DZ | OFL | UFL | IMP */
+       FPE_FLTINV, /* 3D - INV | DZ | OFL | UFL | IMP */
+       FPE_FLTDIV, /* 3E - DNML | DZ | OFL | UFL | IMP */
+       FPE_FLTINV, /* 3F - INV | DNML | DZ | OFL | UFL | IMP */
+       FPE_FLTSUB, /* 40 - STK */
+       FPE_FLTSUB, /* 41 - INV | STK */
+       FPE_FLTUND, /* 42 - DNML | STK */
+       FPE_FLTSUB, /* 43 - INV | DNML | STK */
+       FPE_FLTDIV, /* 44 - DZ | STK */
+       FPE_FLTSUB, /* 45 - INV | DZ | STK */
+       FPE_FLTDIV, /* 46 - DNML | DZ | STK */
+       FPE_FLTSUB, /* 47 - INV | DNML | DZ | STK */
+       FPE_FLTOVF, /* 48 - OFL | STK */
+       FPE_FLTSUB, /* 49 - INV | OFL | STK */
+       FPE_FLTUND, /* 4A - DNML | OFL | STK */
+       FPE_FLTSUB, /* 4B - INV | DNML | OFL | STK */
+       FPE_FLTDIV, /* 4C - DZ | OFL | STK */
+       FPE_FLTSUB, /* 4D - INV | DZ | OFL | STK */
+       FPE_FLTDIV, /* 4E - DNML | DZ | OFL | STK */
+       FPE_FLTSUB, /* 4F - INV | DNML | DZ | OFL | STK */
+       FPE_FLTUND, /* 50 - UFL | STK */
+       FPE_FLTSUB, /* 51 - INV | UFL | STK */
+       FPE_FLTUND, /* 52 - DNML | UFL | STK */
+       FPE_FLTSUB, /* 53 - INV | DNML | UFL | STK */
+       FPE_FLTDIV, /* 54 - DZ | UFL | STK */
+       FPE_FLTSUB, /* 55 - INV | DZ | UFL | STK */
+       FPE_FLTDIV, /* 56 - DNML | DZ | UFL | STK */
+       FPE_FLTSUB, /* 57 - INV | DNML | DZ | UFL | STK */
+       FPE_FLTOVF, /* 58 - OFL | UFL | STK */
+       FPE_FLTSUB, /* 59 - INV | OFL | UFL | STK */
+       FPE_FLTUND, /* 5A - DNML | OFL | UFL | STK */
+       FPE_FLTSUB, /* 5B - INV | DNML | OFL | UFL | STK */
+       FPE_FLTDIV, /* 5C - DZ | OFL | UFL | STK */
+       FPE_FLTSUB, /* 5D - INV | DZ | OFL | UFL | STK */
+       FPE_FLTDIV, /* 5E - DNML | DZ | OFL | UFL | STK */
+       FPE_FLTSUB, /* 5F - INV | DNML | DZ | OFL | UFL | STK */
+       FPE_FLTRES, /* 60 - IMP | STK */
+       FPE_FLTSUB, /* 61 - INV | IMP | STK */
+       FPE_FLTUND, /* 62 - DNML | IMP | STK */
+       FPE_FLTSUB, /* 63 - INV | DNML | IMP | STK */
+       FPE_FLTDIV, /* 64 - DZ | IMP | STK */
+       FPE_FLTSUB, /* 65 - INV | DZ | IMP | STK */
+       FPE_FLTDIV, /* 66 - DNML | DZ | IMP | STK */
+       FPE_FLTSUB, /* 67 - INV | DNML | DZ | IMP | STK */
+       FPE_FLTOVF, /* 68 - OFL | IMP | STK */
+       FPE_FLTSUB, /* 69 - INV | OFL | IMP | STK */
+       FPE_FLTUND, /* 6A - DNML | OFL | IMP | STK */
+       FPE_FLTSUB, /* 6B - INV | DNML | OFL | IMP | STK */
+       FPE_FLTDIV, /* 6C - DZ | OFL | IMP | STK */
+       FPE_FLTSUB, /* 6D - INV | DZ | OFL | IMP | STK */
+       FPE_FLTDIV, /* 6E - DNML | DZ | OFL | IMP | STK */
+       FPE_FLTSUB, /* 6F - INV | DNML | DZ | OFL | IMP | STK */
+       FPE_FLTUND, /* 70 - UFL | IMP | STK */
+       FPE_FLTSUB, /* 71 - INV | UFL | IMP | STK */
+       FPE_FLTUND, /* 72 - DNML | UFL | IMP | STK */
+       FPE_FLTSUB, /* 73 - INV | DNML | UFL | IMP | STK */
+       FPE_FLTDIV, /* 74 - DZ | UFL | IMP | STK */
+       FPE_FLTSUB, /* 75 - INV | DZ | UFL | IMP | STK */
+       FPE_FLTDIV, /* 76 - DNML | DZ | UFL | IMP | STK */
+       FPE_FLTSUB, /* 77 - INV | DNML | DZ | UFL | IMP | STK */
+       FPE_FLTOVF, /* 78 - OFL | UFL | IMP | STK */
+       FPE_FLTSUB, /* 79 - INV | OFL | UFL | IMP | STK */
+       FPE_FLTUND, /* 7A - DNML | OFL | UFL | IMP | STK */
+       FPE_FLTSUB, /* 7B - INV | DNML | OFL | UFL | IMP | STK */
+       FPE_FLTDIV, /* 7C - DZ | OFL | UFL | IMP | STK */
+       FPE_FLTSUB, /* 7D - INV | DZ | OFL | UFL | IMP | STK */
+       FPE_FLTDIV, /* 7E - DNML | DZ | OFL | UFL | IMP | STK */
+       FPE_FLTSUB, /* 7F - INV | DNML | DZ | OFL | UFL | IMP | STK */
+ };
+ 
+ #define ENCODE(_sw, _cw) (fpetable[(_sw & ~_cw & 0x3f) | (_sw & 0x40)])
+ 
  /*
   * Preserve the FP status word, clear FP exceptions, then generate a SIGFPE.
   *
   * Clearing exceptions is necessary mainly to avoid IRQ13 bugs.  We now
   * depend on longjmp() restoring a usable state.  Restoring the state
   * or examining it might fail if we didn't clear exceptions.
   *
!  * The error code chosen will be one of the FPE_... macros. It will be
!  * sent as the second argument to old BSD-style signal handlers and as
!  * "siginfo_t->si_code" (second argument) to SA_SIGINFO signal handlers.
   *
   * XXX the FP state is not preserved across signal handlers.  So signal
   * handlers cannot afford to do FP unless they preserve the state or
***************
*** 520,525 ****
--- 700,706 ----
        void *dummy;
  {
        int code;
+       u_long cw;
        struct intrframe *frame;
  
        if (npxproc == NULL || !npx_exists) {
***************
*** 535,540 ****
--- 716,722 ----
  
        outb(0xf0, 0);
        fnstsw(&curpcb->pcb_savefpu.sv_ex_sw);
+       fnstcw(&cw);
        fnclex();
  
        /*
***************
*** 554,568 ****
                 * just before it is used).
                 */
                curproc->p_md.md_regs = INTR_TO_TRAPFRAME(frame);
- #ifdef notyet
                /*
                 * Encode the appropriate code for detailed information on
                 * this exception.
                 */
!               code = XXX_ENCODE(curpcb->pcb_savefpu.sv_ex_sw);
! #else
!               code = 0;       /* XXX */
! #endif
                trapsignal(curproc, SIGFPE, code);
        } else {
                /*
--- 736,746 ----
                 * just before it is used).
                 */
                curproc->p_md.md_regs = INTR_TO_TRAPFRAME(frame);
                /*
                 * Encode the appropriate code for detailed information on
                 * this exception.
                 */
!               code = ENCODE(curpcb->pcb_savefpu.sv_ex_sw, cw);
                trapsignal(curproc, SIGFPE, code);
        } else {
                /*

Reply via email to