| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  * Linux/PA-RISC Project (http://www.parisc-linux.org/) | 
 | 3 |  * | 
 | 4 |  * Floating-point emulation code | 
 | 5 |  *  Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org> | 
 | 6 |  * | 
 | 7 |  *    This program is free software; you can redistribute it and/or modify | 
 | 8 |  *    it under the terms of the GNU General Public License as published by | 
 | 9 |  *    the Free Software Foundation; either version 2, or (at your option) | 
 | 10 |  *    any later version. | 
 | 11 |  * | 
 | 12 |  *    This program is distributed in the hope that it will be useful, | 
 | 13 |  *    but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 | 14 |  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
 | 15 |  *    GNU General Public License for more details. | 
 | 16 |  * | 
 | 17 |  *    You should have received a copy of the GNU General Public License | 
 | 18 |  *    along with this program; if not, write to the Free Software | 
 | 19 |  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | 
 | 20 |  */ | 
 | 21 |  | 
 | 22 | #ifdef __NO_PA_HDRS | 
 | 23 |     PA header file -- do not include this header file for non-PA builds. | 
 | 24 | #endif | 
 | 25 |  | 
| Simon Arlott | 7022672 | 2007-05-11 20:42:34 +0100 | [diff] [blame] | 26 | /* 32-bit word grabbing functions */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 27 | #define Sgl_firstword(value) Sall(value) | 
 | 28 | #define Sgl_secondword(value) dummy_location | 
 | 29 | #define Sgl_thirdword(value) dummy_location | 
 | 30 | #define Sgl_fourthword(value) dummy_location | 
 | 31 |  | 
 | 32 | #define Sgl_sign(object) Ssign(object) | 
 | 33 | #define Sgl_exponent(object) Sexponent(object) | 
 | 34 | #define Sgl_signexponent(object) Ssignexponent(object) | 
 | 35 | #define Sgl_mantissa(object) Smantissa(object) | 
 | 36 | #define Sgl_exponentmantissa(object) Sexponentmantissa(object) | 
 | 37 | #define Sgl_all(object) Sall(object) | 
 | 38 |  | 
| Simon Arlott | 7022672 | 2007-05-11 20:42:34 +0100 | [diff] [blame] | 39 | /* sgl_and_signs ANDs the sign bits of each argument and puts the result | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 40 |  * into the first argument. sgl_or_signs ors those same sign bits */ | 
 | 41 | #define Sgl_and_signs( src1dst, src2)		\ | 
 | 42 |     Sall(src1dst) = (Sall(src2)|~((unsigned int)1<<31)) & Sall(src1dst) | 
 | 43 | #define Sgl_or_signs( src1dst, src2)		\ | 
 | 44 |     Sall(src1dst) = (Sall(src2)&((unsigned int)1<<31)) | Sall(src1dst) | 
 | 45 |  | 
 | 46 | /* The hidden bit is always the low bit of the exponent */ | 
 | 47 | #define Sgl_clear_exponent_set_hidden(srcdst) Deposit_sexponent(srcdst,1) | 
 | 48 | #define Sgl_clear_signexponent_set_hidden(srcdst) \ | 
 | 49 |     Deposit_ssignexponent(srcdst,1) | 
 | 50 | #define Sgl_clear_sign(srcdst) Sall(srcdst) &= ~((unsigned int)1<<31) | 
 | 51 | #define Sgl_clear_signexponent(srcdst) Sall(srcdst) &= 0x007fffff | 
 | 52 |  | 
 | 53 | /* varamount must be less than 32 for the next three functions */ | 
 | 54 | #define Sgl_rightshift(srcdst, varamount)	\ | 
 | 55 |     Sall(srcdst) >>= varamount | 
 | 56 | #define Sgl_leftshift(srcdst, varamount)	\ | 
 | 57 |     Sall(srcdst) <<= varamount | 
 | 58 | #define Sgl_rightshift_exponentmantissa(srcdst, varamount) \ | 
 | 59 |     Sall(srcdst) = \ | 
 | 60 | 	(Sexponentmantissa(srcdst) >> varamount) | \ | 
 | 61 | 	(Sall(srcdst) & ((unsigned int)1<<31)) | 
 | 62 |  | 
 | 63 | #define Sgl_leftshiftby1_withextent(left,right,result) \ | 
 | 64 |     Shiftdouble(Sall(left),Extall(right),31,Sall(result)) | 
 | 65 |      | 
 | 66 | #define Sgl_rightshiftby1_withextent(left,right,dst)		\ | 
 | 67 |     Shiftdouble(Sall(left),Extall(right),1,Extall(right)) | 
 | 68 | #define Sgl_arithrightshiftby1(srcdst)	\ | 
 | 69 |     Sall(srcdst) = (int)Sall(srcdst) >> 1 | 
 | 70 |      | 
 | 71 | /* Sign extend the sign bit with an integer destination */ | 
 | 72 | #define Sgl_signextendedsign(value) Ssignedsign(value) | 
 | 73 |  | 
 | 74 | #define Sgl_isone_hidden(sgl_value) (Shidden(sgl_value)) | 
 | 75 | #define Sgl_increment(sgl_value) Sall(sgl_value) += 1 | 
 | 76 | #define Sgl_increment_mantissa(sgl_value) \ | 
 | 77 |     Deposit_smantissa(sgl_value,sgl_value+1) | 
 | 78 | #define Sgl_decrement(sgl_value) Sall(sgl_value) -= 1 | 
 | 79 |  | 
 | 80 | #define Sgl_isone_sign(sgl_value) (Is_ssign(sgl_value)!=0) | 
 | 81 | #define Sgl_isone_hiddenoverflow(sgl_value) \ | 
 | 82 |     (Is_shiddenoverflow(sgl_value)!=0) | 
 | 83 | #define Sgl_isone_lowmantissa(sgl_value) (Is_slow(sgl_value)!=0) | 
 | 84 | #define Sgl_isone_signaling(sgl_value) (Is_ssignaling(sgl_value)!=0) | 
 | 85 | #define Sgl_is_signalingnan(sgl_value) (Ssignalingnan(sgl_value)==0x1ff) | 
 | 86 | #define Sgl_isnotzero(sgl_value) (Sall(sgl_value)!=0) | 
 | 87 | #define Sgl_isnotzero_hiddenhigh7mantissa(sgl_value) \ | 
 | 88 |     (Shiddenhigh7mantissa(sgl_value)!=0) | 
 | 89 | #define Sgl_isnotzero_low4(sgl_value) (Slow4(sgl_value)!=0) | 
 | 90 | #define Sgl_isnotzero_exponent(sgl_value) (Sexponent(sgl_value)!=0) | 
 | 91 | #define Sgl_isnotzero_mantissa(sgl_value) (Smantissa(sgl_value)!=0) | 
 | 92 | #define Sgl_isnotzero_exponentmantissa(sgl_value) \ | 
 | 93 |     (Sexponentmantissa(sgl_value)!=0) | 
 | 94 | #define Sgl_iszero(sgl_value) (Sall(sgl_value)==0) | 
 | 95 | #define Sgl_iszero_signaling(sgl_value) (Is_ssignaling(sgl_value)==0) | 
 | 96 | #define Sgl_iszero_hidden(sgl_value) (Is_shidden(sgl_value)==0) | 
 | 97 | #define Sgl_iszero_hiddenoverflow(sgl_value) \ | 
 | 98 |     (Is_shiddenoverflow(sgl_value)==0) | 
 | 99 | #define Sgl_iszero_hiddenhigh3mantissa(sgl_value) \ | 
 | 100 |     (Shiddenhigh3mantissa(sgl_value)==0) | 
 | 101 | #define Sgl_iszero_hiddenhigh7mantissa(sgl_value) \ | 
 | 102 |     (Shiddenhigh7mantissa(sgl_value)==0) | 
 | 103 | #define Sgl_iszero_sign(sgl_value) (Is_ssign(sgl_value)==0) | 
 | 104 | #define Sgl_iszero_exponent(sgl_value) (Sexponent(sgl_value)==0) | 
 | 105 | #define Sgl_iszero_mantissa(sgl_value) (Smantissa(sgl_value)==0) | 
 | 106 | #define Sgl_iszero_exponentmantissa(sgl_value) \ | 
 | 107 |     (Sexponentmantissa(sgl_value)==0) | 
 | 108 | #define Sgl_isinfinity_exponent(sgl_value) 		\ | 
 | 109 |     (Sgl_exponent(sgl_value)==SGL_INFINITY_EXPONENT) | 
 | 110 | #define Sgl_isnotinfinity_exponent(sgl_value) 		\ | 
 | 111 |     (Sgl_exponent(sgl_value)!=SGL_INFINITY_EXPONENT) | 
 | 112 | #define Sgl_isinfinity(sgl_value)			\ | 
 | 113 |     (Sgl_exponent(sgl_value)==SGL_INFINITY_EXPONENT &&	\ | 
 | 114 |     Sgl_mantissa(sgl_value)==0) | 
 | 115 | #define Sgl_isnan(sgl_value)				\ | 
 | 116 |     (Sgl_exponent(sgl_value)==SGL_INFINITY_EXPONENT &&	\ | 
 | 117 |     Sgl_mantissa(sgl_value)!=0) | 
 | 118 | #define Sgl_isnotnan(sgl_value)				\ | 
 | 119 |     (Sgl_exponent(sgl_value)!=SGL_INFINITY_EXPONENT ||	\ | 
 | 120 |     Sgl_mantissa(sgl_value)==0) | 
 | 121 | #define Sgl_islessthan(sgl_op1,sgl_op2)			\ | 
 | 122 |     (Sall(sgl_op1) < Sall(sgl_op2)) | 
 | 123 | #define Sgl_isgreaterthan(sgl_op1,sgl_op2)		\ | 
 | 124 |     (Sall(sgl_op1) > Sall(sgl_op2)) | 
 | 125 | #define Sgl_isnotlessthan(sgl_op1,sgl_op2)		\ | 
 | 126 |     (Sall(sgl_op1) >= Sall(sgl_op2)) | 
 | 127 | #define Sgl_isequal(sgl_op1,sgl_op2)			\ | 
 | 128 |     (Sall(sgl_op1) == Sall(sgl_op2)) | 
 | 129 |  | 
 | 130 | #define Sgl_leftshiftby8(sgl_value) \ | 
 | 131 |     Sall(sgl_value) <<= 8 | 
 | 132 | #define Sgl_leftshiftby4(sgl_value) \ | 
 | 133 |     Sall(sgl_value) <<= 4 | 
 | 134 | #define Sgl_leftshiftby3(sgl_value) \ | 
 | 135 |     Sall(sgl_value) <<= 3 | 
 | 136 | #define Sgl_leftshiftby2(sgl_value) \ | 
 | 137 |     Sall(sgl_value) <<= 2 | 
 | 138 | #define Sgl_leftshiftby1(sgl_value) \ | 
 | 139 |     Sall(sgl_value) <<= 1 | 
 | 140 | #define Sgl_rightshiftby1(sgl_value) \ | 
 | 141 |     Sall(sgl_value) >>= 1 | 
 | 142 | #define Sgl_rightshiftby4(sgl_value) \ | 
 | 143 |     Sall(sgl_value) >>= 4 | 
 | 144 | #define Sgl_rightshiftby8(sgl_value) \ | 
 | 145 |     Sall(sgl_value) >>= 8 | 
 | 146 |      | 
 | 147 | #define Sgl_ismagnitudeless(signlessleft,signlessright)			\ | 
 | 148 | /*  unsigned int signlessleft, signlessright; */			\ | 
 | 149 |       (signlessleft < signlessright)   | 
 | 150 |      | 
 | 151 |  | 
 | 152 | #define Sgl_copytoint_exponentmantissa(source,dest)     \ | 
 | 153 |     dest = Sexponentmantissa(source) | 
 | 154 |  | 
 | 155 | /* A quiet NaN has the high mantissa bit clear and at least on other (in this | 
 | 156 |  * case the adjacent bit) bit set. */ | 
 | 157 | #define Sgl_set_quiet(sgl_value) Deposit_shigh2mantissa(sgl_value,1) | 
 | 158 | #define Sgl_set_exponent(sgl_value,exp) Deposit_sexponent(sgl_value,exp) | 
 | 159 |  | 
 | 160 | #define Sgl_set_mantissa(dest,value) Deposit_smantissa(dest,value) | 
 | 161 | #define Sgl_set_exponentmantissa(dest,value) \ | 
 | 162 |     Deposit_sexponentmantissa(dest,value) | 
 | 163 |  | 
 | 164 | /*  An infinity is represented with the max exponent and a zero mantissa */ | 
 | 165 | #define Sgl_setinfinity_exponent(sgl_value) \ | 
 | 166 |     Deposit_sexponent(sgl_value,SGL_INFINITY_EXPONENT) | 
 | 167 | #define Sgl_setinfinity_exponentmantissa(sgl_value)	\ | 
 | 168 |     Deposit_sexponentmantissa(sgl_value, \ | 
 | 169 | 	(SGL_INFINITY_EXPONENT << (32-(1+SGL_EXP_LENGTH)))) | 
 | 170 | #define Sgl_setinfinitypositive(sgl_value)		\ | 
 | 171 |     Sall(sgl_value) = (SGL_INFINITY_EXPONENT << (32-(1+SGL_EXP_LENGTH))) | 
 | 172 | #define Sgl_setinfinitynegative(sgl_value)		\ | 
 | 173 |     Sall(sgl_value) = (SGL_INFINITY_EXPONENT << (32-(1+SGL_EXP_LENGTH))) \ | 
 | 174 |     | ((unsigned int)1<<31) | 
 | 175 | #define Sgl_setinfinity(sgl_value,sign)					\ | 
 | 176 |     Sall(sgl_value) = (SGL_INFINITY_EXPONENT << (32-(1+SGL_EXP_LENGTH))) | \ | 
 | 177 |      ((unsigned int)sign << 31) | 
 | 178 | #define Sgl_sethigh4bits(sgl_value, extsign)  \ | 
 | 179 |     Deposit_shigh4(sgl_value,extsign) | 
 | 180 | #define Sgl_set_sign(sgl_value,sign) Deposit_ssign(sgl_value,sign) | 
 | 181 | #define Sgl_invert_sign(sgl_value)  \ | 
 | 182 |     Deposit_ssign(sgl_value,~Ssign(sgl_value)) | 
 | 183 | #define Sgl_setone_sign(sgl_value) Deposit_ssign(sgl_value,1) | 
 | 184 | #define Sgl_setone_lowmantissa(sgl_value) Deposit_slow(sgl_value,1) | 
 | 185 | #define Sgl_setzero_sign(sgl_value)  Sall(sgl_value) &= 0x7fffffff | 
 | 186 | #define Sgl_setzero_exponent(sgl_value) Sall(sgl_value) &= 0x807fffff | 
 | 187 | #define Sgl_setzero_mantissa(sgl_value) Sall(sgl_value) &= 0xff800000 | 
 | 188 | #define Sgl_setzero_exponentmantissa(sgl_value)  Sall(sgl_value) &= 0x80000000 | 
 | 189 | #define Sgl_setzero(sgl_value) Sall(sgl_value) = 0 | 
 | 190 | #define Sgl_setnegativezero(sgl_value) Sall(sgl_value) = (unsigned int)1 << 31 | 
 | 191 |  | 
 | 192 | /* Use following macro for both overflow & underflow conditions */ | 
 | 193 | #define ovfl - | 
 | 194 | #define unfl + | 
 | 195 | #define Sgl_setwrapped_exponent(sgl_value,exponent,op) \ | 
 | 196 |     Deposit_sexponent(sgl_value,(exponent op SGL_WRAP)) | 
 | 197 |  | 
 | 198 | #define Sgl_setlargestpositive(sgl_value) 				\ | 
 | 199 |     Sall(sgl_value) = ((SGL_EMAX+SGL_BIAS) << (32-(1+SGL_EXP_LENGTH)))	\ | 
 | 200 |                       | ((1<<(32-(1+SGL_EXP_LENGTH))) - 1 ) | 
 | 201 | #define Sgl_setlargestnegative(sgl_value)				\ | 
 | 202 |     Sall(sgl_value) = ((SGL_EMAX+SGL_BIAS) << (32-(1+SGL_EXP_LENGTH)))	\ | 
 | 203 |                       | ((1<<(32-(1+SGL_EXP_LENGTH))) - 1 )		\ | 
 | 204 | 		      | ((unsigned int)1<<31) | 
 | 205 |  | 
 | 206 | #define Sgl_setnegativeinfinity(sgl_value)	\ | 
 | 207 |     Sall(sgl_value) = 				\ | 
 | 208 |     ((1<<SGL_EXP_LENGTH) | SGL_INFINITY_EXPONENT) << (32-(1+SGL_EXP_LENGTH)) | 
 | 209 | #define Sgl_setlargest(sgl_value,sign) 					\ | 
 | 210 |     Sall(sgl_value) = (unsigned int)sign << 31 |			\ | 
 | 211 |         (((SGL_EMAX+SGL_BIAS) << (32-(1+SGL_EXP_LENGTH)))		\ | 
 | 212 | 	  | ((1 << (32-(1+SGL_EXP_LENGTH))) - 1 )) | 
 | 213 | #define Sgl_setlargest_exponentmantissa(sgl_value)			\ | 
 | 214 |     Sall(sgl_value) = Sall(sgl_value) & ((unsigned int)1<<31) |		\ | 
 | 215 |         (((SGL_EMAX+SGL_BIAS) << (32-(1+SGL_EXP_LENGTH)))		\ | 
 | 216 | 	  | ((1 << (32-(1+SGL_EXP_LENGTH))) - 1 )) | 
 | 217 |  | 
 | 218 | /* The high bit is always zero so arithmetic or logical shifts will work. */ | 
 | 219 | #define Sgl_right_align(srcdst,shift,extent)				\ | 
 | 220 |     /* sgl_floating_point srcdst; int shift; extension extent */	\ | 
 | 221 |     if (shift < 32) {							\ | 
 | 222 | 	Extall(extent) = Sall(srcdst) << (32-(shift));			\ | 
 | 223 |     	Sall(srcdst) >>= shift;						\ | 
 | 224 |     }									\ | 
 | 225 |     else {								\ | 
 | 226 | 	Extall(extent) = Sall(srcdst);					\ | 
 | 227 | 	Sall(srcdst) = 0;						\ | 
 | 228 |     } | 
 | 229 | #define Sgl_hiddenhigh3mantissa(sgl_value) Shiddenhigh3mantissa(sgl_value) | 
 | 230 | #define Sgl_hidden(sgl_value) Shidden(sgl_value) | 
 | 231 | #define Sgl_lowmantissa(sgl_value) Slow(sgl_value) | 
 | 232 |  | 
 | 233 | /* The left argument is never smaller than the right argument */ | 
 | 234 | #define Sgl_subtract(sgl_left,sgl_right,sgl_result) \ | 
 | 235 |     Sall(sgl_result) = Sall(sgl_left) - Sall(sgl_right) | 
 | 236 |  | 
 | 237 | /* Subtract right augmented with extension from left augmented with zeros and | 
 | 238 |  * store into result and extension. */ | 
 | 239 | #define Sgl_subtract_withextension(left,right,extent,result)		\ | 
 | 240 |     /* sgl_floating_point left,right,result; extension extent */	\ | 
 | 241 |   Sgl_subtract(left,right,result);					\ | 
 | 242 |   if((Extall(extent) = 0-Extall(extent)))				\ | 
 | 243 |       Sall(result) = Sall(result)-1 | 
 | 244 |  | 
 | 245 | #define Sgl_addition(sgl_left,sgl_right,sgl_result) \ | 
 | 246 |     Sall(sgl_result) = Sall(sgl_left) + Sall(sgl_right) | 
 | 247 |  | 
 | 248 | #define Sgl_xortointp1(left,right,result)			\ | 
 | 249 |     result = Sall(left) XOR Sall(right); | 
 | 250 |  | 
 | 251 | #define Sgl_xorfromintp1(left,right,result)			\ | 
 | 252 |     Sall(result) = left XOR Sall(right) | 
 | 253 |  | 
 | 254 | /* Need to Initialize */ | 
 | 255 | #define Sgl_makequietnan(dest)						\ | 
 | 256 |     Sall(dest) = ((SGL_EMAX+SGL_BIAS)+1)<< (32-(1+SGL_EXP_LENGTH))	\ | 
 | 257 |                  | (1<<(32-(1+SGL_EXP_LENGTH+2))) | 
 | 258 | #define Sgl_makesignalingnan(dest)					\ | 
 | 259 |     Sall(dest) = ((SGL_EMAX+SGL_BIAS)+1)<< (32-(1+SGL_EXP_LENGTH))	\ | 
 | 260 |                  | (1<<(32-(1+SGL_EXP_LENGTH+1))) | 
 | 261 |  | 
 | 262 | #define Sgl_normalize(sgl_opnd,exponent)			\ | 
 | 263 | 	while(Sgl_iszero_hiddenhigh7mantissa(sgl_opnd)) {	\ | 
 | 264 | 		Sgl_leftshiftby8(sgl_opnd);			\ | 
 | 265 | 		exponent -= 8;					\ | 
 | 266 | 	}							\ | 
 | 267 | 	if(Sgl_iszero_hiddenhigh3mantissa(sgl_opnd)) {		\ | 
 | 268 | 		Sgl_leftshiftby4(sgl_opnd);			\ | 
 | 269 | 		exponent -= 4;					\ | 
 | 270 | 	}							\ | 
 | 271 | 	while(Sgl_iszero_hidden(sgl_opnd)) {			\ | 
 | 272 | 		Sgl_leftshiftby1(sgl_opnd);			\ | 
 | 273 | 		exponent -= 1;					\ | 
 | 274 | 	} | 
 | 275 |  | 
 | 276 | #define Sgl_setoverflow(sgl_opnd)				\ | 
 | 277 | 	/* set result to infinity or largest number */		\ | 
 | 278 | 	switch (Rounding_mode()) {				\ | 
 | 279 | 		case ROUNDPLUS:					\ | 
 | 280 | 			if (Sgl_isone_sign(sgl_opnd)) {		\ | 
 | 281 | 				Sgl_setlargestnegative(sgl_opnd); \ | 
 | 282 | 			}					\ | 
 | 283 | 			else {					\ | 
 | 284 | 				Sgl_setinfinitypositive(sgl_opnd); \ | 
 | 285 | 			}					\ | 
 | 286 | 			break;					\ | 
 | 287 | 		case ROUNDMINUS:				\ | 
 | 288 | 			if (Sgl_iszero_sign(sgl_opnd)) {	\ | 
 | 289 | 				Sgl_setlargestpositive(sgl_opnd); \ | 
 | 290 | 			}					\ | 
 | 291 | 			else {					\ | 
 | 292 | 				Sgl_setinfinitynegative(sgl_opnd); \ | 
 | 293 | 			}					\ | 
 | 294 | 			break;					\ | 
 | 295 | 		case ROUNDNEAREST:				\ | 
 | 296 | 			Sgl_setinfinity_exponentmantissa(sgl_opnd); \ | 
 | 297 | 			break;					\ | 
 | 298 | 		case ROUNDZERO:					\ | 
 | 299 | 			Sgl_setlargest_exponentmantissa(sgl_opnd); \ | 
 | 300 | 	} | 
 | 301 |  | 
 | 302 | #define Sgl_denormalize(opnd,exponent,guard,sticky,inexact)		\ | 
 | 303 | 	Sgl_clear_signexponent_set_hidden(opnd);			\ | 
 | 304 | 	if (exponent >= (1 - SGL_P)) {					\ | 
 | 305 | 		guard = (Sall(opnd) >> -exponent) & 1;			\ | 
 | 306 | 		if (exponent < 0) sticky |= Sall(opnd) << (32+exponent); \ | 
 | 307 | 		inexact = guard | sticky;				\ | 
 | 308 | 		Sall(opnd) >>= (1-exponent);				\ | 
 | 309 | 	}								\ | 
 | 310 | 	else {								\ | 
 | 311 | 		guard = 0;						\ | 
 | 312 | 		sticky |= Sall(opnd);					\ | 
 | 313 | 		inexact = sticky;					\ | 
 | 314 | 		Sgl_setzero(opnd);					\ | 
 | 315 | 	} | 
 | 316 |  | 
 | 317 | /*  | 
 | 318 |  * The fused multiply add instructions requires a single extended format, | 
 | 319 |  * with 48 bits of mantissa. | 
 | 320 |  */ | 
 | 321 | #define SGLEXT_THRESHOLD 48 | 
 | 322 |  | 
 | 323 | #define Sglext_setzero(valA,valB)	\ | 
 | 324 |     Sextallp1(valA) = 0; Sextallp2(valB) = 0 | 
 | 325 |  | 
 | 326 | #define Sglext_isnotzero_mantissap2(valB) (Sextallp2(valB)!=0) | 
 | 327 | #define Sglext_isone_lowp1(val) (Sextlowp1(val)!=0) | 
 | 328 | #define Sglext_isone_highp2(val) (Sexthighp2(val)!=0) | 
 | 329 | #define Sglext_isnotzero_low31p2(val) (Sextlow31p2(val)!=0) | 
 | 330 | #define Sglext_iszero(valA,valB) (Sextallp1(valA)==0 && Sextallp2(valB)==0) | 
 | 331 |  | 
 | 332 | #define Sgl_copytoptr(src,destptr) *destptr = src | 
 | 333 | #define Sgl_copyfromptr(srcptr,dest) dest = *srcptr | 
 | 334 | #define Sglext_copy(srca,srcb,desta,destb) \ | 
 | 335 |     Sextallp1(desta) = Sextallp1(srca);	\ | 
 | 336 |     Sextallp2(destb) = Sextallp2(srcb) | 
 | 337 | #define Sgl_copyto_sglext(src1,dest1,dest2) \ | 
 | 338 | 	Sextallp1(dest1) = Sall(src1); Sextallp2(dest2) = 0 | 
 | 339 |  | 
 | 340 | #define Sglext_swap_lower(leftp2,rightp2)  \ | 
 | 341 |     Sextallp2(leftp2)  = Sextallp2(leftp2) XOR Sextallp2(rightp2);  \ | 
 | 342 |     Sextallp2(rightp2) = Sextallp2(leftp2) XOR Sextallp2(rightp2);  \ | 
 | 343 |     Sextallp2(leftp2)  = Sextallp2(leftp2) XOR Sextallp2(rightp2) | 
 | 344 |  | 
 | 345 | #define Sglext_setone_lowmantissap2(value) Deposit_dlowp2(value,1) | 
 | 346 |  | 
 | 347 | /* The high bit is always zero so arithmetic or logical shifts will work. */ | 
 | 348 | #define Sglext_right_align(srcdstA,srcdstB,shift) \ | 
 | 349 |   {int shiftamt, sticky;						\ | 
 | 350 |     shiftamt = shift % 32;						\ | 
 | 351 |     sticky = 0;								\ | 
 | 352 |     switch (shift/32) {							\ | 
 | 353 |      case 0: if (shiftamt > 0) {					\ | 
 | 354 | 	        sticky = Sextallp2(srcdstB) << 32 - (shiftamt);		\ | 
 | 355 |                 Variable_shift_double(Sextallp1(srcdstA),		\ | 
 | 356 | 		 Sextallp2(srcdstB),shiftamt,Sextallp2(srcdstB));	\ | 
 | 357 | 	        Sextallp1(srcdstA) >>= shiftamt;			\ | 
 | 358 | 	     }								\ | 
 | 359 | 	     break;							\ | 
 | 360 |      case 1: if (shiftamt > 0) {					\ | 
 | 361 | 	        sticky = (Sextallp1(srcdstA) << 32 - (shiftamt)) |	\ | 
 | 362 | 			 Sextallp2(srcdstB);				\ | 
 | 363 | 	     }								\ | 
 | 364 | 	     else {							\ | 
 | 365 | 		sticky = Sextallp2(srcdstB);				\ | 
 | 366 | 	     }								\ | 
 | 367 | 	     Sextallp2(srcdstB) = Sextallp1(srcdstA) >> shiftamt;	\ | 
 | 368 | 	     Sextallp1(srcdstA) = 0;					\ | 
 | 369 | 	     break;							\ | 
 | 370 |     }									\ | 
 | 371 |     if (sticky) Sglext_setone_lowmantissap2(srcdstB);			\ | 
 | 372 |   } | 
 | 373 |  | 
 | 374 | /* The left argument is never smaller than the right argument */ | 
 | 375 | #define Sglext_subtract(lefta,leftb,righta,rightb,resulta,resultb) \ | 
 | 376 |     if( Sextallp2(rightb) > Sextallp2(leftb) ) Sextallp1(lefta)--; \ | 
 | 377 |     Sextallp2(resultb) = Sextallp2(leftb) - Sextallp2(rightb);	\ | 
 | 378 |     Sextallp1(resulta) = Sextallp1(lefta) - Sextallp1(righta) | 
 | 379 |  | 
 | 380 | #define Sglext_addition(lefta,leftb,righta,rightb,resulta,resultb) \ | 
 | 381 |     /* If the sum of the low words is less than either source, then \ | 
 | 382 |      * an overflow into the next word occurred. */ \ | 
 | 383 |     if ((Sextallp2(resultb) = Sextallp2(leftb)+Sextallp2(rightb)) < \ | 
 | 384 |         Sextallp2(rightb)) \ | 
 | 385 | 	    Sextallp1(resulta) = Sextallp1(lefta)+Sextallp1(righta)+1; \ | 
 | 386 |     else Sextallp1(resulta) = Sextallp1(lefta)+Sextallp1(righta) | 
 | 387 |  | 
 | 388 |  | 
 | 389 | #define Sglext_arithrightshiftby1(srcdstA,srcdstB)	\ | 
 | 390 |     Shiftdouble(Sextallp1(srcdstA),Sextallp2(srcdstB),1,Sextallp2(srcdstB)); \ | 
 | 391 |     Sextallp1(srcdstA) = (int)Sextallp1(srcdstA) >> 1 | 
 | 392 |     | 
 | 393 | #define Sglext_leftshiftby8(valA,valB) \ | 
 | 394 |     Shiftdouble(Sextallp1(valA),Sextallp2(valB),24,Sextallp1(valA)); \ | 
 | 395 |     Sextallp2(valB) <<= 8 | 
 | 396 | #define Sglext_leftshiftby4(valA,valB) \ | 
 | 397 |     Shiftdouble(Sextallp1(valA),Sextallp2(valB),28,Sextallp1(valA)); \ | 
 | 398 |     Sextallp2(valB) <<= 4 | 
 | 399 | #define Sglext_leftshiftby3(valA,valB) \ | 
 | 400 |     Shiftdouble(Sextallp1(valA),Sextallp2(valB),29,Sextallp1(valA)); \ | 
 | 401 |     Sextallp2(valB) <<= 3 | 
 | 402 | #define Sglext_leftshiftby2(valA,valB) \ | 
 | 403 |     Shiftdouble(Sextallp1(valA),Sextallp2(valB),30,Sextallp1(valA)); \ | 
 | 404 |     Sextallp2(valB) <<= 2 | 
 | 405 | #define Sglext_leftshiftby1(valA,valB) \ | 
 | 406 |     Shiftdouble(Sextallp1(valA),Sextallp2(valB),31,Sextallp1(valA)); \ | 
 | 407 |     Sextallp2(valB) <<= 1 | 
 | 408 |  | 
 | 409 | #define Sglext_rightshiftby4(valueA,valueB) \ | 
 | 410 |     Shiftdouble(Sextallp1(valueA),Sextallp2(valueB),4,Sextallp2(valueB)); \ | 
 | 411 |     Sextallp1(valueA) >>= 4 | 
 | 412 | #define Sglext_rightshiftby3(valueA,valueB) \ | 
 | 413 |     Shiftdouble(Sextallp1(valueA),Sextallp2(valueB),3,Sextallp2(valueB)); \ | 
 | 414 |     Sextallp1(valueA) >>= 3 | 
 | 415 | #define Sglext_rightshiftby1(valueA,valueB) \ | 
 | 416 |     Shiftdouble(Sextallp1(valueA),Sextallp2(valueB),1,Sextallp2(valueB)); \ | 
 | 417 |     Sextallp1(valueA) >>= 1 | 
 | 418 |  | 
 | 419 | #define Sglext_xortointp1(left,right,result) Sgl_xortointp1(left,right,result) | 
 | 420 | #define Sglext_xorfromintp1(left,right,result) \ | 
 | 421 | 	Sgl_xorfromintp1(left,right,result) | 
 | 422 | #define Sglext_copytoint_exponentmantissa(src,dest) \ | 
 | 423 | 	Sgl_copytoint_exponentmantissa(src,dest) | 
 | 424 | #define Sglext_ismagnitudeless(signlessleft,signlessright) \ | 
 | 425 | 	Sgl_ismagnitudeless(signlessleft,signlessright) | 
 | 426 |  | 
 | 427 | #define Sglext_set_sign(dbl_value,sign)  Sgl_set_sign(dbl_value,sign)   | 
 | 428 | #define Sglext_clear_signexponent_set_hidden(srcdst) \ | 
 | 429 | 	Sgl_clear_signexponent_set_hidden(srcdst)  | 
 | 430 | #define Sglext_clear_signexponent(srcdst) Sgl_clear_signexponent(srcdst)  | 
 | 431 | #define Sglext_clear_sign(srcdst) Sgl_clear_sign(srcdst)  | 
 | 432 | #define Sglext_isone_hidden(dbl_value) Sgl_isone_hidden(dbl_value)  | 
 | 433 |  | 
 | 434 | #define Sglext_denormalize(opndp1,opndp2,exponent,is_tiny)		\ | 
 | 435 |   {int sticky;								\ | 
 | 436 |     is_tiny = TRUE;							\ | 
 | 437 |     if (exponent == 0 && Sextallp2(opndp2)) {				\ | 
 | 438 | 	switch (Rounding_mode()) {					\ | 
 | 439 | 	case ROUNDPLUS:							\ | 
 | 440 | 		if (Sgl_iszero_sign(opndp1))				\ | 
 | 441 | 			if (Sgl_isone_hiddenoverflow(opndp1 + 1))	\ | 
 | 442 | 				is_tiny = FALSE;			\ | 
 | 443 | 		break;							\ | 
 | 444 | 	case ROUNDMINUS:						\ | 
 | 445 | 		if (Sgl_isone_sign(opndp1)) {				\ | 
 | 446 | 			if (Sgl_isone_hiddenoverflow(opndp1 + 1))	\ | 
 | 447 | 				is_tiny = FALSE;			\ | 
 | 448 | 		}							\ | 
 | 449 | 		break;							\ | 
 | 450 | 	case ROUNDNEAREST:						\ | 
 | 451 | 		if (Sglext_isone_highp2(opndp2) &&			\ | 
 | 452 | 		    (Sglext_isone_lowp1(opndp1) || 			\ | 
 | 453 | 		     Sglext_isnotzero_low31p2(opndp2)))			\ | 
 | 454 | 			if (Sgl_isone_hiddenoverflow(opndp1 + 1))	\ | 
 | 455 | 				is_tiny = FALSE;			\ | 
 | 456 | 		break;							\ | 
 | 457 | 	}								\ | 
 | 458 |     }									\ | 
 | 459 |     Sglext_clear_signexponent_set_hidden(opndp1);			\ | 
 | 460 |     if (exponent >= (1-DBL_P)) {					\ | 
 | 461 | 	if (exponent >= -31) {						\ | 
 | 462 | 	    if (exponent > -31) {					\ | 
 | 463 | 		sticky = Sextallp2(opndp2) << 31+exponent;		\ | 
 | 464 | 		Variable_shift_double(opndp1,opndp2,1-exponent,opndp2);	\ | 
 | 465 | 		Sextallp1(opndp1) >>= 1-exponent;			\ | 
 | 466 | 	    }								\ | 
 | 467 | 	    else {							\ | 
 | 468 | 		sticky = Sextallp2(opndp2);				\ | 
 | 469 | 		Sextallp2(opndp2) = Sextallp1(opndp1);			\ | 
 | 470 | 		Sextallp1(opndp1) = 0;					\ | 
 | 471 | 	    }								\ | 
 | 472 | 	}								\ | 
 | 473 | 	else {								\ | 
 | 474 | 	    sticky = (Sextallp1(opndp1) << 31+exponent) | 		\ | 
 | 475 | 		     Sextallp2(opndp2);					\ | 
 | 476 | 	    Sextallp2(opndp2) = Sextallp1(opndp1) >> -31-exponent;	\ | 
 | 477 | 	    Sextallp1(opndp1) = 0;					\ | 
 | 478 | 	}								\ | 
 | 479 |     }									\ | 
 | 480 |     else {								\ | 
 | 481 | 	sticky = Sextallp1(opndp1) | Sextallp2(opndp2);			\ | 
 | 482 | 	Sglext_setzero(opndp1,opndp2);					\ | 
 | 483 |     }									\ | 
 | 484 |     if (sticky) Sglext_setone_lowmantissap2(opndp2);			\ | 
 | 485 |     exponent = 0;							\ | 
 | 486 |   } |