Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
548 serge 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      // for wchar_t
36
#include       // 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