summaryrefslogblamecommitdiffstats
path: root/private/fp32/include/cv.h
blob: 0455b424dc3e942f4d7805ec1e803051ec24f961 (plain) (tree)
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
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531


















































































































































































































































































































































































































































































































































                                                                                      
/***
*cv.h - definitions for floating point conversion
*
*	Copyright (c) 1991-1991, Microsoft Corporation.	All rights reserved.
*
*Purpose:
*   define types, macros, and constants used in floating point
*   conversion routines
*
*Revision History:
*   7-17-91	GDP	initial version
*   9-21-91	GDP	restructured 'ifdef' directives
*  10-29-91	GDP	MIPS port: new defs for ALIGN and DOUBLE
*   3-03-92	GDP	removed os2 16-bit stuff
*   4-30-92	GDP	support intrncvt.c --cleanup and reorganize
*   5-13-92	XY	fixed B_END macros
*   6-16-92	GDP	merged changes from \\orville and \\vangogh trees
*   9-05-92	GDP	included fltintrn.h, new calling convention macros
*   07-16-93    SRW     ALPHA Merge
*   10-02-94    BWT     PPC merge
*
*******************************************************************************/
#ifndef _INC_CV

#ifdef __cplusplus
extern "C" {
#endif

#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

/*
 * For MIPS and Alpha, define DOUBLE as 'double'
 * so that the definition in fltintrn.h is not used.
 * This is done because floating point arguments are passed in the
 * fp register.
 */

#if	defined(_M_MRX000) || defined(_M_ALPHA) || defined(_M_PPC)
#define DOUBLE double
#endif
#include <fltintrn.h>




/* define little endian or big endian memory */

#ifdef i386
#define L_END
#endif

#if	defined(_M_MRX000) || defined(_M_ALPHA) || defined(_M_PPC)
#define L_END
#endif

typedef unsigned char	u_char;   /* should have 1 byte	*/
typedef char		s_char;   /* should have 1 byte	*/
typedef unsigned short	u_short;  /* should have 2 bytes */
typedef signed short	s_short;  /* should have 2 bytes */
typedef unsigned int	u_long;	  /* sholuld have 4 bytes */
typedef int		s_long;	  /* sholuld have 4 bytes */

/* calling conventions */
#define _CALLTYPE5


/*
 * defining _LDSUPPORT enables using long double computations
 * for string conversion. We do not do this even for i386,
 * since we want to avoid using floating point code that
 * may generate IEEE exceptions.
 *
 * Currently our string conversion routines do not conform
 * to the special requirements of the IEEE standard for
 * floating point conversions
 */


#ifndef _LDSUPPORT

#pragma pack(4)
typedef struct {
    u_char ld[10];
} _LDOUBLE;
#pragma pack()

#define PTR_LD(x) ((u_char  *)(&(x)->ld))

#else

typedef long double _LDOUBLE;

#define PTR_LD(x) ((u_char  *)(x))

#endif


#pragma pack(4)
typedef struct {
    u_char ld12[12];
} _LDBL12;
#pragma pack()

typedef struct {
    float f;
} FLOAT;



/*
 * return values for internal conversion routines
 * (12-byte to long double, double, or float)
 */

typedef enum {
    INTRNCVT_OK,
    INTRNCVT_OVERFLOW,
    INTRNCVT_UNDERFLOW
} INTRNCVT_STATUS;


/*
 * return values for strgtold12 routine
 */

#define SLD_UNDERFLOW 1
#define SLD_OVERFLOW 2
#define SLD_NODIGITS 4

#define MAX_MAN_DIGITS 21


/* specifies '%f' format */

#define SO_FFORMAT 1

typedef  struct _FloatOutStruct {
		    short   exp;
		    char    sign;
		    char    ManLen;
		    char    man[MAX_MAN_DIGITS+1];
		    } FOS;



#define PTR_12(x) ((u_char  *)(&(x)->ld12))

#define MAX_USHORT  ((u_short)0xffff)
#define MSB_USHORT  ((u_short)0x8000)
#define MAX_ULONG   ((u_long)0xffffffff)
#define MSB_ULONG   ((u_long)0x80000000)

#define TMAX10 5200	  /* maximum temporary decimal exponent */
#define TMIN10 -5200	  /* minimum temporary decimal exponent */
#define LD_MAX_EXP_LEN 4  /* maximum number of decimal exponent digits */
#define LD_MAX_MAN_LEN 24  /* maximum length of mantissa (decimal)*/
#define LD_MAX_MAN_LEN1 25 /* MAX_MAN_LEN+1 */

#define LD_BIAS	0x3fff	  /* exponent bias for long double */
#define LD_BIASM1 0x3ffe  /* LD_BIAS - 1 */
#define LD_MAXEXP 0x7fff  /* maximum biased exponent */

#define D_BIAS	0x3ff	 /* exponent bias for double */
#define D_BIASM1 0x3fe	/* D_BIAS - 1 */
#define D_MAXEXP 0x7ff	/* maximum biased exponent */


#ifdef M68K
typedef struct _fltl		    /* used by _fltinl */
	  {
	    int flags;
	    int nbytes; 	    /* number of characters read */
	    long lval;
	    _LDOUBLE ldval;	    /* the returned floating point number */
	  }
	    *FLTL;
#endif


#ifdef M68K
char *_clftole(long double *, char *, int, int);
char *_clftolf(long double *, char *, int);
char * _CALLTYPE2 _clftolg(long double *, char *, int, int);
void _CALLTYPE2 _cldcvt( long double *, char *, int, int, int);
#endif


#ifndef	MTHREAD
#ifdef M68K
FLTL _CALLTYPE2 _fltinl( const char *, int, int, int);
STRFLT _CALLTYPE2 _lfltout(long double);

#define _IS_MAN_IND(signbit, manhi, manlo) \
	((signbit) && (manhi)==0xc0000000 && (manlo)==0)

#define _IS_MAN_QNAN(signbit, manhi, manlo) \
	( (manhi)&NAN_BIT )

#define _IS_MAN_SNAN(signbit, manhi, manlo) \
	(!( _IS_MAN_INF(signbit, manhi, manlo) || \
	   _IS_MAN_QNAN(signbit, manhi, manlo) ))

#endif
#endif


/*
 * end of definitions from crt32\h\fltintrn.h
 */




/* Recognizing special patterns in the mantissa field */
#define _EXP_SP  0x7fff
#define NAN_BIT (1<<30)

#define _IS_MAN_INF(signbit, manhi, manlo) \
	( (manhi)==MSB_ULONG && (manlo)==0x0 )


// i386 and Alpha use same NaN format

#if defined(_M_IX86) || defined(_M_ALPHA)

#define _IS_MAN_IND(signbit, manhi, manlo) \
	((signbit) && (manhi)==0xc0000000 && (manlo)==0)

#define _IS_MAN_QNAN(signbit, manhi, manlo) \
	( (manhi)&NAN_BIT )

#define _IS_MAN_SNAN(signbit, manhi, manlo) \
	(!( _IS_MAN_INF(signbit, manhi, manlo) || \
	   _IS_MAN_QNAN(signbit, manhi, manlo) ))


#elif defined(_M_MRX000) || defined(_M_PPC)

#define _IS_MAN_IND(signbit, manhi, manlo) \
	(!(signbit) && (manhi)==0xbfffffff && (manlo)==0xfffff800)

#define _IS_MAN_SNAN(signbit, manhi, manlo) \
	( (manhi)&NAN_BIT )

#define _IS_MAN_QNAN(signbit, manhi, manlo) \
	(!( _IS_MAN_INF(signbit, manhi, manlo) || \
	   _IS_MAN_SNAN(signbit, manhi, manlo) ))
#endif



#if defined (L_END) && !( defined(_M_MRX000) || defined(_M_ALPHA) || defined(_M_PPC) )
/* "little endian" memory */
/* Note: MIPS and Alpha have alignment requirements and have different macros */
/*
 * Manipulation of a 12-byte long double number (an ordinary
 * 10-byte long double plus two extra bytes of mantissa).
 */
/*
 * byte layout:
 *
 *		+-----+--------+--------+-------+
 *		|XT(2)|MANLO(4)|MANHI(4)|EXP(2) |
 *              +-----+--------+--------+-------+
 *              |<-UL_LO->|<-UL_MED->|<-UL_HI ->|
 *                  (4)       (4)        (4)
 */

/* a pointer to the exponent/sign portion */
#define U_EXP_12(p) ((u_short  *)(PTR_12(p)+10))

/* a pointer to the 4 hi-order bytes of the mantissa */
#define UL_MANHI_12(p) ((u_long  *)(PTR_12(p)+6))

/* a pointer to the 4 lo-order bytes of the ordinary (8-byte) mantissa */
#define UL_MANLO_12(p) ((u_long  *)(PTR_12(p)+2))

/* a pointer to the 2 extra bytes of the mantissa */
#define U_XT_12(p) ((u_short  *)PTR_12(p))

/* a pointer to the 4 lo-order bytes of the extended (10-byte) mantissa */
#define UL_LO_12(p) ((u_long  *)PTR_12(p))

/* a pointer to the 4 mid-order bytes of the extended (10-byte) mantissa */
#define UL_MED_12(p) ((u_long  *)(PTR_12(p)+4))

/* a pointer to the 4 hi-order bytes of the extended long double */
#define UL_HI_12(p) ((u_long  *)(PTR_12(p)+8))

/* a pointer to the byte of order i (LSB=0, MSB=9)*/
#define UCHAR_12(p,i) ((u_char	*)PTR_12(p)+(i))

/* a pointer to a u_short with offset i */
#define USHORT_12(p,i) ((u_short  *)((u_char  *)PTR_12(p)+(i)))

/* a pointer to a u_long with offset i */
#define ULONG_12(p,i) ((u_long	*)((u_char  *)PTR_12(p)+(i)))

/* a pointer to the 10 MSBytes of a 12-byte long double */
#define TEN_BYTE_PART(p) ((u_char  *)PTR_12(p)+2)

/*
 * Manipulation of a 10-byte long double number
 */
#define U_EXP_LD(p) ((u_short  *)(PTR_LD(p)+8))
#define UL_MANHI_LD(p) ((u_long  *)(PTR_LD(p)+4))
#define UL_MANLO_LD(p) ((u_long  *)PTR_LD(p))

/*
 * Manipulation of a 64bit IEEE double
 */
#define U_SHORT4_D(p) ((u_short  *)(p) + 3)
#define UL_HI_D(p) ((u_long  *)(p) + 1)
#define UL_LO_D(p) ((u_long  *)(p))

#endif

/* big endian */
#if defined (B_END)

/*
 * byte layout:
 *
 *		+------+-------+---------+------+
 *		|EXP(2)|MANHI(4)|MANLO(4)|XT(2) |
 *              +------+-------+---------+------+
 *              |<-UL_HI->|<-UL_MED->|<-UL_LO ->|
 *                  (4)       (4)        (4)
 */


#define U_EXP_12(p) ((u_short  *)PTR_12(p))
#define UL_MANHI_12(p) ((u_long  *)(PTR_12(p)+2))
#define UL_MANLO_12(p) ((u_long  *)(PTR_12(p)+6))
#define U_XT_12(p) ((u_short  *)(PTR_12(p)+10))

#define UL_LO_12(p) ((u_long  *)(PTR_12(p)+8))
#define UL_MED_12(p) ((u_long  *)(PTR_12(p)+4))
#define UL_HI_12(p) ((u_long  *)PTR_12(p))

#define UCHAR_12(p,i) ((u_char	*)PTR_12(p)+(11-(i)))
#define USHORT_12(p,i)	((u_short  *)((u_char  *)PTR_12(p)+10-(i)))
#define ULONG_12(p,i) ((u_long	*)((u_char  *)PTR_12(p)+8-(i)))
#define TEN_BYTE_PART(p) (u_char  *)PTR_12(p)

#define U_EXP_LD(p) ((u_short  *)PTR_LD(p))
#define UL_MANHI_LD(p) ((u_long  *)(PTR_LD(p)+2))
#define UL_MANLO_LD(p) ((u_long  *)(PTR_LD(p)+6))

/*
 * Manipulation of a 64bit IEEE double
 */
#define U_SHORT4_D(p) ((u_short  *)(p))
#define UL_HI_D(p) ((u_long  *)(p))
#define UL_LO_D(p) ((u_long  *)(p) + 1)

#endif

#if	defined(_M_MRX000) || defined(_M_ALPHA) || defined(_M_PPC)

#define ALIGN(x)  ( (unsigned long  __unaligned *) (x))

#define U_EXP_12(p) ((u_short  *)(PTR_12(p)+10))

#define UL_MANHI_12(p) ((u_long  __unaligned *) (PTR_12(p)+6) )
#define UL_MANLO_12(p) ((u_long  __unaligned *) (PTR_12(p)+2) )


#define U_XT_12(p) ((u_short  *)PTR_12(p))
#define UL_LO_12(p) ((u_long  *)PTR_12(p))
#define UL_MED_12(p) ((u_long  *)(PTR_12(p)+4))
#define UL_HI_12(p) ((u_long  *)(PTR_12(p)+8))

/* the following 3 macros do not take care of proper alignment */
#define UCHAR_12(p,i) ((u_char	*)PTR_12(p)+(i))
#define USHORT_12(p,i) ((u_short  *)((u_char  *)PTR_12(p)+(i)))
#define ULONG_12(p,i) ((u_long	*) ((u_char  *)PTR_12(p)+(i) ))

#define TEN_BYTE_PART(p) ((u_char  *)PTR_12(p)+2)

/*
 * Manipulation of a 10-byte long double number
 */
#define U_EXP_LD(p) ((u_short  *)(PTR_LD(p)+8))

#define UL_MANHI_LD(p) ((u_long  *) (PTR_LD(p)+4) )
#define UL_MANLO_LD(p) ((u_long  *) PTR_LD(p) )

/*
 * Manipulation of a 64bit IEEE double
 */
#define U_SHORT4_D(p) ((u_short  *)(p) + 3)
#define UL_HI_D(p) ((u_long  *)(p) + 1)
#define UL_LO_D(p) ((u_long  *)(p))

#endif


#define PUT_INF_12(p,sign) \
		  *UL_HI_12(p) = (sign)?0xffff8000:0x7fff8000; \
		  *UL_MED_12(p) = 0; \
		  *UL_LO_12(p) = 0;

#define PUT_ZERO_12(p) *UL_HI_12(p) = 0; \
		  *UL_MED_12(p) = 0; \
		  *UL_LO_12(p) = 0;

#define ISZERO_12(p) ((*UL_HI_12(p)&0x7fffffff) == 0 && \
		      *UL_MED_12(p) == 0 && \
		      *UL_LO_12(p) == 0 )

#define PUT_INF_LD(p,sign) \
		  *U_EXP_LD(p) = (sign)?0xffff:0x7fff; \
		  *UL_MANHI_LD(p) = 0x8000; \
		  *UL_MANLO_LD(p) = 0;

#define PUT_ZERO_LD(p) *U_EXP_LD(p) = 0; \
		  *UL_MANHI_LD(p) = 0; \
		  *UL_MANLO_LD(p) = 0;

#define ISZERO_LD(p) ((*U_EXP_LD(p)&0x7fff) == 0 && \
		      *UL_MANHI_LD(p) == 0 && \
		      *UL_MANLO_LD(p) == 0 )


/*********************************************************
 *
 *   Function Prototypes
 *
 *********************************************************/

/* from mantold.c */
void _CALLTYPE5 __mtold12(char	*manptr, unsigned manlen,_LDBL12 *ld12);
int  _CALLTYPE5 __addl(u_long x, u_long y, u_long  *sum);
void _CALLTYPE5 __shl_12(_LDBL12  *ld12);
void _CALLTYPE5 __shr_12(_LDBL12  *ld12);
void _CALLTYPE5 __add_12(_LDBL12  *x, _LDBL12  *y);

/* from tenpow.c */
void _CALLTYPE5 __multtenpow12(_LDBL12	*pld12,int pow, unsigned mult12);
void _CALLTYPE5 __ld12mul(_LDBL12  *px, _LDBL12  *py);

/* from strgtold.c */
unsigned int __strgtold12(_LDBL12 *pld12,
	    const char * *p_end_ptr,
	    const char * str,
	    int mult12,
	    int scale,
	    int decpt,
	    int implicit_E);

unsigned _CALLTYPE5 __STRINGTOLD(_LDOUBLE *pld,
	    const char	* *p_end_ptr,
	    const char	*str,
	    int mult12);


/* from x10fout.c */
/* this is defined as void in convert.h
 * After porting the asm files to c, we need a return value for
 * i10_output, that used to reside in reg. ax
 */
int _CALLTYPE5	$I10_OUTPUT(_LDOUBLE ld, int ndigits,
		    unsigned output_flags, FOS	*fos);


/* for cvt.c and fltused.c */
/* The following functions are #defined as macros in fltintrn.h */
#undef _cfltcvt
#undef _cropzeros
#undef _fassign
#undef _forcdecpt
#undef _positive

void _CALLTYPE2 _cfltcvt(double *arg, char *buffer,
			 int format, int precision,
			 int caps);
void _CALLTYPE2 _cropzeros(char *buf);
void _CALLTYPE2 _fassign(int flag, char  *argument, char *number);
void _CALLTYPE2 _forcdecpt(char *buf);
int _CALLTYPE2 _positive(double *arg);

/* from intrncvt.c */
void _atodbl(DOUBLE *d, char *str);
void _atoldbl(_LDOUBLE *ld, char *str);
void _atoflt(FLOAT *f, char *str);
INTRNCVT_STATUS _ld12tod(_LDBL12 *ifp, DOUBLE *d);
INTRNCVT_STATUS _ld12tof(_LDBL12 *ifp, FLOAT *f);
INTRNCVT_STATUS _ld12told(_LDBL12 *ifp, _LDOUBLE *ld);



#ifdef __cplusplus
}
#endif

#define _INC_CV
#endif	/* _INC_CV */