|
|
1.1 root 1:
2: /*============================================================================
3:
4: This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
5: Package, Release 2b.
6:
7: Written by John R. Hauser. This work was made possible in part by the
8: International Computer Science Institute, located at Suite 600, 1947 Center
9: Street, Berkeley, California 94704. Funding was partially provided by the
10: National Science Foundation under grant MIP-9311980. The original version
11: of this code was written as part of a project to build a fixed-point vector
12: processor in collaboration with the University of California at Berkeley,
13: overseen by Profs. Nelson Morgan and John Wawrzynek. More information
14: is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
15: arithmetic/SoftFloat.html'.
16:
17: THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
18: been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
19: RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
20: AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
21: COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
22: EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
23: INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
24: OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
25:
26: Derivative works are acceptable, even for commercial purposes, so long as
27: (1) the source code for the derivative work includes prominent notice that
28: the work is derivative, and (2) the source code includes prominent notice with
29: these four paragraphs for those parts of this code that are retained.
30:
31: =============================================================================*/
32:
33: #ifndef SOFTFLOAT_H
34: #define SOFTFLOAT_H
35: /*----------------------------------------------------------------------------
36: | The macro `FLOATX80' must be defined to enable the extended double-precision
37: | floating-point format `floatx80'. If this macro is not defined, the
38: | `floatx80' type will not be defined, and none of the functions that either
39: | input or output the `floatx80' type will be defined. The same applies to
40: | the `FLOAT128' macro and the quadruple-precision format `float128'.
41: *----------------------------------------------------------------------------*/
42: #define FLOATX80
43: #define FLOAT128
44:
45: /*----------------------------------------------------------------------------
46: | Software IEC/IEEE floating-point types.
47: *----------------------------------------------------------------------------*/
48:
49: #include "mamesf.h"
50:
51: typedef bits32 float32;
52: typedef bits64 float64;
53: #ifdef FLOATX80
54: typedef struct {
55: bits16 high;
56: bits64 low;
57: } floatx80;
58: #endif
59: #ifdef FLOAT128
60: typedef struct {
61: bits64 high, low;
62: } float128;
63: #endif
64:
65: /*----------------------------------------------------------------------------
66: | Primitive arithmetic functions, including multi-word arithmetic, and
67: | division and square root approximations. (Can be specialized to target if
68: | desired.)
69: *----------------------------------------------------------------------------*/
70: #include "softfloat-macros.h"
71:
72: /*----------------------------------------------------------------------------
73: | Software IEC/IEEE floating-point underflow tininess-detection mode.
74: *----------------------------------------------------------------------------*/
75: extern int8 float_detect_tininess;
76: enum {
77: float_tininess_after_rounding = 0,
78: float_tininess_before_rounding = 1
79: };
80:
81: /*----------------------------------------------------------------------------
82: | Software IEC/IEEE floating-point rounding mode.
83: *----------------------------------------------------------------------------*/
84: extern int8 float_rounding_mode;
85: #ifdef SOFTFLOAT_I860
86: extern int8 float_rounding_mode2;
87: #endif
88: enum {
89: float_round_nearest_even = 0,
90: float_round_to_zero = 1,
91: float_round_down = 2,
92: float_round_up = 3
93: };
94:
95: /*----------------------------------------------------------------------------
96: | Software IEC/IEEE floating-point exception flags.
97: *----------------------------------------------------------------------------*/
98: extern int8 float_exception_flags;
99: #ifdef SOFTFLOAT_I860
100: extern int8 float_exception_flags2;
101: #endif
102: enum {
103: float_flag_invalid = 0x01, float_flag_denormal = 0x02, float_flag_divbyzero = 0x04, float_flag_overflow = 0x08,
104: float_flag_underflow = 0x10, float_flag_inexact = 0x20, float_flag_signaling = 0x40, float_flag_decimal = 0x80
105: };
106:
107: /*----------------------------------------------------------------------------
108: | Variables for storing sign, exponent and significand of internal extended
109: | double-precision floating-point value for external use.
110: *----------------------------------------------------------------------------*/
111: extern flag floatx80_internal_sign;
112: extern int32 floatx80_internal_exp;
113: extern bits64 floatx80_internal_sig0;
114: extern bits64 floatx80_internal_sig1;
115: extern int8 floatx80_internal_precision;
116: extern int8 floatx80_internal_mode;
117:
118: /*----------------------------------------------------------------------------
119: | Function for getting sign, exponent and significand of extended
120: | double-precision floating-point intermediate result for external use.
121: *----------------------------------------------------------------------------*/
122: floatx80 getFloatInternalOverflow( void );
123: floatx80 getFloatInternalUnderflow( void );
124: floatx80 getFloatInternalRoundedAll( void );
125: floatx80 getFloatInternalRoundedSome( void );
126: floatx80 getFloatInternalUnrounded( void );
127: floatx80 getFloatInternalFloatx80( void );
128: bits64 getFloatInternalGRS( void );
129:
130: /*----------------------------------------------------------------------------
131: | Routine to raise any or all of the software IEC/IEEE floating-point
132: | exception flags.
133: *----------------------------------------------------------------------------*/
134: void float_raise( int8 );
135: #ifdef SOFTFLOAT_I860
136: void float_raise2( int8 );
137: #endif
138:
139: /*----------------------------------------------------------------------------
140: | The pattern for a default generated single-precision NaN.
141: *----------------------------------------------------------------------------*/
142: #define float32_default_nan 0x7FFFFFFF
143:
144: /*----------------------------------------------------------------------------
145: | The pattern for a default generated double-precision NaN.
146: *----------------------------------------------------------------------------*/
147: #define float64_default_nan LIT64( 0x7FFFFFFFFFFFFFFF )
148:
149: #ifdef FLOATX80
150: /*----------------------------------------------------------------------------
151: | The pattern for a default generated extended double-precision NaN. The
152: | `high' and `low' values hold the most- and least-significant bits,
153: | respectively.
154: *----------------------------------------------------------------------------*/
155: #define floatx80_default_nan_high 0x7FFF
156: #define floatx80_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
157: #endif
158: #ifdef FLOAT128
159: /*----------------------------------------------------------------------------
160: | The pattern for a default generated quadruple-precision NaN. The `high' and
161: | `low' values hold the most- and least-significant bits, respectively.
162: *----------------------------------------------------------------------------*/
163: #define float128_default_nan_high LIT64( 0x7FFFFFFFFFFFFFFF )
164: #define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
165: #endif
166: #ifdef FLOATX80
167: /*----------------------------------------------------------------------------
168: | The pattern for a default generated extended double-precision infinity.
169: *----------------------------------------------------------------------------*/
170: #define floatx80_default_infinity_low LIT64( 0x0000000000000000 )
171: #endif
172:
173: /*----------------------------------------------------------------------------
174: | Software IEC/IEEE integer-to-floating-point conversion routines.
175: *----------------------------------------------------------------------------*/
176: float32 int32_to_float32( int32 );
177: float64 int32_to_float64( int32 );
178: #ifdef FLOATX80
179: floatx80 int32_to_floatx80( int32 );
180: #endif
181: #ifdef FLOAT128
182: float128 int32_to_float128( int32 );
183: #endif
184: float32 int64_to_float32( int64 );
185: float64 int64_to_float64( int64 );
186: #ifdef FLOATX80
187: floatx80 int64_to_floatx80( int64 );
188: #endif
189: #ifdef FLOAT128
190: float128 int64_to_float128( int64 );
191: #endif
192:
193: /*----------------------------------------------------------------------------
194: | Software IEC/IEEE single-precision conversion routines.
195: *----------------------------------------------------------------------------*/
196: int32 float32_to_int32( float32 );
197: int32 float32_to_int32_round_to_zero( float32 );
198: int64 float32_to_int64( float32 );
199: int64 float32_to_int64_round_to_zero( float32 );
200: float64 float32_to_float64( float32 );
201: #ifdef FLOATX80
202: floatx80 float32_to_floatx80( float32 );
203: floatx80 float32_to_floatx80_allowunnormal( float32 );
204: #endif
205: #ifdef FLOAT128
206: float128 float32_to_float128( float32 );
207: #endif
208:
209: /*----------------------------------------------------------------------------
210: | Software IEC/IEEE single-precision operations.
211: *----------------------------------------------------------------------------*/
212: float32 float32_round_to_int( float32 );
213: float32 float32_add( float32, float32 );
214: float32 float32_sub( float32, float32 );
215: float32 float32_mul( float32, float32 );
216: float32 float32_div( float32, float32 );
217: float32 float32_rem( float32, float32 );
218: float32 float32_sqrt( float32 );
219: flag float32_eq( float32, float32 );
220: flag float32_le( float32, float32 );
221: flag float32_lt( float32, float32 );
222: #ifdef SOFTFLOAT_I860
223: flag float32_gt( float32, float32 );
224: #endif
225: flag float32_eq_signaling( float32, float32 );
226: flag float32_le_quiet( float32, float32 );
227: flag float32_lt_quiet( float32, float32 );
228: flag float32_is_signaling_nan( float32 );
229:
230: /*----------------------------------------------------------------------------
231: | Software IEC/IEEE double-precision conversion routines.
232: *----------------------------------------------------------------------------*/
233: int32 float64_to_int32( float64 );
234: int32 float64_to_int32_round_to_zero( float64 );
235: int64 float64_to_int64( float64 );
236: int64 float64_to_int64_round_to_zero( float64 );
237: float32 float64_to_float32( float64 );
238: #ifdef FLOATX80
239: floatx80 float64_to_floatx80( float64 );
240: floatx80 float64_to_floatx80_allowunnormal( float64 );
241: #endif
242: #ifdef FLOAT128
243: float128 float64_to_float128( float64 );
244: #endif
245:
246: /*----------------------------------------------------------------------------
247: | Software IEC/IEEE double-precision operations.
248: *----------------------------------------------------------------------------*/
249: float64 float64_round_to_int( float64 );
250: float64 float64_add( float64, float64 );
251: float64 float64_sub( float64, float64 );
252: float64 float64_mul( float64, float64 );
253: float64 float64_div( float64, float64 );
254: float64 float64_rem( float64, float64 );
255: float64 float64_sqrt( float64 );
256: flag float64_eq( float64, float64 );
257: flag float64_le( float64, float64 );
258: flag float64_lt( float64, float64 );
259: #ifdef SOFTFLOAT_I860
260: flag float64_gt( float64, float64 );
261: #endif
262: flag float64_eq_signaling( float64, float64 );
263: flag float64_le_quiet( float64, float64 );
264: flag float64_lt_quiet( float64, float64 );
265: flag float64_is_signaling_nan( float64 );
266:
267: #ifdef FLOATX80
268:
269: /*----------------------------------------------------------------------------
270: | Software IEC/IEEE extended double-precision conversion routines.
271: *----------------------------------------------------------------------------*/
272: int32 floatx80_to_int32( floatx80 );
273: #ifdef SOFTFLOAT_68K
274: int16 floatx80_to_int16( floatx80 );
275: int8 floatx80_to_int8( floatx80 );
276: #endif
277: int32 floatx80_to_int32_round_to_zero( floatx80 );
278: int64 floatx80_to_int64( floatx80 );
279: int64 floatx80_to_int64_round_to_zero( floatx80 );
280: float32 floatx80_to_float32( floatx80 );
281: float64 floatx80_to_float64( floatx80 );
282: #ifdef SOFTFLOAT_68K
283: floatx80 floatx80_to_floatx80( floatx80 );
284: floatx80 floatdecimal_to_floatx80( floatx80 );
285: floatx80 floatx80_to_floatdecimal(floatx80, int32*);
286: #endif
287: #ifdef FLOAT128
288: float128 floatx80_to_float128( floatx80 );
289: #endif
290: bits64 extractFloatx80Frac( floatx80 a );
291: int32 extractFloatx80Exp( floatx80 a );
292: flag extractFloatx80Sign( floatx80 a );
293:
294: /*----------------------------------------------------------------------------
295: | Software IEC/IEEE extended double-precision rounding precision. Valid
296: | values are 32, 64, and 80.
297: *----------------------------------------------------------------------------*/
298: extern int8 floatx80_rounding_precision;
299:
300: /*----------------------------------------------------------------------------
301: | Software IEC/IEEE extended double-precision operations.
302: *----------------------------------------------------------------------------*/
303: floatx80 floatx80_round_to_int( floatx80 );
304: #ifdef SOFTFLOAT_68K
305: floatx80 floatx80_round_to_int_toward_zero( floatx80 );
306: floatx80 floatx80_round_to_float32( floatx80 );
307: floatx80 floatx80_round_to_float64( floatx80 );
308: floatx80 floatx80_round32( floatx80 );
309: floatx80 floatx80_round64( floatx80 );
310: floatx80 floatx80_normalize( floatx80 );
311: floatx80 floatx80_denormalize( floatx80, flag );
312: #endif
313: floatx80 floatx80_add( floatx80, floatx80 );
314: floatx80 floatx80_sub( floatx80, floatx80 );
315: floatx80 floatx80_mul( floatx80, floatx80 );
316: floatx80 floatx80_div( floatx80, floatx80 );
317: #ifndef SOFTFLOAT_68K
318: floatx80 floatx80_rem( floatx80, floatx80 );
319: #endif
320: floatx80 floatx80_sqrt( floatx80 );
321:
322: flag floatx80_eq( floatx80, floatx80 );
323: flag floatx80_le( floatx80, floatx80 );
324: flag floatx80_lt( floatx80, floatx80 );
325: flag floatx80_eq_signaling( floatx80, floatx80 );
326: flag floatx80_le_quiet( floatx80, floatx80 );
327: flag floatx80_lt_quiet( floatx80, floatx80 );
328:
329: flag floatx80_is_signaling_nan( floatx80 );
330: flag floatx80_is_nan( floatx80 );
331: #ifdef SOFTFLOAT_68K
332: flag floatx80_is_zero( floatx80 );
333: flag floatx80_is_infinity( floatx80 );
334: flag floatx80_is_negative( floatx80 );
335: flag floatx80_is_denormal( floatx80 );
336: flag floatx80_is_unnormal( floatx80 );
337: flag floatx80_is_normal( floatx80 );
338:
339: // functions are in softfloat.c
340: floatx80 floatx80_move( floatx80 a );
341: floatx80 floatx80_abs( floatx80 a );
342: floatx80 floatx80_neg( floatx80 a );
343: floatx80 floatx80_getexp( floatx80 a );
344: floatx80 floatx80_getman( floatx80 a );
345: floatx80 floatx80_scale(floatx80 a, floatx80 b);
346: floatx80 floatx80_rem( floatx80 a, floatx80 b, bits64 *q, flag *s );
347: floatx80 floatx80_mod( floatx80 a, floatx80 b, bits64 *q, flag *s );
348: floatx80 floatx80_sglmul( floatx80 a, floatx80 b );
349: floatx80 floatx80_sgldiv( floatx80 a, floatx80 b );
350: floatx80 floatx80_cmp( floatx80 a, floatx80 b );
351: floatx80 floatx80_tst( floatx80 a );
352:
353: // functions are in softfloat_fpsp.c
354: floatx80 floatx80_acos(floatx80 a);
355: floatx80 floatx80_asin(floatx80 a);
356: floatx80 floatx80_atan(floatx80 a);
357: floatx80 floatx80_atanh(floatx80 a);
358: floatx80 floatx80_cos(floatx80 a);
359: floatx80 floatx80_cosh(floatx80 a);
360: floatx80 floatx80_etox(floatx80 a);
361: floatx80 floatx80_etoxm1(floatx80 a);
362: floatx80 floatx80_log10(floatx80 a);
363: floatx80 floatx80_log2(floatx80 a);
364: floatx80 floatx80_logn(floatx80 a);
365: floatx80 floatx80_lognp1(floatx80 a);
366: floatx80 floatx80_sin(floatx80 a);
367: floatx80 floatx80_sinh(floatx80 a);
368: floatx80 floatx80_tan(floatx80 a);
369: floatx80 floatx80_tanh(floatx80 a);
370: floatx80 floatx80_tentox(floatx80 a);
371: floatx80 floatx80_twotox(floatx80 a);
372: #endif
373:
374: // functions originally internal to softfloat.c
375: void normalizeFloatx80Subnormal( bits64 aSig, int32 *zExpPtr, bits64 *zSigPtr );
376: floatx80 packFloatx80( flag zSign, int32 zExp, bits64 zSig );
377: floatx80 roundAndPackFloatx80(int8 roundingPrecision, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1);
378:
379: // functions are in softfloat-specialize.h
380: floatx80 propagateFloatx80NaNOneArg( floatx80 a );
381: floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b );
382:
383: #endif
384:
385: #ifdef FLOAT128
386:
387: /*----------------------------------------------------------------------------
388: | Software IEC/IEEE quadruple-precision conversion routines.
389: *----------------------------------------------------------------------------*/
390: int32 float128_to_int32( float128 );
391: int32 float128_to_int32_round_to_zero( float128 );
392: int64 float128_to_int64( float128 );
393: int64 float128_to_int64_round_to_zero( float128 );
394: float32 float128_to_float32( float128 );
395: float64 float128_to_float64( float128 );
396: #ifdef FLOATX80
397: floatx80 float128_to_floatx80( float128 );
398: #endif
399:
400: /*----------------------------------------------------------------------------
401: | Software IEC/IEEE quadruple-precision operations.
402: *----------------------------------------------------------------------------*/
403: float128 float128_round_to_int( float128 );
404: float128 float128_add( float128, float128 );
405: float128 float128_sub( float128, float128 );
406: float128 float128_mul( float128, float128 );
407: float128 float128_div( float128, float128 );
408: float128 float128_rem( float128, float128 );
409: float128 float128_sqrt( float128 );
410: flag float128_eq( float128, float128 );
411: flag float128_le( float128, float128 );
412: flag float128_lt( float128, float128 );
413: flag float128_eq_signaling( float128, float128 );
414: flag float128_le_quiet( float128, float128 );
415: flag float128_lt_quiet( float128, float128 );
416: flag float128_is_signaling_nan( float128 );
417:
418: // functions originally internal to softfloat.c
419: float128 packFloat128( flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 );
420: float128 roundAndPackFloat128( flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1, bits64 zSig2 );
421: float128 normalizeRoundAndPackFloat128( flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 );
422:
423: #endif
424:
425: #endif //SOFTFLOAT_H
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.