fcnvxf.c revision 1.1 1 /* $NetBSD: fcnvxf.c,v 1.1 2002/06/05 01:04:25 fredette Exp $ */
2
3 /* $OpenBSD: fcnvxf.c,v 1.5 2001/03/29 03:58:18 mickey Exp $ */
4
5 /*
6 * Copyright 1996 1995 by Open Software Foundation, Inc.
7 * All Rights Reserved
8 *
9 * Permission to use, copy, modify, and distribute this software and
10 * its documentation for any purpose and without fee is hereby granted,
11 * provided that the above copyright notice appears in all copies and
12 * that both the copyright notice and this permission notice appear in
13 * supporting documentation.
14 *
15 * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
17 * FOR A PARTICULAR PURPOSE.
18 *
19 * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
21 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
22 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
23 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24 *
25 */
26 /*
27 * pmk1.1
28 */
29 /*
30 * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
31 *
32 * To anyone who acknowledges that this file is provided "AS IS"
33 * without any express or implied warranty:
34 * permission to use, copy, modify, and distribute this file
35 * for any purpose is hereby granted without fee, provided that
36 * the above copyright notice and this notice appears in all
37 * copies, and that the name of Hewlett-Packard Company not be
38 * used in advertising or publicity pertaining to distribution
39 * of the software without specific, written prior permission.
40 * Hewlett-Packard Company makes no representations about the
41 * suitability of this software for any purpose.
42 */
43
44 #include "../spmath/float.h"
45 #include "../spmath/sgl_float.h"
46 #include "../spmath/dbl_float.h"
47 #include "../spmath/cnv_float.h"
48
49 /*
50 * Convert single fixed-point to single floating-point format
51 */
52 int
53 sgl_to_sgl_fcnvxf(srcptr,dstptr,status)
54
55 int *srcptr;
56 sgl_floating_point *dstptr;
57 unsigned int *status;
58 {
59 register int src, dst_exponent;
60 register unsigned int result = 0;
61
62 src = *srcptr;
63 /*
64 * set sign bit of result and get magnitude of source
65 */
66 if (src < 0) {
67 Sgl_setone_sign(result);
68 Int_negate(src);
69 }
70 else {
71 Sgl_setzero_sign(result);
72 /* Check for zero */
73 if (src == 0) {
74 Sgl_setzero(result);
75 *dstptr = result;
76 return(NOEXCEPTION);
77 }
78 }
79 /*
80 * Generate exponent and normalized mantissa
81 */
82 dst_exponent = 16; /* initialize for normalization */
83 /*
84 * Check word for most significant bit set. Returns
85 * a value in dst_exponent indicating the bit position,
86 * between -1 and 30.
87 */
88 Find_ms_one_bit(src,dst_exponent);
89 /* left justify source, with msb at bit position 1 */
90 if (dst_exponent >= 0) src <<= dst_exponent;
91 else src = 1 << 30;
92 Sgl_set_mantissa(result, src >> (SGL_EXP_LENGTH-1));
93 Sgl_set_exponent(result, 30+SGL_BIAS - dst_exponent);
94
95 /* check for inexact */
96 if (Int_isinexact_to_sgl(src)) {
97 switch (Rounding_mode()) {
98 case ROUNDPLUS:
99 if (Sgl_iszero_sign(result))
100 Sgl_increment(result);
101 break;
102 case ROUNDMINUS:
103 if (Sgl_isone_sign(result))
104 Sgl_increment(result);
105 break;
106 case ROUNDNEAREST:
107 Sgl_roundnearest_from_int(src,result);
108 }
109 if (Is_inexacttrap_enabled()) {
110 *dstptr = result;
111 return(INEXACTEXCEPTION);
112 }
113 else Set_inexactflag();
114 }
115 *dstptr = result;
116 return(NOEXCEPTION);
117 }
118
119 /*
120 * Single Fixed-point to Double Floating-point
121 */
122 int
123 sgl_to_dbl_fcnvxf(srcptr,dstptr,status)
124
125 int *srcptr;
126 dbl_floating_point *dstptr;
127 unsigned int *status;
128 {
129 register int src, dst_exponent;
130 register unsigned int resultp1 = 0, resultp2 = 0;
131
132 src = *srcptr;
133 /*
134 * set sign bit of result and get magnitude of source
135 */
136 if (src < 0) {
137 Dbl_setone_sign(resultp1);
138 Int_negate(src);
139 }
140 else {
141 Dbl_setzero_sign(resultp1);
142 /* Check for zero */
143 if (src == 0) {
144 Dbl_setzero(resultp1,resultp2);
145 Dbl_copytoptr(resultp1,resultp2,dstptr);
146 return(NOEXCEPTION);
147 }
148 }
149 /*
150 * Generate exponent and normalized mantissa
151 */
152 dst_exponent = 16; /* initialize for normalization */
153 /*
154 * Check word for most significant bit set. Returns
155 * a value in dst_exponent indicating the bit position,
156 * between -1 and 30.
157 */
158 Find_ms_one_bit(src,dst_exponent);
159 /* left justify source, with msb at bit position 1 */
160 if (dst_exponent >= 0) src <<= dst_exponent;
161 else src = 1 << 30;
162 Dbl_set_mantissap1(resultp1, (src >> (DBL_EXP_LENGTH - 1)));
163 Dbl_set_mantissap2(resultp2, (src << (33-DBL_EXP_LENGTH)));
164 Dbl_set_exponent(resultp1, (30+DBL_BIAS) - dst_exponent);
165 Dbl_copytoptr(resultp1,resultp2,dstptr);
166 return(NOEXCEPTION);
167 }
168
169 /*
170 * Double Fixed-point to Single Floating-point
171 */
172 int
173 dbl_to_sgl_fcnvxf(srcptr,dstptr,status)
174
175 dbl_integer *srcptr;
176 sgl_floating_point *dstptr;
177 unsigned int *status;
178 {
179 int dst_exponent, srcp1;
180 unsigned int result = 0, srcp2;
181
182 Dint_copyfromptr(srcptr,srcp1,srcp2);
183 /*
184 * set sign bit of result and get magnitude of source
185 */
186 if (srcp1 < 0) {
187 Sgl_setone_sign(result);
188 Dint_negate(srcp1,srcp2);
189 }
190 else {
191 Sgl_setzero_sign(result);
192 /* Check for zero */
193 if (srcp1 == 0 && srcp2 == 0) {
194 Sgl_setzero(result);
195 *dstptr = result;
196 return(NOEXCEPTION);
197 }
198 }
199 /*
200 * Generate exponent and normalized mantissa
201 */
202 dst_exponent = 16; /* initialize for normalization */
203 if (srcp1 == 0) {
204 /*
205 * Check word for most significant bit set. Returns
206 * a value in dst_exponent indicating the bit position,
207 * between -1 and 30.
208 */
209 Find_ms_one_bit(srcp2,dst_exponent);
210 /* left justify source, with msb at bit position 1 */
211 if (dst_exponent >= 0) {
212 srcp1 = srcp2 << dst_exponent;
213 srcp2 = 0;
214 }
215 else {
216 srcp1 = srcp2 >> 1;
217 srcp2 <<= 31;
218 }
219 /*
220 * since msb set is in second word, need to
221 * adjust bit position count
222 */
223 dst_exponent += 32;
224 }
225 else {
226 /*
227 * Check word for most significant bit set. Returns
228 * a value in dst_exponent indicating the bit position,
229 * between -1 and 30.
230 *
231 */
232 Find_ms_one_bit(srcp1,dst_exponent);
233 /* left justify source, with msb at bit position 1 */
234 if (dst_exponent > 0) {
235 Variable_shift_double(srcp1,srcp2,(32-dst_exponent),
236 srcp1);
237 srcp2 <<= dst_exponent;
238 }
239 /*
240 * If dst_exponent = 0, we don't need to shift anything.
241 * If dst_exponent = -1, src = - 2**63 so we won't need to
242 * shift srcp2.
243 */
244 else srcp1 >>= -(dst_exponent);
245 }
246 Sgl_set_mantissa(result, (srcp1 >> (SGL_EXP_LENGTH - 1)));
247 Sgl_set_exponent(result, (62+SGL_BIAS) - dst_exponent);
248
249 /* check for inexact */
250 if (Dint_isinexact_to_sgl(srcp1,srcp2)) {
251 switch (Rounding_mode()) {
252 case ROUNDPLUS:
253 if (Sgl_iszero_sign(result))
254 Sgl_increment(result);
255 break;
256 case ROUNDMINUS:
257 if (Sgl_isone_sign(result))
258 Sgl_increment(result);
259 break;
260 case ROUNDNEAREST:
261 Sgl_roundnearest_from_dint(srcp1,srcp2,result);
262 }
263 if (Is_inexacttrap_enabled()) {
264 *dstptr = result;
265 return(INEXACTEXCEPTION);
266 }
267 else Set_inexactflag();
268 }
269 *dstptr = result;
270 return(NOEXCEPTION);
271 }
272
273 /*
274 * Double Fixed-point to Double Floating-point
275 */
276 int
277 dbl_to_dbl_fcnvxf(srcptr,dstptr,status)
278
279 dbl_integer *srcptr;
280 dbl_floating_point *dstptr;
281 unsigned int *status;
282 {
283 register int srcp1, dst_exponent;
284 register unsigned int srcp2, resultp1 = 0, resultp2 = 0;
285
286 Dint_copyfromptr(srcptr,srcp1,srcp2);
287 /*
288 * set sign bit of result and get magnitude of source
289 */
290 if (srcp1 < 0) {
291 Dbl_setone_sign(resultp1);
292 Dint_negate(srcp1,srcp2);
293 }
294 else {
295 Dbl_setzero_sign(resultp1);
296 /* Check for zero */
297 if (srcp1 == 0 && srcp2 ==0) {
298 Dbl_setzero(resultp1,resultp2);
299 Dbl_copytoptr(resultp1,resultp2,dstptr);
300 return(NOEXCEPTION);
301 }
302 }
303 /*
304 * Generate exponent and normalized mantissa
305 */
306 dst_exponent = 16; /* initialize for normalization */
307 if (srcp1 == 0) {
308 /*
309 * Check word for most significant bit set. Returns
310 * a value in dst_exponent indicating the bit position,
311 * between -1 and 30.
312 */
313 Find_ms_one_bit(srcp2,dst_exponent);
314 /* left justify source, with msb at bit position 1 */
315 if (dst_exponent >= 0) {
316 srcp1 = srcp2 << dst_exponent;
317 srcp2 = 0;
318 }
319 else {
320 srcp1 = srcp2 >> 1;
321 srcp2 <<= 31;
322 }
323 /*
324 * since msb set is in second word, need to
325 * adjust bit position count
326 */
327 dst_exponent += 32;
328 }
329 else {
330 /*
331 * Check word for most significant bit set. Returns
332 * a value in dst_exponent indicating the bit position,
333 * between -1 and 30.
334 */
335 Find_ms_one_bit(srcp1,dst_exponent);
336 /* left justify source, with msb at bit position 1 */
337 if (dst_exponent > 0) {
338 Variable_shift_double(srcp1,srcp2,(32-dst_exponent),
339 srcp1);
340 srcp2 <<= dst_exponent;
341 }
342 /*
343 * If dst_exponent = 0, we don't need to shift anything.
344 * If dst_exponent = -1, src = - 2**63 so we won't need to
345 * shift srcp2.
346 */
347 else srcp1 >>= -(dst_exponent);
348 }
349 Dbl_set_mantissap1(resultp1, srcp1 >> (DBL_EXP_LENGTH-1));
350 Shiftdouble(srcp1,srcp2,DBL_EXP_LENGTH-1,resultp2);
351 Dbl_set_exponent(resultp1, (62+DBL_BIAS) - dst_exponent);
352
353 /* check for inexact */
354 if (Dint_isinexact_to_dbl(srcp2)) {
355 switch (Rounding_mode()) {
356 case ROUNDPLUS:
357 if (Dbl_iszero_sign(resultp1)) {
358 Dbl_increment(resultp1,resultp2);
359 }
360 break;
361 case ROUNDMINUS:
362 if (Dbl_isone_sign(resultp1)) {
363 Dbl_increment(resultp1,resultp2);
364 }
365 break;
366 case ROUNDNEAREST:
367 Dbl_roundnearest_from_dint(srcp2,resultp1,
368 resultp2);
369 }
370 if (Is_inexacttrap_enabled()) {
371 Dbl_copytoptr(resultp1,resultp2,dstptr);
372 return(INEXACTEXCEPTION);
373 }
374 else Set_inexactflag();
375 }
376 Dbl_copytoptr(resultp1,resultp2,dstptr);
377 return(NOEXCEPTION);
378 }
379