Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /****************************************************************************
  2. *
  3. *                            Open Watcom Project
  4. *
  5. *    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
  6. *
  7. *  ========================================================================
  8. *
  9. *    This file contains Original Code and/or Modifications of Original
  10. *    Code as defined in and that are subject to the Sybase Open Watcom
  11. *    Public License version 1.0 (the 'License'). You may not use this file
  12. *    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
  13. *    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
  14. *    provided with the Original Code and Modifications, and is also
  15. *    available at www.sybase.com/developer/opensource.
  16. *
  17. *    The Original Code and all software distributed under the License are
  18. *    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  19. *    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
  20. *    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
  21. *    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
  22. *    NON-INFRINGEMENT. Please see the License for the specific language
  23. *    governing rights and limitations under the License.
  24. *
  25. *  ========================================================================
  26. *
  27. * Description:  C/C++ run-time library floating-point definitions.
  28. *
  29. ****************************************************************************/
  30.  
  31.  
  32. #ifndef _XFLOAT_H_INCLUDED
  33. #define _XFLOAT_H_INCLUDED
  34.  
  35. #include <stddef.h>     // for wchar_t
  36. #include <float.h>      // for LDBL_DIG
  37.  
  38. #ifdef __cplusplus
  39. extern "C" {
  40. #endif
  41.  
  42. #if (defined(__386__) || defined(M_I86)) && defined(__WATCOMC__)
  43.  #define _LONG_DOUBLE_
  44. #endif
  45.  
  46. typedef struct {                // This layout matches Intel 8087
  47.   #ifdef _LONG_DOUBLE_
  48.     unsigned long low_word;     // - low word of fraction
  49.     unsigned long high_word;    // - high word of fraction
  50.     unsigned short exponent;    // - exponent and sign
  51.   #else                         // use this for all other 32-bit RISC
  52.     union {
  53.         double          value;  // - double value
  54.         unsigned long   word[2];// - so we can access bits
  55.     };
  56.   #endif
  57. } long_double;
  58.  
  59. typedef struct {                // Layout of IEEE 754 double (FD)
  60.     union {
  61.         double          value;  // - double value
  62.         unsigned long   word[2];// - so we can access bits
  63.     };
  64. } float_double;
  65.  
  66. typedef struct {                // Layout of IEEE 754 single (FS)
  67.     union {
  68.         float           value;  // - double value
  69.         unsigned long   word;   // - so we can access bits
  70.     };
  71. } float_single;
  72.  
  73. /* NB: The following values *must* match FP_ macros in math.h! */
  74. enum    ld_classification {
  75.     __ZERO      = 0,
  76.     __DENORMAL  = 1,
  77.     __NONZERO   = 2,
  78.     __NAN       = 3,
  79.     __INFINITY  = 4
  80. };
  81.  
  82. enum    ldcvt_flags {
  83.     E_FMT       = 0x0001,       // 'E' format
  84.     F_FMT       = 0x0002,       // 'F' format
  85.     G_FMT       = 0x0004,       // 'G' format
  86.     F_CVT       = 0x0008,       // __cvt routine format rules
  87.     F_DOT       = 0x0010,       // always put '.' in result
  88.     LONG_DOUBLE = 0x0020,       // number is true long double
  89.     NO_TRUNC    = 0x0040,       // always provide ndigits in buffer
  90.     IN_CAPS     = 0x0080,       // 'inf'/'nan' is uppercased
  91. };
  92.  
  93. typedef struct cvt_info {
  94.       int       ndigits;        // INPUT: number of digits
  95.       int       scale;          // INPUT: FORTRAN scale factor
  96.       int       flags;          // INPUT: flags (see ldcvt_flags)
  97.       int       expchar;        // INPUT: exponent character to use
  98.       int       expwidth;       // INPUT/OUTPUT: number of exponent digits
  99.       int       sign;           // OUTPUT: 0 => +ve; otherwise -ve
  100.       int       decimal_place;  // OUTPUT: position of '.'
  101.       int       n1;             // OUTPUT: number of leading characters
  102.       int       nz1;            // OUTPUT: followed by this many '0's
  103.       int       n2;             // OUTPUT: followed by these characters
  104.       int       nz2;            // OUTPUT: followed by this many '0's
  105. } CVT_INFO;
  106.  
  107. _WMRTLINK extern void __LDcvt(
  108.                          long_double *pld,      // pointer to long_double
  109.                          CVT_INFO  *cvt,        // conversion info
  110.                          char      *buf );      // buffer
  111. #if defined( __WATCOMC__ )
  112. _WMRTLINK extern int __Strtold(
  113.                         const char *bufptr,
  114.                         long_double *pld,
  115.                         char **endptr );
  116. #endif
  117. extern  int     __LDClass( long_double * );
  118. extern  void    __ZBuf2LD(char _WCNEAR *, long_double _WCNEAR *);
  119. extern  void    _LDScale10x(long_double _WCNEAR *,int);
  120. _WMRTLINK extern void  __cnvd2ld( double _WCNEAR *src, long_double _WCNEAR *dst );
  121. _WMRTLINK extern void  __cnvs2d( char *buf, double *value );
  122. _WMRTLINK extern int   __cnvd2f( double *src, float *tgt );
  123. #ifdef _LONG_DOUBLE_
  124. extern  void    __iLDFD(long_double _WCNEAR *, double _WCNEAR *);
  125. extern  void    __iLDFS(long_double _WCNEAR *, float _WCNEAR *);
  126. extern  void    __iFDLD(double _WCNEAR *,long_double _WCNEAR *);
  127. extern  void    __iFSLD(float _WCNEAR *,long_double _WCNEAR *);
  128. extern  long    __LDI4(long_double _WCNEAR *);
  129. extern  void    __I4LD(long,long_double _WCNEAR *);
  130. extern  void    __U4LD(unsigned long,long_double _WCNEAR *);
  131. extern void __FLDA(long_double _WCNEAR *,long_double _WCNEAR *,long_double _WCNEAR *);
  132. extern void __FLDS(long_double _WCNEAR *,long_double _WCNEAR *,long_double _WCNEAR *);
  133. extern void __FLDM(long_double _WCNEAR *,long_double _WCNEAR *,long_double _WCNEAR *);
  134. extern void __FLDD(long_double _WCNEAR *,long_double _WCNEAR *,long_double _WCNEAR *);
  135. extern int  __FLDC(long_double _WCNEAR *,long_double _WCNEAR *);
  136. #endif
  137.  
  138. #ifdef __WATCOMC__
  139. #if defined(__386__)
  140.  #pragma aux    __ZBuf2LD       "*"  parm caller [eax] [edx];
  141.  #if defined(__FPI__)
  142.   extern unsigned __Get87CW(void);
  143.   extern void __Set87CW(unsigned short);
  144.   #pragma aux   __Get87CW = \
  145.                 "push 0"\
  146.         float   "fstcw [esp]"\
  147.         float   "fwait"\
  148.                 "pop eax"\
  149.                 value [eax];
  150.   #pragma aux   __Set87CW = \
  151.                 "push eax"\
  152.         float   "fldcw [esp]"\
  153.                 "pop eax"\
  154.                 parm caller [eax];
  155.   #pragma aux   __FLDA = \
  156.         float   "fld tbyte ptr [eax]"\
  157.         float   "fld tbyte ptr [edx]"\
  158.         float   "fadd"\
  159.         float   "fstp tbyte ptr [ebx]"\
  160.                 parm caller [eax] [edx] [ebx];
  161.   #pragma aux   __FLDS = \
  162.         float   "fld tbyte ptr [eax]"\
  163.         float   "fld tbyte ptr [edx]"\
  164.         float   "fsub"\
  165.         float   "fstp tbyte ptr [ebx]"\
  166.                 parm caller [eax] [edx] [ebx];
  167.   #pragma aux   __FLDM = \
  168.         float   "fld tbyte ptr [eax]"\
  169.         float   "fld tbyte ptr [edx]"\
  170.         float   "fmul"\
  171.         float   "fstp tbyte ptr [ebx]"\
  172.                 parm caller [eax] [edx] [ebx];
  173.   #pragma aux   __FLDD = \
  174.         float   "fld tbyte ptr [eax]"\
  175.         float   "fld tbyte ptr [edx]"\
  176.         float   "fdiv"\
  177.         float   "fstp tbyte ptr [ebx]"\
  178.                 parm caller [eax] [edx] [ebx];
  179.   #pragma aux   __FLDC = \
  180.                 /* ST(1) */\
  181.         float   "fld tbyte ptr [edx]"\
  182.                 /* ST(0) */\
  183.         float   "fld tbyte ptr [eax]"\
  184.                 /* compare ST(0) with ST(1) */\
  185.         float   "fcompp"\
  186.         float   "fstsw  ax"\
  187.                 "sahf"\
  188.                 "sbb  edx,edx"\
  189.                 "shl  edx,1"\
  190.                 "shl  ah,2"\
  191.                 "cmc"\
  192.                 "adc  edx,0"\
  193.                 /* edx will be -1,0,+1 if [eax] <, ==, > [edx] */\
  194.                 parm caller [eax] [edx] value [edx];
  195.   #pragma aux   __LDI4 = \
  196.         float   "fld tbyte ptr [eax]"\
  197.                 "push  eax"\
  198.                 "push  eax"\
  199.         float   "fstcw [esp]"\
  200.         float   "fwait"\
  201.                 "pop eax"\
  202.                 "push eax"\
  203.                 "or ah,0x0c"\
  204.                 "push eax"\
  205.         float   "fldcw [esp]"\
  206.                 "pop eax"\
  207.         float   "fistp dword ptr 4[esp]"\
  208.         float   "fldcw [esp]"\
  209.                 "pop   eax"\
  210.                 "pop   eax"\
  211.                 parm caller [eax] value [eax];
  212.   #pragma aux   __I4LD = \
  213.                 "push  eax"\
  214.         float   "fild  dword ptr [esp]"\
  215.                 "pop   eax"\
  216.         float   "fstp tbyte ptr [edx]"\
  217.                 parm caller [eax] [edx];
  218.   #pragma aux   __U4LD = \
  219.                 "push  0"\
  220.                 "push  eax"\
  221.         float   "fild  qword ptr [esp]"\
  222.                 "pop   eax"\
  223.                 "pop   eax"\
  224.         float   "fstp tbyte ptr [edx]"\
  225.                 parm caller [eax] [edx];
  226.   #pragma aux   __iFDLD = \
  227.         float   "fld  qword ptr [eax]"\
  228.         float   "fstp tbyte ptr [edx]"\
  229.                 parm caller [eax] [edx];
  230.   #pragma aux   __iFSLD = \
  231.         float   "fld  dword ptr [eax]"\
  232.         float   "fstp tbyte ptr [edx]"\
  233.                 parm caller [eax] [edx];
  234.   #pragma aux   __iLDFD = \
  235.         float   "fld  tbyte ptr [eax]"\
  236.         float   "fstp qword ptr [edx]"\
  237.                 parm caller [eax] [edx];
  238.   #pragma aux   __iLDFS = \
  239.         float   "fld  tbyte ptr [eax]"\
  240.         float   "fstp dword ptr [edx]"\
  241.                 parm caller [eax] [edx];
  242.  #else  // floating-point calls
  243.   #pragma aux   __FLDA  "*"  parm caller [eax] [edx] [ebx];
  244.   #pragma aux   __FLDS  "*"  parm caller [eax] [edx] [ebx];
  245.   #pragma aux   __FLDM  "*"  parm caller [eax] [edx] [ebx];
  246.   #pragma aux   __FLDD  "*"  parm caller [eax] [edx] [ebx];
  247.   #pragma aux   __LDI4  "*"  parm caller [eax] value [eax];
  248.   #pragma aux   __I4LD  "*"  parm caller [eax] [edx];
  249.   #pragma aux   __U4LD  "*"  parm caller [eax] [edx];
  250.   #pragma aux   __iFDLD "*"  parm caller [eax] [edx];
  251.   #pragma aux   __iFSLD "*"  parm caller [eax] [edx];
  252.   #pragma aux   __iLDFD "*"  parm caller [eax] [edx];
  253.   #pragma aux   __iLDFS "*"  parm caller [eax] [edx];
  254.   #pragma aux   __FLDC  "*"  parm caller [eax] [edx] value [eax];
  255.  #endif
  256. #elif defined(M_I86)            // 16-bit pragmas
  257.  #pragma aux     __ZBuf2LD      "*"  parm caller [ax] [dx];
  258.  #if defined(__FPI__)
  259.   extern unsigned __Get87CW(void);
  260.   extern void __Set87CW(unsigned short);
  261.   #pragma aux   __Get87CW = \
  262.                 "push ax"\
  263.                 "push bp"\
  264.                 "mov  bp,sp"\
  265.         float   "fstcw 2[bp]"\
  266.         float   "fwait"\
  267.                 "pop bp"\
  268.                 "pop ax"\
  269.                 value [ax];
  270.   #pragma aux   __Set87CW = \
  271.                 "push ax"\
  272.                 "push bp"\
  273.                 "mov  bp,sp"\
  274.         float   "fldcw 2[bp]"\
  275.                 "pop bp"\
  276.                 "pop ax"\
  277.                 parm caller [ax];
  278.   #pragma aux   __FLDA = \
  279.                 "push bp"\
  280.                 "mov  bp,ax"\
  281.         float   "fld  tbyte ptr [bp]"\
  282.                 "mov  bp,dx"\
  283.         float   "fld  tbyte ptr [bp]"\
  284.         float   "fadd"\
  285.                 "mov  bp,bx"\
  286.         float   "fstp tbyte ptr [bp]"\
  287.                 "pop  bp"\
  288.                 parm caller [ax] [dx] [bx];
  289.   #pragma aux   __FLDS = \
  290.                 "push bp"\
  291.                 "mov  bp,ax"\
  292.         float   "fld  tbyte ptr [bp]"\
  293.                 "mov  bp,dx"\
  294.         float   "fld  tbyte ptr [bp]"\
  295.         float   "fsub"\
  296.                 "mov  bp,bx"\
  297.         float   "fstp tbyte ptr [bp]"\
  298.                 "pop  bp"\
  299.                 parm caller [ax] [dx] [bx];
  300.   #pragma aux   __FLDM = \
  301.                 "push bp"\
  302.                 "mov  bp,ax"\
  303.         float   "fld  tbyte ptr [bp]"\
  304.                 "mov  bp,dx"\
  305.         float   "fld  tbyte ptr [bp]"\
  306.         float   "fmul"\
  307.                 "mov  bp,bx"\
  308.         float   "fstp tbyte ptr [bp]"\
  309.                 "pop  bp"\
  310.                 parm caller [ax] [dx] [bx];
  311.   #pragma aux   __FLDD = \
  312.                 "push bp"\
  313.                 "mov  bp,ax"\
  314.         float   "fld  tbyte ptr [bp]"\
  315.                 "mov  bp,dx"\
  316.         float   "fld  tbyte ptr [bp]"\
  317.         float   "fdiv"\
  318.                 "mov  bp,bx"\
  319.         float   "fstp tbyte ptr [bp]"\
  320.                 "pop  bp"\
  321.                 parm caller [ax] [dx] [bx];
  322.   #pragma aux   __FLDC = \
  323.                 "push bp"\
  324.                 "mov  bp,dx"\
  325.                 /* ST(1) */\
  326.         float   "fld  tbyte ptr [bp]"\
  327.                 "mov  bp,ax"\
  328.                 /* ST(0) */\
  329.         float   "fld  tbyte ptr [bp]"\
  330.                 /* compare ST(0) with ST(1) */\
  331.         float   "fcompp"\
  332.                 "push ax"\
  333.                 "mov  bp,sp"\
  334.         float   "fstsw 0[bp]"\
  335.         float   "fwait"\
  336.                 "pop  ax"\
  337.                 "sahf"\
  338.                 "sbb  dx,dx"\
  339.                 "shl  dx,1"\
  340.                 "shl  ah,1"\
  341.                 "shl  ah,1"\
  342.                 "cmc"\
  343.                 "adc  dx,0"\
  344.                 "pop  bp"\
  345.                 parm caller [ax] [dx] value [dx];
  346.   #pragma aux   __LDI4 = \
  347.                 "push bp"\
  348.                 "mov  bp,ax"\
  349.         float   "fld  tbyte ptr [bp]"\
  350.                 "push dx"\
  351.                 "push ax"\
  352.                 "push ax"\
  353.                 "mov  bp,sp"\
  354.         float   "fstcw [bp]"\
  355.         float   "fwait"\
  356.                 "pop  ax"\
  357.                 "push ax"\
  358.                 "or   ah,0x0c"\
  359.                 "mov  2[bp],ax"\
  360.         float   "fldcw 2[bp]"\
  361.         float   "fistp dword ptr 2[bp]"\
  362.         float   "fldcw [bp]"\
  363.                 "pop   ax"\
  364.                 "pop   ax"\
  365.                 "pop   dx"\
  366.                 "pop   bp"\
  367.                 parm caller [ax] value [dx ax];
  368.   #pragma aux   __I4LD = \
  369.                 "push  bp"\
  370.                 "push  dx"\
  371.                 "push  ax"\
  372.                 "mov   bp,sp"\
  373.         float   "fild  dword ptr [bp]"\
  374.                 "pop   ax"\
  375.                 "pop   dx"\
  376.                 "mov   bp,bx"\
  377.         float   "fstp  tbyte ptr [bp]"\
  378.                 "pop   bp"\
  379.                 parm caller [dx ax] [bx];
  380.   #pragma aux   __U4LD = \
  381.                 "push  bp"\
  382.                 "push  ax"\
  383.                 "push  ax"\
  384.                 "push  dx"\
  385.                 "push  ax"\
  386.                 "mov   bp,sp"\
  387.                 "sub   ax,ax"\
  388.                 "mov   4[bp],ax"\
  389.                 "mov   6[bp],ax"\
  390.         float   "fild  qword ptr 2[bp]"\
  391.                 "pop   ax"\
  392.                 "pop   dx"\
  393.                 "pop   ax"\
  394.                 "pop   ax"\
  395.                 "mov   bp,bx"\
  396.         float   "fstp  tbyte ptr [bp]"\
  397.                 "pop   bp"\
  398.                 parm caller [dx ax] [bx];
  399.   #pragma aux   __iFDLD = \
  400.                 "push  bp"\
  401.                 "mov   bp,ax"\
  402.         float   "fld   qword ptr [bp]"\
  403.                 "mov   bp,dx"\
  404.         float   "fstp  tbyte ptr [bp]"\
  405.                 "pop   bp"\
  406.                 parm caller [ax] [dx];
  407.   #pragma aux   __iFSLD = \
  408.                 "push  bp"\
  409.                 "mov   bp,ax"\
  410.         float   "fld   dword ptr [bp]"\
  411.                 "mov   bp,dx"\
  412.         float   "fstp  tbyte ptr [bp]"\
  413.                 "pop   bp"\
  414.                 parm caller [ax] [dx];
  415.   #pragma aux   __iLDFD = \
  416.                 "push  bp"\
  417.                 "mov   bp,ax"\
  418.         float   "fld   tbyte ptr [bp]"\
  419.                 "mov   bp,dx"\
  420.         float   "fstp  qword ptr [bp]"\
  421.                 "pop   bp"\
  422.                 parm caller [ax] [dx];
  423.   #pragma aux   __iLDFS = \
  424.                 "push  bp"\
  425.                 "mov   bp,ax"\
  426.         float   "fld   tbyte ptr [bp]"\
  427.                 "mov   bp,dx"\
  428.         float   "fstp  dword ptr [bp]"\
  429.                 "pop   bp"\
  430.                 parm caller [ax] [dx];
  431.  #else  // floating-point calls
  432.   #pragma aux   __FLDA  "*"  parm caller [ax] [dx] [bx];
  433.   #pragma aux   __FLDS  "*"  parm caller [ax] [dx] [bx];
  434.   #pragma aux   __FLDM  "*"  parm caller [ax] [dx] [bx];
  435.   #pragma aux   __FLDD  "*"  parm caller [ax] [dx] [bx];
  436.   #pragma aux   __LDI4  "*"  parm caller [ax] value [dx ax];
  437.   #pragma aux   __I4LD  "*"  parm caller [dx ax] [bx];
  438.   #pragma aux   __U4LD  "*"  parm caller [dx ax] [bx];
  439.   #pragma aux   __iFDLD "*"  parm caller [ax] [dx];
  440.   #pragma aux   __iFSLD "*"  parm caller [ax] [dx];
  441.   #pragma aux   __iLDFD "*"  parm caller [ax] [dx];
  442.   #pragma aux   __iLDFS "*"  parm caller [ax] [dx];
  443.   #pragma aux   __FLDC  "*"  parm caller [ax] [dx] value [ax];
  444.  #endif
  445. #endif
  446. #endif
  447.  
  448. #ifdef _LONG_DOUBLE_
  449.   // macros to allow old source code names to still work
  450.   #define __FDLD __iFDLD
  451.   #define __FSLD __iFSLD
  452.   #define __LDFD __iLDFD
  453.   #define __LDFS __iLDFS
  454. #endif
  455.  
  456. // define number of significant digits for long double numbers (80-bit)
  457. // it will be defined in float.h as soon as OW support long double
  458. // used in mathlib/c/ldcvt.c
  459.  
  460. #ifdef _LONG_DOUBLE_
  461. #if LDBL_DIG == 15
  462. #undef LDBL_DIG
  463. #define LDBL_DIG        19
  464. #else
  465. #error LDBL_DIG has changed from 15
  466. #endif
  467. #endif
  468.  
  469. // floating point conversion buffer length definition
  470. // used by various floating point conversion routines
  471. // used in clib/startup/c/cvtbuf.c and lib_misc/h/thread.h
  472. // it must be equal maximum FP precision ( LDBL_DIG )
  473.  
  474. #define __FPCVT_BUFFERLEN  19
  475.  
  476. #ifdef __cplusplus
  477. };
  478. #endif
  479. #endif
  480.