1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate * CDDL HEADER START
3*0Sstevel@tonic-gate *
4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
7*0Sstevel@tonic-gate * with the License.
8*0Sstevel@tonic-gate *
9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate * and limitations under the License.
13*0Sstevel@tonic-gate *
14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate *
20*0Sstevel@tonic-gate * CDDL HEADER END
21*0Sstevel@tonic-gate */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate * Copyright (c) 1988-1995, by Sun Microsystems, Inc.
24*0Sstevel@tonic-gate */
25*0Sstevel@tonic-gate
26*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
27*0Sstevel@tonic-gate
28*0Sstevel@tonic-gate #include "base_conversion.h"
29*0Sstevel@tonic-gate
30*0Sstevel@tonic-gate void
_fp_rightshift(pu,n)31*0Sstevel@tonic-gate _fp_rightshift(pu, n)
32*0Sstevel@tonic-gate unpacked *pu;
33*0Sstevel@tonic-gate int n;
34*0Sstevel@tonic-gate
35*0Sstevel@tonic-gate /* Right shift significand sticky by n bits. */
36*0Sstevel@tonic-gate
37*0Sstevel@tonic-gate {
38*0Sstevel@tonic-gate int i;
39*0Sstevel@tonic-gate
40*0Sstevel@tonic-gate if (n >= (32 * UNPACKED_SIZE)) { /* drastic */
41*0Sstevel@tonic-gate for (i = 0; (pu->significand[i] == 0) && (i < UNPACKED_SIZE); i++);
42*0Sstevel@tonic-gate if (i >= UNPACKED_SIZE) {
43*0Sstevel@tonic-gate pu->fpclass = fp_zero;
44*0Sstevel@tonic-gate return;
45*0Sstevel@tonic-gate } else {
46*0Sstevel@tonic-gate for (i = 0; i < (UNPACKED_SIZE - 1); i++)
47*0Sstevel@tonic-gate pu->significand[i] = 0;
48*0Sstevel@tonic-gate pu->significand[UNPACKED_SIZE - 1] = 1;
49*0Sstevel@tonic-gate return;
50*0Sstevel@tonic-gate }
51*0Sstevel@tonic-gate }
52*0Sstevel@tonic-gate while (n >= 32) { /* big shift */
53*0Sstevel@tonic-gate if (pu->significand[UNPACKED_SIZE - 1] != 0)
54*0Sstevel@tonic-gate pu->significand[UNPACKED_SIZE - 2] |= 1;
55*0Sstevel@tonic-gate for (i = UNPACKED_SIZE - 2; i >= 0; i--)
56*0Sstevel@tonic-gate pu->significand[i + 1] = pu->significand[i];
57*0Sstevel@tonic-gate pu->significand[0] = 0;
58*0Sstevel@tonic-gate n -= 32;
59*0Sstevel@tonic-gate }
60*0Sstevel@tonic-gate if (n >= 1) { /* small shift */
61*0Sstevel@tonic-gate unsigned long high, low, shiftout = 0;
62*0Sstevel@tonic-gate for (i = 0; i < UNPACKED_SIZE; i++) {
63*0Sstevel@tonic-gate high = pu->significand[i] >> n;
64*0Sstevel@tonic-gate low = pu->significand[i] << (32 - n);
65*0Sstevel@tonic-gate pu->significand[i] = shiftout | high;
66*0Sstevel@tonic-gate shiftout = low;
67*0Sstevel@tonic-gate }
68*0Sstevel@tonic-gate if (shiftout != 0)
69*0Sstevel@tonic-gate pu->significand[UNPACKED_SIZE - 1] |= 1;
70*0Sstevel@tonic-gate }
71*0Sstevel@tonic-gate }
72*0Sstevel@tonic-gate
73*0Sstevel@tonic-gate PRIVATE int
overflow_to_infinity(sign)74*0Sstevel@tonic-gate overflow_to_infinity(sign)
75*0Sstevel@tonic-gate int sign;
76*0Sstevel@tonic-gate
77*0Sstevel@tonic-gate /* Returns 1 if overflow should go to infinity, 0 if to max finite. */
78*0Sstevel@tonic-gate
79*0Sstevel@tonic-gate {
80*0Sstevel@tonic-gate int inf;
81*0Sstevel@tonic-gate
82*0Sstevel@tonic-gate switch (_fp_current_direction) {
83*0Sstevel@tonic-gate case fp_nearest:
84*0Sstevel@tonic-gate inf = 1;
85*0Sstevel@tonic-gate break;
86*0Sstevel@tonic-gate case fp_tozero:
87*0Sstevel@tonic-gate inf = 0;
88*0Sstevel@tonic-gate break;
89*0Sstevel@tonic-gate case fp_positive:
90*0Sstevel@tonic-gate inf = !sign;
91*0Sstevel@tonic-gate break;
92*0Sstevel@tonic-gate case fp_negative:
93*0Sstevel@tonic-gate inf = sign;
94*0Sstevel@tonic-gate break;
95*0Sstevel@tonic-gate }
96*0Sstevel@tonic-gate return (inf);
97*0Sstevel@tonic-gate }
98*0Sstevel@tonic-gate
99*0Sstevel@tonic-gate PRIVATE void
round(pu,roundword)100*0Sstevel@tonic-gate round(pu, roundword)
101*0Sstevel@tonic-gate unpacked *pu;
102*0Sstevel@tonic-gate
103*0Sstevel@tonic-gate /*
104*0Sstevel@tonic-gate * Round according to current rounding mode. pu must be shifted to so that
105*0Sstevel@tonic-gate * the roundbit is pu->significand[roundword] & 0x80000000
106*0Sstevel@tonic-gate */
107*0Sstevel@tonic-gate
108*0Sstevel@tonic-gate {
109*0Sstevel@tonic-gate int increment; /* boolean to indicate round up */
110*0Sstevel@tonic-gate int is;
111*0Sstevel@tonic-gate unsigned msw; /* msw before increment */
112*0Sstevel@tonic-gate
113*0Sstevel@tonic-gate for (is = (roundword + 1); is < UNPACKED_SIZE; is++)
114*0Sstevel@tonic-gate if (pu->significand[is] != 0) { /* Condense extra bits into
115*0Sstevel@tonic-gate * sticky bottom of
116*0Sstevel@tonic-gate * roundword. */
117*0Sstevel@tonic-gate pu->significand[roundword] |= 1;
118*0Sstevel@tonic-gate break;
119*0Sstevel@tonic-gate }
120*0Sstevel@tonic-gate if (pu->significand[roundword] == 0)
121*0Sstevel@tonic-gate return;
122*0Sstevel@tonic-gate _fp_set_exception(fp_inexact);
123*0Sstevel@tonic-gate switch (_fp_current_direction) {
124*0Sstevel@tonic-gate case fp_nearest:
125*0Sstevel@tonic-gate increment = pu->significand[roundword] >= 0x80000000;
126*0Sstevel@tonic-gate break;
127*0Sstevel@tonic-gate case fp_tozero:
128*0Sstevel@tonic-gate increment = 0;
129*0Sstevel@tonic-gate break;
130*0Sstevel@tonic-gate case fp_positive:
131*0Sstevel@tonic-gate increment = (pu->sign == 0) & (pu->significand[roundword] != 0);
132*0Sstevel@tonic-gate break;
133*0Sstevel@tonic-gate case fp_negative:
134*0Sstevel@tonic-gate increment = (pu->sign != 0) & (pu->significand[roundword] != 0);
135*0Sstevel@tonic-gate break;
136*0Sstevel@tonic-gate }
137*0Sstevel@tonic-gate if (increment) {
138*0Sstevel@tonic-gate msw=pu->significand[0]; /* save msw before round */
139*0Sstevel@tonic-gate is = roundword;
140*0Sstevel@tonic-gate do {
141*0Sstevel@tonic-gate is--;
142*0Sstevel@tonic-gate pu->significand[is]++;
143*0Sstevel@tonic-gate }
144*0Sstevel@tonic-gate while ((pu->significand[is] == 0) && (is > 0));
145*0Sstevel@tonic-gate if (pu->significand[0] < msw) { /* rounding carried out */
146*0Sstevel@tonic-gate pu->exponent++;
147*0Sstevel@tonic-gate pu->significand[0] = 0x80000000;
148*0Sstevel@tonic-gate }
149*0Sstevel@tonic-gate }
150*0Sstevel@tonic-gate if ((_fp_current_direction == fp_nearest) && (pu->significand[roundword] == 0x80000000)) { /* ambiguous case */
151*0Sstevel@tonic-gate pu->significand[roundword - 1] &= ~1; /* force round to even */
152*0Sstevel@tonic-gate }
153*0Sstevel@tonic-gate }
154*0Sstevel@tonic-gate
155*0Sstevel@tonic-gate void
_pack_single(pu,px)156*0Sstevel@tonic-gate _pack_single(pu, px)
157*0Sstevel@tonic-gate unpacked *pu; /* unpacked result */
158*0Sstevel@tonic-gate single *px; /* packed single */
159*0Sstevel@tonic-gate {
160*0Sstevel@tonic-gate single_equivalence kluge;
161*0Sstevel@tonic-gate
162*0Sstevel@tonic-gate kluge.f.msw.sign = pu->sign;
163*0Sstevel@tonic-gate switch (pu->fpclass) {
164*0Sstevel@tonic-gate case fp_zero:
165*0Sstevel@tonic-gate kluge.f.msw.exponent = 0;
166*0Sstevel@tonic-gate kluge.f.msw.significand = 0;
167*0Sstevel@tonic-gate break;
168*0Sstevel@tonic-gate case fp_infinity:
169*0Sstevel@tonic-gate infinity:
170*0Sstevel@tonic-gate kluge.f.msw.exponent = 0xff;
171*0Sstevel@tonic-gate kluge.f.msw.significand = 0;
172*0Sstevel@tonic-gate break;
173*0Sstevel@tonic-gate case fp_quiet:
174*0Sstevel@tonic-gate kluge.f.msw.exponent = 0xff;
175*0Sstevel@tonic-gate kluge.f.msw.significand = 0x400000 | (0x3fffff & (pu->significand[0] >> 8));
176*0Sstevel@tonic-gate break;
177*0Sstevel@tonic-gate case fp_normal:
178*0Sstevel@tonic-gate _fp_rightshift(pu, 8);
179*0Sstevel@tonic-gate pu->exponent += SINGLE_BIAS;
180*0Sstevel@tonic-gate if (pu->exponent <= 0) {
181*0Sstevel@tonic-gate kluge.f.msw.exponent = 0;
182*0Sstevel@tonic-gate _fp_rightshift(pu, 1 - pu->exponent);
183*0Sstevel@tonic-gate round(pu, 1);
184*0Sstevel@tonic-gate if (pu->significand[0] == 0x800000) { /* rounded back up to
185*0Sstevel@tonic-gate * normal */
186*0Sstevel@tonic-gate kluge.f.msw.exponent = 1;
187*0Sstevel@tonic-gate kluge.f.msw.significand = 0;
188*0Sstevel@tonic-gate _fp_set_exception(fp_underflow);
189*0Sstevel@tonic-gate goto ret;
190*0Sstevel@tonic-gate }
191*0Sstevel@tonic-gate if (_fp_current_exceptions & (1 << fp_inexact))
192*0Sstevel@tonic-gate _fp_set_exception(fp_underflow);
193*0Sstevel@tonic-gate kluge.f.msw.significand = 0x7fffff & pu->significand[0];
194*0Sstevel@tonic-gate goto ret;
195*0Sstevel@tonic-gate }
196*0Sstevel@tonic-gate round(pu, 1);
197*0Sstevel@tonic-gate if (pu->significand[0] == 0x1000000) { /* rounding overflow */
198*0Sstevel@tonic-gate pu->significand[0] = 0x800000;
199*0Sstevel@tonic-gate pu->exponent += 1;
200*0Sstevel@tonic-gate }
201*0Sstevel@tonic-gate if (pu->exponent >= 0xff) {
202*0Sstevel@tonic-gate _fp_set_exception(fp_overflow);
203*0Sstevel@tonic-gate _fp_set_exception(fp_inexact);
204*0Sstevel@tonic-gate if (overflow_to_infinity(pu->sign))
205*0Sstevel@tonic-gate goto infinity;
206*0Sstevel@tonic-gate kluge.f.msw.exponent = 0xfe;
207*0Sstevel@tonic-gate kluge.f.msw.significand = 0x7fffff;
208*0Sstevel@tonic-gate goto ret;
209*0Sstevel@tonic-gate }
210*0Sstevel@tonic-gate kluge.f.msw.exponent = pu->exponent;
211*0Sstevel@tonic-gate kluge.f.msw.significand = 0x7fffff & pu->significand[0];
212*0Sstevel@tonic-gate }
213*0Sstevel@tonic-gate ret:
214*0Sstevel@tonic-gate *px = kluge.x;
215*0Sstevel@tonic-gate }
216*0Sstevel@tonic-gate
217*0Sstevel@tonic-gate void
_pack_double(pu,px)218*0Sstevel@tonic-gate _pack_double(pu, px)
219*0Sstevel@tonic-gate unpacked *pu; /* unpacked result */
220*0Sstevel@tonic-gate double *px; /* packed double */
221*0Sstevel@tonic-gate {
222*0Sstevel@tonic-gate double_equivalence kluge;
223*0Sstevel@tonic-gate
224*0Sstevel@tonic-gate kluge.f.msw.sign = pu->sign;
225*0Sstevel@tonic-gate switch (pu->fpclass) {
226*0Sstevel@tonic-gate case fp_zero:
227*0Sstevel@tonic-gate kluge.f.msw.exponent = 0;
228*0Sstevel@tonic-gate kluge.f.msw.significand = 0;
229*0Sstevel@tonic-gate kluge.f.significand2 = 0;
230*0Sstevel@tonic-gate break;
231*0Sstevel@tonic-gate case fp_infinity:
232*0Sstevel@tonic-gate infinity:
233*0Sstevel@tonic-gate kluge.f.msw.exponent = 0x7ff;
234*0Sstevel@tonic-gate kluge.f.msw.significand = 0;
235*0Sstevel@tonic-gate kluge.f.significand2 = 0;
236*0Sstevel@tonic-gate break;
237*0Sstevel@tonic-gate case fp_quiet:
238*0Sstevel@tonic-gate kluge.f.msw.exponent = 0x7ff;
239*0Sstevel@tonic-gate _fp_rightshift(pu, 11);
240*0Sstevel@tonic-gate kluge.f.msw.significand = 0x80000 | (0x7ffff & pu->significand[0]);
241*0Sstevel@tonic-gate kluge.f.significand2 = pu->significand[1];
242*0Sstevel@tonic-gate break;
243*0Sstevel@tonic-gate case fp_normal:
244*0Sstevel@tonic-gate _fp_rightshift(pu, 11);
245*0Sstevel@tonic-gate pu->exponent += DOUBLE_BIAS;
246*0Sstevel@tonic-gate if (pu->exponent <= 0) { /* underflow */
247*0Sstevel@tonic-gate kluge.f.msw.exponent = 0;
248*0Sstevel@tonic-gate _fp_rightshift(pu, 1 - pu->exponent);
249*0Sstevel@tonic-gate round(pu, 2);
250*0Sstevel@tonic-gate if (pu->significand[0] == 0x100000) { /* rounded back up to
251*0Sstevel@tonic-gate * normal */
252*0Sstevel@tonic-gate kluge.f.msw.exponent = 1;
253*0Sstevel@tonic-gate kluge.f.msw.significand = 0;
254*0Sstevel@tonic-gate kluge.f.significand2 = 0;
255*0Sstevel@tonic-gate _fp_set_exception(fp_underflow);
256*0Sstevel@tonic-gate goto ret;
257*0Sstevel@tonic-gate }
258*0Sstevel@tonic-gate if (_fp_current_exceptions & (1 << fp_inexact))
259*0Sstevel@tonic-gate _fp_set_exception(fp_underflow);
260*0Sstevel@tonic-gate kluge.f.msw.exponent = 0;
261*0Sstevel@tonic-gate kluge.f.msw.significand = 0xfffff & pu->significand[0];
262*0Sstevel@tonic-gate kluge.f.significand2 = pu->significand[1];
263*0Sstevel@tonic-gate goto ret;
264*0Sstevel@tonic-gate }
265*0Sstevel@tonic-gate round(pu, 2);
266*0Sstevel@tonic-gate if (pu->significand[0] == 0x200000) { /* rounding overflow */
267*0Sstevel@tonic-gate pu->significand[0] = 0x100000;
268*0Sstevel@tonic-gate pu->exponent += 1;
269*0Sstevel@tonic-gate }
270*0Sstevel@tonic-gate if (pu->exponent >= 0x7ff) { /* overflow */
271*0Sstevel@tonic-gate _fp_set_exception(fp_overflow);
272*0Sstevel@tonic-gate _fp_set_exception(fp_inexact);
273*0Sstevel@tonic-gate if (overflow_to_infinity(pu->sign))
274*0Sstevel@tonic-gate goto infinity;
275*0Sstevel@tonic-gate kluge.f.msw.exponent = 0x7fe;
276*0Sstevel@tonic-gate kluge.f.msw.significand = 0xfffff;
277*0Sstevel@tonic-gate kluge.f.significand2 = 0xffffffff;
278*0Sstevel@tonic-gate goto ret;
279*0Sstevel@tonic-gate }
280*0Sstevel@tonic-gate kluge.f.msw.exponent = pu->exponent;
281*0Sstevel@tonic-gate kluge.f.msw.significand = 0xfffff & pu->significand[0];
282*0Sstevel@tonic-gate kluge.f.significand2 = pu->significand[1];
283*0Sstevel@tonic-gate break;
284*0Sstevel@tonic-gate }
285*0Sstevel@tonic-gate ret:
286*0Sstevel@tonic-gate *px = kluge.x;
287*0Sstevel@tonic-gate }
288*0Sstevel@tonic-gate
289*0Sstevel@tonic-gate void
_pack_extended(pu,px)290*0Sstevel@tonic-gate _pack_extended(pu, px)
291*0Sstevel@tonic-gate unpacked *pu; /* unpacked result */
292*0Sstevel@tonic-gate extended *px; /* packed extended */
293*0Sstevel@tonic-gate {
294*0Sstevel@tonic-gate extended_equivalence kluge;
295*0Sstevel@tonic-gate
296*0Sstevel@tonic-gate kluge.f.msw.sign = pu->sign;
297*0Sstevel@tonic-gate switch (pu->fpclass) {
298*0Sstevel@tonic-gate case fp_zero:
299*0Sstevel@tonic-gate kluge.f.msw.exponent = 0;
300*0Sstevel@tonic-gate kluge.f.significand = 0;
301*0Sstevel@tonic-gate kluge.f.significand2 = 0;
302*0Sstevel@tonic-gate break;
303*0Sstevel@tonic-gate case fp_infinity:
304*0Sstevel@tonic-gate infinity:
305*0Sstevel@tonic-gate kluge.f.msw.exponent = 0x7fff;
306*0Sstevel@tonic-gate kluge.f.significand = 0;
307*0Sstevel@tonic-gate kluge.f.significand2 = 0;
308*0Sstevel@tonic-gate break;
309*0Sstevel@tonic-gate case fp_quiet:
310*0Sstevel@tonic-gate kluge.f.msw.exponent = 0x7fff;
311*0Sstevel@tonic-gate kluge.f.significand = 0x40000000 | (0x7fffffff & pu->significand[0]);
312*0Sstevel@tonic-gate kluge.f.significand2 = pu->significand[1];
313*0Sstevel@tonic-gate break;
314*0Sstevel@tonic-gate case fp_normal:
315*0Sstevel@tonic-gate switch (_fp_current_precision) {
316*0Sstevel@tonic-gate case fp_single:
317*0Sstevel@tonic-gate {
318*0Sstevel@tonic-gate single s;
319*0Sstevel@tonic-gate _pack_single(pu, &s);
320*0Sstevel@tonic-gate _unpack_single(pu, &s);
321*0Sstevel@tonic-gate break;
322*0Sstevel@tonic-gate }
323*0Sstevel@tonic-gate case fp_double:
324*0Sstevel@tonic-gate {
325*0Sstevel@tonic-gate double s;
326*0Sstevel@tonic-gate _pack_double(pu, &s);
327*0Sstevel@tonic-gate _unpack_double(pu, &s);
328*0Sstevel@tonic-gate break;
329*0Sstevel@tonic-gate }
330*0Sstevel@tonic-gate }
331*0Sstevel@tonic-gate pu->exponent += EXTENDED_BIAS;
332*0Sstevel@tonic-gate if (pu->exponent <= 0) { /* underflow */
333*0Sstevel@tonic-gate kluge.f.msw.exponent = 0;
334*0Sstevel@tonic-gate _fp_rightshift(pu, -pu->exponent);
335*0Sstevel@tonic-gate round(pu, 2);
336*0Sstevel@tonic-gate if (_fp_current_exceptions & (1 << fp_inexact))
337*0Sstevel@tonic-gate _fp_set_exception(fp_underflow);
338*0Sstevel@tonic-gate kluge.f.msw.exponent = 0;
339*0Sstevel@tonic-gate kluge.f.significand = pu->significand[0];
340*0Sstevel@tonic-gate kluge.f.significand2 = pu->significand[1];
341*0Sstevel@tonic-gate goto ret;
342*0Sstevel@tonic-gate }
343*0Sstevel@tonic-gate round(pu, 2);
344*0Sstevel@tonic-gate if (pu->exponent >= 0x7fff) { /* overflow */
345*0Sstevel@tonic-gate _fp_set_exception(fp_overflow);
346*0Sstevel@tonic-gate _fp_set_exception(fp_inexact);
347*0Sstevel@tonic-gate if (overflow_to_infinity(pu->sign))
348*0Sstevel@tonic-gate goto infinity;
349*0Sstevel@tonic-gate kluge.f.msw.exponent = 0x7ffe;
350*0Sstevel@tonic-gate kluge.f.significand = 0xffffffff;
351*0Sstevel@tonic-gate kluge.f.significand2 = 0xffffffff;
352*0Sstevel@tonic-gate goto ret;
353*0Sstevel@tonic-gate }
354*0Sstevel@tonic-gate kluge.f.msw.exponent = pu->exponent;
355*0Sstevel@tonic-gate kluge.f.significand = pu->significand[0];
356*0Sstevel@tonic-gate kluge.f.significand2 = pu->significand[1];
357*0Sstevel@tonic-gate break;
358*0Sstevel@tonic-gate }
359*0Sstevel@tonic-gate ret:
360*0Sstevel@tonic-gate (*px)[0] = kluge.x[0];
361*0Sstevel@tonic-gate (*px)[1] = kluge.x[1];
362*0Sstevel@tonic-gate (*px)[2] = kluge.x[2];
363*0Sstevel@tonic-gate }
364*0Sstevel@tonic-gate
365*0Sstevel@tonic-gate void
_pack_quadruple(pu,px)366*0Sstevel@tonic-gate _pack_quadruple(pu, px)
367*0Sstevel@tonic-gate unpacked *pu; /* unpacked result */
368*0Sstevel@tonic-gate quadruple *px; /* packed quadruple */
369*0Sstevel@tonic-gate {
370*0Sstevel@tonic-gate quadruple_equivalence kluge;
371*0Sstevel@tonic-gate int i;
372*0Sstevel@tonic-gate
373*0Sstevel@tonic-gate kluge.f.msw.sign = pu->sign;
374*0Sstevel@tonic-gate switch (pu->fpclass) {
375*0Sstevel@tonic-gate case fp_zero:
376*0Sstevel@tonic-gate kluge.f.msw.exponent = 0;
377*0Sstevel@tonic-gate kluge.f.msw.significand = 0;
378*0Sstevel@tonic-gate kluge.f.significand2 = 0;
379*0Sstevel@tonic-gate kluge.f.significand3 = 0;
380*0Sstevel@tonic-gate kluge.f.significand4 = 0;
381*0Sstevel@tonic-gate break;
382*0Sstevel@tonic-gate case fp_infinity:
383*0Sstevel@tonic-gate infinity:
384*0Sstevel@tonic-gate kluge.f.msw.exponent = 0x7fff;
385*0Sstevel@tonic-gate kluge.f.msw.significand = 0;
386*0Sstevel@tonic-gate kluge.f.significand2 = 0;
387*0Sstevel@tonic-gate kluge.f.significand3 = 0;
388*0Sstevel@tonic-gate kluge.f.significand4 = 0;
389*0Sstevel@tonic-gate break;
390*0Sstevel@tonic-gate case fp_quiet:
391*0Sstevel@tonic-gate kluge.f.msw.exponent = 0x7fff;
392*0Sstevel@tonic-gate _fp_rightshift(pu, 15);
393*0Sstevel@tonic-gate kluge.f.msw.significand = 0x8000 | (0xffff & pu->significand[0]);
394*0Sstevel@tonic-gate kluge.f.significand2 = pu->significand[1];
395*0Sstevel@tonic-gate kluge.f.significand3 = pu->significand[2];
396*0Sstevel@tonic-gate kluge.f.significand4 = pu->significand[3];
397*0Sstevel@tonic-gate break;
398*0Sstevel@tonic-gate case fp_normal:
399*0Sstevel@tonic-gate _fp_rightshift(pu, 15);
400*0Sstevel@tonic-gate pu->exponent += QUAD_BIAS;
401*0Sstevel@tonic-gate if (pu->exponent <= 0) { /* underflow */
402*0Sstevel@tonic-gate kluge.f.msw.exponent = 0;
403*0Sstevel@tonic-gate _fp_rightshift(pu, 1 - pu->exponent);
404*0Sstevel@tonic-gate round(pu, 4);
405*0Sstevel@tonic-gate if (pu->significand[0] == 0x10000) { /* rounded back up to
406*0Sstevel@tonic-gate * normal */
407*0Sstevel@tonic-gate kluge.f.msw.exponent = 1;
408*0Sstevel@tonic-gate kluge.f.msw.significand = 0;
409*0Sstevel@tonic-gate kluge.f.significand2 = 0;
410*0Sstevel@tonic-gate kluge.f.significand3 = 0;
411*0Sstevel@tonic-gate kluge.f.significand4 = 0;
412*0Sstevel@tonic-gate _fp_set_exception(fp_underflow);
413*0Sstevel@tonic-gate goto ret;
414*0Sstevel@tonic-gate }
415*0Sstevel@tonic-gate if (_fp_current_exceptions & (1 << fp_inexact))
416*0Sstevel@tonic-gate _fp_set_exception(fp_underflow);
417*0Sstevel@tonic-gate kluge.f.msw.exponent = 0;
418*0Sstevel@tonic-gate kluge.f.msw.significand = 0xffff & pu->significand[0];
419*0Sstevel@tonic-gate kluge.f.significand2 = pu->significand[1];
420*0Sstevel@tonic-gate kluge.f.significand3 = pu->significand[2];
421*0Sstevel@tonic-gate kluge.f.significand4 = pu->significand[3];
422*0Sstevel@tonic-gate goto ret;
423*0Sstevel@tonic-gate }
424*0Sstevel@tonic-gate round(pu, 4);
425*0Sstevel@tonic-gate if (pu->significand[0] == 0x20000) { /* rounding overflow */
426*0Sstevel@tonic-gate pu->significand[0] = 0x10000;
427*0Sstevel@tonic-gate pu->exponent += 1;
428*0Sstevel@tonic-gate }
429*0Sstevel@tonic-gate if (pu->exponent >= 0x7fff) { /* overflow */
430*0Sstevel@tonic-gate _fp_set_exception(fp_overflow);
431*0Sstevel@tonic-gate _fp_set_exception(fp_inexact);
432*0Sstevel@tonic-gate if (overflow_to_infinity(pu->sign))
433*0Sstevel@tonic-gate goto infinity;
434*0Sstevel@tonic-gate kluge.f.msw.exponent = 0x7ffe;
435*0Sstevel@tonic-gate kluge.f.msw.significand = 0xffff;
436*0Sstevel@tonic-gate kluge.f.significand2 = 0xffffffff;
437*0Sstevel@tonic-gate kluge.f.significand3 = 0xffffffff;
438*0Sstevel@tonic-gate kluge.f.significand4 = 0xffffffff;
439*0Sstevel@tonic-gate goto ret;
440*0Sstevel@tonic-gate }
441*0Sstevel@tonic-gate kluge.f.msw.exponent = pu->exponent;
442*0Sstevel@tonic-gate kluge.f.msw.significand = pu->significand[0] & 0xffff;
443*0Sstevel@tonic-gate kluge.f.significand2 = pu->significand[1];
444*0Sstevel@tonic-gate kluge.f.significand3 = pu->significand[2];
445*0Sstevel@tonic-gate kluge.f.significand4 = pu->significand[3];
446*0Sstevel@tonic-gate break;
447*0Sstevel@tonic-gate }
448*0Sstevel@tonic-gate ret:
449*0Sstevel@tonic-gate #ifdef __STDC__
450*0Sstevel@tonic-gate *px = kluge.x;
451*0Sstevel@tonic-gate #else
452*0Sstevel@tonic-gate for (i = 0; i < 4; i++)
453*0Sstevel@tonic-gate px->u[i] = kluge.x.u[i];
454*0Sstevel@tonic-gate #endif
455*0Sstevel@tonic-gate }
456