Merge tag 'sound-5.3-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai...
[linux-2.6-microblaze.git] / arch / parisc / math-emu / fcnvfxt.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Linux/PA-RISC Project (http://www.parisc-linux.org/)
4  *
5  * Floating-point emulation code
6  *  Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
7  */
8 /*
9  * BEGIN_DESC
10  *
11  *  File:
12  *      @(#)    pa/spmath/fcnvfxt.c             $Revision: 1.1 $
13  *
14  *  Purpose:
15  *      Single Floating-point to Single Fixed-point /w truncated result
16  *      Single Floating-point to Double Fixed-point /w truncated result
17  *      Double Floating-point to Single Fixed-point /w truncated result
18  *      Double Floating-point to Double Fixed-point /w truncated result
19  *
20  *  External Interfaces:
21  *      dbl_to_dbl_fcnvfxt(srcptr,nullptr,dstptr,status)
22  *      dbl_to_sgl_fcnvfxt(srcptr,nullptr,dstptr,status)
23  *      sgl_to_dbl_fcnvfxt(srcptr,nullptr,dstptr,status)
24  *      sgl_to_sgl_fcnvfxt(srcptr,nullptr,dstptr,status)
25  *
26  *  Internal Interfaces:
27  *
28  *  Theory:
29  *      <<please update with a overview of the operation of this file>>
30  *
31  * END_DESC
32 */
33
34
35 #include "float.h"
36 #include "sgl_float.h"
37 #include "dbl_float.h"
38 #include "cnv_float.h"
39
40 /*
41  *  Convert single floating-point to single fixed-point format
42  *  with truncated result
43  */
44 /*ARGSUSED*/
45 int
46 sgl_to_sgl_fcnvfxt(
47                     sgl_floating_point *srcptr,
48                     unsigned int *nullptr,
49                     int *dstptr,
50                     unsigned int *status)
51 {
52         register unsigned int src, temp;
53         register int src_exponent, result;
54
55         src = *srcptr;
56         src_exponent = Sgl_exponent(src) - SGL_BIAS;
57
58         /* 
59          * Test for overflow
60          */
61         if (src_exponent > SGL_FX_MAX_EXP) {
62                 /* check for MININT */
63                 if ((src_exponent > SGL_FX_MAX_EXP + 1) || 
64                 Sgl_isnotzero_mantissa(src) || Sgl_iszero_sign(src)) {
65                         if (Sgl_iszero_sign(src)) result = 0x7fffffff;
66                         else result = 0x80000000; 
67
68                         if (Is_invalidtrap_enabled()) {
69                             return(INVALIDEXCEPTION);
70                         }
71                         Set_invalidflag();
72                         *dstptr = result;
73                         return(NOEXCEPTION);
74                 }
75         }
76         /*
77          * Generate result
78          */
79         if (src_exponent >= 0) {
80                 temp = src;
81                 Sgl_clear_signexponent_set_hidden(temp);
82                 Int_from_sgl_mantissa(temp,src_exponent);
83                 if (Sgl_isone_sign(src))  result = -Sgl_all(temp);
84                 else result = Sgl_all(temp);
85                 *dstptr = result;
86
87                 /* check for inexact */
88                 if (Sgl_isinexact_to_fix(src,src_exponent)) {
89                         if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
90                         else Set_inexactflag();
91                 }
92         }
93         else {
94                 *dstptr = 0;
95
96                 /* check for inexact */
97                 if (Sgl_isnotzero_exponentmantissa(src)) {
98                         if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
99                         else Set_inexactflag();
100                 }
101         }
102         return(NOEXCEPTION);
103 }
104
105 /*
106  *  Single Floating-point to Double Fixed-point 
107  */
108 /*ARGSUSED*/
109 int
110 sgl_to_dbl_fcnvfxt(
111                     sgl_floating_point *srcptr,
112                     unsigned int *nullptr,
113                     dbl_integer *dstptr,
114                     unsigned int *status)
115 {
116         register int src_exponent, resultp1;
117         register unsigned int src, temp, resultp2;
118
119         src = *srcptr;
120         src_exponent = Sgl_exponent(src) - SGL_BIAS;
121
122         /* 
123          * Test for overflow
124          */
125         if (src_exponent > DBL_FX_MAX_EXP) {
126                 /* check for MININT */
127                 if ((src_exponent > DBL_FX_MAX_EXP + 1) || 
128                 Sgl_isnotzero_mantissa(src) || Sgl_iszero_sign(src)) {
129                         if (Sgl_iszero_sign(src)) {
130                               resultp1 = 0x7fffffff;
131                               resultp2 = 0xffffffff;
132                         }
133                         else {
134                             resultp1 = 0x80000000; 
135                             resultp2 = 0;
136                         }
137                         if (Is_invalidtrap_enabled()) {
138                             return(INVALIDEXCEPTION);
139                         }
140                         Set_invalidflag();
141                         Dint_copytoptr(resultp1,resultp2,dstptr);
142                         return(NOEXCEPTION);
143                 }
144                 Dint_set_minint(resultp1,resultp2);
145                 Dint_copytoptr(resultp1,resultp2,dstptr);
146                 return(NOEXCEPTION);
147         }
148         /*
149          * Generate result
150          */
151         if (src_exponent >= 0) {
152                 temp = src;
153                 Sgl_clear_signexponent_set_hidden(temp);
154                 Dint_from_sgl_mantissa(temp,src_exponent,resultp1,resultp2);
155                 if (Sgl_isone_sign(src)) {
156                         Dint_setone_sign(resultp1,resultp2);
157                 }
158                 Dint_copytoptr(resultp1,resultp2,dstptr);
159
160                 /* check for inexact */
161                 if (Sgl_isinexact_to_fix(src,src_exponent)) {
162                         if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
163                         else Set_inexactflag();
164                 }
165         }
166         else {
167                 Dint_setzero(resultp1,resultp2);
168                 Dint_copytoptr(resultp1,resultp2,dstptr);
169
170                 /* check for inexact */
171                 if (Sgl_isnotzero_exponentmantissa(src)) {
172                         if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
173                         else Set_inexactflag();
174                 }
175         }
176         return(NOEXCEPTION);
177 }
178
179 /*
180  *  Double Floating-point to Single Fixed-point 
181  */
182 /*ARGSUSED*/
183 int
184 dbl_to_sgl_fcnvfxt(
185                         dbl_floating_point *srcptr,
186                         unsigned int *nullptr,
187                         int *dstptr,
188                         unsigned int *status)
189 {
190         register unsigned int srcp1, srcp2, tempp1, tempp2;
191         register int src_exponent, result;
192
193         Dbl_copyfromptr(srcptr,srcp1,srcp2);
194         src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
195
196         /* 
197          * Test for overflow
198          */
199         if (src_exponent > SGL_FX_MAX_EXP) {
200                 /* check for MININT */
201                 if (Dbl_isoverflow_to_int(src_exponent,srcp1,srcp2)) {
202                         if (Dbl_iszero_sign(srcp1)) result = 0x7fffffff;
203                         else result = 0x80000000; 
204
205                         if (Is_invalidtrap_enabled()) {
206                             return(INVALIDEXCEPTION);
207                         }
208                         Set_invalidflag();
209                         *dstptr = result;
210                         return(NOEXCEPTION);
211                 }
212         }
213         /*
214          * Generate result
215          */
216         if (src_exponent >= 0) {
217                 tempp1 = srcp1;
218                 tempp2 = srcp2;
219                 Dbl_clear_signexponent_set_hidden(tempp1);
220                 Int_from_dbl_mantissa(tempp1,tempp2,src_exponent);
221                 if (Dbl_isone_sign(srcp1) && (src_exponent <= SGL_FX_MAX_EXP))
222                         result = -Dbl_allp1(tempp1);
223                 else result = Dbl_allp1(tempp1);
224                 *dstptr = result;
225
226                 /* check for inexact */
227                 if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) {
228                         if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
229                         else Set_inexactflag();
230                 }
231         }
232         else {
233                 *dstptr = 0;
234
235                 /* check for inexact */
236                 if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
237                         if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
238                         else Set_inexactflag();
239                 }
240         }
241         return(NOEXCEPTION);
242 }
243
244 /*
245  *  Double Floating-point to Double Fixed-point 
246  */
247 /*ARGSUSED*/
248 int
249 dbl_to_dbl_fcnvfxt(
250                         dbl_floating_point *srcptr,
251                         unsigned int *nullptr,
252                         dbl_integer *dstptr,
253                         unsigned int *status)
254 {
255         register int src_exponent, resultp1;
256         register unsigned int srcp1, srcp2, tempp1, tempp2, resultp2;
257
258         Dbl_copyfromptr(srcptr,srcp1,srcp2);
259         src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
260
261         /* 
262          * Test for overflow
263          */
264         if (src_exponent > DBL_FX_MAX_EXP) {
265                 /* check for MININT */
266                 if ((src_exponent > DBL_FX_MAX_EXP + 1) || 
267                 Dbl_isnotzero_mantissa(srcp1,srcp2) || Dbl_iszero_sign(srcp1)) {
268                         if (Dbl_iszero_sign(srcp1)) {
269                               resultp1 = 0x7fffffff;
270                               resultp2 = 0xffffffff;
271                         }
272                         else {
273                             resultp1 = 0x80000000; 
274                             resultp2 = 0;
275                         }
276                         if (Is_invalidtrap_enabled()) {
277                             return(INVALIDEXCEPTION);
278                         }
279                         Set_invalidflag();
280                         Dint_copytoptr(resultp1,resultp2,dstptr);
281                         return(NOEXCEPTION);
282                 }
283         }
284         /*
285          * Generate result
286          */
287         if (src_exponent >= 0) {
288                 tempp1 = srcp1;
289                 tempp2 = srcp2;
290                 Dbl_clear_signexponent_set_hidden(tempp1);
291                 Dint_from_dbl_mantissa(tempp1,tempp2,src_exponent,
292                 resultp1,resultp2);
293                 if (Dbl_isone_sign(srcp1)) {
294                         Dint_setone_sign(resultp1,resultp2);
295                 }
296                 Dint_copytoptr(resultp1,resultp2,dstptr);
297
298                 /* check for inexact */
299                 if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) {
300                         if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
301                         else Set_inexactflag();
302                 }
303         }
304         else {
305                 Dint_setzero(resultp1,resultp2);
306                 Dint_copytoptr(resultp1,resultp2,dstptr);
307
308                 /* check for inexact */
309                 if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
310                         if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
311                         else Set_inexactflag();
312                 }
313         }
314         return(NOEXCEPTION);
315 }