src/share/vm/runtime/sharedRuntimeMath.hpp

changeset 7002
a073be2ce5c2
parent 7000
631c3a4ea10c
child 7003
69ea58782b1a
equal deleted inserted replaced
7001:b6a8cc1e0d92 7002:a073be2ce5c2
25 #ifndef SHARE_VM_RUNTIME_SHAREDRUNTIMEMATH_HPP 25 #ifndef SHARE_VM_RUNTIME_SHAREDRUNTIMEMATH_HPP
26 #define SHARE_VM_RUNTIME_SHAREDRUNTIMEMATH_HPP 26 #define SHARE_VM_RUNTIME_SHAREDRUNTIMEMATH_HPP
27 27
28 #include <math.h> 28 #include <math.h>
29 29
30 // VM_LITTLE_ENDIAN is #defined appropriately in the Makefiles 30 // Used to access the lower/higher 32 bits of a double
31 // [jk] this is not 100% correct because the float word order may different 31 typedef union {
32 // from the byte order (e.g. on ARM FPA) 32 double d;
33 struct {
33 #ifdef VM_LITTLE_ENDIAN 34 #ifdef VM_LITTLE_ENDIAN
34 # define __HI(x) *(1+(int*)&x) 35 int lo;
35 # define __LO(x) *(int*)&x 36 int hi;
36 #else 37 #else
37 # define __HI(x) *(int*)&x 38 int hi;
38 # define __LO(x) *(1+(int*)&x) 39 int lo;
39 #endif 40 #endif
41 } split;
42 } DoubleIntConv;
43
44 static inline int high(double d) {
45 DoubleIntConv x = { d };
46 return x.split.hi;
47 }
48
49 static inline int low(double d) {
50 DoubleIntConv x = { d };
51 return x.split.lo;
52 }
53
54 static inline void set_high(double* d, int high) {
55 DoubleIntConv conv = { *d };
56 conv.split.hi = high;
57 *d = conv.d;
58 }
59
60 static inline void set_low(double* d, int low) {
61 DoubleIntConv conv = { *d };
62 conv.split.lo = low;
63 *d = conv.d;
64 }
40 65
41 static double copysignA(double x, double y) { 66 static double copysignA(double x, double y) {
42 __HI(x) = (__HI(x)&0x7fffffff)|(__HI(y)&0x80000000); 67 DoubleIntConv convX = { x };
43 return x; 68 convX.split.hi = (convX.split.hi & 0x7fffffff) | (high(y) & 0x80000000);
69 return convX.d;
44 } 70 }
45 71
46 /* 72 /*
47 * ==================================================== 73 * ====================================================
48 * Copyright (c) 1998 Oracle and/or its affiliates. All rights reserved. 74 * Copyright (c) 1998 Oracle and/or its affiliates. All rights reserved.
65 two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ 91 two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
66 twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */ 92 twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */
67 hugeX = 1.0e+300, 93 hugeX = 1.0e+300,
68 tiny = 1.0e-300; 94 tiny = 1.0e-300;
69 95
70 static double scalbnA (double x, int n) { 96 static double scalbnA(double x, int n) {
71 int k,hx,lx; 97 int k,hx,lx;
72 hx = __HI(x); 98 hx = high(x);
73 lx = __LO(x); 99 lx = low(x);
74 k = (hx&0x7ff00000)>>20; /* extract exponent */ 100 k = (hx&0x7ff00000)>>20; /* extract exponent */
75 if (k==0) { /* 0 or subnormal x */ 101 if (k==0) { /* 0 or subnormal x */
76 if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */ 102 if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */
77 x *= two54; 103 x *= two54;
78 hx = __HI(x); 104 hx = high(x);
79 k = ((hx&0x7ff00000)>>20) - 54; 105 k = ((hx&0x7ff00000)>>20) - 54;
80 if (n< -50000) return tiny*x; /*underflow*/ 106 if (n< -50000) return tiny*x; /*underflow*/
81 } 107 }
82 if (k==0x7ff) return x+x; /* NaN or Inf */ 108 if (k==0x7ff) return x+x; /* NaN or Inf */
83 k = k+n; 109 k = k+n;
84 if (k > 0x7fe) return hugeX*copysignA(hugeX,x); /* overflow */ 110 if (k > 0x7fe) return hugeX*copysignA(hugeX,x); /* overflow */
85 if (k > 0) /* normal result */ 111 if (k > 0) { /* normal result */
86 {__HI(x) = (hx&0x800fffff)|(k<<20); return x;} 112 set_high(&x, (hx&0x800fffff)|(k<<20));
113 return x;
114 }
87 if (k <= -54) { 115 if (k <= -54) {
88 if (n > 50000) /* in case integer overflow in n+k */ 116 if (n > 50000) /* in case integer overflow in n+k */
89 return hugeX*copysignA(hugeX,x); /*overflow*/ 117 return hugeX*copysignA(hugeX,x); /*overflow*/
90 else return tiny*copysignA(tiny,x); /*underflow*/ 118 else return tiny*copysignA(tiny,x); /*underflow*/
91 } 119 }
92 k += 54; /* subnormal result */ 120 k += 54; /* subnormal result */
93 __HI(x) = (hx&0x800fffff)|(k<<20); 121 set_high(&x, (hx&0x800fffff)|(k<<20));
94 return x*twom54; 122 return x*twom54;
95 } 123 }
96 124
97 #endif // SHARE_VM_RUNTIME_SHAREDRUNTIMEMATH_HPP 125 #endif // SHARE_VM_RUNTIME_SHAREDRUNTIMEMATH_HPP

mercurial