7174532: jdk/test/java/lang/Math/WorstCaseTests.java failing on x86
Summary: increase precision on x86 for the steps of the computation of exp and pow.
Reviewed-by: kvn
--- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp Mon Jun 11 22:38:28 2012 -0700
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp Tue Jun 12 10:02:36 2012 +0200
@@ -6927,21 +6927,42 @@
addptr(rsp,sizeof(jdouble));
}
+void MacroAssembler::increase_precision() {
+ subptr(rsp, BytesPerWord);
+ fnstcw(Address(rsp, 0));
+ movl(rax, Address(rsp, 0));
+ orl(rax, 0x300);
+ push(rax);
+ fldcw(Address(rsp, 0));
+ pop(rax);
+}
+
+void MacroAssembler::restore_precision() {
+ fldcw(Address(rsp, 0));
+ addptr(rsp, BytesPerWord);
+}
+
void MacroAssembler::fast_pow() {
// computes X^Y = 2^(Y * log2(X))
// if fast computation is not possible, result is NaN. Requires
// fallback from user of this macro.
+ // increase precision for intermediate steps of the computation
+ increase_precision();
fyl2x(); // Stack: (Y*log2(X)) ...
pow_exp_core_encoding(); // Stack: exp(X) ...
+ restore_precision();
}
void MacroAssembler::fast_exp() {
// computes exp(X) = 2^(X * log2(e))
// if fast computation is not possible, result is NaN. Requires
// fallback from user of this macro.
+ // increase precision for intermediate steps of the computation
+ increase_precision();
fldl2e(); // Stack: log2(e) X ...
fmulp(1); // Stack: (X*log2(e)) ...
pow_exp_core_encoding(); // Stack: exp(X) ...
+ restore_precision();
}
void MacroAssembler::pow_or_exp(bool is_exp, int num_fpu_regs_in_use) {
--- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp Mon Jun 11 22:38:28 2012 -0700
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp Tue Jun 12 10:02:36 2012 +0200
@@ -2395,6 +2395,8 @@
// runtime call.
void fast_pow();
void fast_exp();
+ void increase_precision();
+ void restore_precision();
// computes exp(x). Fallback to runtime call included.
void exp_with_fallback(int num_fpu_regs_in_use) { pow_or_exp(true, num_fpu_regs_in_use); }