1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Linux/PA-RISC Project (http://www.parisc-linux.org/)
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Floating-point emulation code
6*4882a593Smuzhiyun * Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
7*4882a593Smuzhiyun */
8*4882a593Smuzhiyun /*
9*4882a593Smuzhiyun * BEGIN_DESC
10*4882a593Smuzhiyun *
11*4882a593Smuzhiyun * File:
12*4882a593Smuzhiyun * @(#) pa/spmath/fcnvfu.c $Revision: 1.1 $
13*4882a593Smuzhiyun *
14*4882a593Smuzhiyun * Purpose:
15*4882a593Smuzhiyun * Floating-point to Unsigned Fixed-point Converts
16*4882a593Smuzhiyun *
17*4882a593Smuzhiyun * External Interfaces:
18*4882a593Smuzhiyun * dbl_to_dbl_fcnvfu(srcptr,nullptr,dstptr,status)
19*4882a593Smuzhiyun * dbl_to_sgl_fcnvfu(srcptr,nullptr,dstptr,status)
20*4882a593Smuzhiyun * sgl_to_dbl_fcnvfu(srcptr,nullptr,dstptr,status)
21*4882a593Smuzhiyun * sgl_to_sgl_fcnvfu(srcptr,nullptr,dstptr,status)
22*4882a593Smuzhiyun *
23*4882a593Smuzhiyun * Internal Interfaces:
24*4882a593Smuzhiyun *
25*4882a593Smuzhiyun * Theory:
26*4882a593Smuzhiyun * <<please update with a overview of the operation of this file>>
27*4882a593Smuzhiyun *
28*4882a593Smuzhiyun * END_DESC
29*4882a593Smuzhiyun */
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun #include "float.h"
33*4882a593Smuzhiyun #include "sgl_float.h"
34*4882a593Smuzhiyun #include "dbl_float.h"
35*4882a593Smuzhiyun #include "cnv_float.h"
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun /************************************************************************
38*4882a593Smuzhiyun * Floating-point to Unsigned Fixed-point Converts *
39*4882a593Smuzhiyun ************************************************************************/
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun /*
42*4882a593Smuzhiyun * Single Floating-point to Single Unsigned Fixed
43*4882a593Smuzhiyun */
44*4882a593Smuzhiyun /*ARGSUSED*/
45*4882a593Smuzhiyun int
sgl_to_sgl_fcnvfu(sgl_floating_point * srcptr,unsigned int * nullptr,unsigned int * dstptr,unsigned int * status)46*4882a593Smuzhiyun sgl_to_sgl_fcnvfu(
47*4882a593Smuzhiyun sgl_floating_point *srcptr,
48*4882a593Smuzhiyun unsigned int *nullptr,
49*4882a593Smuzhiyun unsigned int *dstptr,
50*4882a593Smuzhiyun unsigned int *status)
51*4882a593Smuzhiyun {
52*4882a593Smuzhiyun register unsigned int src, result;
53*4882a593Smuzhiyun register int src_exponent;
54*4882a593Smuzhiyun register boolean inexact = FALSE;
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun src = *srcptr;
57*4882a593Smuzhiyun src_exponent = Sgl_exponent(src) - SGL_BIAS;
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun /*
60*4882a593Smuzhiyun * Test for overflow
61*4882a593Smuzhiyun */
62*4882a593Smuzhiyun if (src_exponent > SGL_FX_MAX_EXP + 1) {
63*4882a593Smuzhiyun if (Sgl_isone_sign(src)) {
64*4882a593Smuzhiyun result = 0;
65*4882a593Smuzhiyun } else {
66*4882a593Smuzhiyun result = 0xffffffff;
67*4882a593Smuzhiyun }
68*4882a593Smuzhiyun if (Is_invalidtrap_enabled()) {
69*4882a593Smuzhiyun return(INVALIDEXCEPTION);
70*4882a593Smuzhiyun }
71*4882a593Smuzhiyun Set_invalidflag();
72*4882a593Smuzhiyun *dstptr = result;
73*4882a593Smuzhiyun return(NOEXCEPTION);
74*4882a593Smuzhiyun }
75*4882a593Smuzhiyun /*
76*4882a593Smuzhiyun * Generate result
77*4882a593Smuzhiyun */
78*4882a593Smuzhiyun if (src_exponent >= 0) {
79*4882a593Smuzhiyun /*
80*4882a593Smuzhiyun * Check sign.
81*4882a593Smuzhiyun * If negative, trap unimplemented.
82*4882a593Smuzhiyun */
83*4882a593Smuzhiyun if (Sgl_isone_sign(src)) {
84*4882a593Smuzhiyun result = 0;
85*4882a593Smuzhiyun if (Is_invalidtrap_enabled()) {
86*4882a593Smuzhiyun return(INVALIDEXCEPTION);
87*4882a593Smuzhiyun }
88*4882a593Smuzhiyun Set_invalidflag();
89*4882a593Smuzhiyun *dstptr = result;
90*4882a593Smuzhiyun return(NOEXCEPTION);
91*4882a593Smuzhiyun }
92*4882a593Smuzhiyun Sgl_clear_signexponent_set_hidden(src);
93*4882a593Smuzhiyun Suint_from_sgl_mantissa(src,src_exponent,result);
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun /* check for inexact */
96*4882a593Smuzhiyun if (Sgl_isinexact_to_unsigned(src,src_exponent)) {
97*4882a593Smuzhiyun inexact = TRUE;
98*4882a593Smuzhiyun /* round result */
99*4882a593Smuzhiyun switch (Rounding_mode()) {
100*4882a593Smuzhiyun case ROUNDPLUS:
101*4882a593Smuzhiyun result++;
102*4882a593Smuzhiyun break;
103*4882a593Smuzhiyun case ROUNDMINUS: /* never negative */
104*4882a593Smuzhiyun break;
105*4882a593Smuzhiyun case ROUNDNEAREST:
106*4882a593Smuzhiyun if (Sgl_isone_roundbit(src,src_exponent) &&
107*4882a593Smuzhiyun (Sgl_isone_stickybit(src,src_exponent) ||
108*4882a593Smuzhiyun (result & 1))) {
109*4882a593Smuzhiyun result++;
110*4882a593Smuzhiyun }
111*4882a593Smuzhiyun break;
112*4882a593Smuzhiyun }
113*4882a593Smuzhiyun }
114*4882a593Smuzhiyun } else {
115*4882a593Smuzhiyun result = 0;
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun /* check for inexact */
118*4882a593Smuzhiyun if (Sgl_isnotzero_exponentmantissa(src)) {
119*4882a593Smuzhiyun inexact = TRUE;
120*4882a593Smuzhiyun /* round result */
121*4882a593Smuzhiyun switch (Rounding_mode()) {
122*4882a593Smuzhiyun case ROUNDPLUS:
123*4882a593Smuzhiyun if (Sgl_iszero_sign(src)) {
124*4882a593Smuzhiyun result++;
125*4882a593Smuzhiyun }
126*4882a593Smuzhiyun break;
127*4882a593Smuzhiyun case ROUNDMINUS:
128*4882a593Smuzhiyun if (Sgl_isone_sign(src)) {
129*4882a593Smuzhiyun result = 0;
130*4882a593Smuzhiyun if (Is_invalidtrap_enabled()) {
131*4882a593Smuzhiyun return(INVALIDEXCEPTION);
132*4882a593Smuzhiyun }
133*4882a593Smuzhiyun Set_invalidflag();
134*4882a593Smuzhiyun inexact = FALSE;
135*4882a593Smuzhiyun }
136*4882a593Smuzhiyun break;
137*4882a593Smuzhiyun case ROUNDNEAREST:
138*4882a593Smuzhiyun if (src_exponent == -1 &&
139*4882a593Smuzhiyun Sgl_isnotzero_mantissa(src)) {
140*4882a593Smuzhiyun if (Sgl_isone_sign(src)) {
141*4882a593Smuzhiyun result = 0;
142*4882a593Smuzhiyun if (Is_invalidtrap_enabled()) {
143*4882a593Smuzhiyun return(INVALIDEXCEPTION);
144*4882a593Smuzhiyun }
145*4882a593Smuzhiyun Set_invalidflag();
146*4882a593Smuzhiyun inexact = FALSE;
147*4882a593Smuzhiyun }
148*4882a593Smuzhiyun else result++;
149*4882a593Smuzhiyun }
150*4882a593Smuzhiyun break;
151*4882a593Smuzhiyun }
152*4882a593Smuzhiyun }
153*4882a593Smuzhiyun }
154*4882a593Smuzhiyun *dstptr = result;
155*4882a593Smuzhiyun if (inexact) {
156*4882a593Smuzhiyun if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
157*4882a593Smuzhiyun else Set_inexactflag();
158*4882a593Smuzhiyun }
159*4882a593Smuzhiyun return(NOEXCEPTION);
160*4882a593Smuzhiyun }
161*4882a593Smuzhiyun
162*4882a593Smuzhiyun /*
163*4882a593Smuzhiyun * Single Floating-point to Double Unsigned Fixed
164*4882a593Smuzhiyun */
165*4882a593Smuzhiyun /*ARGSUSED*/
166*4882a593Smuzhiyun int
sgl_to_dbl_fcnvfu(sgl_floating_point * srcptr,unsigned int * nullptr,dbl_unsigned * dstptr,unsigned int * status)167*4882a593Smuzhiyun sgl_to_dbl_fcnvfu(
168*4882a593Smuzhiyun sgl_floating_point *srcptr,
169*4882a593Smuzhiyun unsigned int *nullptr,
170*4882a593Smuzhiyun dbl_unsigned *dstptr,
171*4882a593Smuzhiyun unsigned int *status)
172*4882a593Smuzhiyun {
173*4882a593Smuzhiyun register int src_exponent;
174*4882a593Smuzhiyun register unsigned int src, resultp1, resultp2;
175*4882a593Smuzhiyun register boolean inexact = FALSE;
176*4882a593Smuzhiyun
177*4882a593Smuzhiyun src = *srcptr;
178*4882a593Smuzhiyun src_exponent = Sgl_exponent(src) - SGL_BIAS;
179*4882a593Smuzhiyun
180*4882a593Smuzhiyun /*
181*4882a593Smuzhiyun * Test for overflow
182*4882a593Smuzhiyun */
183*4882a593Smuzhiyun if (src_exponent > DBL_FX_MAX_EXP + 1) {
184*4882a593Smuzhiyun if (Sgl_isone_sign(src)) {
185*4882a593Smuzhiyun resultp1 = resultp2 = 0;
186*4882a593Smuzhiyun } else {
187*4882a593Smuzhiyun resultp1 = resultp2 = 0xffffffff;
188*4882a593Smuzhiyun }
189*4882a593Smuzhiyun if (Is_invalidtrap_enabled()) {
190*4882a593Smuzhiyun return(INVALIDEXCEPTION);
191*4882a593Smuzhiyun }
192*4882a593Smuzhiyun Set_invalidflag();
193*4882a593Smuzhiyun Duint_copytoptr(resultp1,resultp2,dstptr);
194*4882a593Smuzhiyun return(NOEXCEPTION);
195*4882a593Smuzhiyun }
196*4882a593Smuzhiyun /*
197*4882a593Smuzhiyun * Generate result
198*4882a593Smuzhiyun */
199*4882a593Smuzhiyun if (src_exponent >= 0) {
200*4882a593Smuzhiyun /*
201*4882a593Smuzhiyun * Check sign.
202*4882a593Smuzhiyun * If negative, trap unimplemented.
203*4882a593Smuzhiyun */
204*4882a593Smuzhiyun if (Sgl_isone_sign(src)) {
205*4882a593Smuzhiyun resultp1 = resultp2 = 0;
206*4882a593Smuzhiyun if (Is_invalidtrap_enabled()) {
207*4882a593Smuzhiyun return(INVALIDEXCEPTION);
208*4882a593Smuzhiyun }
209*4882a593Smuzhiyun Set_invalidflag();
210*4882a593Smuzhiyun Duint_copytoptr(resultp1,resultp2,dstptr);
211*4882a593Smuzhiyun return(NOEXCEPTION);
212*4882a593Smuzhiyun }
213*4882a593Smuzhiyun Sgl_clear_signexponent_set_hidden(src);
214*4882a593Smuzhiyun Duint_from_sgl_mantissa(src,src_exponent,resultp1,resultp2);
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun /* check for inexact */
217*4882a593Smuzhiyun if (Sgl_isinexact_to_unsigned(src,src_exponent)) {
218*4882a593Smuzhiyun inexact = TRUE;
219*4882a593Smuzhiyun /* round result */
220*4882a593Smuzhiyun switch (Rounding_mode()) {
221*4882a593Smuzhiyun case ROUNDPLUS:
222*4882a593Smuzhiyun Duint_increment(resultp1,resultp2);
223*4882a593Smuzhiyun break;
224*4882a593Smuzhiyun case ROUNDMINUS: /* never negative */
225*4882a593Smuzhiyun break;
226*4882a593Smuzhiyun case ROUNDNEAREST:
227*4882a593Smuzhiyun if (Sgl_isone_roundbit(src,src_exponent) &&
228*4882a593Smuzhiyun (Sgl_isone_stickybit(src,src_exponent) ||
229*4882a593Smuzhiyun Duint_isone_lowp2(resultp2))) {
230*4882a593Smuzhiyun Duint_increment(resultp1,resultp2);
231*4882a593Smuzhiyun }
232*4882a593Smuzhiyun break;
233*4882a593Smuzhiyun }
234*4882a593Smuzhiyun }
235*4882a593Smuzhiyun } else {
236*4882a593Smuzhiyun Duint_setzero(resultp1,resultp2);
237*4882a593Smuzhiyun
238*4882a593Smuzhiyun /* check for inexact */
239*4882a593Smuzhiyun if (Sgl_isnotzero_exponentmantissa(src)) {
240*4882a593Smuzhiyun inexact = TRUE;
241*4882a593Smuzhiyun /* round result */
242*4882a593Smuzhiyun switch (Rounding_mode()) {
243*4882a593Smuzhiyun case ROUNDPLUS:
244*4882a593Smuzhiyun if (Sgl_iszero_sign(src)) {
245*4882a593Smuzhiyun Duint_increment(resultp1,resultp2);
246*4882a593Smuzhiyun }
247*4882a593Smuzhiyun break;
248*4882a593Smuzhiyun case ROUNDMINUS:
249*4882a593Smuzhiyun if (Sgl_isone_sign(src)) {
250*4882a593Smuzhiyun resultp1 = resultp2 = 0;
251*4882a593Smuzhiyun if (Is_invalidtrap_enabled()) {
252*4882a593Smuzhiyun return(INVALIDEXCEPTION);
253*4882a593Smuzhiyun }
254*4882a593Smuzhiyun Set_invalidflag();
255*4882a593Smuzhiyun inexact = FALSE;
256*4882a593Smuzhiyun }
257*4882a593Smuzhiyun break;
258*4882a593Smuzhiyun case ROUNDNEAREST:
259*4882a593Smuzhiyun if (src_exponent == -1 &&
260*4882a593Smuzhiyun Sgl_isnotzero_mantissa(src)) {
261*4882a593Smuzhiyun if (Sgl_isone_sign(src)) {
262*4882a593Smuzhiyun resultp1 = 0;
263*4882a593Smuzhiyun resultp2 = 0;
264*4882a593Smuzhiyun if (Is_invalidtrap_enabled()) {
265*4882a593Smuzhiyun return(INVALIDEXCEPTION);
266*4882a593Smuzhiyun }
267*4882a593Smuzhiyun Set_invalidflag();
268*4882a593Smuzhiyun inexact = FALSE;
269*4882a593Smuzhiyun }
270*4882a593Smuzhiyun else Duint_increment(resultp1,resultp2);
271*4882a593Smuzhiyun }
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun }
274*4882a593Smuzhiyun }
275*4882a593Smuzhiyun Duint_copytoptr(resultp1,resultp2,dstptr);
276*4882a593Smuzhiyun if (inexact) {
277*4882a593Smuzhiyun if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
278*4882a593Smuzhiyun else Set_inexactflag();
279*4882a593Smuzhiyun }
280*4882a593Smuzhiyun return(NOEXCEPTION);
281*4882a593Smuzhiyun }
282*4882a593Smuzhiyun
283*4882a593Smuzhiyun /*
284*4882a593Smuzhiyun * Double Floating-point to Single Unsigned Fixed
285*4882a593Smuzhiyun */
286*4882a593Smuzhiyun /*ARGSUSED*/
287*4882a593Smuzhiyun int
dbl_to_sgl_fcnvfu(dbl_floating_point * srcptr,unsigned int * nullptr,unsigned int * dstptr,unsigned int * status)288*4882a593Smuzhiyun dbl_to_sgl_fcnvfu (dbl_floating_point * srcptr, unsigned int *nullptr,
289*4882a593Smuzhiyun unsigned int *dstptr, unsigned int *status)
290*4882a593Smuzhiyun {
291*4882a593Smuzhiyun register unsigned int srcp1, srcp2, result;
292*4882a593Smuzhiyun register int src_exponent;
293*4882a593Smuzhiyun register boolean inexact = FALSE;
294*4882a593Smuzhiyun
295*4882a593Smuzhiyun Dbl_copyfromptr(srcptr,srcp1,srcp2);
296*4882a593Smuzhiyun src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
297*4882a593Smuzhiyun
298*4882a593Smuzhiyun /*
299*4882a593Smuzhiyun * Test for overflow
300*4882a593Smuzhiyun */
301*4882a593Smuzhiyun if (src_exponent > SGL_FX_MAX_EXP + 1) {
302*4882a593Smuzhiyun if (Dbl_isone_sign(srcp1)) {
303*4882a593Smuzhiyun result = 0;
304*4882a593Smuzhiyun } else {
305*4882a593Smuzhiyun result = 0xffffffff;
306*4882a593Smuzhiyun }
307*4882a593Smuzhiyun if (Is_invalidtrap_enabled()) {
308*4882a593Smuzhiyun return(INVALIDEXCEPTION);
309*4882a593Smuzhiyun }
310*4882a593Smuzhiyun Set_invalidflag();
311*4882a593Smuzhiyun *dstptr = result;
312*4882a593Smuzhiyun return(NOEXCEPTION);
313*4882a593Smuzhiyun }
314*4882a593Smuzhiyun /*
315*4882a593Smuzhiyun * Generate result
316*4882a593Smuzhiyun */
317*4882a593Smuzhiyun if (src_exponent >= 0) {
318*4882a593Smuzhiyun /*
319*4882a593Smuzhiyun * Check sign.
320*4882a593Smuzhiyun * If negative, trap unimplemented.
321*4882a593Smuzhiyun */
322*4882a593Smuzhiyun if (Dbl_isone_sign(srcp1)) {
323*4882a593Smuzhiyun result = 0;
324*4882a593Smuzhiyun if (Is_invalidtrap_enabled()) {
325*4882a593Smuzhiyun return(INVALIDEXCEPTION);
326*4882a593Smuzhiyun }
327*4882a593Smuzhiyun Set_invalidflag();
328*4882a593Smuzhiyun *dstptr = result;
329*4882a593Smuzhiyun return(NOEXCEPTION);
330*4882a593Smuzhiyun }
331*4882a593Smuzhiyun Dbl_clear_signexponent_set_hidden(srcp1);
332*4882a593Smuzhiyun Suint_from_dbl_mantissa(srcp1,srcp2,src_exponent,result);
333*4882a593Smuzhiyun
334*4882a593Smuzhiyun /* check for inexact */
335*4882a593Smuzhiyun if (Dbl_isinexact_to_unsigned(srcp1,srcp2,src_exponent)) {
336*4882a593Smuzhiyun inexact = TRUE;
337*4882a593Smuzhiyun /* round result */
338*4882a593Smuzhiyun switch (Rounding_mode()) {
339*4882a593Smuzhiyun case ROUNDPLUS:
340*4882a593Smuzhiyun result++;
341*4882a593Smuzhiyun break;
342*4882a593Smuzhiyun case ROUNDMINUS: /* never negative */
343*4882a593Smuzhiyun break;
344*4882a593Smuzhiyun case ROUNDNEAREST:
345*4882a593Smuzhiyun if(Dbl_isone_roundbit(srcp1,srcp2,src_exponent) &&
346*4882a593Smuzhiyun (Dbl_isone_stickybit(srcp1,srcp2,src_exponent)||
347*4882a593Smuzhiyun result&1))
348*4882a593Smuzhiyun result++;
349*4882a593Smuzhiyun break;
350*4882a593Smuzhiyun }
351*4882a593Smuzhiyun /* check for overflow */
352*4882a593Smuzhiyun if (result == 0) {
353*4882a593Smuzhiyun result = 0xffffffff;
354*4882a593Smuzhiyun if (Is_invalidtrap_enabled()) {
355*4882a593Smuzhiyun return(INVALIDEXCEPTION);
356*4882a593Smuzhiyun }
357*4882a593Smuzhiyun Set_invalidflag();
358*4882a593Smuzhiyun *dstptr = result;
359*4882a593Smuzhiyun return(NOEXCEPTION);
360*4882a593Smuzhiyun }
361*4882a593Smuzhiyun }
362*4882a593Smuzhiyun } else {
363*4882a593Smuzhiyun result = 0;
364*4882a593Smuzhiyun
365*4882a593Smuzhiyun /* check for inexact */
366*4882a593Smuzhiyun if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
367*4882a593Smuzhiyun inexact = TRUE;
368*4882a593Smuzhiyun /* round result */
369*4882a593Smuzhiyun switch (Rounding_mode()) {
370*4882a593Smuzhiyun case ROUNDPLUS:
371*4882a593Smuzhiyun if (Dbl_iszero_sign(srcp1)) result++;
372*4882a593Smuzhiyun break;
373*4882a593Smuzhiyun case ROUNDMINUS:
374*4882a593Smuzhiyun if (Dbl_isone_sign(srcp1)) {
375*4882a593Smuzhiyun result = 0;
376*4882a593Smuzhiyun if (Is_invalidtrap_enabled()) {
377*4882a593Smuzhiyun return(INVALIDEXCEPTION);
378*4882a593Smuzhiyun }
379*4882a593Smuzhiyun Set_invalidflag();
380*4882a593Smuzhiyun inexact = FALSE;
381*4882a593Smuzhiyun }
382*4882a593Smuzhiyun break;
383*4882a593Smuzhiyun case ROUNDNEAREST:
384*4882a593Smuzhiyun if (src_exponent == -1 &&
385*4882a593Smuzhiyun Dbl_isnotzero_mantissa(srcp1,srcp2))
386*4882a593Smuzhiyun if (Dbl_isone_sign(srcp1)) {
387*4882a593Smuzhiyun result = 0;
388*4882a593Smuzhiyun if (Is_invalidtrap_enabled()) {
389*4882a593Smuzhiyun return(INVALIDEXCEPTION);
390*4882a593Smuzhiyun }
391*4882a593Smuzhiyun Set_invalidflag();
392*4882a593Smuzhiyun inexact = FALSE;
393*4882a593Smuzhiyun }
394*4882a593Smuzhiyun else result++;
395*4882a593Smuzhiyun }
396*4882a593Smuzhiyun }
397*4882a593Smuzhiyun }
398*4882a593Smuzhiyun *dstptr = result;
399*4882a593Smuzhiyun if (inexact) {
400*4882a593Smuzhiyun if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
401*4882a593Smuzhiyun else Set_inexactflag();
402*4882a593Smuzhiyun }
403*4882a593Smuzhiyun return(NOEXCEPTION);
404*4882a593Smuzhiyun }
405*4882a593Smuzhiyun
406*4882a593Smuzhiyun /*
407*4882a593Smuzhiyun * Double Floating-point to Double Unsigned Fixed
408*4882a593Smuzhiyun */
409*4882a593Smuzhiyun /*ARGSUSED*/
410*4882a593Smuzhiyun int
dbl_to_dbl_fcnvfu(dbl_floating_point * srcptr,unsigned int * nullptr,dbl_unsigned * dstptr,unsigned int * status)411*4882a593Smuzhiyun dbl_to_dbl_fcnvfu (dbl_floating_point * srcptr, unsigned int *nullptr,
412*4882a593Smuzhiyun dbl_unsigned * dstptr, unsigned int *status)
413*4882a593Smuzhiyun {
414*4882a593Smuzhiyun register int src_exponent;
415*4882a593Smuzhiyun register unsigned int srcp1, srcp2, resultp1, resultp2;
416*4882a593Smuzhiyun register boolean inexact = FALSE;
417*4882a593Smuzhiyun
418*4882a593Smuzhiyun Dbl_copyfromptr(srcptr,srcp1,srcp2);
419*4882a593Smuzhiyun src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
420*4882a593Smuzhiyun
421*4882a593Smuzhiyun /*
422*4882a593Smuzhiyun * Test for overflow
423*4882a593Smuzhiyun */
424*4882a593Smuzhiyun if (src_exponent > DBL_FX_MAX_EXP + 1) {
425*4882a593Smuzhiyun if (Dbl_isone_sign(srcp1)) {
426*4882a593Smuzhiyun resultp1 = resultp2 = 0;
427*4882a593Smuzhiyun } else {
428*4882a593Smuzhiyun resultp1 = resultp2 = 0xffffffff;
429*4882a593Smuzhiyun }
430*4882a593Smuzhiyun if (Is_invalidtrap_enabled()) {
431*4882a593Smuzhiyun return(INVALIDEXCEPTION);
432*4882a593Smuzhiyun }
433*4882a593Smuzhiyun Set_invalidflag();
434*4882a593Smuzhiyun Duint_copytoptr(resultp1,resultp2,dstptr);
435*4882a593Smuzhiyun return(NOEXCEPTION);
436*4882a593Smuzhiyun }
437*4882a593Smuzhiyun
438*4882a593Smuzhiyun /*
439*4882a593Smuzhiyun * Generate result
440*4882a593Smuzhiyun */
441*4882a593Smuzhiyun if (src_exponent >= 0) {
442*4882a593Smuzhiyun /*
443*4882a593Smuzhiyun * Check sign.
444*4882a593Smuzhiyun * If negative, trap unimplemented.
445*4882a593Smuzhiyun */
446*4882a593Smuzhiyun if (Dbl_isone_sign(srcp1)) {
447*4882a593Smuzhiyun resultp1 = resultp2 = 0;
448*4882a593Smuzhiyun if (Is_invalidtrap_enabled()) {
449*4882a593Smuzhiyun return(INVALIDEXCEPTION);
450*4882a593Smuzhiyun }
451*4882a593Smuzhiyun Set_invalidflag();
452*4882a593Smuzhiyun Duint_copytoptr(resultp1,resultp2,dstptr);
453*4882a593Smuzhiyun return(NOEXCEPTION);
454*4882a593Smuzhiyun }
455*4882a593Smuzhiyun Dbl_clear_signexponent_set_hidden(srcp1);
456*4882a593Smuzhiyun Duint_from_dbl_mantissa(srcp1,srcp2,src_exponent,resultp1,
457*4882a593Smuzhiyun resultp2);
458*4882a593Smuzhiyun
459*4882a593Smuzhiyun /* check for inexact */
460*4882a593Smuzhiyun if (Dbl_isinexact_to_unsigned(srcp1,srcp2,src_exponent)) {
461*4882a593Smuzhiyun inexact = TRUE;
462*4882a593Smuzhiyun /* round result */
463*4882a593Smuzhiyun switch (Rounding_mode()) {
464*4882a593Smuzhiyun case ROUNDPLUS:
465*4882a593Smuzhiyun Duint_increment(resultp1,resultp2);
466*4882a593Smuzhiyun break;
467*4882a593Smuzhiyun case ROUNDMINUS: /* never negative */
468*4882a593Smuzhiyun break;
469*4882a593Smuzhiyun case ROUNDNEAREST:
470*4882a593Smuzhiyun if(Dbl_isone_roundbit(srcp1,srcp2,src_exponent))
471*4882a593Smuzhiyun if(Dbl_isone_stickybit(srcp1,srcp2,src_exponent) ||
472*4882a593Smuzhiyun Duint_isone_lowp2(resultp2))
473*4882a593Smuzhiyun Duint_increment(resultp1,resultp2);
474*4882a593Smuzhiyun }
475*4882a593Smuzhiyun }
476*4882a593Smuzhiyun } else {
477*4882a593Smuzhiyun Duint_setzero(resultp1,resultp2);
478*4882a593Smuzhiyun
479*4882a593Smuzhiyun /* check for inexact */
480*4882a593Smuzhiyun if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
481*4882a593Smuzhiyun inexact = TRUE;
482*4882a593Smuzhiyun /* round result */
483*4882a593Smuzhiyun switch (Rounding_mode()) {
484*4882a593Smuzhiyun case ROUNDPLUS:
485*4882a593Smuzhiyun if (Dbl_iszero_sign(srcp1)) {
486*4882a593Smuzhiyun Duint_increment(resultp1,resultp2);
487*4882a593Smuzhiyun }
488*4882a593Smuzhiyun break;
489*4882a593Smuzhiyun case ROUNDMINUS:
490*4882a593Smuzhiyun if (Dbl_isone_sign(srcp1)) {
491*4882a593Smuzhiyun resultp1 = resultp2 = 0;
492*4882a593Smuzhiyun if (Is_invalidtrap_enabled()) {
493*4882a593Smuzhiyun return(INVALIDEXCEPTION);
494*4882a593Smuzhiyun }
495*4882a593Smuzhiyun Set_invalidflag();
496*4882a593Smuzhiyun inexact = FALSE;
497*4882a593Smuzhiyun }
498*4882a593Smuzhiyun break;
499*4882a593Smuzhiyun case ROUNDNEAREST:
500*4882a593Smuzhiyun if (src_exponent == -1 &&
501*4882a593Smuzhiyun Dbl_isnotzero_mantissa(srcp1,srcp2))
502*4882a593Smuzhiyun if (Dbl_iszero_sign(srcp1)) {
503*4882a593Smuzhiyun Duint_increment(resultp1,resultp2);
504*4882a593Smuzhiyun } else {
505*4882a593Smuzhiyun resultp1 = 0;
506*4882a593Smuzhiyun resultp2 = 0;
507*4882a593Smuzhiyun if (Is_invalidtrap_enabled()) {
508*4882a593Smuzhiyun return(INVALIDEXCEPTION);
509*4882a593Smuzhiyun }
510*4882a593Smuzhiyun Set_invalidflag();
511*4882a593Smuzhiyun inexact = FALSE;
512*4882a593Smuzhiyun }
513*4882a593Smuzhiyun }
514*4882a593Smuzhiyun }
515*4882a593Smuzhiyun }
516*4882a593Smuzhiyun Duint_copytoptr(resultp1,resultp2,dstptr);
517*4882a593Smuzhiyun if (inexact) {
518*4882a593Smuzhiyun if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
519*4882a593Smuzhiyun else Set_inexactflag();
520*4882a593Smuzhiyun }
521*4882a593Smuzhiyun return(NOEXCEPTION);
522*4882a593Smuzhiyun }
523*4882a593Smuzhiyun
524