xref: /titanic_50/usr/src/lib/libbc/libc/gen/common/unpack_float.c (revision 5d54f3d8999eac1762fe0a8c7177d20f1f201fae)
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