root/arch/parisc/math-emu/cnv_float.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


   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) 

/* [<][>][^][v][top][bottom][index][help] */