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