Annotation of sys/arch/hppa/spmath/fcnvff.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: fcnvff.c,v 1.7 2003/04/10 17:27:58 mickey Exp $ */
2: /*
3: (c) Copyright 1986 HEWLETT-PACKARD COMPANY
4: To anyone who acknowledges that this file is provided "AS IS"
5: without any express or implied warranty:
6: permission to use, copy, modify, and distribute this file
7: for any purpose is hereby granted without fee, provided that
8: the above copyright notice and this notice appears in all
9: copies, and that the name of Hewlett-Packard Company not be
10: used in advertising or publicity pertaining to distribution
11: of the software without specific, written prior permission.
12: Hewlett-Packard Company makes no representations about the
13: suitability of this software for any purpose.
14: */
15: /* @(#)fcnvff.c: Revision: 2.8.88.1 Date: 93/12/07 15:06:09 */
16:
17: #include "float.h"
18: #include "sgl_float.h"
19: #include "dbl_float.h"
20: #include "cnv_float.h"
21:
22: /*
23: * Single Floating-point to Double Floating-point
24: */
25: /*ARGSUSED*/
26: int
27: sgl_to_dbl_fcnvff(srcptr, null, dstptr, status)
28: sgl_floating_point *srcptr, *null;
29: dbl_floating_point *dstptr;
30: unsigned int *status;
31: {
32: register unsigned int src, resultp1, resultp2;
33: register int src_exponent;
34:
35: src = *srcptr;
36: src_exponent = Sgl_exponent(src);
37: Dbl_allp1(resultp1) = Sgl_all(src); /* set sign of result */
38: /*
39: * Test for NaN or infinity
40: */
41: if (src_exponent == SGL_INFINITY_EXPONENT) {
42: /*
43: * determine if NaN or infinity
44: */
45: if (Sgl_iszero_mantissa(src)) {
46: /*
47: * is infinity; want to return double infinity
48: */
49: Dbl_setinfinity_exponentmantissa(resultp1,resultp2);
50: Dbl_copytoptr(resultp1,resultp2,dstptr);
51: return(NOEXCEPTION);
52: }
53: else {
54: /*
55: * is NaN; signaling or quiet?
56: */
57: if (Sgl_isone_signaling(src)) {
58: /* trap if INVALIDTRAP enabled */
59: if (Is_invalidtrap_enabled())
60: return(INVALIDEXCEPTION);
61: /* make NaN quiet */
62: else {
63: Set_invalidflag();
64: Sgl_set_quiet(src);
65: }
66: }
67: /*
68: * NaN is quiet, return as double NaN
69: */
70: Dbl_setinfinity_exponent(resultp1);
71: Sgl_to_dbl_mantissa(src,resultp1,resultp2);
72: Dbl_copytoptr(resultp1,resultp2,dstptr);
73: return(NOEXCEPTION);
74: }
75: }
76: /*
77: * Test for zero or denormalized
78: */
79: if (src_exponent == 0) {
80: /*
81: * determine if zero or denormalized
82: */
83: if (Sgl_isnotzero_mantissa(src)) {
84: /*
85: * is denormalized; want to normalize
86: */
87: Sgl_clear_signexponent(src);
88: Sgl_leftshiftby1(src);
89: Sgl_normalize(src,src_exponent);
90: Sgl_to_dbl_exponent(src_exponent,resultp1);
91: Sgl_to_dbl_mantissa(src,resultp1,resultp2);
92: }
93: else {
94: Dbl_setzero_exponentmantissa(resultp1,resultp2);
95: }
96: Dbl_copytoptr(resultp1,resultp2,dstptr);
97: return(NOEXCEPTION);
98: }
99: /*
100: * No special cases, just complete the conversion
101: */
102: Sgl_to_dbl_exponent(src_exponent, resultp1);
103: Sgl_to_dbl_mantissa(Sgl_mantissa(src), resultp1,resultp2);
104: Dbl_copytoptr(resultp1,resultp2,dstptr);
105: return(NOEXCEPTION);
106: }
107:
108: /*
109: * Double Floating-point to Single Floating-point
110: */
111: /*ARGSUSED*/
112: int
113: dbl_to_sgl_fcnvff(srcptr, null, dstptr, status)
114: dbl_floating_point *srcptr, *null;
115: sgl_floating_point *dstptr;
116: unsigned int *status;
117: {
118: register unsigned int srcp1, srcp2, result;
119: register int src_exponent, dest_exponent, dest_mantissa;
120: register int inexact = FALSE, guardbit = FALSE, stickybit = FALSE;
121: register int lsb_odd = FALSE;
122: int is_tiny;
123:
124: Dbl_copyfromptr(srcptr,srcp1,srcp2);
125: src_exponent = Dbl_exponent(srcp1);
126: Sgl_all(result) = Dbl_allp1(srcp1); /* set sign of result */
127: /*
128: * Test for NaN or infinity
129: */
130: if (src_exponent == DBL_INFINITY_EXPONENT) {
131: /*
132: * determine if NaN or infinity
133: */
134: if (Dbl_iszero_mantissa(srcp1,srcp2)) {
135: /*
136: * is infinity; want to return single infinity
137: */
138: Sgl_setinfinity_exponentmantissa(result);
139: *dstptr = result;
140: return(NOEXCEPTION);
141: }
142: /*
143: * is NaN; signaling or quiet?
144: */
145: if (Dbl_isone_signaling(srcp1)) {
146: /* trap if INVALIDTRAP enabled */
147: if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
148: else {
149: Set_invalidflag();
150: /* make NaN quiet */
151: Dbl_set_quiet(srcp1);
152: }
153: }
154: /*
155: * NaN is quiet, return as single NaN
156: */
157: Sgl_setinfinity_exponent(result);
158: Sgl_set_mantissa(result,Dallp1(srcp1)<<3 | Dallp2(srcp2)>>29);
159: if (Sgl_iszero_mantissa(result)) Sgl_set_quiet(result);
160: *dstptr = result;
161: return(NOEXCEPTION);
162: }
163: /*
164: * Generate result
165: */
166: Dbl_to_sgl_exponent(src_exponent,dest_exponent);
167: if (dest_exponent > 0) {
168: Dbl_to_sgl_mantissa(srcp1,srcp2,dest_mantissa,inexact,guardbit,
169: stickybit,lsb_odd);
170: }
171: else {
172: if (Dbl_iszero_exponentmantissa(srcp1,srcp2)){
173: Sgl_setzero_exponentmantissa(result);
174: *dstptr = result;
175: return(NOEXCEPTION);
176: }
177: if (Is_underflowtrap_enabled()) {
178: Dbl_to_sgl_mantissa(srcp1,srcp2,dest_mantissa,inexact,
179: guardbit,stickybit,lsb_odd);
180: }
181: else {
182: /* compute result, determine inexact info,
183: * and set Underflowflag if appropriate
184: */
185: Dbl_to_sgl_denormalized(srcp1,srcp2,dest_exponent,
186: dest_mantissa,inexact,guardbit,stickybit,lsb_odd,
187: is_tiny);
188: }
189: }
190: /*
191: * Now round result if not exact
192: */
193: if (inexact) {
194: switch (Rounding_mode()) {
195: case ROUNDPLUS:
196: if (Sgl_iszero_sign(result)) dest_mantissa++;
197: break;
198: case ROUNDMINUS:
199: if (Sgl_isone_sign(result)) dest_mantissa++;
200: break;
201: case ROUNDNEAREST:
202: if (guardbit) {
203: if (stickybit || lsb_odd) dest_mantissa++;
204: }
205: }
206: }
207: Sgl_set_exponentmantissa(result,dest_mantissa);
208:
209: /*
210: * check for mantissa overflow after rounding
211: */
212: if ((dest_exponent>0 || Is_underflowtrap_enabled()) &&
213: Sgl_isone_hidden(result)) dest_exponent++;
214:
215: /*
216: * Test for overflow
217: */
218: if (dest_exponent >= SGL_INFINITY_EXPONENT) {
219: /* trap if OVERFLOWTRAP enabled */
220: if (Is_overflowtrap_enabled()) {
221: /*
222: * Check for gross overflow
223: */
224: if (dest_exponent >= SGL_INFINITY_EXPONENT+SGL_WRAP)
225: return(UNIMPLEMENTEDEXCEPTION);
226:
227: /*
228: * Adjust bias of result
229: */
230: Sgl_setwrapped_exponent(result,dest_exponent,ovfl);
231: *dstptr = result;
232: if (inexact) {
233: if (Is_inexacttrap_enabled())
234: return(OVERFLOWEXCEPTION|INEXACTEXCEPTION);
235: else
236: Set_inexactflag();
237: }
238: return(OVERFLOWEXCEPTION);
239: }
240: Set_overflowflag();
241: inexact = TRUE;
242: /* set result to infinity or largest number */
243: Sgl_setoverflow(result);
244: }
245: /*
246: * Test for underflow
247: */
248: else if (dest_exponent <= 0) {
249: /* trap if UNDERFLOWTRAP enabled */
250: if (Is_underflowtrap_enabled()) {
251: /*
252: * Check for gross underflow
253: */
254: if (dest_exponent <= -(SGL_WRAP))
255: return(UNIMPLEMENTEDEXCEPTION);
256: /*
257: * Adjust bias of result
258: */
259: Sgl_setwrapped_exponent(result,dest_exponent,unfl);
260: *dstptr = result;
261: if (inexact) {
262: if (Is_inexacttrap_enabled())
263: return(UNDERFLOWEXCEPTION|INEXACTEXCEPTION);
264: else
265: Set_inexactflag();
266: }
267: return(UNDERFLOWEXCEPTION);
268: }
269: /*
270: * result is denormalized or signed zero
271: */
272: if (inexact && is_tiny) Set_underflowflag();
273:
274: }
275: else Sgl_set_exponent(result,dest_exponent);
276: *dstptr = result;
277: /*
278: * Trap if inexact trap is enabled
279: */
280: if (inexact) {
281: if (Is_inexacttrap_enabled())
282: return(INEXACTEXCEPTION);
283: else
284: Set_inexactflag();
285: }
286: return(NOEXCEPTION);
287: }
CVSweb