# HG changeset patch # User twisti # Date 1386206561 28800 # Node ID ca061aaeddaf197c01306774756cc2d328c4e07d # Parent ff43107fd697a44d2c61e6a950f9aaea4642749a added Math.pow method substitution with code for handling some special cases diff -r ff43107fd697 -r ca061aaeddaf graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/Math_pow.java --- 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); + } } diff -r ff43107fd697 -r ca061aaeddaf graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/MathSubstitutionsX86.java --- 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