Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / arch / parisc / math-emu / cnv_float.h
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 #ifdef __NO_PA_HDRS
10     PA header file -- do not include this header file for non-PA builds.
11 #endif
12
13 /*
14  * Some more constants
15  */
16 #define SGL_FX_MAX_EXP 30
17 #define DBL_FX_MAX_EXP 62
18 #define QUAD_FX_MAX_EXP 126
19
20 #define Dintp1(object) (object)
21 #define Dintp2(object) (object)
22
23 #define Duintp1(object) (object)
24 #define Duintp2(object) (object)
25
26 #define Qintp0(object) (object)
27 #define Qintp1(object) (object)
28 #define Qintp2(object) (object)
29 #define Qintp3(object) (object)
30
31
32 /*
33  * These macros will be used specifically by the convert instructions.
34  *
35  *
36  * Single format macros
37  */
38
39 #define Sgl_to_dbl_exponent(src_exponent,dest)                  \
40     Deposit_dexponent(dest,src_exponent+(DBL_BIAS-SGL_BIAS))
41
42 #define Sgl_to_dbl_mantissa(src_mantissa,destA,destB)   \
43     Deposit_dmantissap1(destA,src_mantissa>>3);         \
44     Dmantissap2(destB) = src_mantissa << 29
45
46 #define Sgl_isinexact_to_fix(sgl_value,exponent)        \
47     ((exponent < (SGL_P - 1)) ?                         \
48      (Sall(sgl_value) << (SGL_EXP_LENGTH + 1 + exponent)) : FALSE)
49
50 #define Int_isinexact_to_sgl(int_value) ((int_value << 33 - SGL_EXP_LENGTH) != 0)
51
52 #define Sgl_roundnearest_from_int(int_value,sgl_value)                  \
53     if (int_value & 1<<(SGL_EXP_LENGTH - 2))   /* round bit */          \
54         if (((int_value << 34 - SGL_EXP_LENGTH) != 0) || Slow(sgl_value)) \
55                 Sall(sgl_value)++
56
57 #define Dint_isinexact_to_sgl(dint_valueA,dint_valueB)          \
58     (((Dintp1(dint_valueA) << 33 - SGL_EXP_LENGTH) != 0) || Dintp2(dint_valueB))
59
60 #define Sgl_roundnearest_from_dint(dint_valueA,dint_valueB,sgl_value)   \
61     if (Dintp1(dint_valueA) & 1<<(SGL_EXP_LENGTH - 2))                  \
62         if (((Dintp1(dint_valueA) << 34 - SGL_EXP_LENGTH) != 0) ||      \
63         Dintp2(dint_valueB) || Slow(sgl_value)) Sall(sgl_value)++
64
65 #define Dint_isinexact_to_dbl(dint_value)       \
66     (Dintp2(dint_value) << 33 - DBL_EXP_LENGTH)
67
68 #define Dbl_roundnearest_from_dint(dint_opndB,dbl_opndA,dbl_opndB)      \
69     if (Dintp2(dint_opndB) & 1<<(DBL_EXP_LENGTH - 2))                   \
70        if ((Dintp2(dint_opndB) << 34 - DBL_EXP_LENGTH) || Dlowp2(dbl_opndB))  \
71           if ((++Dallp2(dbl_opndB))==0) Dallp1(dbl_opndA)++
72
73 #define Sgl_isone_roundbit(sgl_value,exponent)                  \
74     ((Sall(sgl_value) << (SGL_EXP_LENGTH + 1 + exponent)) >> 31)
75
76 #define Sgl_isone_stickybit(sgl_value,exponent)         \
77     (exponent < (SGL_P - 2) ?                           \
78      Sall(sgl_value) << (SGL_EXP_LENGTH + 2 + exponent) : FALSE)
79
80
81 /* 
82  * Double format macros
83  */
84
85 #define Dbl_to_sgl_exponent(src_exponent,dest)                  \
86     dest = src_exponent + (SGL_BIAS - DBL_BIAS)
87
88 #define Dbl_to_sgl_mantissa(srcA,srcB,dest,inexact,guard,sticky,odd)    \
89     Shiftdouble(Dmantissap1(srcA),Dmantissap2(srcB),29,dest);   \
90     guard = Dbit3p2(srcB);                                      \
91     sticky = Dallp2(srcB)<<4;                                   \
92     inexact = guard | sticky;                                   \
93     odd = Dbit2p2(srcB)
94
95 #define Dbl_to_sgl_denormalized(srcA,srcB,exp,dest,inexact,guard,sticky,odd,tiny) \
96     Deposit_dexponent(srcA,1);                                          \
97     tiny = TRUE;                                                        \
98     if (exp >= -2) {                                                    \
99         if (exp == 0) {                                                 \
100             inexact = Dallp2(srcB) << 3;                                \
101             guard = inexact >> 31;                                      \
102             sticky = inexact << 1;                                      \
103             Shiftdouble(Dmantissap1(srcA),Dmantissap2(srcB),29,dest);   \
104             odd = dest << 31;                                           \
105             if (inexact) {                                              \
106                 switch(Rounding_mode()) {                               \
107                     case ROUNDPLUS:                                     \
108                         if (Dbl_iszero_sign(srcA)) {                    \
109                             dest++;                                     \
110                             if (Sgl_isone_hidden(dest)) \
111                                 tiny = FALSE;                           \
112                             dest--;                                     \
113                         }                                               \
114                         break;                                          \
115                     case ROUNDMINUS:                                    \
116                         if (Dbl_isone_sign(srcA)) {                     \
117                             dest++;                                     \
118                             if (Sgl_isone_hidden(dest)) \
119                                 tiny = FALSE;                           \
120                             dest--;                                     \
121                         }                                               \
122                         break;                                          \
123                     case ROUNDNEAREST:                                  \
124                         if (guard && (sticky || odd)) {                 \
125                             dest++;                                     \
126                             if (Sgl_isone_hidden(dest)) \
127                                 tiny = FALSE;                           \
128                             dest--;                                     \
129                         }                                               \
130                         break;                                          \
131                 }                                                       \
132             }                                                           \
133                 /* shift right by one to get correct result */          \
134                 guard = odd;                                            \
135                 sticky = inexact;                                       \
136                 inexact |= guard;                                       \
137                 dest >>= 1;                                             \
138                 Deposit_dsign(srcA,0);                                  \
139                 Shiftdouble(Dallp1(srcA),Dallp2(srcB),30,dest);         \
140                 odd = dest << 31;                                       \
141         }                                                               \
142         else {                                                          \
143             inexact = Dallp2(srcB) << (2 + exp);                        \
144             guard = inexact >> 31;                                      \
145             sticky = inexact << 1;                                      \
146             Deposit_dsign(srcA,0);                                      \
147             if (exp == -2) dest = Dallp1(srcA);                         \
148             else Variable_shift_double(Dallp1(srcA),Dallp2(srcB),30-exp,dest); \
149             odd = dest << 31;                                           \
150         }                                                               \
151     }                                                                   \
152     else {                                                              \
153         Deposit_dsign(srcA,0);                                          \
154         if (exp > (1 - SGL_P)) {                                        \
155             dest = Dallp1(srcA) >> (- 2 - exp);                         \
156             inexact = Dallp1(srcA) << (34 + exp);                       \
157             guard = inexact >> 31;                                      \
158             sticky = (inexact << 1) | Dallp2(srcB);                     \
159             inexact |= Dallp2(srcB);                                    \
160             odd = dest << 31;                                           \
161         }                                                               \
162         else {                                                          \
163             dest = 0;                                                   \
164             inexact = Dallp1(srcA) | Dallp2(srcB);                      \
165             if (exp == (1 - SGL_P)) {                                   \
166                 guard = Dhidden(srcA);                                  \
167                 sticky = Dmantissap1(srcA) | Dallp2(srcB);              \
168             }                                                           \
169             else {                                                      \
170                 guard = 0;                                              \
171                 sticky = inexact;                                       \
172             }                                                           \
173             odd = 0;                                                    \
174         }                                                               \
175     }                                                                   \
176     exp = 0
177
178 #define Dbl_isinexact_to_fix(dbl_valueA,dbl_valueB,exponent)            \
179     (exponent < (DBL_P-33) ?                                            \
180      Dallp2(dbl_valueB) || Dallp1(dbl_valueA) << (DBL_EXP_LENGTH+1+exponent) : \
181      (exponent < (DBL_P-1) ? Dallp2(dbl_valueB) << (exponent + (33-DBL_P)) :   \
182       FALSE))
183
184 #define Dbl_isoverflow_to_int(exponent,dbl_valueA,dbl_valueB)           \
185     ((exponent > SGL_FX_MAX_EXP + 1) || Dsign(dbl_valueA)==0 ||         \
186      Dmantissap1(dbl_valueA)!=0 || (Dallp2(dbl_valueB)>>21)!=0 ) 
187
188 #define Dbl_isone_roundbit(dbl_valueA,dbl_valueB,exponent)              \
189     ((exponent < (DBL_P - 33) ?                                         \
190       Dallp1(dbl_valueA) >> ((30 - DBL_EXP_LENGTH) - exponent) :        \
191       Dallp2(dbl_valueB) >> ((DBL_P - 2) - exponent)) & 1)
192
193 #define Dbl_isone_stickybit(dbl_valueA,dbl_valueB,exponent)             \
194     (exponent < (DBL_P-34) ?                                            \
195      (Dallp2(dbl_valueB) || Dallp1(dbl_valueA)<<(DBL_EXP_LENGTH+2+exponent)) : \
196      (exponent<(DBL_P-2) ? (Dallp2(dbl_valueB) << (exponent + (34-DBL_P))) : \
197       FALSE))
198
199
200 /* Int macros */
201
202 #define Int_from_sgl_mantissa(sgl_value,exponent)       \
203     Sall(sgl_value) =                           \
204         (unsigned)(Sall(sgl_value) << SGL_EXP_LENGTH)>>(31 - exponent)
205
206 #define Int_from_dbl_mantissa(dbl_valueA,dbl_valueB,exponent)   \
207     Shiftdouble(Dallp1(dbl_valueA),Dallp2(dbl_valueB),22,Dallp1(dbl_valueA)); \
208     if (exponent < 31) Dallp1(dbl_valueA) >>= 30 - exponent;    \
209     else Dallp1(dbl_valueA) <<= 1
210
211 #define Int_negate(int_value) int_value = -int_value
212
213
214 /* Dint macros */
215
216 #define Dint_from_sgl_mantissa(sgl_value,exponent,dresultA,dresultB)    \
217     {Sall(sgl_value) <<= SGL_EXP_LENGTH;  /*  left-justify  */          \
218     if (exponent <= 31) {                                               \
219         Dintp1(dresultA) = 0;                                           \
220         Dintp2(dresultB) = (unsigned)Sall(sgl_value) >> (31 - exponent); \
221     }                                                                   \
222     else {                                                              \
223         Dintp1(dresultA) = Sall(sgl_value) >> (63 - exponent);          \
224         Dintp2(dresultB) = Sall(sgl_value) << (exponent - 31);          \
225     }}
226
227
228 #define Dint_from_dbl_mantissa(dbl_valueA,dbl_valueB,exponent,destA,destB) \
229     {if (exponent < 32) {                                               \
230         Dintp1(destA) = 0;                                              \
231         if (exponent <= 20)                                             \
232             Dintp2(destB) = Dallp1(dbl_valueA) >> 20-exponent;          \
233         else Variable_shift_double(Dallp1(dbl_valueA),Dallp2(dbl_valueB), \
234              52-exponent,Dintp2(destB));                                        \
235     }                                                                   \
236     else {                                                              \
237         if (exponent <= 52) {                                           \
238             Dintp1(destA) = Dallp1(dbl_valueA) >> 52-exponent;          \
239             if (exponent == 52) Dintp2(destB) = Dallp2(dbl_valueB);     \
240             else Variable_shift_double(Dallp1(dbl_valueA),Dallp2(dbl_valueB), \
241             52-exponent,Dintp2(destB));                                 \
242         }                                                               \
243         else {                                                          \
244             Variable_shift_double(Dallp1(dbl_valueA),Dallp2(dbl_valueB), \
245             84-exponent,Dintp1(destA));                                 \
246             Dintp2(destB) = Dallp2(dbl_valueB) << exponent-52;          \
247         }                                                               \
248     }}
249
250 #define Dint_setzero(dresultA,dresultB)         \
251     Dintp1(dresultA) = 0;       \
252     Dintp2(dresultB) = 0
253
254 #define Dint_setone_sign(dresultA,dresultB)             \
255     Dintp1(dresultA) = ~Dintp1(dresultA);               \
256     if ((Dintp2(dresultB) = -Dintp2(dresultB)) == 0) Dintp1(dresultA)++
257
258 #define Dint_set_minint(dresultA,dresultB)              \
259     Dintp1(dresultA) = (unsigned int)1<<31;             \
260     Dintp2(dresultB) = 0
261
262 #define Dint_isone_lowp2(dresultB)  (Dintp2(dresultB) & 01)
263
264 #define Dint_increment(dresultA,dresultB)               \
265     if ((++Dintp2(dresultB))==0) Dintp1(dresultA)++
266
267 #define Dint_decrement(dresultA,dresultB)               \
268     if ((Dintp2(dresultB)--)==0) Dintp1(dresultA)--
269
270 #define Dint_negate(dresultA,dresultB)                  \
271     Dintp1(dresultA) = ~Dintp1(dresultA);               \
272     if ((Dintp2(dresultB) = -Dintp2(dresultB))==0) Dintp1(dresultA)++
273
274 #define Dint_copyfromptr(src,destA,destB) \
275      Dintp1(destA) = src->wd0;          \
276      Dintp2(destB) = src->wd1
277 #define Dint_copytoptr(srcA,srcB,dest)  \
278     dest->wd0 = Dintp1(srcA);           \
279     dest->wd1 = Dintp2(srcB)
280
281
282 /* other macros  */
283
284 #define Find_ms_one_bit(value, position)        \
285     {                                           \
286         int var;                                \
287         for (var=8; var >=1; var >>= 1) {       \
288             if (value >> 32 - position)         \
289                 position -= var;                \
290                 else position += var;           \
291         }                                       \
292         if ((value >> 32 - position) == 0)      \
293             position--;                         \
294         else position -= 2;                     \
295     }
296
297
298 /*
299  * Unsigned int macros
300  */
301 #define Duint_copyfromptr(src,destA,destB) \
302     Dint_copyfromptr(src,destA,destB)
303 #define Duint_copytoptr(srcA,srcB,dest) \
304     Dint_copytoptr(srcA,srcB,dest)
305
306 #define Suint_isinexact_to_sgl(int_value) \
307     (int_value << 32 - SGL_EXP_LENGTH)
308
309 #define Sgl_roundnearest_from_suint(suint_value,sgl_value)              \
310     if (suint_value & 1<<(SGL_EXP_LENGTH - 1))   /* round bit */        \
311         if ((suint_value << 33 - SGL_EXP_LENGTH) || Slow(sgl_value))    \
312                 Sall(sgl_value)++
313
314 #define Duint_isinexact_to_sgl(duint_valueA,duint_valueB)       \
315     ((Duintp1(duint_valueA) << 32 - SGL_EXP_LENGTH) || Duintp2(duint_valueB))
316
317 #define Sgl_roundnearest_from_duint(duint_valueA,duint_valueB,sgl_value) \
318     if (Duintp1(duint_valueA) & 1<<(SGL_EXP_LENGTH - 1))                \
319         if ((Duintp1(duint_valueA) << 33 - SGL_EXP_LENGTH) ||           \
320         Duintp2(duint_valueB) || Slow(sgl_value)) Sall(sgl_value)++
321
322 #define Duint_isinexact_to_dbl(duint_value)     \
323     (Duintp2(duint_value) << 32 - DBL_EXP_LENGTH)
324
325 #define Dbl_roundnearest_from_duint(duint_opndB,dbl_opndA,dbl_opndB)    \
326     if (Duintp2(duint_opndB) & 1<<(DBL_EXP_LENGTH - 1))                 \
327        if ((Duintp2(duint_opndB) << 33 - DBL_EXP_LENGTH) || Dlowp2(dbl_opndB)) \
328           if ((++Dallp2(dbl_opndB))==0) Dallp1(dbl_opndA)++
329
330 #define Suint_from_sgl_mantissa(src,exponent,result)    \
331     Sall(result) = (unsigned)(Sall(src) << SGL_EXP_LENGTH)>>(31 - exponent)
332
333 #define Sgl_isinexact_to_unsigned(sgl_value,exponent)   \
334     Sgl_isinexact_to_fix(sgl_value,exponent)
335
336 #define Duint_from_sgl_mantissa(sgl_value,exponent,dresultA,dresultB)   \
337   {unsigned int val = Sall(sgl_value) << SGL_EXP_LENGTH;                \
338     if (exponent <= 31) {                                               \
339         Dintp1(dresultA) = 0;                                           \
340         Dintp2(dresultB) = val >> (31 - exponent);                      \
341     }                                                                   \
342     else {                                                              \
343         Dintp1(dresultA) = val >> (63 - exponent);                      \
344         Dintp2(dresultB) = exponent <= 62 ? val << (exponent - 31) : 0; \
345     }                                                                   \
346   }
347
348 #define Duint_setzero(dresultA,dresultB)        \
349     Dint_setzero(dresultA,dresultB)
350
351 #define Duint_increment(dresultA,dresultB) Dint_increment(dresultA,dresultB) 
352
353 #define Duint_isone_lowp2(dresultB)  Dint_isone_lowp2(dresultB)
354
355 #define Suint_from_dbl_mantissa(srcA,srcB,exponent,dest) \
356     Shiftdouble(Dallp1(srcA),Dallp2(srcB),21,dest); \
357     dest = (unsigned)dest >> 31 - exponent
358
359 #define Dbl_isinexact_to_unsigned(dbl_valueA,dbl_valueB,exponent) \
360     Dbl_isinexact_to_fix(dbl_valueA,dbl_valueB,exponent)
361
362 #define Duint_from_dbl_mantissa(dbl_valueA,dbl_valueB,exponent,destA,destB) \
363     Dint_from_dbl_mantissa(dbl_valueA,dbl_valueB,exponent,destA,destB)