home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 15 / 15.iso / s / s053 / 38.ddi / root.3 / usr / include / ieeefp.h / ieeefp.h
Encoding:
C/C++ Source or Header  |  1990-10-02  |  16.2 KB  |  446 lines

  1. /*    Copyright (c) 1990 UNIX System Laboratories, Inc.    */
  2. /*    Copyright (c) 1988 AT&T    */
  3. /*      All Rights Reserved      */
  4.  
  5. /*    THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF         */
  6. /*    UNIX System Laboratories, Inc.                         */
  7. /*    The copyright notice above does not evidence any       */
  8. /*    actual or intended publication of such source code.    */
  9.  
  10. #ifndef _IEEEFP_H
  11. #define _IEEEFP_H
  12.  
  13. #ident    "@(#)/usr/include/ieeefp.h.sl 1.2 5.0 08/27/90 45074 AT&T-USO 1.3"
  14.  
  15. /*
  16.  * Floating point enviornment for machines that support
  17.  * the IEEE 754 floating-point standard.  This file currently 
  18.  * supports the 3B2 and 80*87 families.
  19.  *
  20.  * This header defines the following interfaces:
  21.  *    1) Classes of floating point numbers
  22.  *    2) Rounding Control
  23.  *    3) Exception Control
  24.  *    4) Exception Handling
  25.  *    5) Utility Macros
  26.  *    6) Full Exception Environment Control
  27.  */
  28. #if defined(__STDC__)
  29. #define __i386 #machine(i386)
  30. #else
  31. #define __i386 i386
  32. #endif
  33.  
  34. /* CLASSES of floating point numbers *************************
  35.  * IEEE floating point values fall into 1 of the following 10
  36.  * classes
  37.  */
  38. typedef    enum    fpclass_t {
  39.     FP_SNAN = 0,    /* signaling NaN */
  40.     FP_QNAN = 1,    /* quiet NaN */
  41.     FP_NINF = 2,    /* negative infinity */
  42.     FP_PINF = 3,    /* positive infinity */
  43.     FP_NDENORM = 4, /* negative denormalized non-zero */
  44.     FP_PDENORM = 5, /* positive denormalized non-zero */
  45.     FP_NZERO = 6,    /* -0.0 */
  46.     FP_PZERO = 7,   /* +0.0 */
  47.     FP_NNORM = 8,    /* negative normalized non-zero */
  48.     FP_PNORM = 9    /* positive normalized non-zero */
  49.     } fpclass_t;
  50.  
  51. #if defined(__STDC__)
  52. extern fpclass_t fpclass(double);    /* get class of double value */
  53. extern int    finite( double );
  54. extern int    unordered( double, double );
  55. #else
  56. extern fpclass_t fpclass();    /* get class of double value */
  57. #endif
  58.  
  59. /* ROUNDING CONTROL ******************************************
  60.  *
  61.  * At all times, floating-point math is done using one of four
  62.  * mutually-exclusive rounding modes.
  63.  */
  64.  
  65. #if __i386
  66.  
  67. /*
  68.  * NOTE: the values given are chosen to match those used by the
  69.  * 80*87 rounding mode field in the control word.
  70.  */
  71. typedef    enum    fp_rnd {
  72.     FP_RN = 0,    /* round to nearest representable number, tie -> even */
  73.     FP_RM = 1,  /* round toward minus infinity                        */
  74.     FP_RP = 2,  /* round toward plus infinity                         */
  75.     FP_RZ = 3    /* round toward zero (truncate)                  */
  76.     } fp_rnd;
  77.  
  78. #else  /* 3B */
  79.  
  80. /* NOTE: the values given are chosen to match
  81.  * the values needed by the FPA and MAU rounding-control fields.
  82.  */
  83. typedef    enum    fp_rnd {
  84.     FP_RN = 0,    /* round to nearest representable number, tie -> even */
  85.     FP_RP = 1,    /* round toward plus infinity                  */
  86.     FP_RM = 2,    /* round toward minus infinity                  */
  87.     FP_RZ = 3    /* round toward zero (truncate)                  */
  88.     } fp_rnd;
  89.  
  90. #endif
  91.  
  92. #if defined(__STDC__)
  93. extern fp_rnd   fpsetround(fp_rnd);     /* set rounding mode, return previous */
  94. extern fp_rnd   fpgetround(void);       /* return current rounding mode       */
  95.  
  96. #else
  97. extern fp_rnd    fpsetround();    /* set rounding mode, return previous */
  98. extern fp_rnd    fpgetround();    /* return current rounding mode       */
  99.  
  100. #endif
  101.  
  102. /* EXCEPTION CONTROL *****************************************
  103.  *
  104.  */
  105.  
  106. #define    fp_except    int
  107.  
  108. #define    FP_DISABLE    0    /* exception will be ignored    */
  109. #define    FP_ENABLE    1    /* exception will cause SIGFPE    */
  110. #define    FP_CLEAR    0    /* exception has not occurred    */
  111. #define    FP_SET        1    /* exception has occurred    */
  112.  
  113. #if __i386
  114.  
  115. /*
  116.  * There are six floating point exceptions, which can be individually
  117.  * ENABLED (== 1) or DISABLED (== 0).  When an exception occurs
  118.  * (ENABLED or not), the fact is noted by changing an associated
  119.  * "sticky bit" from CLEAR (==0) to SET (==1).
  120.  *
  121.  * NOTE: the bit positions in fp_except are chosen to match those of
  122.  * the 80*87 control word mask bits.  Although the 87 chips actually
  123.  * ENABLE exceptions with a mask value of 0 (not 1, as on the 3b), it
  124.  * is felt that switching these values may create more problems than
  125.  * it solves.
  126.  */
  127.  
  128. /* an fp_except can have the following (not exclusive) values:  */
  129. #define FP_X_INV        0x01    /* invalid operation exception  */
  130. #define FP_X_DNML       0x02    /* denormalization exception    */
  131. #define FP_X_DZ         0x04    /* divide-by-zero exception     */
  132. #define    FP_X_OFL    0x08    /* overflow exception        */
  133. #define FP_X_UFL        0x10    /* underflow exception          */
  134. #define FP_X_IMP        0x20    /* imprecise (loss of precision)*/
  135.  
  136. #else /* 3B */
  137.  
  138. /*
  139.  * There are five floating-point exceptions, which can be individually
  140.  * ENABLED (== 1) or DISABLED (== 0).  When an exception occurs
  141.  * (ENABLED or not), the fact is noted by changing an associated
  142.  * "sticky bit" from CLEAR (==0) to SET (==1).
  143.  *
  144.  * NOTE: the bit positions in an fp_except are chosen to match that in
  145.  * the MAU and the FPA hardware mask bits.
  146.  */
  147.  
  148. /* an fp_except can have the following (not exclusive) values:  */
  149. #define    FP_X_INV    0x10    /* invalid operation exception    */
  150. #define    FP_X_OFL    0x08    /* overflow exception        */
  151. #define    FP_X_UFL    0x04    /* underflow exception        */
  152. #define    FP_X_DZ        0x02    /* divide-by-zero exception    */
  153. #define    FP_X_IMP    0x01    /* imprecise (loss of precision)*/
  154.  
  155. #endif
  156.  
  157. #if defined(__STDC__)
  158. extern fp_except fpgetmask(void);               /* current exception mask       */
  159. extern fp_except fpsetmask(fp_except);          /* set mask, return previous    */
  160. extern fp_except fpgetsticky(void);             /* return logged exceptions     */
  161. extern fp_except fpsetsticky(fp_except);        /* change logged exceptions     */
  162.  
  163. #else
  164. extern fp_except fpgetmask();    /* current exception mask       */
  165. extern fp_except fpsetmask();    /* set mask, return previous    */
  166. extern fp_except fpgetsticky();    /* return logged exceptions     */
  167. extern fp_except fpsetsticky();    /* change logged exceptions     */
  168.  
  169. #endif 
  170.  
  171. /* UTILITY MACROS ********************************************
  172.  */
  173.  
  174. #if defined(__STDC__)
  175. extern int isnanf(float);               
  176. extern int isnand(double);
  177.  
  178. #else
  179. extern int isnand();
  180. #define isnanf(x)    (((*(long *)&(x) & 0x7f800000L)==0x7f800000L)&& \
  181.              ((*(long *)&(x) & 0x007fffffL)!=0x00000000L) )
  182. #endif
  183.  
  184. #if __i386
  185.  
  186. #ifndef SS
  187. #include <sys/reg.h>
  188. #endif
  189. /* EXCEPTION HANDLING ****************************************
  190.  *
  191.  * When a signal handler catches an FPE, it will have a freshly initialized
  192.  * coprocessor.  This allows signal handling routines to make use of
  193.  * floating point arithmetic, if need be.  The previous state of the 87
  194.  * chip is available, however.  There are two ways to get at this information,
  195.  * depending on how the signal handler was set up.
  196.  *
  197.  * If the handler was set via signal() or sigset(), the old, SVR3, method
  198.  * should be used: the signal handler assumes that it has a single parameter,
  199.  * which is of type struct _fpstackframe, defined below.  By investigating
  200.  * this parameter, the cause of the FPE may be determined.  By modifying it,
  201.  * the state of the coprocessor can be changed upon return to the main task.
  202.  * THIS METHOD IS OBSOLETE, AND MAY NOT BE SUPPORTED IN FUTURE RELEASES.
  203.  *
  204.  * If the handler was set via sigaction(), the new, SVR4, method should be
  205.  * used: the third argument to the handler will be a pointer to a ucontext
  206.  * structure (see sys/ucontext.h).  The uc_mcontext.fpregs member of the
  207.  * ucontext structure holds the saved floating-point registers.  This can be
  208.  * examined and/or modified.  By modifying it, the state of the coprocessor
  209.  * can be changed upon return to the main task.
  210.  */
  211.  
  212. struct _fpstackframe {  /* signal handler's argument                    */
  213.     long signo;             /* signal number arg                    */
  214.     long regs[SS+1];        /* all registers                        */
  215.     struct _fpstate *fpsp;  /* address of saved 387 state           */
  216.     char *wsp;              /* address of saved Weitek state        */
  217. };
  218.  
  219. struct _fpreg {         /* structure of a temp real fp register         */
  220.     unsigned short significand[4];  /* 64 bit mantissa value        */
  221.     unsigned short exponent;        /* 15 bit exponent and sign bit */
  222. };
  223.  
  224. struct _fpstate {       /* saved state info from an exception           */
  225.     unsigned long cw,       /* cotrol word                          */
  226.               sw,       /* status word after fnclex-not useful  */
  227.               tag,      /* tag word                             */
  228.               ipoff,    /* %eip register                        */
  229.               cssel,    /* code segment selector                */
  230.               dataoff,  /* data operand address                 */
  231.               datasel;  /* data operand selector                */
  232.     struct _fpreg _st[8];   /* saved register stack                 */
  233.     unsigned long status;   /* status word saved at exception       */
  234. };
  235.  
  236. /* The structure of the 80*87 status and control words are given by the
  237.  * following structs.
  238.  */
  239. struct _cw87 {
  240.     unsigned    mask:   6,  /* exception masks                      */
  241.             res1:   2,  /* not used                             */
  242.             prec:   2,  /* precision control field              */
  243.             rnd:    2,  /* rounding control field               */
  244.             inf:    1,  /* infinity control (not on 387)        */
  245.             res2:   3;  /* not used                             */
  246. };
  247.  
  248. struct _sw87 {
  249.     unsigned    excp:   6,  /* exception sticky bits                */
  250.             res1:   1,  /* not used                             */
  251.             errs:   1,  /* error summary-set if unmasked excep  */
  252.             c012:   3,  /* condition code bits 0..2             */
  253.             stkt:   3,  /* stack top pointer                    */
  254.             c3:     1,  /* condition code bit 3                 */
  255.             busy:   1;  /* coprocessor busy                     */
  256. };
  257.  
  258. #else /* 3B */
  259.  
  260. /* EXCEPTION HANDLING ****************************************
  261.  * When a floating-point exception handler is entered, the variables
  262.  * _fpftype -- floating-point fault type, and
  263.  * _fpfault -- pointer to floating-point exception structure
  264.  * will be established. _fpftype identifies the primary exception
  265.  * (if both underflow and inexact are generated, _fpftype is underflow)
  266.  * and _fpfault points to all the other information needed.
  267.  * Two integer faults also use this mechanism: "integer overflow" and
  268.  * "integer divide by zero". If either of these faults is indicated,
  269.  * or if _fpftype == UNKNOWN, _fpfault will be NULL.
  270.  */
  271.  
  272. #undef UNKNOWN
  273.  
  274. typedef    enum    fp_ftype {
  275.     UNKNOWN    = 0,    /* library code could not determine type      */
  276.     INT_DIVZ    = 1,    /* integer divide by zero              */
  277.     INT_OVFLW    = 2,    /* integer overflow, including float->int conv*/
  278.     FP_OVFLW    = 3,    /* floating-point overflow              */
  279.     FP_UFLW    = 4,    /* floating-point underflow              */
  280.     FP_INXACT    = 5,    /* floating-point loss of precision          */
  281.     FP_DIVZ    = 6,    /* floating-point divide by zero          */
  282.     FP_INVLD    = 7,    /* floating-point invalid operation          */
  283.     FP_IN_OVFLW = 8,    /* inexact AND overflow                       */
  284.     FP_IN_UFLW  = 9    /* inexact AND underflow                      */
  285.     } fp_ftype;
  286.  
  287. extern fp_ftype _fpftype;
  288.  
  289. /* reporting a floating-point exception requires a discriminated union
  290.  * of all relevant data-types. The following defines the discriminant.
  291.  * The particular values are arbitrary.
  292.  */
  293. typedef    enum    fp_type {
  294.     FP_NULL    = 0,    /* uninitialized data                  */
  295.     FP_C    = 1,    /* result of comparison, returned from trap   */
  296.     FP_L    = 2,    /* long int data, being converted to/from flt.*/
  297.     FP_F    = 3,    /* single-precision floating-point          */
  298.     FP_D    = 4,    /* double-precision floating-point          */
  299.     FP_X    = 5,    /* double-extended-precision floating-point   */
  300.     FP_P    = 6,    /* packed-decimal floating-point          */
  301.     FP_U    = 7,    /* unsigned int data, being converted           */
  302.     FP_S    = 8,    /* short int data                  */
  303.     FP_DEC    = 9    /* decimal ascii data being converted          */
  304.     }    fp_type;
  305.  
  306. /* floating-point data types                    */
  307. typedef struct extended { /* double-extended floating point    */
  308.     unsigned long    w[3];
  309.     } extended;
  310.  
  311. typedef struct packdec { /* packed-decimal floating point    */
  312.     unsigned long    w[3];
  313.     } packdec;
  314.  
  315. typedef struct decimal { /* ascii-decimal floating point    */
  316.     char *    i;        /* significand ascii digit string    */
  317.     char *    e;        /* exponent ascii digit string        */
  318.     char    sign;        /* sign of number            */
  319.                 /*     0    +            */
  320.                 /*     1    -            */
  321.     char    esign;        /* sign of exponent            */
  322.                 /*     0    +            */
  323.                 /*     1    -            */
  324.                 /*    2    NaN            */
  325.                 /*    3    infinity        */
  326.     int        ilen;        /* # digits in significand        */
  327.     int        elen;        /* # digits in exponent            */
  328.     } decimal;
  329.  
  330. typedef    enum    fp_cmp { /* result of comparison        */
  331.     FP_LT    = -1,    /* less than    */
  332.     FP_EQ    =  0,    /* equal    */
  333.     FP_GT    =  1,    /* greater than    */
  334.     FP_UO    =  2    /* unordered    */
  335.     } fp_cmp;
  336.  
  337. typedef union fp_union { /* union of all types            */
  338.     fp_cmp    c;
  339.     long    l;
  340.     unsigned    u;
  341.     float    f;
  342.     double    d;
  343.     extended    x;    /* not used on 3B20  */
  344.     packdec    p;    /* not used on 3B20  */
  345.     short    s;      /* only used on 3B20 */
  346.     decimal    *dec;
  347.     } fp_union;
  348.  
  349. typedef struct fp_dunion { /* discriminated union        */
  350.     fp_type    type;
  351.     fp_union    value;
  352.     } fp_dunion;
  353.  
  354. /* the rest of the information pointed to by _fp_fault includes:
  355.  *    the type of operation being performed,
  356.  *    the types and values of the operands,
  357.  *    the type of a trapped value (if any), and
  358.  *    the desired type of the result.
  359.  * the following defines and struct give the information layout.
  360.  */
  361.  
  362. typedef    enum    fp_op {    /* floating-point operations              */
  363.     FP_ADD  = 0,    /* floating-point addition              */
  364.     FP_SUB  = 1,    /* floating-point subtraction              */
  365.     FP_MULT = 2,    /* floating-point multiplication          */
  366.     FP_DIV  = 3,    /* floating-point division              */
  367.     FP_SQRT = 4,    /* floating-point square root              */
  368.     FP_REM  = 5,    /* floating-point remainder              */
  369.     FP_CONV = 6,    /* data movement, including changing format   */
  370.     FP_RNDI = 7,    /* round to integer (keep in floating format) */
  371.     FP_CMPT = 8,    /* trapping floating-point compare          */
  372.     FP_CMP  = 9,    /* non-trapping floating-point compare          */
  373.     FP_NEG  = 10,    /* (MAU) negate operation              */
  374.     FP_ABS  = 11,    /* (MAU) absolute value operation          */
  375.     FP_SIN  = 12,    /* floating-point sine                  */
  376.     FP_COS  = 13,    /* floating-point cosine              */
  377.     FP_ATN  = 14    /* floating-point arc tangent              */
  378.     }    fp_op;
  379.  
  380. struct fp_fault {
  381.     fp_op    operation;
  382.     fp_dunion    operand[2];
  383.     fp_dunion    t_value;
  384.     fp_dunion    result;
  385.     };
  386.  
  387. extern struct fp_fault    * _fpfault;
  388.  
  389.  
  390. /* FULL EXCEPTION ENVIRONMENT CONTROL ************************
  391.  *
  392.  * The complete exception environment defined above requires
  393.  * a significant amount of code to be picked up from the libraries.
  394.  * The "glue" routines _getfltsw() and _getflthw() are provided
  395.  * in two versions, one with full capability and one without.
  396.  * The version without full capability has the following behavior:
  397.  *    floating-point faults will raise SIGFPE, but
  398.  *    the user handler will have _fpftype == UNKNOWN, and
  399.  *    _fpfault == NULL. If SIGFPE is set to SIG_DFL, a core dump
  400.  *    will be produced.
  401.  * If ANY module in the final a.out #includes ieeefp.h (except as noted
  402.  * below), the code below will force in the FULL environment,
  403.  * 
  404.  * NOTES: 1) code in the library (e.g. for setround(), etc.) which
  405.  *    needs the definitions above, but does not care which fault
  406.  *    environment is picked up SHOULD #define P754_NOFAULT
  407.  *    before #including ieeefp.h.
  408.  *    2) If a user program does not wish to do any fault recovery,
  409.  *    just produce a core dump, it MAY also #define P754_NOFAULT,
  410.  *    and may gain a code size reduction. However, if it uses a
  411.  *    routine    in the math library that does request the full fault
  412.  *    environment then the full environment WILL be included.
  413.  */
  414. #ifndef P754_NOFAULT
  415. #define    P754_NOFAULT    1
  416.  
  417. #if defined(__STDC__)
  418. extern void    _getflthw(int *, int (*)());
  419. extern fp_union    _getfltsw(fp_ftype,fp_op,char *,fp_union *,fp_union *,fp_union *);
  420. static void    (* _p754_1)(int *, int (*)()) = _getflthw;
  421. static fp_union    (* _p754_2)(fp_ftype,fp_op,char *,fp_union *,fp_union *,fp_union *) =    _getfltsw;
  422.  
  423. extern void _s2dec(float *, decimal *, int);
  424. extern void _d2dec(double *, decimal *, int);
  425. extern void _dec2s(decimal *, float *, int);
  426. extern void _dec2d(decimal *, double *, int);
  427.  
  428. #else
  429. extern void    _getflthw();
  430. extern fp_union    _getfltsw();
  431. static void    (* _p754_1)() = _getflthw;
  432. static fp_union    (* _p754_2)() =    _getfltsw;
  433.  
  434. extern void _s2dec();
  435. extern void _d2dec();
  436. extern void _dec2s();
  437. extern void _dec2d();
  438. #endif
  439.  
  440. #endif  /* ndef P&%$_NOFAULT 1 */
  441.  
  442. #endif  /* __i386 */
  443.  
  444. #endif  /* _IEEEFP_H */
  445.  
  446.