xref: /openbmc/linux/arch/parisc/math-emu/cnv_float.h (revision 75bf465f0bc33e9b776a46d6a1b9b990f5fb7c37)
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)
364