RFR(M): 7133857: exp() and pow() should use the x87 ISA on x86

Roland Westrelin roland.westrelin at oracle.com
Thu Apr 5 09:31:13 PDT 2012


> That looks good.  Did you run the PowTests.java regression test from the JDK for all the configurations?

I found a couple problems when I ran this test on x86 so here is a new webrev:

http://cr.openjdk.java.net/~roland/7133857/webrev.02/

With c1, this code was missing:

diff --git a/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp b/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp
--- a/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp
+++ b/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp
@@ -848,6 +848,10 @@
    LIR_Opr calc_input2 = NULL;
    if (x->id() == vmIntrinsics::_dpow) {
      LIRItem extra_arg(x->argument_at(1), this);
+    if (UseSSE < 2) {
+      extra_arg.set_destroys_register();
+    }
+    extra_arg.load_item();
      calc_input2 = extra_arg.result();
    }
    LIR_Opr calc_result = rlock_result(x);


Also one corner case was not well handled by the interpreter/c1 assembly code. For x^y, when x < 0, y has to be an integer and we need to test whether it's odd or even. The previous code would fallback to the runtime code if y was too large for a 32 bit integer. So for instance Math.pow(x,y) with x < 0 and a large y would be computed by the C code but Math.pow(-x, y) which should be +/- Math.pow(x, y) depending on y's parity would be computed by the assembly code and results would differ. So on the x < 0 code path, I now check for y+1 == y which is true for very large numbers that are all odd and if the test fails I use a 64 bit rather than a 32 bit integer which is guaranteed to not overflow for numbers where y+1 != y.

Roland.


More information about the hotspot-compiler-dev mailing list