src/share/vm/runtime/sharedRuntimeMath.hpp

changeset 7002
a073be2ce5c2
parent 7000
631c3a4ea10c
child 7003
69ea58782b1a
     1.1 --- a/src/share/vm/runtime/sharedRuntimeMath.hpp	Tue Jul 29 13:54:16 2014 +0200
     1.2 +++ b/src/share/vm/runtime/sharedRuntimeMath.hpp	Tue Jul 29 13:56:29 2014 +0200
     1.3 @@ -27,20 +27,46 @@
     1.4  
     1.5  #include <math.h>
     1.6  
     1.7 -// VM_LITTLE_ENDIAN is #defined appropriately in the Makefiles
     1.8 -// [jk] this is not 100% correct because the float word order may different
     1.9 -// from the byte order (e.g. on ARM FPA)
    1.10 +// Used to access the lower/higher 32 bits of a double
    1.11 +typedef union {
    1.12 +    double d;
    1.13 +    struct {
    1.14  #ifdef VM_LITTLE_ENDIAN
    1.15 -# define __HI(x) *(1+(int*)&x)
    1.16 -# define __LO(x) *(int*)&x
    1.17 +      int lo;
    1.18 +      int hi;
    1.19  #else
    1.20 -# define __HI(x) *(int*)&x
    1.21 -# define __LO(x) *(1+(int*)&x)
    1.22 +      int hi;
    1.23 +      int lo;
    1.24  #endif
    1.25 +    } split;
    1.26 +} DoubleIntConv;
    1.27 +
    1.28 +static inline int high(double d) {
    1.29 +  DoubleIntConv x = { d };
    1.30 +  return x.split.hi;
    1.31 +}
    1.32 +
    1.33 +static inline int low(double d) {
    1.34 +  DoubleIntConv x = { d };
    1.35 +  return x.split.lo;
    1.36 +}
    1.37 +
    1.38 +static inline void set_high(double* d, int high) {
    1.39 +  DoubleIntConv conv = { *d };
    1.40 +  conv.split.hi = high;
    1.41 +  *d = conv.d;
    1.42 +}
    1.43 +
    1.44 +static inline void set_low(double* d, int low) {
    1.45 +  DoubleIntConv conv = { *d };
    1.46 +  conv.split.lo = low;
    1.47 +  *d = conv.d;
    1.48 +}
    1.49  
    1.50  static double copysignA(double x, double y) {
    1.51 -  __HI(x) = (__HI(x)&0x7fffffff)|(__HI(y)&0x80000000);
    1.52 -  return x;
    1.53 +  DoubleIntConv convX = { x };
    1.54 +  convX.split.hi = (convX.split.hi & 0x7fffffff) | (high(y) & 0x80000000);
    1.55 +  return convX.d;
    1.56  }
    1.57  
    1.58  /*
    1.59 @@ -67,30 +93,32 @@
    1.60  hugeX  = 1.0e+300,
    1.61  tiny   = 1.0e-300;
    1.62  
    1.63 -static double scalbnA (double x, int n) {
    1.64 +static double scalbnA(double x, int n) {
    1.65    int  k,hx,lx;
    1.66 -  hx = __HI(x);
    1.67 -  lx = __LO(x);
    1.68 +  hx = high(x);
    1.69 +  lx = low(x);
    1.70    k = (hx&0x7ff00000)>>20;              /* extract exponent */
    1.71    if (k==0) {                           /* 0 or subnormal x */
    1.72      if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */
    1.73      x *= two54;
    1.74 -    hx = __HI(x);
    1.75 +    hx = high(x);
    1.76      k = ((hx&0x7ff00000)>>20) - 54;
    1.77      if (n< -50000) return tiny*x;       /*underflow*/
    1.78    }
    1.79    if (k==0x7ff) return x+x;             /* NaN or Inf */
    1.80    k = k+n;
    1.81 -  if (k >  0x7fe) return hugeX*copysignA(hugeX,x); /* overflow  */
    1.82 -  if (k > 0)                            /* normal result */
    1.83 -    {__HI(x) = (hx&0x800fffff)|(k<<20); return x;}
    1.84 +  if (k > 0x7fe) return hugeX*copysignA(hugeX,x); /* overflow  */
    1.85 +  if (k > 0) {                          /* normal result */
    1.86 +    set_high(&x, (hx&0x800fffff)|(k<<20));
    1.87 +    return x;
    1.88 +  }
    1.89    if (k <= -54) {
    1.90      if (n > 50000)      /* in case integer overflow in n+k */
    1.91        return hugeX*copysignA(hugeX,x);  /*overflow*/
    1.92      else return tiny*copysignA(tiny,x); /*underflow*/
    1.93    }
    1.94    k += 54;                              /* subnormal result */
    1.95 -  __HI(x) = (hx&0x800fffff)|(k<<20);
    1.96 +  set_high(&x, (hx&0x800fffff)|(k<<20));
    1.97    return x*twom54;
    1.98  }
    1.99  

mercurial