1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
|
/***
*trans.h - definitions for computing transcendentals
*
* Copyright (c) 1991-1991, Microsoft Corporation. All rights reserved.
*
*Purpose: Define constants and macros that are used for computing
* transcendentals. Some of the definitions are machine dependent.
* Double is assumed to conform to the IEEE 754 std format.
*
*Revision History:
* 08-14-91 GDP written
* 10-29-91 GDP removed unused prototypes, added _frnd
* 01-20-92 GDP significant changes -- IEEE exc. support
* 03-27-92 GDP put IEEE definitions in fpieee.h
* 03-31-92 GDP add internal constants for _ctrlfp, _statfp
* 05-08-92 PLM added M68K switch
* 05-18-92 XY added exception macro under M68K switch
* 06-23-92 GDP added macro for negative zero
* 09-06-92 GDP include cruntime.h, calling convention macros
* 07-16-93 SRW ALPHA Merge
* 01-13-94 RDL Added #ifndef _LANGUAGE_ASSEMBLY for asm includes.
* 10-02-94 BWT PPC merge
*
*******************************************************************************/
#ifndef _INC_TRANS
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _LANGUAGE_ASSEMBLY
#include <cruntime.h>
/*
* Conditional macro definition for function calling type and variable type
* qualifiers.
*/
#if ( (_MSC_VER >= 800) && (_M_IX86 >= 300) )
/*
* Definitions for MS C8-32 (386/486) compiler
*/
#define _CRTAPI1 __cdecl
#define _CRTAPI2 __cdecl
#elif ( _MSC_VER == 600 )
/*
* Definitions for old MS C6-386 compiler
*/
#define _CRTAPI1 _cdecl
#define _CRTAPI2 _cdecl
#define _CRTVAR1 _cdecl
#define _M_IX86 300
#else
/*
* Other compilers (e.g., MIPS)
*/
#define _CRTAPI1
#define _CRTAPI2
#define _CRTVAR1
#endif
#include <fpieee.h>
#define D_BIASM1 0x3fe /* off by one to compensate for the implied bit */
#ifdef B_END
/* big endian */
#define D_EXP(x) ((unsigned short *)&(x))
#define D_HI(x) ((unsigned long *)&(x))
#define D_LO(x) ((unsigned long *)&(x)+1)
#else
#define D_EXP(x) ((unsigned short *)&(x)+3)
#define D_HI(x) ((unsigned long *)&(x)+1)
#define D_LO(x) ((unsigned long *)&(x))
#endif
/* return the int representation of the exponent
* if x = .f * 2^n, 0.5<=f<1, return n (unbiased)
* e.g. INTEXP(3.0) == 2
*/
#define INTEXP(x) ((signed short)((*D_EXP(x) & 0x7ff0) >> 4) - D_BIASM1)
/* check for infinity, NAN */
#define D_ISINF(x) ((*D_HI(x) & 0x7fffffff) == 0x7ff00000 && *D_LO(x) == 0)
#define IS_D_SPECIAL(x) ((*D_EXP(x) & 0x7ff0) == 0x7ff0)
#define IS_D_NAN(x) (IS_D_SPECIAL(x) && !D_ISINF(x))
#ifdef _M_MRX000
#define IS_D_SNAN(x) ((*D_EXP(x) & 0x7ff8) == 0x7ff8)
#define IS_D_QNAN(x) ((*D_EXP(x) & 0x7ff8) == 0x7ff0 && \
(*D_HI(x) << 13 || *D_LO(x)))
#else
#define IS_D_QNAN(x) ((*D_EXP(x) & 0x7ff8) == 0x7ff8)
#define IS_D_SNAN(x) ((*D_EXP(x) & 0x7ff8) == 0x7ff0 && \
(*D_HI(x) << 13 || *D_LO(x)))
#endif
#define IS_D_DENORM(x) ((*D_EXP(x) & 0x7ff0) == 0 && \
(*D_HI(x) << 12 || *D_LO(x)))
#define IS_D_INF(x) (*D_HI(x) == 0x7ff00000 && *D_LO(x) == 0)
#define IS_D_MINF(x) (*D_HI(x) == 0xfff00000 && *D_LO(x) == 0)
#ifdef _M_MRX000
#define D_IND_HI 0x7ff7ffff
#define D_IND_LO 0xffffffff
#else
#define D_IND_HI 0xfff80000
#define D_IND_LO 0x0
#endif
typedef union {
long lng[2];
double dbl;
} _dbl;
extern _dbl _d_inf;
extern _dbl _d_ind;
extern _dbl _d_max;
extern _dbl _d_min;
extern _dbl _d_mzero;
#define D_INF (_d_inf.dbl)
#define D_IND (_d_ind.dbl)
#define D_MAX (_d_max.dbl)
#define D_MIN (_d_min.dbl)
#define D_MZERO (_d_mzero.dbl) /* minus zero */
/* min and max exponents for normalized numbers in the
* form: 0.xxxxx... * 2^exp (NOT 1.xxxx * 2^exp !)
*/
#define MAXEXP 1024
#define MINEXP -1021
#endif /* _LANGUAGE_ASSEMBLY */
#if defined(_M_IX86)
/* Control word for computation of transcendentals */
#define ICW 0x133f
#define IMCW 0xffff
#define IMCW_EM 0x003f /* interrupt Exception Masks */
#define IEM_INVALID 0x0001 /* invalid */
#define IEM_DENORMAL 0x0002 /* denormal */
#define IEM_ZERODIVIDE 0x0004 /* zero divide */
#define IEM_OVERFLOW 0x0008 /* overflow */
#define IEM_UNDERFLOW 0x0010 /* underflow */
#define IEM_INEXACT 0x0020 /* inexact (precision) */
#define IMCW_RC 0x0c00 /* Rounding Control */
#define IRC_CHOP 0x0c00 /* chop */
#define IRC_UP 0x0800 /* up */
#define IRC_DOWN 0x0400 /* down */
#define IRC_NEAR 0x0000 /* near */
#define ISW_INVALID 0x0001 /* invalid */
#define ISW_DENORMAL 0x0002 /* denormal */
#define ISW_ZERODIVIDE 0x0004 /* zero divide */
#define ISW_OVERFLOW 0x0008 /* overflow */
#define ISW_UNDERFLOW 0x0010 /* underflow */
#define ISW_INEXACT 0x0020 /* inexact (precision) */
#define IMCW_PC 0x0300 /* Precision Control */
#define IPC_24 0x0000 /* 24 bits */
#define IPC_53 0x0200 /* 53 bits */
#define IPC_64 0x0300 /* 64 bits */
#define IMCW_IC 0x1000 /* Infinity Control */
#define IIC_AFFINE 0x1000 /* affine */
#define IIC_PROJECTIVE 0x0000 /* projective */
#elif defined(_M_MRX000)
#define ICW 0x00000f80 /* Internal CW for transcendentals */
#define IMCW 0xffffff83 /* Internal CW Mask */
#define IMCW_EM 0x00000f80 /* interrupt Exception Masks */
#define IEM_INVALID 0x00000800 /* invalid */
#define IEM_ZERODIVIDE 0x00000400 /* zero divide */
#define IEM_OVERFLOW 0x00000200 /* overflow */
#define IEM_UNDERFLOW 0x00000100 /* underflow */
#define IEM_INEXACT 0x00000080 /* inexact (precision) */
#define IMCW_RC 0x00000003 /* Rounding Control */
#define IRC_CHOP 0x00000001 /* chop */
#define IRC_UP 0x00000002 /* up */
#define IRC_DOWN 0x00000003 /* down */
#define IRC_NEAR 0x00000000 /* near */
#define ISW_INVALID (1<<6) /* invalid */
#define ISW_ZERODIVIDE (1<<5) /* zero divide */
#define ISW_OVERFLOW (1<<4) /* overflow */
#define ISW_UNDERFLOW (1<<3) /* underflow */
#define ISW_INEXACT (1<<2) /* inexact (precision) */
#elif defined(_M_ALPHA)
//
// ICW is the Internal Control Word for transcendentals: all five exceptions
// are masked and round to nearest mode is set. IMCW is the mask: all bits
// are set, except for the ISW bits.
//
#define ICW (IEM_INEXACT | IEM_UNDERFLOW | IEM_OVERFLOW | IEM_ZERODIVIDE | IEM_INVALID | IRC_NEAR)
#define ISW (ISW_INEXACT | ISW_UNDERFLOW | ISW_OVERFLOW | ISW_ZERODIVIDE | ISW_INVALID)
#define IMCW (0xffffffff ^ ISW)
//
// The defines for the internal control word match the format of the Alpha
// AXP software FPCR except for the rounding mode which is obtained from the
// Alpha AXP hardware FPCR and shifted right 32 bits.
//
//
// Internal Exception Mask bits.
// Each bit _disables_ an exception (they are not _enable_ bits).
//
#define IMCW_EM 0x0000003e /* interrupt Exception Masks */
#define IEM_INEXACT 0x00000020 /* inexact (precision) */
#define IEM_UNDERFLOW 0x00000010 /* underflow */
#define IEM_OVERFLOW 0x00000008 /* overflow */
#define IEM_ZERODIVIDE 0x00000004 /* zero divide */
#define IEM_INVALID 0x00000002 /* invalid */
//
// Internal Rounding Control values.
//
#define IMCW_RC (0x3 << 26) /* Rounding Control */
#define IRC_CHOP (0x0 << 26) /* chop */
#define IRC_DOWN (0x1 << 26) /* down */
#define IRC_NEAR (0x2 << 26) /* near */
#define IRC_UP (0x3 << 26) /* up */
//
// Internal Status Word bits.
//
#define ISW_INEXACT 0x00200000 /* inexact (precision) */
#define ISW_UNDERFLOW 0x00100000 /* underflow */
#define ISW_OVERFLOW 0x00080000 /* overflow */
#define ISW_ZERODIVIDE 0x00040000 /* zero divide */
#define ISW_INVALID 0x00020000 /* invalid */
#elif defined(_M_PPC)
#define IMCW_EM 0x000000f8 /* Exception Enable Mask */
#define IEM_INVALID 0x00000080 /* invalid */
#define IEM_OVERFLOW 0x00000040 /* overflow */
#define IEM_UNDERFLOW 0x00000020 /* underflow */
#define IEM_ZERODIVIDE 0x00000010 /* zero divide */
#define IEM_INEXACT 0x00000008 /* inexact (precision) */
#define IMCW_RC 0x00000003 /* Rounding Control Mask */
#define IRC_NEAR 0x00000000 /* near */
#define IRC_CHOP 0x00000001 /* chop */
#define IRC_UP 0x00000002 /* up */
#define IRC_DOWN 0x00000003 /* down */
#define IMCW_SW 0x3E000000 /* Status Mask */
#define ISW_INVALID 0x20000000 /* invalid summary */
#define ISW_OVERFLOW 0x10000000 /* overflow */
#define ISW_UNDERFLOW 0x08000000 /* underflow */
#define ISW_ZERODIVIDE 0x04000000 /* zero divide */
#define ISW_INEXACT 0x02000000 /* inexact (precision) */
#define IMCW_VX 0x01F80100 /* Invalid Cause Mask */
#define IVX_SNAN 0x01000000 /* SNaN */
#define IVX_ISI 0x00800000 /* infinity - infinity */
#define IVX_IDI 0x00400000 /* infinity / infinity */
#define IVX_ZDZ 0x00200000 /* zero / zero */
#define IVX_IMZ 0x00100000 /* infinity * zero */
#define IVX_VC 0x00080000 /* inv flpt compare */
#define IVX_CVI 0x00000100 /* inv integer convert */
/* Internal CW for transcendentals */
#define ICW (IMCW_EM)
/* Internal CW Mask (non-status bits) */
#define IMCW (0xffffffff & (~(IMCW_SW|IMCW_VX)))
#endif
#ifndef _LANGUAGE_ASSEMBLY
#define RETURN(fpcw,result) return _rstorfp(fpcw),(result)
#define RETURN_INEXACT1(op,arg1,res,cw) \
if (cw & IEM_INEXACT) { \
_rstorfp(cw); \
return res; \
} \
else { \
return _except1(FP_P, op, arg1, res, cw); \
}
#define RETURN_INEXACT2(op,arg1,arg2,res,cw) \
if (cw & IEM_INEXACT) { \
_rstorfp(cw); \
return res; \
} \
else { \
return _except2(FP_P, op, arg1, arg2, res, cw); \
}
#ifdef _M_ALPHA
//
// Since fp32 is not compiled in IEEE exception mode perform Alpha NaN
// propagation in software to avoid hardware/kernel trap involvement.
//
extern double _nan2qnan(double);
#define _d_snan2(x,y) _nan2qnan(y)
#define _s2qnan(x) _nan2qnan(x)
#else
//handle NaN propagation
#define _d_snan2(x,y) ((x)+(y))
#define _s2qnan(x) ((x)+1.0)
#endif
#define _maskfp() _ctrlfp(ICW, IMCW)
#ifdef _ALPHA_
#define _rstorfp(cw) 0
#else
#define _rstorfp(cw) _ctrlfp(cw, IMCW)
#endif
#define ABS(x) ((x)<0 ? -(x) : (x) )
int _d_inttype(double);
#endif /* _LANGUAGE_ASSEMBLY */
#define _D_NOINT 0
#define _D_ODD 1
#define _D_EVEN 2
// IEEE exceptions
#define FP_O 0x01
#define FP_U 0x02
#define FP_Z 0x04
#define FP_I 0x08
#define FP_P 0x10
// An extra flag for matherr support
// Set together with FP_I from trig functions when the argument is too large
#define FP_TLOSS 0x20
#ifndef _LANGUAGE_ASSEMBLY
#ifdef B_END
#define SET_DBL(msw, lsw) msw, lsw
#else
#define SET_DBL(msw, lsw) lsw, msw
#endif
#endif /* _LANGUAGE_ASSEMBLY */
// special types
#define T_PINF 1
#define T_NINF 2
#define T_QNAN 3
#define T_SNAN 4
// exponent adjustment for IEEE overflow/underflow exceptions
// used before passing the result to the trap handler
#define IEEE_ADJUST 1536
// QNAN values
#define INT_NAN (~0)
#define QNAN_SQRT D_IND
#define QNAN_LOG D_IND
#define QNAN_LOG10 D_IND
#define QNAN_POW D_IND
#define QNAN_SINH D_IND
#define QNAN_COSH D_IND
#define QNAN_TANH D_IND
#define QNAN_SIN1 D_IND
#define QNAN_SIN2 D_IND
#define QNAN_COS1 D_IND
#define QNAN_COS2 D_IND
#define QNAN_TAN1 D_IND
#define QNAN_TAN2 D_IND
#define QNAN_ACOS D_IND
#define QNAN_ASIN D_IND
#define QNAN_ATAN2 D_IND
#define QNAN_CEIL D_IND
#define QNAN_FLOOR D_IND
#define QNAN_MODF D_IND
#define QNAN_LDEXP D_IND
#define QNAN_FMOD D_IND
#define QNAN_FREXP D_IND
/*
* Function prototypes
*/
#ifndef _LANGUAGE_ASSEMBLY
double _copysign(double x, double y);
double _set_exp(double x, int exp);
double _set_bexp(double x, int exp);
double _add_exp(double x, int exp);
double _frnd(double);
double _fsqrt(double);
/* Must have these declarations (or a suitable macro) or the C implementations
* of a great many FP functions fail badly when there is an exception */
#ifndef _except1
double _except1(int flags, int opcode, double arg, double res, unsigned int cw);
#endif
#ifndef _except2
double _except2(int flags, int opcode, double arg1, double arg2, double res, unsigned int cw);
#endif
int _sptype(double);
int _get_exp(double);
double _decomp(double, int *);
int _powhlp(double x, double y, double * result);
extern unsigned int _fpstatus;
double _frnd(double);
double _exphlp(double, int *);
double _handle_qnan1(unsigned int op, double arg, unsigned int cw);
double _handle_qnan2(unsigned int op,double arg1,double arg2,unsigned int cw);
unsigned int _clhwfp(void);
unsigned int _setfpcw(unsigned int);
int _errcode(unsigned int flags);
void _set_errno(int matherrtype);
int _handle_exc(unsigned int flags, double * presult, unsigned int cw);
unsigned int _clrfp(void);
unsigned int _ctrlfp(unsigned int,unsigned int);
unsigned int _statfp(void);
void _set_statfp(unsigned int);
#endif /* _LANGUAGE_ASSEMBLY */
#ifdef __cplusplus
}
#endif
#define _INC_TRANS
#endif /* _INC_TRANS */
|