xref: /openbsd/sys/arch/hppa/spmath/cnv_float.h (revision 7eec34da)
1 /*	$OpenBSD: cnv_float.h,v 1.9 2003/04/10 17:27:58 mickey Exp $	*/
2 /*
3   (c) Copyright 1986 HEWLETT-PACKARD COMPANY
4   To anyone who acknowledges that this file is provided "AS IS"
5   without any express or implied warranty:
6       permission to use, copy, modify, and distribute this file
7   for any purpose is hereby granted without fee, provided that
8   the above copyright notice and this notice appears in all
9   copies, and that the name of Hewlett-Packard Company not be
10   used in advertising or publicity pertaining to distribution
11   of the software without specific, written prior permission.
12   Hewlett-Packard Company makes no representations about the
13   suitability of this software for any purpose.
14 */
15 /* @(#)cnv_float.h: Revision: 2.9.88.1 Date: 93/12/07 15:05:29 */
16 
17 /*
18  * Some more constants
19  */
20 #define SGL_FX_MAX_EXP 30
21 #define DBL_FX_MAX_EXP 62
22 #define QUAD_FX_MAX_EXP 126
23 
24 
25 #define Dintp1(object) (object)
26 #define Dintp2(object) (object)
27 
28 #define Qintp0(object) (object)
29 #define Qintp1(object) (object)
30 #define Qintp2(object) (object)
31 #define Qintp3(object) (object)
32 
33 
34 /*
35  * These macros will be used specifically by the convert instructions.
36  *
37  *
38  * Single format macros
39  */
40 
41 #define Sgl_to_dbl_exponent(src_exponent,dest)			\
42     Deposit_dexponent(dest,src_exponent+(DBL_BIAS-SGL_BIAS))
43 
44 #define Sgl_to_dbl_mantissa(src_mantissa,destA,destB)	\
45     Deposit_dmantissap1(destA,src_mantissa>>3);		\
46     Dmantissap2(destB) = src_mantissa << 29
47 
48 #define Sgl_isinexact_to_fix(sgl_value,exponent)	\
49     ((exponent < (SGL_P - 1)) ?				\
50      (Sall(sgl_value) << (SGL_EXP_LENGTH + 1 + exponent)) : FALSE)
51 
52 #define Int_isinexact_to_sgl(int_value)	(int_value << (33 - SGL_EXP_LENGTH))
53 
54 #define Sgl_roundnearest_from_int(int_value,sgl_value)			\
55     if (int_value & 1<<(SGL_EXP_LENGTH - 2))   /* round bit */		\
56 	if ((int_value << (34 - SGL_EXP_LENGTH)) || Slow(sgl_value))	\
57 		Sall(sgl_value)++
58 
59 #define Dint_isinexact_to_sgl(dint_valueA,dint_valueB)		\
60     ((Dintp1(dint_valueA) << (33 - SGL_EXP_LENGTH)) || Dintp2(dint_valueB))
61 
62 #define Sgl_roundnearest_from_dint(dint_valueA,dint_valueB,sgl_value)	\
63     if (Dintp1(dint_valueA) & 1<<(SGL_EXP_LENGTH - 2))			\
64 	if ((Dintp1(dint_valueA) << (34 - SGL_EXP_LENGTH)) ||		\
65 	Dintp2(dint_valueB) || Slow(sgl_value)) Sall(sgl_value)++
66 
67 #define Dint_isinexact_to_dbl(dint_value)	\
68     (Dintp2(dint_value) << (33 - DBL_EXP_LENGTH))
69 
70 #define Dbl_roundnearest_from_dint(dint_opndB,dbl_opndA,dbl_opndB)	\
71     if (Dintp2(dint_opndB) & 1<<(DBL_EXP_LENGTH - 2))			\
72        if ((Dintp2(dint_opndB) << (34 - DBL_EXP_LENGTH)) || Dlowp2(dbl_opndB))  \
73           if ((++Dallp2(dbl_opndB))==0) Dallp1(dbl_opndA)++
74 
75 #define Sgl_isone_roundbit(sgl_value,exponent)			\
76     ((Sall(sgl_value) << (SGL_EXP_LENGTH + 1 + exponent)) >> 31)
77 
78 #define Sgl_isone_stickybit(sgl_value,exponent)		\
79     (exponent < (SGL_P - 2) ?				\
80      Sall(sgl_value) << (SGL_EXP_LENGTH + 2 + exponent) : FALSE)
81 
82 
83 /*
84  * Double format macros
85  */
86 
87 #define Dbl_to_sgl_exponent(src_exponent,dest)			\
88     dest = src_exponent + (SGL_BIAS - DBL_BIAS)
89 
90 #define Dbl_to_sgl_mantissa(srcA,srcB,dest,inexact,guard,sticky,odd)	\
91     Shiftdouble(Dmantissap1(srcA),Dmantissap2(srcB),29,dest);	\
92     guard = Dbit3p2(srcB);					\
93     sticky = Dallp2(srcB)<<4;					\
94     inexact = guard | sticky;					\
95     odd = Dbit2p2(srcB)
96 
97 #define Dbl_to_sgl_denormalized(srcA,srcB,exp,dest,inexact,guard,sticky,odd,tiny) \
98     Deposit_dexponent(srcA,1);						\
99     tiny = TRUE;							\
100     if (exp >= -2) {							\
101 	if (exp == 0) {							\
102 	    inexact = Dallp2(srcB) << 3;				\
103 	    guard = inexact >> 31;					\
104 	    sticky = inexact << 1;					\
105 	    Shiftdouble(Dmantissap1(srcA),Dmantissap2(srcB),29,dest);	\
106 	    odd = dest << 31;						\
107 	    if (inexact) {						\
108 		switch(Rounding_mode()) {				\
109 		    case ROUNDPLUS:					\
110 			if (Dbl_iszero_sign(srcA)) {			\
111 			    dest++;					\
112 			    if (Sgl_isone_hidden(dest))	\
113 				tiny = FALSE;				\
114 			    dest--;					\
115 			}						\
116 			break;						\
117 		    case ROUNDMINUS:					\
118 			if (Dbl_isone_sign(srcA)) {			\
119 			    dest++;					\
120 			    if (Sgl_isone_hidden(dest))	\
121 				tiny = FALSE;				\
122 			    dest--;					\
123 			}						\
124 			break;						\
125 		    case ROUNDNEAREST:					\
126 			if (guard && (sticky || odd)) {			\
127 			    dest++;					\
128 			    if (Sgl_isone_hidden(dest))	\
129 				tiny = FALSE;				\
130 			    dest--;					\
131 			}						\
132 			break;						\
133 		}							\
134 	    }								\
135 		/* shift right by one to get correct result */		\
136 		guard = odd;						\
137 		sticky = inexact;					\
138 		inexact |= guard;					\
139 		dest >>= 1;						\
140 		Deposit_dsign(srcA,0);					\
141 	        Shiftdouble(Dallp1(srcA),Dallp2(srcB),30,dest);		\
142 	        odd = dest << 31;					\
143 	}								\
144 	else {								\
145 	    inexact = Dallp2(srcB) << (2 + exp);			\
146 	    guard = inexact >> 31;					\
147 	    sticky = inexact << 1;					\
148 	    Deposit_dsign(srcA,0);					\
149 	    if (exp == -2) dest = Dallp1(srcA);				\
150 	    else Variable_shift_double(Dallp1(srcA),Dallp2(srcB),30-exp,dest); \
151 	    odd = dest << 31;						\
152 	}								\
153     }									\
154     else {								\
155 	Deposit_dsign(srcA,0);						\
156 	if (exp > (1 - SGL_P)) {					\
157 	    dest = Dallp1(srcA) >> (- 2 - exp);				\
158 	    inexact = Dallp1(srcA) << (34 + exp);			\
159 	    guard = inexact >> 31;					\
160 	    sticky = (inexact << 1) | Dallp2(srcB);			\
161 	    inexact |= Dallp2(srcB);					\
162 	    odd = dest << 31;						\
163 	}								\
164 	else {								\
165 	    dest = 0;							\
166 	    inexact = Dallp1(srcA) | Dallp2(srcB);			\
167 	    if (exp == (1 - SGL_P)) {					\
168 		guard = Dhidden(srcA);					\
169 		sticky = Dmantissap1(srcA) | Dallp2(srcB);		\
170 	    }								\
171 	    else {							\
172 		guard = 0;						\
173 		sticky = inexact;					\
174 	    }								\
175 	    odd = 0;							\
176 	}								\
177     }									\
178     exp = 0
179 
180 #define Dbl_isinexact_to_fix(dbl_valueA,dbl_valueB,exponent)		\
181     (exponent < (DBL_P-33) ?						\
182      Dallp2(dbl_valueB) || Dallp1(dbl_valueA) << (DBL_EXP_LENGTH+1+exponent) : \
183      (exponent < (DBL_P-1) ? Dallp2(dbl_valueB) << (exponent + (33-DBL_P)) :   \
184       FALSE))
185 
186 #define Dbl_isoverflow_to_int(exponent,dbl_valueA,dbl_valueB)		\
187     ((exponent > SGL_FX_MAX_EXP + 1) || Dsign(dbl_valueA)==0 ||		\
188      Dmantissap1(dbl_valueA)!=0 || (Dallp2(dbl_valueB)>>21)!=0 )
189 
190 #define Dbl_isone_roundbit(dbl_valueA,dbl_valueB,exponent)              \
191     ((exponent < (DBL_P - 33) ?						\
192       Dallp1(dbl_valueA) >> ((30 - DBL_EXP_LENGTH) - exponent) :	\
193       Dallp2(dbl_valueB) >> ((DBL_P - 2) - exponent)) & 1)
194 
195 #define Dbl_isone_stickybit(dbl_valueA,dbl_valueB,exponent)		\
196     (exponent < (DBL_P-34) ?						\
197      (Dallp2(dbl_valueB) || Dallp1(dbl_valueA)<<(DBL_EXP_LENGTH+2+exponent)) : \
198      (exponent<(DBL_P-2) ? (Dallp2(dbl_valueB) << (exponent + (34-DBL_P))) : \
199       FALSE))
200 
201 
202 /* Int macros */
203 
204 #define Int_from_sgl_mantissa(sgl_value,exponent)	\
205     Sall(sgl_value) =				\
206 	(unsigned)(Sall(sgl_value) << SGL_EXP_LENGTH)>>(31 - exponent)
207 
208 #define Int_from_dbl_mantissa(dbl_valueA,dbl_valueB,exponent)	\
209     Shiftdouble(Dallp1(dbl_valueA),Dallp2(dbl_valueB),22,Dallp1(dbl_valueA)); \
210     if (exponent < 31) Dallp1(dbl_valueA) >>= 30 - exponent;	\
211     else Dallp1(dbl_valueA) <<= 1
212 
213 #define Int_negate(int_value) int_value = -int_value
214 
215 
216 /* Dint macros */
217 
218 #define Dint_from_sgl_mantissa(sgl_value,exponent,dresultA,dresultB)	\
219     {Sall(sgl_value) <<= SGL_EXP_LENGTH;  /*  left-justify  */		\
220     if (exponent <= 31) {						\
221 	Dintp1(dresultA) = 0;						\
222 	Dintp2(dresultB) = (unsigned)Sall(sgl_value) >> (31 - exponent); \
223     }									\
224     else {								\
225 	Dintp1(dresultA) = Sall(sgl_value) >> (63 - exponent);		\
226 	Dintp2(dresultB) = Sall(sgl_value) << (exponent - 31);		\
227     }}
228 
229 
230 #define Dint_from_dbl_mantissa(dbl_valueA,dbl_valueB,exponent,destA,destB) \
231     {if (exponent < 32) {						\
232 	Dintp1(destA) = 0;						\
233 	if (exponent <= 20)						\
234 	    Dintp2(destB) = Dallp1(dbl_valueA) >> (20-exponent);	\
235 	else Variable_shift_double(Dallp1(dbl_valueA),Dallp2(dbl_valueB), \
236 	     52-exponent,Dintp2(destB));					\
237     }									\
238     else {								\
239 	if (exponent <= 52) {						\
240 	    Dintp1(destA) = Dallp1(dbl_valueA) >> (52-exponent);	\
241 	    if (exponent == 52) Dintp2(destB) = Dallp2(dbl_valueB);	\
242 	    else Variable_shift_double(Dallp1(dbl_valueA),Dallp2(dbl_valueB), \
243 	    52-exponent,Dintp2(destB));					\
244         }								\
245 	else {								\
246 	    Variable_shift_double(Dallp1(dbl_valueA),Dallp2(dbl_valueB), \
247 	    84-exponent,Dintp1(destA));					\
248 	    Dintp2(destB) = Dallp2(dbl_valueB) << (exponent-52);	\
249 	}								\
250     }}
251 
252 #define Dint_setzero(dresultA,dresultB)		\
253     Dintp1(dresultA) = 0;			\
254     Dintp2(dresultB) = 0
255 
256 #define Dint_setone_sign(dresultA,dresultB)		\
257     Dintp1(dresultA) = ~Dintp1(dresultA);		\
258     if ((Dintp2(dresultB) = -Dintp2(dresultB)) == 0) Dintp1(dresultA)++
259 
260 #define Dint_set_minint(dresultA,dresultB)		\
261     Dintp1(dresultA) = 1<<31;				\
262     Dintp2(dresultB) = 0
263 
264 #define Dint_isone_lowp2(dresultB)  (Dintp2(dresultB) & 01)
265 
266 #define Dint_increment(dresultA,dresultB)		\
267     if ((++Dintp2(dresultB))==0) Dintp1(dresultA)++
268 
269 #define Dint_decrement(dresultA,dresultB)		\
270     if ((Dintp2(dresultB)--)==0) Dintp1(dresultA)--
271 
272 #define Dint_negate(dresultA,dresultB)			\
273     Dintp1(dresultA) = ~Dintp1(dresultA);		\
274     if ((Dintp2(dresultB) = -Dintp2(dresultB))==0) Dintp1(dresultA)++
275 
276 #define Dint_copyfromptr(src,destA,destB) \
277      Dintp1(destA) = src->wd0;		\
278      Dintp2(destB) = src->wd1
279 #define Dint_copytoptr(srcA,srcB,dest)	\
280     dest->wd0 = Dintp1(srcA);		\
281     dest->wd1 = Dintp2(srcB)
282 
283 
284 /* other macros  */
285 
286 #define Find_ms_one_bit(value, position)	\
287     {						\
288 	int var;				\
289 	for (var = 8; var >= 1; var >>= 1) {	\
290 	    if (value >> (32 - position))	\
291 		position -= var;		\
292 		else position += var;		\
293 	}					\
294 	if ((value >> (32 - position)) == 0)	\
295 	    position--;				\
296 	else position -= 2;			\
297     }
298 
299 int sgl_to_sgl_fcnvfx(sgl_floating_point *, sgl_floating_point *, sgl_floating_point *, unsigned int *);
300 int sgl_to_dbl_fcnvfx(sgl_floating_point *, sgl_floating_point *, dbl_integer *, unsigned int *);
301 int dbl_to_sgl_fcnvfx(dbl_floating_point *, dbl_floating_point *, int *, unsigned int *);
302 int dbl_to_dbl_fcnvfx(dbl_floating_point *, dbl_floating_point *, dbl_integer *, unsigned int *);
303 
304 int sgl_to_sgl_fcnvfxt(sgl_floating_point *, sgl_floating_point *, int *, unsigned int *);
305 int sgl_to_dbl_fcnvfxt(sgl_floating_point *, sgl_floating_point *, dbl_integer *, unsigned int *);
306 int dbl_to_sgl_fcnvfxt(dbl_floating_point *, dbl_floating_point *, int *, unsigned int *);
307 int dbl_to_dbl_fcnvfxt(dbl_floating_point *, dbl_floating_point *, dbl_integer *, unsigned int *);
308 
309 int sgl_to_sgl_fcnvxf(int *, int *, sgl_floating_point *, unsigned int *);
310 int sgl_to_dbl_fcnvxf(int *, int *, dbl_floating_point *, unsigned int *);
311 int dbl_to_sgl_fcnvxf(dbl_integer *, dbl_integer *, sgl_floating_point *, unsigned int *);
312 int dbl_to_dbl_fcnvxf(dbl_integer *, dbl_integer *, dbl_floating_point *, unsigned int *);
313