Merge tag 'trace-v5.11-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt...
[linux/fpc-iii.git] / arch / parisc / math-emu / fcnvff.c
blob0530e6127797471faff378604abdaa9c1a6a8485
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Linux/PA-RISC Project (http://www.parisc-linux.org/)
5 * Floating-point emulation code
6 * Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
7 */
8 /*
9 * BEGIN_DESC
11 * File:
12 * @(#) pa/spmath/fcnvff.c $Revision: 1.1 $
14 * Purpose:
15 * Single Floating-point to Double Floating-point
16 * Double Floating-point to Single Floating-point
18 * External Interfaces:
19 * dbl_to_sgl_fcnvff(srcptr,nullptr,dstptr,status)
20 * sgl_to_dbl_fcnvff(srcptr,nullptr,dstptr,status)
22 * Internal Interfaces:
24 * Theory:
25 * <<please update with a overview of the operation of this file>>
27 * END_DESC
31 #include "float.h"
32 #include "sgl_float.h"
33 #include "dbl_float.h"
34 #include "cnv_float.h"
37 * Single Floating-point to Double Floating-point
39 /*ARGSUSED*/
40 int
41 sgl_to_dbl_fcnvff(
42 sgl_floating_point *srcptr,
43 unsigned int *nullptr,
44 dbl_floating_point *dstptr,
45 unsigned int *status)
47 register unsigned int src, resultp1, resultp2;
48 register int src_exponent;
50 src = *srcptr;
51 src_exponent = Sgl_exponent(src);
52 Dbl_allp1(resultp1) = Sgl_all(src); /* set sign of result */
53 /*
54 * Test for NaN or infinity
56 if (src_exponent == SGL_INFINITY_EXPONENT) {
58 * determine if NaN or infinity
60 if (Sgl_iszero_mantissa(src)) {
62 * is infinity; want to return double infinity
64 Dbl_setinfinity_exponentmantissa(resultp1,resultp2);
65 Dbl_copytoptr(resultp1,resultp2,dstptr);
66 return(NOEXCEPTION);
68 else {
69 /*
70 * is NaN; signaling or quiet?
72 if (Sgl_isone_signaling(src)) {
73 /* trap if INVALIDTRAP enabled */
74 if (Is_invalidtrap_enabled())
75 return(INVALIDEXCEPTION);
76 /* make NaN quiet */
77 else {
78 Set_invalidflag();
79 Sgl_set_quiet(src);
82 /*
83 * NaN is quiet, return as double NaN
85 Dbl_setinfinity_exponent(resultp1);
86 Sgl_to_dbl_mantissa(src,resultp1,resultp2);
87 Dbl_copytoptr(resultp1,resultp2,dstptr);
88 return(NOEXCEPTION);
91 /*
92 * Test for zero or denormalized
94 if (src_exponent == 0) {
96 * determine if zero or denormalized
98 if (Sgl_isnotzero_mantissa(src)) {
100 * is denormalized; want to normalize
102 Sgl_clear_signexponent(src);
103 Sgl_leftshiftby1(src);
104 Sgl_normalize(src,src_exponent);
105 Sgl_to_dbl_exponent(src_exponent,resultp1);
106 Sgl_to_dbl_mantissa(src,resultp1,resultp2);
108 else {
109 Dbl_setzero_exponentmantissa(resultp1,resultp2);
111 Dbl_copytoptr(resultp1,resultp2,dstptr);
112 return(NOEXCEPTION);
115 * No special cases, just complete the conversion
117 Sgl_to_dbl_exponent(src_exponent, resultp1);
118 Sgl_to_dbl_mantissa(Sgl_mantissa(src), resultp1,resultp2);
119 Dbl_copytoptr(resultp1,resultp2,dstptr);
120 return(NOEXCEPTION);
124 * Double Floating-point to Single Floating-point
126 /*ARGSUSED*/
128 dbl_to_sgl_fcnvff(
129 dbl_floating_point *srcptr,
130 unsigned int *nullptr,
131 sgl_floating_point *dstptr,
132 unsigned int *status)
134 register unsigned int srcp1, srcp2, result;
135 register int src_exponent, dest_exponent, dest_mantissa;
136 register boolean inexact = FALSE, guardbit = FALSE, stickybit = FALSE;
137 register boolean lsb_odd = FALSE;
138 boolean is_tiny = FALSE;
140 Dbl_copyfromptr(srcptr,srcp1,srcp2);
141 src_exponent = Dbl_exponent(srcp1);
142 Sgl_all(result) = Dbl_allp1(srcp1); /* set sign of result */
144 * Test for NaN or infinity
146 if (src_exponent == DBL_INFINITY_EXPONENT) {
148 * determine if NaN or infinity
150 if (Dbl_iszero_mantissa(srcp1,srcp2)) {
152 * is infinity; want to return single infinity
154 Sgl_setinfinity_exponentmantissa(result);
155 *dstptr = result;
156 return(NOEXCEPTION);
159 * is NaN; signaling or quiet?
161 if (Dbl_isone_signaling(srcp1)) {
162 /* trap if INVALIDTRAP enabled */
163 if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
164 else {
165 Set_invalidflag();
166 /* make NaN quiet */
167 Dbl_set_quiet(srcp1);
171 * NaN is quiet, return as single NaN
173 Sgl_setinfinity_exponent(result);
174 Sgl_set_mantissa(result,Dallp1(srcp1)<<3 | Dallp2(srcp2)>>29);
175 if (Sgl_iszero_mantissa(result)) Sgl_set_quiet(result);
176 *dstptr = result;
177 return(NOEXCEPTION);
180 * Generate result
182 Dbl_to_sgl_exponent(src_exponent,dest_exponent);
183 if (dest_exponent > 0) {
184 Dbl_to_sgl_mantissa(srcp1,srcp2,dest_mantissa,inexact,guardbit,
185 stickybit,lsb_odd);
187 else {
188 if (Dbl_iszero_exponentmantissa(srcp1,srcp2)){
189 Sgl_setzero_exponentmantissa(result);
190 *dstptr = result;
191 return(NOEXCEPTION);
193 if (Is_underflowtrap_enabled()) {
194 Dbl_to_sgl_mantissa(srcp1,srcp2,dest_mantissa,inexact,
195 guardbit,stickybit,lsb_odd);
197 else {
198 /* compute result, determine inexact info,
199 * and set Underflowflag if appropriate
201 Dbl_to_sgl_denormalized(srcp1,srcp2,dest_exponent,
202 dest_mantissa,inexact,guardbit,stickybit,lsb_odd,
203 is_tiny);
207 * Now round result if not exact
209 if (inexact) {
210 switch (Rounding_mode()) {
211 case ROUNDPLUS:
212 if (Sgl_iszero_sign(result)) dest_mantissa++;
213 break;
214 case ROUNDMINUS:
215 if (Sgl_isone_sign(result)) dest_mantissa++;
216 break;
217 case ROUNDNEAREST:
218 if (guardbit) {
219 if (stickybit || lsb_odd) dest_mantissa++;
223 Sgl_set_exponentmantissa(result,dest_mantissa);
226 * check for mantissa overflow after rounding
228 if ((dest_exponent>0 || Is_underflowtrap_enabled()) &&
229 Sgl_isone_hidden(result)) dest_exponent++;
232 * Test for overflow
234 if (dest_exponent >= SGL_INFINITY_EXPONENT) {
235 /* trap if OVERFLOWTRAP enabled */
236 if (Is_overflowtrap_enabled()) {
238 * Check for gross overflow
240 if (dest_exponent >= SGL_INFINITY_EXPONENT+SGL_WRAP)
241 return(UNIMPLEMENTEDEXCEPTION);
244 * Adjust bias of result
246 Sgl_setwrapped_exponent(result,dest_exponent,ovfl);
247 *dstptr = result;
248 if (inexact)
249 if (Is_inexacttrap_enabled())
250 return(OVERFLOWEXCEPTION|INEXACTEXCEPTION);
251 else Set_inexactflag();
252 return(OVERFLOWEXCEPTION);
254 Set_overflowflag();
255 inexact = TRUE;
256 /* set result to infinity or largest number */
257 Sgl_setoverflow(result);
260 * Test for underflow
262 else if (dest_exponent <= 0) {
263 /* trap if UNDERFLOWTRAP enabled */
264 if (Is_underflowtrap_enabled()) {
266 * Check for gross underflow
268 if (dest_exponent <= -(SGL_WRAP))
269 return(UNIMPLEMENTEDEXCEPTION);
271 * Adjust bias of result
273 Sgl_setwrapped_exponent(result,dest_exponent,unfl);
274 *dstptr = result;
275 if (inexact)
276 if (Is_inexacttrap_enabled())
277 return(UNDERFLOWEXCEPTION|INEXACTEXCEPTION);
278 else Set_inexactflag();
279 return(UNDERFLOWEXCEPTION);
282 * result is denormalized or signed zero
284 if (inexact && is_tiny) Set_underflowflag();
287 else Sgl_set_exponent(result,dest_exponent);
288 *dstptr = result;
290 * Trap if inexact trap is enabled
292 if (inexact)
293 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
294 else Set_inexactflag();
295 return(NOEXCEPTION);