1.1 --- a/src/cpu/x86/vm/assembler_x86.cpp Mon Jun 11 22:38:28 2012 -0700 1.2 +++ b/src/cpu/x86/vm/assembler_x86.cpp Tue Jun 12 10:02:36 2012 +0200 1.3 @@ -6927,21 +6927,42 @@ 1.4 addptr(rsp,sizeof(jdouble)); 1.5 } 1.6 1.7 +void MacroAssembler::increase_precision() { 1.8 + subptr(rsp, BytesPerWord); 1.9 + fnstcw(Address(rsp, 0)); 1.10 + movl(rax, Address(rsp, 0)); 1.11 + orl(rax, 0x300); 1.12 + push(rax); 1.13 + fldcw(Address(rsp, 0)); 1.14 + pop(rax); 1.15 +} 1.16 + 1.17 +void MacroAssembler::restore_precision() { 1.18 + fldcw(Address(rsp, 0)); 1.19 + addptr(rsp, BytesPerWord); 1.20 +} 1.21 + 1.22 void MacroAssembler::fast_pow() { 1.23 // computes X^Y = 2^(Y * log2(X)) 1.24 // if fast computation is not possible, result is NaN. Requires 1.25 // fallback from user of this macro. 1.26 + // increase precision for intermediate steps of the computation 1.27 + increase_precision(); 1.28 fyl2x(); // Stack: (Y*log2(X)) ... 1.29 pow_exp_core_encoding(); // Stack: exp(X) ... 1.30 + restore_precision(); 1.31 } 1.32 1.33 void MacroAssembler::fast_exp() { 1.34 // computes exp(X) = 2^(X * log2(e)) 1.35 // if fast computation is not possible, result is NaN. Requires 1.36 // fallback from user of this macro. 1.37 + // increase precision for intermediate steps of the computation 1.38 + increase_precision(); 1.39 fldl2e(); // Stack: log2(e) X ... 1.40 fmulp(1); // Stack: (X*log2(e)) ... 1.41 pow_exp_core_encoding(); // Stack: exp(X) ... 1.42 + restore_precision(); 1.43 } 1.44 1.45 void MacroAssembler::pow_or_exp(bool is_exp, int num_fpu_regs_in_use) {