From owner-freebsd-current Wed Sep 9 03:16:41 1998 Return-Path: Received: (from majordom@localhost) by hub.freebsd.org (8.8.8/8.8.8) id DAA17153 for freebsd-current-outgoing; Wed, 9 Sep 1998 03:16:41 -0700 (PDT) (envelope-from owner-freebsd-current@FreeBSD.ORG) Received: from cons.org (knight.cons.org [194.233.237.86]) by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id DAA17117 for ; Wed, 9 Sep 1998 03:16:35 -0700 (PDT) (envelope-from cracauer@cons.org) Received: (from cracauer@localhost) by cons.org (8.8.8/8.7.3) id MAA19380; Wed, 9 Sep 1998 12:16:15 +0200 (CEST) Message-ID: <19980909121614.A19326@cons.org> Date: Wed, 9 Sep 1998 12:16:14 +0200 From: Martin Cracauer To: Bruce Evans , cracauer@cons.org, current@FreeBSD.ORG Subject: Proposed implementation of trapcodes for SIGFPE References: <199809010132.LAA14077@godzilla.zeta.org.au> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary=sm4nu43k4a2Rpi4c X-Mailer: Mutt 0.93.1i In-Reply-To: <199809010132.LAA14077@godzilla.zeta.org.au>; from Bruce Evans on Tue, Sep 01, 1998 at 11:32:44AM +1000 Sender: owner-freebsd-current@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG --sm4nu43k4a2Rpi4c Content-Type: text/plain; charset=us-ascii Find appended a proposed implementation of trapcodes for SIGFPE. It contains a diff against -current, a test program (freebsd-signal.c) and a program to generate the fpetable (npxvals.c). This strickly implements the 8 portable FPE_...... values, with mapping everything that is an illegal access of some kind to FPE_FLTSUB. Determination of more exact reasons should be part of a new interface that passes the control and status word to the new signal handler (SA_SIGINFO). Questions: - Does it work on your machine, everyone (especially older ones)? - The fpetable is rather large, should u_char be used insted of int? - As npxvals.c shows, the code path to get the values in the table is rather short, maybe it is an alternative to run this function instead of using a table? Martin -- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Martin Cracauer http://www.cons.org/cracauer Tel.: (private) +4940 5221829 Fax.: (private) +4940 5228536 Paper: (private) Waldstrasse 200, 22846 Norderstedt, Germany --sm4nu43k4a2Rpi4c Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="diff.fpetrapcode" ? conf/WINGS ? conf/WINGS.from-SMP-GENERIC Index: i386/trap.c =================================================================== RCS file: /home/CVS-FreeBSD/src/sys/i386/i386/trap.c,v retrieving revision 1.128 diff -c -r1.128 trap.c *** trap.c 1998/08/23 10:16:26 1.128 --- trap.c 1998/09/09 00:27:03 *************** *** 328,334 **** break; case T_DIVIDE: /* integer divide fault */ ! ucode = FPE_INTDIV_TRAP; i = SIGFPE; break; --- 328,334 ---- break; case T_DIVIDE: /* integer divide fault */ ! ucode = FPE_INTDIV; i = SIGFPE; break; *************** *** 350,361 **** #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; --- 350,361 ---- #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: 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 1998/09/09 00:27:05 *************** *** 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: 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 1998/09/09 00:27:05 *************** *** 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: isa/npx.c =================================================================== RCS file: /home/CVS-FreeBSD/src/sys/i386/isa/npx.c,v retrieving revision 1.61 diff -c -r1.61 npx.c *** npx.c 1998/06/21 18:02:39 1.61 --- npx.c 1998/09/09 00:27:07 *************** *** 474,479 **** --- 474,637 ---- #endif } + /* + * Table with FPE_ values for every possible combination of exception bits. + * The precedence is based upon Intel Document "Numerical Applications", + * Chapter "Special Computational Situations". That means when the user + * process enter with more than one unmasked exceptions bit (can be + * when it modified the control word), we through away bits as would the + * FPU if one instruction would cause more than one exception to be raised. + * + * Precisly, it is: + * 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 int 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 */ + }; + + /* + * Return the right FPE_ value (from trap.h) based on current control and + * status word. + */ + #define ENCODE(_sw, _cw) (fpetable[_sw & ~_cw & 0x3f | _sw & 0x40]) + /* * Preserve the FP status word, clear FP exceptions, then generate a SIGFPE. * *************** *** 500,505 **** --- 658,664 ---- int unit; { int code; + u_long cw; struct intrframe *frame; if (npxproc == NULL || !npx_exists) { *************** *** 515,520 **** --- 674,680 ---- outb(0xf0, 0); fnstsw(&curpcb->pcb_savefpu.sv_ex_sw); + fnstcw(&cw); fnclex(); /* *************** *** 534,548 **** * just before it is used). */ curproc->p_md.md_regs = (struct trapframe *)&frame->if_es; - #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 { /* --- 694,704 ---- * just before it is used). */ curproc->p_md.md_regs = (struct trapframe *)&frame->if_es; /* * Encode the appropriate code for detailed information on * this exception. */ ! code = ENCODE(curpcb->pcb_savefpu.sv_ex_sw, cw); trapsignal(curproc, SIGFPE, code); } else { /* --sm4nu43k4a2Rpi4c Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="npxvals.c" #include #include #if 0 #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, not used on FreeBSD */ #define FP_X_INV 0x01 /* invalid operation */ #define FP_X_DNML 0x02 /* denormal */ #define FP_X_DZ 0x04 /* zero divide */ #define FP_X_OFL 0x08 /* overflow */ #define FP_X_UFL 0x10 /* underflow */ #define FP_X_IMP 0x20 /* (im)precision */ #endif char *names[] = { "INV", "DNML", "DZ", "OFL", "UFL", "IMP", "STK" }; /* * 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) * 4) Denormal operand (FP_X_DNML) * 5) Numeric over/underflow (FP_X_OFL, FP_X_UFL) * 6) Inexact result (FP_X_IMP) */ int main(void) { int i,j; int first; /* OK, los gehts */ for (i = 1; i < 128 ; i++) { printf("\t"); if (i & FP_X_INV) { if (i & FP_X_STK) printf("FPE_FLTSUB"); else printf("FPE_FLTINV"); goto done; } if (i & FP_X_DZ) { printf("FPE_FLTDIV"); goto done; } if (i & FP_X_DNML) { printf("FPE_FLTUND"); goto done; } if (i & FP_X_OFL) { printf("FPE_FLTOVF"); goto done; } if (i & FP_X_UFL) { printf("FPE_FLTUND"); goto done; } if (i & FP_X_IMP) { printf("FPE_FLTRES"); goto done; } if (i & FP_X_STK) {/* Can't happen */ printf("FPE_FLTSUB"); goto done; } done: printf(", /* %2X - ", i); first = 1; for ( j=0; j<7 ; j++) { if (i & (1< #include #include #include #include #include #include #include volatile static sig_atomic_t sig_fpe_was_here = 0; volatile static int sig_sig; volatile static int sig_code; static struct sigcontext sig_context; static jmp_buf jmpbuf; static int handler(int sig, int code, struct sigcontext *scp) { #if 0 #define TMP "FPE handler\n" write(2,TMP,sizeof(TMP)-1); #undef TMP #endif sig_fpe_was_here++; sig_sig = sig; sig_code = code; memcpy(&sig_context, scp, sizeof(*scp)); longjmp(jmpbuf,1); return sig; } static const char * codestring(int code) { switch (code) { case FPE_INTDIV: return "FPE_INTDIV"; case FPE_INTOVF: return "FPE_INTOVF"; case FPE_FLTDIV: return "FPE_FLTDIV"; case FPE_FLTOVF: return "FPE_FLTOVF"; case FPE_FLTUND: return "FPE_FLTUND"; case FPE_FLTRES: return "FPE_FLTRES"; case FPE_FLTINV: return "FPE_FLTINV"; case FPE_FLTSUB: return "FPE_FLTSUB"; default: return "Unknwon code"; } } #if 0 static double deopt(double d) { return d; } #endif static double l_idiv(double p1, double p2) { return (double)((int)p1 / (int)p2); } static double l_fadd(double p1, double p2) { return p1 + p2; } static double l_fmul(double p1, double p2) { return p1 * p2; } static double l_fdiv(double p1, double p2) { return p1 / p2; } static double l_fsub(double p1, double p2) { return p1 - p2; } static double l_sin(double p1, double p2) { return sin(p1); } static double l_sqrt(double p1, double p2) { return sqrt(p1); } static double l_stkofl(double p1, double p2) { asm("fldz"); asm("fldz"); asm("fldz"); asm("fldz"); asm("fldz"); asm("fldz"); asm("fldz"); asm("fldz"); return p1 + p2; } static double l_stkufl(double p1, double p2) { asm("fdivp %st(0)"); return p1 + p2; } typedef double (test_f_t)(double, double); struct funcpair { test_f_t *func; const double p1; const double p2; const char *const descr; } const funcs[] = { {l_stkofl, 0.0, 0.0, "stack oflow "}, {l_stkufl, 0.0, 0.0, "stack uflow "}, {l_idiv, 0.0, 0.0, "int 0/0 "}, {l_idiv, 1.0, 0.0, "int 1/0 "}, {l_fdiv, 0.0, 0.0, "dbl 0/0 "}, {l_fdiv, 1.0, 0.0, "dbl 1/0 "}, {l_fdiv, DBL_MIN, DBL_MIN, "dbl MIN/MIN "}, {l_fdiv, DBL_MIN, 2.0, "dbl MIN/2 "}, {l_fsub, DBL_MIN, DBL_MIN, "dbl MIN-MIN "}, {l_fmul, DBL_MAX, 2.0, "dbl 2*MAX "}, {l_fmul, DBL_MAX, DBL_MAX, "dbl MAX*MAX "}, {l_fadd, DBL_MAX, DBL_MAX, "dbl MAX+MAX "}, {l_sin, 10.0, 0.0, "dbl sin(10.0)"}, {l_sqrt, -1.0, 0.0, "dbl sqrt(-1) "}, {NULL, NULL} }; #define forcefpe() asm("wait") static void dotests(void) { const struct funcpair *volatile it; double res; it = funcs; while (it->func) { fprintf(stderr, "Function '%s'", it->descr); if (setjmp(jmpbuf) == 0) { res = it->func(it->p1, it->p2); forcefpe(); fprintf(stderr, " survived, res: %g", res); } else { if (sig_fpe_was_here != 1) { fprintf(stderr,"Strange, %d exceptions after jongjmp\n" , sig_fpe_was_here); exit(2); } sig_fpe_was_here = 0; fprintf(stderr, " signal %d, code %-20s (%2d)" , sig_sig , codestring(sig_code) , sig_code ); } fputc('\n', stderr); it++; } } int main(int argc, char *argv[]) { int oldmask; fprintf(stderr,"Round: %x, Precision: %x\n", fpgetround(), fpgetprec()); oldmask = fpgetmask(); signal(SIGFPE,(__sighandler_t *)handler); fprintf(stderr,"Testing with all exceptions enabled\n"); fpsetmask(FP_X_INV|FP_X_DNML|FP_X_DZ|FP_X_OFL|FP_X_UFL|FP_X_IMP); dotests(); fprintf(stderr,"Testing with all exceptions except precision loss\n"); fpsetmask(FP_X_INV|FP_X_DNML|FP_X_DZ|FP_X_OFL|FP_X_UFL); dotests(); fprintf(stderr,"Testing with exceptions disabled\n"); fpsetmask(0L); dotests(); fprintf(stderr,"Round: %x, Precision: %x\n", fpgetround(), fpgetprec()); return 0; } --sm4nu43k4a2Rpi4c-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message