4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 1988 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include "base_conversion.h"
31 /* Normalize a number. Does not affect zeros, infs, or NaNs. */
33 _fp_normalize(unpacked
*pu
)
36 short unsigned nlzwords
, nlzbits
;
39 if ((*pu
).fpclass
== fp_normal
) {
40 for (nlzwords
= 0; (pu
->significand
[nlzwords
] == 0) && (nlzwords
< UNPACKED_SIZE
); nlzwords
++);
41 if (nlzwords
>= UNPACKED_SIZE
) {
42 (*pu
).fpclass
= fp_zero
;
46 for (i
= 0; i
< UNPACKED_SIZE
- nlzwords
; i
++)
47 pu
->significand
[i
] = pu
->significand
[i
+ nlzwords
];
48 for (; i
< UNPACKED_SIZE
; i
++)
49 pu
->significand
[i
] = 0;
50 pu
->exponent
-= 32 * nlzwords
;
52 for (; pu
->significand
[UNPACKED_SIZE
- 1 - nlzwords
] == 0; nlzwords
++);
53 /* nlzwords is now the count of trailing zero words. */
56 t
= pu
->significand
[0];
57 /* TESTS to determine normalize count. */
59 #define SHIFTMACRO(n) if (t <= (((unsigned long) 0xffffffff) >> n)) { t = t<<n ; nlzbits += n ; }
65 pu
->exponent
-= nlzbits
;
66 if (nlzbits
>= 1) { /* small shift */
67 unsigned long high
, low
, shiftout
= 0;
68 for (i
= UNPACKED_SIZE
- 1 - nlzwords
; i
>= 0; i
--) {
69 high
= pu
->significand
[i
] << nlzbits
;
70 low
= pu
->significand
[i
] >> (32 - nlzbits
);
71 pu
->significand
[i
] = shiftout
| high
;
78 /* Set the exception bit in the current exception register. */
80 _fp_set_exception(enum fp_exception_type ex
)
82 _fp_current_exceptions
|= 1 << (int) ex
;
86 _class_double(double *x
)
88 double_equivalence kluge
;
91 if (kluge
.f
.msw
.exponent
== 0) { /* 0 or sub */
92 if ((kluge
.f
.msw
.significand
== 0) && (kluge
.f
.significand2
== 0))
96 } else if (kluge
.f
.msw
.exponent
== 0x7ff) { /* inf or nan */
97 if ((kluge
.f
.msw
.significand
== 0) && (kluge
.f
.significand2
== 0))
99 else if (kluge
.f
.msw
.significand
>= 0x40000)
108 /* Left shift significand by 11 <= n <= 16 bits. Affect all classes. */
110 _fp_leftshift(unpacked
*pu
, unsigned n
)
114 unsigned long high
, low
, shiftout
= 0;
115 for (i
= UNPACKED_SIZE
- 1; i
>= 0; i
--) {
116 high
= pu
->significand
[i
] << n
;
117 low
= pu
->significand
[i
] >> (32 - n
);
118 pu
->significand
[i
] = shiftout
| high
;
125 _unpack_double(unpacked
*pu
, double *px
)
127 double_equivalence x
;
131 (*pu
).sign
= x
.f
.msw
.sign
;
132 pu
->significand
[1] = x
.f
.significand2
;
133 for (i
= 2; i
< UNPACKED_SIZE
; i
++)
134 pu
->significand
[i
] = 0;
135 if (x
.f
.msw
.exponent
== 0) { /* zero or sub */
136 if ((x
.f
.msw
.significand
== 0) && (x
.f
.significand2
== 0)) { /* zero */
137 pu
->fpclass
= fp_zero
;
139 } else { /* subnormal */
140 pu
->fpclass
= fp_normal
;
141 pu
->exponent
= 12 - DOUBLE_BIAS
;
142 pu
->significand
[0] = x
.f
.msw
.significand
;
146 } else if (x
.f
.msw
.exponent
== 0x7ff) { /* inf or nan */
147 if ((x
.f
.msw
.significand
== 0) && (x
.f
.significand2
== 0)) { /* inf */
148 pu
->fpclass
= fp_infinity
;
151 if ((x
.f
.msw
.significand
& 0x80000) != 0) { /* quiet */
152 pu
->fpclass
= fp_quiet
;
153 } else {/* signaling */
154 pu
->fpclass
= fp_quiet
;
155 _fp_set_exception(fp_invalid
);
157 pu
->significand
[0] = 0x80000 | x
.f
.msw
.significand
;
158 _fp_leftshift(pu
, 11);
162 (*pu
).exponent
= x
.f
.msw
.exponent
- DOUBLE_BIAS
;
163 (*pu
).fpclass
= fp_normal
;
164 (*pu
).significand
[0] = 0x100000 | x
.f
.msw
.significand
;
165 _fp_leftshift(pu
, 11);
169 _class_quadruple(quadruple
*x
)
171 quadruple_equivalence kluge
;
174 for (i
= 0; i
< 4; i
++)
178 kluge
.x
.u
[i
] = x
->u
[i
];
180 if (kluge
.f
.msw
.exponent
== 0) { /* 0 or sub */
181 if ((kluge
.f
.msw
.significand
== 0) && (kluge
.f
.significand2
== 0) && (kluge
.f
.significand3
== 0) && (kluge
.f
.significand4
== 0))
185 } else if (kluge
.f
.msw
.exponent
== 0x7fff) { /* inf or nan */
186 if ((kluge
.f
.msw
.significand
== 0) && (kluge
.f
.significand2
== 0) && (kluge
.f
.significand3
== 0) && (kluge
.f
.significand4
== 0))
188 else if ((kluge
.f
.msw
.significand
& 0xffff) >= 0x8000)
197 _unpack_quadruple(unpacked
*pu
, quadruple
*px
)
199 quadruple_equivalence x
;
202 for (i
= 0; i
< 4; i
++)
208 (*pu
).sign
= x
.f
.msw
.sign
;
209 pu
->significand
[1] = x
.f
.significand2
;
210 pu
->significand
[2] = x
.f
.significand3
;
211 pu
->significand
[3] = x
.f
.significand4
;
212 for (i
= 4; i
< UNPACKED_SIZE
; i
++)
213 pu
->significand
[i
] = 0;
214 if (x
.f
.msw
.exponent
== 0) { /* zero or sub */
215 if ((x
.f
.msw
.significand
| x
.f
.significand2
| x
.f
.significand3
| x
.f
.significand4
) == 0) { /* zero */
216 pu
->fpclass
= fp_zero
;
218 } else { /* subnormal */
219 pu
->fpclass
= fp_normal
;
220 pu
->exponent
= 16 - QUAD_BIAS
;
221 pu
->significand
[0] = x
.f
.msw
.significand
;
225 } else if (x
.f
.msw
.exponent
== 0x7fff) { /* inf or nan */
226 if ((x
.f
.msw
.significand
| x
.f
.significand2
| x
.f
.significand3
| x
.f
.significand4
) == 0) { /* inf */
227 pu
->fpclass
= fp_infinity
;
230 if ((x
.f
.msw
.significand
& 0x8000) != 0) { /* quiet */
231 pu
->fpclass
= fp_quiet
;
232 } else {/* signaling */
233 pu
->fpclass
= fp_quiet
;
234 _fp_set_exception(fp_invalid
);
236 pu
->significand
[0] = 0x8000 | x
.f
.msw
.significand
;
237 _fp_leftshift(pu
, 16);
241 (*pu
).exponent
= x
.f
.msw
.exponent
- QUAD_BIAS
;
242 (*pu
).fpclass
= fp_normal
;
243 (*pu
).significand
[0] = 0x10000 | x
.f
.msw
.significand
;
244 _fp_leftshift(pu
, 15);
247 * printf("/n _unpack_quadruple ") ; _display_unpacked(pu);