changeset 13250:ca061aaeddaf

added Math.pow method substitution with code for handling some special cases
author twisti
date Wed, 04 Dec 2013 17:22:41 -0800
parents ff43107fd697
children 3a8a4042229f
files graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Math_pow.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/MathSubstitutionsX86.java
diffstat 2 files changed, 87 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Math_pow.java	Wed Dec 04 22:31:18 2013 +0100
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Math_pow.java	Wed Dec 04 17:22:41 2013 -0800
@@ -29,18 +29,57 @@
  */
 public class Math_pow extends JTTTest {
 
-    public static double test(double pow) {
-        return Math.pow(2.0d, pow);
+    public static double test(double x, double y) {
+        return Math.pow(x, y);
     }
 
     @Test
     public void run0() throws Throwable {
-        runTest("test", 2d);
+        runTest("test", 2d, 0d);
     }
 
     @Test
     public void run1() throws Throwable {
-        runTest("test", 3.1d);
+        runTest("test", 2d, 0.5d);
+    }
+
+    @Test
+    public void run2() throws Throwable {
+        runTest("test", -2d, 0.5d);
+    }
+
+    @Test
+    public void run3() throws Throwable {
+        runTest("test", 2d, 1d);
+    }
+
+    @Test
+    public void run4() throws Throwable {
+        runTest("test", 2d, -1d);
     }
 
+    @Test
+    public void run5() throws Throwable {
+        runTest("test", 2d, 2d);
+    }
+
+    @Test
+    public void run6() throws Throwable {
+        runTest("test", 2d, 3.1d);
+    }
+
+    @Test
+    public void run7() throws Throwable {
+        runTest("test", 2d, Double.NaN);
+    }
+
+    @Test
+    public void run8() throws Throwable {
+        runTest("test", Double.NaN, 0d);
+    }
+
+    @Test
+    public void run9() throws Throwable {
+        runTest("test", Double.NaN, 23d);
+    }
 }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/MathSubstitutionsX86.java	Wed Dec 04 22:31:18 2013 +0100
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/MathSubstitutionsX86.java	Wed Dec 04 17:22:41 2013 -0800
@@ -36,7 +36,7 @@
 @ClassSubstitution(java.lang.Math.class)
 public class MathSubstitutionsX86 {
 
-    private static final double PI_4 = 0.7853981633974483;
+    private static final double PI_4 = Math.PI / 4;
 
     @MethodSubstitution
     public static double abs(double x) {
@@ -58,6 +58,49 @@
         return MathIntrinsicNode.compute(x, Operation.LOG10);
     }
 
+    /**
+     * Special cases from {@link Math#pow} and __ieee754_pow (in sharedRuntimeTrans.cpp).
+     */
+    @MethodSubstitution
+    public static double pow(double x, double y) {
+        // If the second argument is positive or negative zero, then the result is 1.0.
+        if (y == 0) {
+            return 1;
+        }
+
+        // If the second argument is 1.0, then the result is the same as the first argument.
+        if (y == 1) {
+            return x;
+        }
+
+        // If the second argument is NaN, then the result is NaN.
+        if (Double.isNaN(y)) {
+            return Double.NaN;
+        }
+
+        // If the first argument is NaN and the second argument is nonzero, then the result is NaN.
+        if (Double.isNaN(x) && y != 0) {
+            return Double.NaN;
+        }
+
+        // x**-1 = 1/x
+        if (y == -1) {
+            return 1 / x;
+        }
+
+        // x**2 = x*x
+        if (y == 2) {
+            return x * x;
+        }
+
+        // x**0.5 = sqrt(x)
+        if (y == 0.5 && x >= 0) {
+            return sqrt(x);
+        }
+
+        return pow(x, y);
+    }
+
     // NOTE on snippets below:
     // Math.sin(), .cos() and .tan() guarantee a value within 1 ULP of the
     // exact result, but x87 trigonometric FPU instructions are only that