1 /* $OpenBSD: fcnvxf.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 /* @(#)fcnvxf.c: Revision: 2.7.88.1 Date: 93/12/07 15:06:16 */
16
17 #include "float.h"
18 #include "sgl_float.h"
19 #include "dbl_float.h"
20 #include "cnv_float.h"
21
22 /*
23 * Convert single fixed-point to single floating-point format
24 */
25 int
sgl_to_sgl_fcnvxf(srcptr,null,dstptr,status)26 sgl_to_sgl_fcnvxf(srcptr, null, dstptr, status)
27 int *srcptr, *null;
28 sgl_floating_point *dstptr;
29 unsigned int *status;
30 {
31 register int src, dst_exponent;
32 register unsigned int result = 0;
33
34 src = *srcptr;
35 /*
36 * set sign bit of result and get magnitude of source
37 */
38 if (src < 0) {
39 Sgl_setone_sign(result);
40 Int_negate(src);
41 }
42 else {
43 Sgl_setzero_sign(result);
44 /* Check for zero */
45 if (src == 0) {
46 Sgl_setzero(result);
47 *dstptr = result;
48 return(NOEXCEPTION);
49 }
50 }
51 /*
52 * Generate exponent and normalized mantissa
53 */
54 dst_exponent = 16; /* initialize for normalization */
55 /*
56 * Check word for most significant bit set. Returns
57 * a value in dst_exponent indicating the bit position,
58 * between -1 and 30.
59 */
60 Find_ms_one_bit(src,dst_exponent);
61 /* left justify source, with msb at bit position 1 */
62 if (dst_exponent >= 0) src <<= dst_exponent;
63 else src = 1 << 30;
64 Sgl_set_mantissa(result, src >> (SGL_EXP_LENGTH-1));
65 Sgl_set_exponent(result, 30+SGL_BIAS - dst_exponent);
66
67 /* check for inexact */
68 if (Int_isinexact_to_sgl(src)) {
69 switch (Rounding_mode()) {
70 case ROUNDPLUS:
71 if (Sgl_iszero_sign(result))
72 Sgl_increment(result);
73 break;
74 case ROUNDMINUS:
75 if (Sgl_isone_sign(result))
76 Sgl_increment(result);
77 break;
78 case ROUNDNEAREST:
79 Sgl_roundnearest_from_int(src,result);
80 }
81 if (Is_inexacttrap_enabled()) {
82 *dstptr = result;
83 return(INEXACTEXCEPTION);
84 }
85 else Set_inexactflag();
86 }
87 *dstptr = result;
88 return(NOEXCEPTION);
89 }
90
91 /*
92 * Single Fixed-point to Double Floating-point
93 */
94 int
sgl_to_dbl_fcnvxf(srcptr,null,dstptr,status)95 sgl_to_dbl_fcnvxf(srcptr, null, dstptr, status)
96 int *srcptr, *null;
97 dbl_floating_point *dstptr;
98 unsigned int *status;
99 {
100 register int src, dst_exponent;
101 register unsigned int resultp1 = 0, resultp2 = 0;
102
103 src = *srcptr;
104 /*
105 * set sign bit of result and get magnitude of source
106 */
107 if (src < 0) {
108 Dbl_setone_sign(resultp1);
109 Int_negate(src);
110 }
111 else {
112 Dbl_setzero_sign(resultp1);
113 /* Check for zero */
114 if (src == 0) {
115 Dbl_setzero(resultp1,resultp2);
116 Dbl_copytoptr(resultp1,resultp2,dstptr);
117 return(NOEXCEPTION);
118 }
119 }
120 /*
121 * Generate exponent and normalized mantissa
122 */
123 dst_exponent = 16; /* initialize for normalization */
124 /*
125 * Check word for most significant bit set. Returns
126 * a value in dst_exponent indicating the bit position,
127 * between -1 and 30.
128 */
129 Find_ms_one_bit(src,dst_exponent);
130 /* left justify source, with msb at bit position 1 */
131 if (dst_exponent >= 0) src <<= dst_exponent;
132 else src = 1 << 30;
133 Dbl_set_mantissap1(resultp1, (src >> (DBL_EXP_LENGTH - 1)));
134 Dbl_set_mantissap2(resultp2, (src << (33-DBL_EXP_LENGTH)));
135 Dbl_set_exponent(resultp1, (30+DBL_BIAS) - dst_exponent);
136 Dbl_copytoptr(resultp1,resultp2,dstptr);
137 return(NOEXCEPTION);
138 }
139
140 /*
141 * Double Fixed-point to Single Floating-point
142 */
143 int
dbl_to_sgl_fcnvxf(srcptr,null,dstptr,status)144 dbl_to_sgl_fcnvxf(srcptr, null, dstptr, status)
145 dbl_integer *srcptr, *null;
146 sgl_floating_point *dstptr;
147 unsigned int *status;
148 {
149 int dst_exponent, srcp1;
150 unsigned int result = 0, srcp2;
151
152 Dint_copyfromptr(srcptr,srcp1,srcp2);
153 /*
154 * set sign bit of result and get magnitude of source
155 */
156 if (srcp1 < 0) {
157 Sgl_setone_sign(result);
158 Dint_negate(srcp1,srcp2);
159 }
160 else {
161 Sgl_setzero_sign(result);
162 /* Check for zero */
163 if (srcp1 == 0 && srcp2 == 0) {
164 Sgl_setzero(result);
165 *dstptr = result;
166 return(NOEXCEPTION);
167 }
168 }
169 /*
170 * Generate exponent and normalized mantissa
171 */
172 dst_exponent = 16; /* initialize for normalization */
173 if (srcp1 == 0) {
174 /*
175 * Check word for most significant bit set. Returns
176 * a value in dst_exponent indicating the bit position,
177 * between -1 and 30.
178 */
179 Find_ms_one_bit(srcp2,dst_exponent);
180 /* left justify source, with msb at bit position 1 */
181 if (dst_exponent >= 0) {
182 srcp1 = srcp2 << dst_exponent;
183 srcp2 = 0;
184 }
185 else {
186 srcp1 = srcp2 >> 1;
187 srcp2 <<= 31;
188 }
189 /*
190 * since msb set is in second word, need to
191 * adjust bit position count
192 */
193 dst_exponent += 32;
194 }
195 else {
196 /*
197 * Check word for most significant bit set. Returns
198 * a value in dst_exponent indicating the bit position,
199 * between -1 and 30.
200 *
201 */
202 Find_ms_one_bit(srcp1,dst_exponent);
203 /* left justify source, with msb at bit position 1 */
204 if (dst_exponent > 0) {
205 Variable_shift_double(srcp1,srcp2,(32-dst_exponent),
206 srcp1);
207 srcp2 <<= dst_exponent;
208 }
209 /*
210 * If dst_exponent = 0, we don't need to shift anything.
211 * If dst_exponent = -1, src = - 2**63 so we won't need to
212 * shift srcp2.
213 */
214 else srcp1 >>= -(dst_exponent);
215 }
216 Sgl_set_mantissa(result, (srcp1 >> (SGL_EXP_LENGTH - 1)));
217 Sgl_set_exponent(result, (62+SGL_BIAS) - dst_exponent);
218
219 /* check for inexact */
220 if (Dint_isinexact_to_sgl(srcp1,srcp2)) {
221 switch (Rounding_mode()) {
222 case ROUNDPLUS:
223 if (Sgl_iszero_sign(result))
224 Sgl_increment(result);
225 break;
226 case ROUNDMINUS:
227 if (Sgl_isone_sign(result))
228 Sgl_increment(result);
229 break;
230 case ROUNDNEAREST:
231 Sgl_roundnearest_from_dint(srcp1,srcp2,result);
232 }
233 if (Is_inexacttrap_enabled()) {
234 *dstptr = result;
235 return(INEXACTEXCEPTION);
236 }
237 else Set_inexactflag();
238 }
239 *dstptr = result;
240 return(NOEXCEPTION);
241 }
242
243 /*
244 * Double Fixed-point to Double Floating-point
245 */
246 int
dbl_to_dbl_fcnvxf(srcptr,null,dstptr,status)247 dbl_to_dbl_fcnvxf(srcptr, null, dstptr, status)
248 dbl_integer *srcptr, *null;
249 dbl_floating_point *dstptr;
250 unsigned int *status;
251 {
252 register int srcp1, dst_exponent;
253 register unsigned int srcp2, resultp1 = 0, resultp2 = 0;
254
255 Dint_copyfromptr(srcptr,srcp1,srcp2);
256 /*
257 * set sign bit of result and get magnitude of source
258 */
259 if (srcp1 < 0) {
260 Dbl_setone_sign(resultp1);
261 Dint_negate(srcp1,srcp2);
262 }
263 else {
264 Dbl_setzero_sign(resultp1);
265 /* Check for zero */
266 if (srcp1 == 0 && srcp2 ==0) {
267 Dbl_setzero(resultp1,resultp2);
268 Dbl_copytoptr(resultp1,resultp2,dstptr);
269 return(NOEXCEPTION);
270 }
271 }
272 /*
273 * Generate exponent and normalized mantissa
274 */
275 dst_exponent = 16; /* initialize for normalization */
276 if (srcp1 == 0) {
277 /*
278 * Check word for most significant bit set. Returns
279 * a value in dst_exponent indicating the bit position,
280 * between -1 and 30.
281 */
282 Find_ms_one_bit(srcp2,dst_exponent);
283 /* left justify source, with msb at bit position 1 */
284 if (dst_exponent >= 0) {
285 srcp1 = srcp2 << dst_exponent;
286 srcp2 = 0;
287 }
288 else {
289 srcp1 = srcp2 >> 1;
290 srcp2 <<= 31;
291 }
292 /*
293 * since msb set is in second word, need to
294 * adjust bit position count
295 */
296 dst_exponent += 32;
297 }
298 else {
299 /*
300 * Check word for most significant bit set. Returns
301 * a value in dst_exponent indicating the bit position,
302 * between -1 and 30.
303 */
304 Find_ms_one_bit(srcp1,dst_exponent);
305 /* left justify source, with msb at bit position 1 */
306 if (dst_exponent > 0) {
307 Variable_shift_double(srcp1,srcp2,(32-dst_exponent),
308 srcp1);
309 srcp2 <<= dst_exponent;
310 }
311 /*
312 * If dst_exponent = 0, we don't need to shift anything.
313 * If dst_exponent = -1, src = - 2**63 so we won't need to
314 * shift srcp2.
315 */
316 else srcp1 >>= -(dst_exponent);
317 }
318 Dbl_set_mantissap1(resultp1, srcp1 >> (DBL_EXP_LENGTH-1));
319 Shiftdouble(srcp1,srcp2,DBL_EXP_LENGTH-1,resultp2);
320 Dbl_set_exponent(resultp1, (62+DBL_BIAS) - dst_exponent);
321
322 /* check for inexact */
323 if (Dint_isinexact_to_dbl(srcp2)) {
324 switch (Rounding_mode()) {
325 case ROUNDPLUS:
326 if (Dbl_iszero_sign(resultp1)) {
327 Dbl_increment(resultp1,resultp2);
328 }
329 break;
330 case ROUNDMINUS:
331 if (Dbl_isone_sign(resultp1)) {
332 Dbl_increment(resultp1,resultp2);
333 }
334 break;
335 case ROUNDNEAREST:
336 Dbl_roundnearest_from_dint(srcp2,resultp1,
337 resultp2);
338 }
339 if (Is_inexacttrap_enabled()) {
340 Dbl_copytoptr(resultp1,resultp2,dstptr);
341 return(INEXACTEXCEPTION);
342 }
343 else Set_inexactflag();
344 }
345 Dbl_copytoptr(resultp1,resultp2,dstptr);
346 return(NOEXCEPTION);
347 }
348