| 1 |
|
| 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) <[email protected]>
|
| 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)) \
|
| 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 | \
|
| 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 |
|
| 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 |
|
| 215 |
|
| 216 | #define Dint_from_sgl_mantissa(sgl_value,exponent,dresultA,dresultB) \
|
| 217 | {Sall(sgl_value) <<= SGL_EXP_LENGTH; \
|
| 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 |
|
| 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)) \
|
| 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)
|