1 /*
2 * CDDL HEADER START
3 *
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
7 * with the License.
8 *
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.
13 *
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]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 1988 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 /* IEEE function implementations. */
30
31 #include "base_conversion.h"
32
33 enum fp_class_type
_class_single(single * x)34 _class_single(single *x)
35 {
36 single_equivalence kluge;
37
38 kluge.x = *x;
39 if (kluge.f.msw.exponent == 0) { /* 0 or sub */
40 if (kluge.f.msw.significand == 0)
41 return fp_zero;
42 else
43 return fp_subnormal;
44 } else if (kluge.f.msw.exponent == 0xff) { /* inf or nan */
45 if (kluge.f.msw.significand == 0)
46 return fp_infinity;
47 else if (kluge.f.msw.significand >= 0x400000)
48 return fp_quiet;
49 else
50 return fp_signaling;
51 } else
52 return fp_normal;
53 }
54
55 enum fp_class_type
_class_extended(extended * x)56 _class_extended(extended *x)
57 {
58 extended_equivalence kluge;
59
60 kluge.x[0] = (*x)[0];
61 kluge.x[1] = (*x)[1];
62 kluge.x[2] = (*x)[2];
63 if (kluge.f.msw.exponent == 0) { /* 0 or sub */
64 if ((kluge.f.significand == 0) && (kluge.f.significand2 == 0))
65 return fp_zero;
66 else
67 return fp_subnormal;
68 } else if (kluge.f.msw.exponent == 0x7fff) { /* inf or nan */
69 if (((kluge.f.significand & 0x7fffffff) == 0) && (kluge.f.significand2 == 0))
70 return fp_infinity;
71 else if ((kluge.f.significand & 0x7fffffff) >= 0x40000000)
72 return fp_quiet;
73 else
74 return fp_signaling;
75 } else
76 return fp_normal;
77 }
78
79 void
_unpack_single(unpacked * pu,single * px)80 _unpack_single(unpacked *pu, single *px)
81 {
82 single_equivalence x;
83 int i;
84
85 x.x = *px;
86 (*pu).sign = x.f.msw.sign;
87 for (i = 1; i < UNPACKED_SIZE; i++)
88 pu->significand[i] = 0;
89 if (x.f.msw.exponent == 0) { /* zero or sub */
90 if (x.f.msw.significand == 0) { /* zero */
91 pu->fpclass = fp_zero;
92 return;
93 } else { /* subnormal */
94 pu->fpclass = fp_normal;
95 pu->exponent = -SINGLE_BIAS;
96 pu->significand[0] = x.f.msw.significand << 9;
97 _fp_normalize(pu);
98 return;
99 }
100 } else if (x.f.msw.exponent == 0xff) { /* inf or nan */
101 if (x.f.msw.significand == 0) { /* inf */
102 pu->fpclass = fp_infinity;
103 return;
104 } else { /* nan */
105 if ((x.f.msw.significand & 0x400000) != 0) { /* quiet */
106 pu->fpclass = fp_quiet;
107 } else {/* signaling */
108 pu->fpclass = fp_quiet;
109 _fp_set_exception(fp_invalid);
110 }
111 pu->significand[0] = 0x40000000 | (x.f.msw.significand << 8);
112 return;
113 }
114 }
115 (*pu).exponent = x.f.msw.exponent - SINGLE_BIAS;
116 (*pu).fpclass = fp_normal;
117 (*pu).significand[0] = 0x80000000 | (x.f.msw.significand << 8);
118 }
119
120 void
_unpack_extended(unpacked * pu,extended * px)121 _unpack_extended(unpacked *pu, extended *px)
122 {
123 extended_equivalence x;
124 int i;
125
126 x.x[0] = (*px)[0];
127 x.x[1] = (*px)[1];
128 x.x[2] = (*px)[2];
129 pu->sign = x.f.msw.sign;
130 pu->fpclass = fp_normal;
131 pu->exponent = x.f.msw.exponent - EXTENDED_BIAS;
132 pu->significand[0] = x.f.significand;
133 pu->significand[1] = x.f.significand2;
134 for (i = 2; i < UNPACKED_SIZE; i++)
135 pu->significand[i] = 0;
136 if (x.f.msw.exponent == 0x7fff) { /* inf or nan */
137 if (((x.f.significand & 0x7fffffff) == 0) && (x.f.significand2 == 0)) { /* inf */
138 pu->fpclass = fp_infinity;
139 return;
140 } else { /* nan */
141 if ((x.f.significand & 0x40000000) != 0) { /* quiet */
142 pu->fpclass = fp_quiet;
143 } else {/* signaling */
144 pu->fpclass = fp_quiet;
145 _fp_set_exception(fp_invalid);
146 }
147 return;
148 }
149 }
150 if (x.f.significand < 0x80000000) { /* zero or unnormal */
151 if ((x.f.significand == 0) && (x.f.significand2 == 0)) { /* zero */
152 pu->fpclass = fp_zero;
153 return;
154 } else { /* unnormal */
155 pu->fpclass = fp_normal;
156 _fp_normalize(pu);
157 return;
158 }
159 }
160 }
161
162 void
_display_unpacked(unpacked * pu)163 _display_unpacked(unpacked *pu)
164 {
165 int i, e;
166
167 (void) printf(" unpacked ");
168 if (pu->sign == 1)
169 (void) printf("-");
170 else
171 (void) printf("+");
172 switch (pu->fpclass) {
173 case fp_zero:
174 (void) printf("0");
175 break;
176 case fp_infinity:
177 (void) printf("Infinity");
178 break;
179 case fp_quiet:
180 (void) printf("NaN(quiet)");
181 break;
182 case fp_signaling:
183 (void) printf("NaN(signaling)");
184 break;
185 case fp_subnormal:
186 case fp_normal:
187 e = 1 + pu->exponent;
188 for (i = 0; i < UNPACKED_SIZE; i++) {
189 e -= 32;
190 (void) printf(" %8X *2**%d + ", pu->significand[i], e);
191 }
192 }
193 (void) printf("\n");
194 }
195