xref: /openbsd/sys/arch/hppa/spmath/sgl_float.h (revision 36fd90dc)
1 /*	$OpenBSD: sgl_float.h,v 1.13 2021/03/11 11:16:57 jsg 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 /* @(#)sgl_float.h: Revision: 2.8.88.1 Date: 93/12/07 15:07:17 */
16 
17 #include <sys/cdefs.h>
18 
19 /******************************
20  * Single precision functions *
21  ******************************/
22 
23 /* 32-bit word grabbing functions */
24 #define Sgl_firstword(value) Sall(value)
25 #define Sgl_secondword(value) dummy_location
26 #define Sgl_thirdword(value) dummy_location
27 #define Sgl_fourthword(value) dummy_location
28 
29 #define Sgl_sign(object) Ssign(object)
30 #define Sgl_exponent(object) Sexponent(object)
31 #define Sgl_signexponent(object) Ssignexponent(object)
32 #define Sgl_mantissa(object) Smantissa(object)
33 #define Sgl_exponentmantissa(object) Sexponentmantissa(object)
34 #define Sgl_all(object) Sall(object)
35 
36 /* sgl_and_signs ands the sign bits of each argument and puts the result
37  * into the first argument. sgl_or_signs ors those same sign bits */
38 #define Sgl_and_signs( src1dst, src2)		\
39     Sall(src1dst) = (Sall(src2)|~(1<<31)) & Sall(src1dst)
40 #define Sgl_or_signs( src1dst, src2)		\
41     Sall(src1dst) = (Sall(src2)&(1<<31)) | Sall(src1dst)
42 
43 /* The hidden bit is always the low bit of the exponent */
44 #define Sgl_clear_exponent_set_hidden(srcdst) Deposit_sexponent(srcdst,1)
45 #define Sgl_clear_signexponent_set_hidden(srcdst) \
46     Deposit_ssignexponent(srcdst,1)
47 #define Sgl_clear_sign(srcdst) Sall(srcdst) &= ~(1<<31)
48 #define Sgl_clear_signexponent(srcdst) Sall(srcdst) &= 0x007fffff
49 
50 /* varamount must be less than 32 for the next three functions */
51 #define Sgl_rightshift(srcdst, varamount)	\
52     Sall(srcdst) >>= varamount
53 #define Sgl_leftshift(srcdst, varamount)	\
54     Sall(srcdst) <<= varamount
55 #define Sgl_rightshift_exponentmantissa(srcdst, varamount) \
56     Sall(srcdst) = \
57 	(Sexponentmantissa(srcdst) >> (varamount)) | (Sall(srcdst) & (1<<31))
58 
59 #define Sgl_leftshiftby1_withextent(left,right,result) \
60     Shiftdouble(Sall(left),Extall(right),31,Sall(result))
61 
62 #define Sgl_rightshiftby1_withextent(left,right,dst)		\
63     Shiftdouble(Sall(left),Extall(right),1,Extall(right))
64 #define Sgl_arithrightshiftby1(srcdst)	\
65     Sall(srcdst) = (int)Sall(srcdst) >> 1
66 
67 /* Sign extend the sign bit with an integer destination */
68 #define Sgl_signextendedsign(value) Ssignedsign(value)
69 
70 #define Sgl_isone_hidden(sgl_value) (Shidden(sgl_value))
71 #define Sgl_increment(sgl_value) Sall(sgl_value) += 1
72 #define Sgl_increment_mantissa(sgl_value) \
73     Deposit_smantissa(sgl_value,sgl_value+1)
74 #define Sgl_decrement(sgl_value) Sall(sgl_value) -= 1
75 
76 #define Sgl_isone_sign(sgl_value) (Is_ssign(sgl_value)!=0)
77 #define Sgl_isone_hiddenoverflow(sgl_value) \
78     (Is_shiddenoverflow(sgl_value)!=0)
79 #define Sgl_isone_lowmantissa(sgl_value) (Is_slow(sgl_value)!=0)
80 #define Sgl_isone_signaling(sgl_value) (Is_ssignaling(sgl_value)!=0)
81 #define Sgl_is_signalingnan(sgl_value) (Ssignalingnan(sgl_value)==0x1ff)
82 #define Sgl_isnotzero(sgl_value) (Sall(sgl_value)!=0)
83 #define Sgl_isnotzero_hiddenhigh7mantissa(sgl_value) \
84     (Shiddenhigh7mantissa(sgl_value)!=0)
85 #define Sgl_isnotzero_low4(sgl_value) (Slow4(sgl_value)!=0)
86 #define Sgl_isnotzero_exponent(sgl_value) (Sexponent(sgl_value)!=0)
87 #define Sgl_isnotzero_mantissa(sgl_value) (Smantissa(sgl_value)!=0)
88 #define Sgl_isnotzero_exponentmantissa(sgl_value) \
89     (Sexponentmantissa(sgl_value)!=0)
90 #define Sgl_iszero(sgl_value) (Sall(sgl_value)==0)
91 #define Sgl_iszero_signaling(sgl_value) (Is_ssignaling(sgl_value)==0)
92 #define Sgl_iszero_hidden(sgl_value) (Is_shidden(sgl_value)==0)
93 #define Sgl_iszero_hiddenoverflow(sgl_value) \
94     (Is_shiddenoverflow(sgl_value)==0)
95 #define Sgl_iszero_hiddenhigh3mantissa(sgl_value) \
96     (Shiddenhigh3mantissa(sgl_value)==0)
97 #define Sgl_iszero_hiddenhigh7mantissa(sgl_value) \
98     (Shiddenhigh7mantissa(sgl_value)==0)
99 #define Sgl_iszero_sign(sgl_value) (Is_ssign(sgl_value)==0)
100 #define Sgl_iszero_exponent(sgl_value) (Sexponent(sgl_value)==0)
101 #define Sgl_iszero_mantissa(sgl_value) (Smantissa(sgl_value)==0)
102 #define Sgl_iszero_exponentmantissa(sgl_value) \
103     (Sexponentmantissa(sgl_value)==0)
104 #define Sgl_isinfinity_exponent(sgl_value)		\
105     (Sgl_exponent(sgl_value)==SGL_INFINITY_EXPONENT)
106 #define Sgl_isnotinfinity_exponent(sgl_value)		\
107     (Sgl_exponent(sgl_value)!=SGL_INFINITY_EXPONENT)
108 #define Sgl_isinfinity(sgl_value)			\
109     (Sgl_exponent(sgl_value)==SGL_INFINITY_EXPONENT &&	\
110     Sgl_mantissa(sgl_value)==0)
111 #define Sgl_isnan(sgl_value)				\
112     (Sgl_exponent(sgl_value)==SGL_INFINITY_EXPONENT &&	\
113     Sgl_mantissa(sgl_value)!=0)
114 #define Sgl_isnotnan(sgl_value)				\
115     (Sgl_exponent(sgl_value)!=SGL_INFINITY_EXPONENT ||	\
116     Sgl_mantissa(sgl_value)==0)
117 #define Sgl_islessthan(sgl_op1,sgl_op2)			\
118     (Sall(sgl_op1) < Sall(sgl_op2))
119 #define Sgl_isgreaterthan(sgl_op1,sgl_op2)		\
120     (Sall(sgl_op1) > Sall(sgl_op2))
121 #define Sgl_isnotlessthan(sgl_op1,sgl_op2)		\
122     (Sall(sgl_op1) >= Sall(sgl_op2))
123 #define Sgl_isequal(sgl_op1,sgl_op2)			\
124     (Sall(sgl_op1) == Sall(sgl_op2))
125 
126 #define Sgl_leftshiftby8(sgl_value) \
127     Sall(sgl_value) <<= 8
128 #define Sgl_leftshiftby4(sgl_value) \
129     Sall(sgl_value) <<= 4
130 #define Sgl_leftshiftby3(sgl_value) \
131     Sall(sgl_value) <<= 3
132 #define Sgl_leftshiftby2(sgl_value) \
133     Sall(sgl_value) <<= 2
134 #define Sgl_leftshiftby1(sgl_value) \
135     Sall(sgl_value) <<= 1
136 #define Sgl_rightshiftby1(sgl_value) \
137     Sall(sgl_value) >>= 1
138 #define Sgl_rightshiftby4(sgl_value) \
139     Sall(sgl_value) >>= 4
140 #define Sgl_rightshiftby8(sgl_value) \
141     Sall(sgl_value) >>= 8
142 
143 #define Sgl_ismagnitudeless(signlessleft,signlessright)			\
144 /*  unsigned int signlessleft, signlessright; */			\
145       (signlessleft < signlessright)
146 
147 
148 #define Sgl_copytoint_exponentmantissa(source,dest)     \
149     dest = Sexponentmantissa(source)
150 
151 /* A quiet NaN has the high mantissa bit clear and at least on other (in this
152  * case the adjacent bit) bit set. */
153 #define Sgl_set_quiet(sgl_value) Deposit_shigh2mantissa(sgl_value,1)
154 #define Sgl_set_exponent(sgl_value,exp) Deposit_sexponent(sgl_value,exp)
155 
156 #define Sgl_set_mantissa(dest,value) Deposit_smantissa(dest,value)
157 #define Sgl_set_exponentmantissa(dest,value) \
158     Deposit_sexponentmantissa(dest,value)
159 
160 /*  An infinity is represented with the max exponent and a zero mantissa */
161 #define Sgl_setinfinity_exponent(sgl_value) \
162     Deposit_sexponent(sgl_value,SGL_INFINITY_EXPONENT)
163 #define Sgl_setinfinity_exponentmantissa(sgl_value)	\
164     Deposit_sexponentmantissa(sgl_value, \
165 	(SGL_INFINITY_EXPONENT << (32-(1+SGL_EXP_LENGTH))))
166 #define Sgl_setinfinitypositive(sgl_value)		\
167     Sall(sgl_value) = (SGL_INFINITY_EXPONENT << (32-(1+SGL_EXP_LENGTH)))
168 #define Sgl_setinfinitynegative(sgl_value)		\
169     Sall(sgl_value) = (SGL_INFINITY_EXPONENT << (32-(1+SGL_EXP_LENGTH))) \
170     | (1<<31)
171 #define Sgl_setinfinity(sgl_value,sign)					\
172     Sall(sgl_value) = (SGL_INFINITY_EXPONENT << (32-(1+SGL_EXP_LENGTH))) | \
173      (sign << 31)
174 #define Sgl_sethigh4bits(sgl_value, extsign)  \
175     Deposit_shigh4(sgl_value,extsign)
176 #define Sgl_set_sign(sgl_value,sign) Deposit_ssign(sgl_value,sign)
177 #define Sgl_invert_sign(sgl_value)  \
178     Deposit_ssign(sgl_value,~Ssign(sgl_value))
179 #define Sgl_setone_sign(sgl_value) Deposit_ssign(sgl_value,1)
180 #define Sgl_setone_lowmantissa(sgl_value) Deposit_slow(sgl_value,1)
181 #define Sgl_setzero_sign(sgl_value)  Sall(sgl_value) &= 0x7fffffff
182 #define Sgl_setzero_exponent(sgl_value) Sall(sgl_value) &= 0x807fffff
183 #define Sgl_setzero_mantissa(sgl_value) Sall(sgl_value) &= 0xff800000
184 #define Sgl_setzero_exponentmantissa(sgl_value)  Sall(sgl_value) &= 0x80000000
185 #define Sgl_setzero(sgl_value) Sall(sgl_value) = 0
186 #define Sgl_setnegativezero(sgl_value) Sall(sgl_value) = 1U << 31
187 
188 /* Use following macro for both overflow & underflow conditions */
189 #define ovfl -
190 #define unfl +
191 #define Sgl_setwrapped_exponent(sgl_value,exponent,op) \
192     Deposit_sexponent(sgl_value,(exponent op SGL_WRAP))
193 
194 #define Sgl_setlargestpositive(sgl_value)				\
195     Sall(sgl_value) = ((SGL_EMAX+SGL_BIAS) << (32-(1+SGL_EXP_LENGTH)))	\
196 			| ((1<<(32-(1+SGL_EXP_LENGTH))) - 1)
197 #define Sgl_setlargestnegative(sgl_value)				\
198     Sall(sgl_value) = ((SGL_EMAX+SGL_BIAS) << (32-(1+SGL_EXP_LENGTH)))	\
199 			| ((1<<(32-(1+SGL_EXP_LENGTH))) - 1 ) | (1<<31)
200 
201 #define Sgl_setnegativeinfinity(sgl_value)	\
202     Sall(sgl_value) =				\
203     ((1<<SGL_EXP_LENGTH) | SGL_INFINITY_EXPONENT) << (32-(1+SGL_EXP_LENGTH))
204 #define Sgl_setlargest(sgl_value,sign)					\
205     Sall(sgl_value) = ((sign) << 31) |					\
206 	(((SGL_EMAX+SGL_BIAS) << (32-(1+SGL_EXP_LENGTH)))		\
207 	  | ((1 << (32-(1+SGL_EXP_LENGTH))) - 1 ))
208 #define Sgl_setlargest_exponentmantissa(sgl_value)			\
209     Sall(sgl_value) = (Sall(sgl_value) & (1<<31)) |			\
210 	(((SGL_EMAX+SGL_BIAS) << (32-(1+SGL_EXP_LENGTH)))		\
211 	  | ((1 << (32-(1+SGL_EXP_LENGTH))) - 1 ))
212 
213 /* The high bit is always zero so arithmetic or logical shifts will work. */
214 #define Sgl_right_align(srcdst,shift,extent)				\
215     /* sgl_floating_point srcdst; int shift; extension extent */	\
216     if (shift < 32) {							\
217 	Extall(extent) = Sall(srcdst) << (32-(shift));			\
218 	Sall(srcdst) >>= shift;						\
219     }									\
220     else {								\
221 	Extall(extent) = Sall(srcdst);					\
222 	Sall(srcdst) = 0;						\
223     }
224 #define Sgl_hiddenhigh3mantissa(sgl_value) Shiddenhigh3mantissa(sgl_value)
225 #define Sgl_hidden(sgl_value) Shidden(sgl_value)
226 #define Sgl_lowmantissa(sgl_value) Slow(sgl_value)
227 
228 /* The left argument is never smaller than the right argument */
229 #define Sgl_subtract(sgl_left,sgl_right,sgl_result) \
230     Sall(sgl_result) = Sall(sgl_left) - Sall(sgl_right)
231 
232 /* Subtract right augmented with extension from left augmented with zeros and
233  * store into result and extension. */
234 #define Sgl_subtract_withextension(left,right,extent,result)		\
235     /* sgl_floating_point left,right,result; extension extent */	\
236   Sgl_subtract(left,right,result);					\
237   if((Extall(extent) = 0-Extall(extent)))				\
238       Sall(result) = Sall(result)-1
239 
240 #define Sgl_addition(sgl_left,sgl_right,sgl_result) \
241     Sall(sgl_result) = Sall(sgl_left) + Sall(sgl_right)
242 
243 #define Sgl_xortointp1(left,right,result)			\
244     result = Sall(left) XOR Sall(right);
245 
246 #define Sgl_xorfromintp1(left,right,result)			\
247     Sall(result) = left XOR Sall(right)
248 
249 /* Need to Initialize */
250 #define Sgl_makequietnan(dest)						\
251     Sall(dest) = ((SGL_EMAX+SGL_BIAS)+1)<< (32-(1+SGL_EXP_LENGTH))	\
252 		| (1<<(32-(1+SGL_EXP_LENGTH+2)))
253 #define Sgl_makesignalingnan(dest)					\
254     Sall(dest) = ((SGL_EMAX+SGL_BIAS)+1)<< (32-(1+SGL_EXP_LENGTH))	\
255 		| (1<<(32-(1+SGL_EXP_LENGTH+1)))
256 
257 #define Sgl_normalize(sgl_opnd,exponent)			\
258 	while(Sgl_iszero_hiddenhigh7mantissa(sgl_opnd)) {	\
259 		Sgl_leftshiftby8(sgl_opnd);			\
260 		exponent -= 8;					\
261 	}							\
262 	if(Sgl_iszero_hiddenhigh3mantissa(sgl_opnd)) {		\
263 		Sgl_leftshiftby4(sgl_opnd);			\
264 		exponent -= 4;					\
265 	}							\
266 	while(Sgl_iszero_hidden(sgl_opnd)) {			\
267 		Sgl_leftshiftby1(sgl_opnd);			\
268 		exponent -= 1;					\
269 	}
270 
271 #define Sgl_setoverflow(sgl_opnd)				\
272 	/* set result to infinity or largest number */		\
273 	switch (Rounding_mode()) {				\
274 		case ROUNDPLUS:					\
275 			if (Sgl_isone_sign(sgl_opnd)) {		\
276 				Sgl_setlargestnegative(sgl_opnd); \
277 			}					\
278 			else {					\
279 				Sgl_setinfinitypositive(sgl_opnd); \
280 			}					\
281 			break;					\
282 		case ROUNDMINUS:				\
283 			if (Sgl_iszero_sign(sgl_opnd)) {	\
284 				Sgl_setlargestpositive(sgl_opnd); \
285 			}					\
286 			else {					\
287 				Sgl_setinfinitynegative(sgl_opnd); \
288 			}					\
289 			break;					\
290 		case ROUNDNEAREST:				\
291 			Sgl_setinfinity_exponentmantissa(sgl_opnd); \
292 			break;					\
293 		case ROUNDZERO:					\
294 			Sgl_setlargest_exponentmantissa(sgl_opnd); \
295 	}
296 
297 #define Sgl_denormalize(opnd,exponent,guard,sticky,inexact)		\
298 	Sgl_clear_signexponent_set_hidden(opnd);			\
299 	if (exponent >= (1 - SGL_P)) {					\
300 		guard = (Sall(opnd) >> (-(exponent))) & 1;		\
301 		if (exponent < 0) sticky |= Sall(opnd) << (32+exponent); \
302 		inexact = (guard) | (sticky);				\
303 		Sall(opnd) >>= (1-exponent);				\
304 	}								\
305 	else {								\
306 		guard = 0;						\
307 		sticky |= Sall(opnd);					\
308 		inexact = sticky;					\
309 		Sgl_setzero(opnd);					\
310 	}
311 
312 int sgl_fadd(sgl_floating_point *, sgl_floating_point *, sgl_floating_point *, unsigned int *);
313 int sgl_fcmp(sgl_floating_point *, sgl_floating_point *, unsigned int, unsigned int *);
314 int sgl_fdiv(sgl_floating_point *, sgl_floating_point *, sgl_floating_point *, unsigned int *);
315 int sgl_fmpy(sgl_floating_point *, sgl_floating_point *, sgl_floating_point *, unsigned int *);
316 int sgl_frem(sgl_floating_point *, sgl_floating_point *, sgl_floating_point *, unsigned int *);
317 int sgl_fsqrt(sgl_floating_point *, sgl_floating_point *, sgl_floating_point *, unsigned int *);
318 int sgl_fsub(sgl_floating_point *, sgl_floating_point *, sgl_floating_point *, unsigned int *);
319 int sgl_frnd(sgl_floating_point *, sgl_floating_point *, sgl_floating_point *, unsigned int *);
320