--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp Wed Dec 23 16:24:19 2015 -0800
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp Wed Dec 23 21:09:50 2015 -0800
@@ -3060,50 +3060,6 @@
}
}
-void MacroAssembler::pow_exp_core_encoding() {
- // kills rax, rcx, rdx
- subptr(rsp,sizeof(jdouble));
- // computes 2^X. Stack: X ...
- // f2xm1 computes 2^X-1 but only operates on -1<=X<=1. Get int(X) and
- // keep it on the thread's stack to compute 2^int(X) later
- // then compute 2^(X-int(X)) as (2^(X-int(X)-1+1)
- // final result is obtained with: 2^X = 2^int(X) * 2^(X-int(X))
- fld_s(0); // Stack: X X ...
- frndint(); // Stack: int(X) X ...
- fsuba(1); // Stack: int(X) X-int(X) ...
- fistp_s(Address(rsp,0)); // move int(X) as integer to thread's stack. Stack: X-int(X) ...
- f2xm1(); // Stack: 2^(X-int(X))-1 ...
- fld1(); // Stack: 1 2^(X-int(X))-1 ...
- faddp(1); // Stack: 2^(X-int(X))
- // computes 2^(int(X)): add exponent bias (1023) to int(X), then
- // shift int(X)+1023 to exponent position.
- // Exponent is limited to 11 bits if int(X)+1023 does not fit in 11
- // bits, set result to NaN. 0x000 and 0x7FF are reserved exponent
- // values so detect them and set result to NaN.
- movl(rax,Address(rsp,0));
- movl(rcx, -2048); // 11 bit mask and valid NaN binary encoding
- addl(rax, 1023);
- movl(rdx,rax);
- shll(rax,20);
- // Check that 0 < int(X)+1023 < 2047. Otherwise set rax to NaN.
- addl(rdx,1);
- // Check that 1 < int(X)+1023+1 < 2048
- // in 3 steps:
- // 1- (int(X)+1023+1)&-2048 == 0 => 0 <= int(X)+1023+1 < 2048
- // 2- (int(X)+1023+1)&-2048 != 0
- // 3- (int(X)+1023+1)&-2048 != 1
- // Do 2- first because addl just updated the flags.
- cmov32(Assembler::equal,rax,rcx);
- cmpl(rdx,1);
- cmov32(Assembler::equal,rax,rcx);
- testl(rdx,rcx);
- cmov32(Assembler::notEqual,rax,rcx);
- movl(Address(rsp,4),rax);
- movl(Address(rsp,0),0);
- fmul_d(Address(rsp,0)); // Stack: 2^X ...
- addptr(rsp,sizeof(jdouble));
-}
-
void MacroAssembler::increase_precision() {
subptr(rsp, BytesPerWord);
fnstcw(Address(rsp, 0));
@@ -3119,194 +3075,6 @@
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
- BLOCK_COMMENT("fast_pow {");
- increase_precision();
- fyl2x(); // Stack: (Y*log2(X)) ...
- pow_exp_core_encoding(); // Stack: exp(X) ...
- restore_precision();
- BLOCK_COMMENT("} fast_pow");
-}
-
-void MacroAssembler::pow_or_exp(int num_fpu_regs_in_use) {
- // kills rax, rcx, rdx
- // pow and exp needs 2 extra registers on the fpu stack.
- Label slow_case, done;
- Register tmp = noreg;
- if (!VM_Version::supports_cmov()) {
- // fcmp needs a temporary so preserve rdx,
- tmp = rdx;
- }
- Register tmp2 = rax;
- Register tmp3 = rcx;
-
- // Stack: X Y
- Label x_negative, y_not_2;
-
- static double two = 2.0;
- ExternalAddress two_addr((address)&two);
-
- // constant maybe too far on 64 bit
- lea(tmp2, two_addr);
- fld_d(Address(tmp2, 0)); // Stack: 2 X Y
- fcmp(tmp, 2, true, false); // Stack: X Y
- jcc(Assembler::parity, y_not_2);
- jcc(Assembler::notEqual, y_not_2);
-
- fxch(); fpop(); // Stack: X
- fmul(0); // Stack: X*X
-
- jmp(done);
-
- bind(y_not_2);
-
- fldz(); // Stack: 0 X Y
- fcmp(tmp, 1, true, false); // Stack: X Y
- jcc(Assembler::above, x_negative);
-
- // X >= 0
-
- fld_s(1); // duplicate arguments for runtime call. Stack: Y X Y
- fld_s(1); // Stack: X Y X Y
- fast_pow(); // Stack: X^Y X Y
- fcmp(tmp, 0, false, false); // Stack: X^Y X Y
- // X^Y not equal to itself: X^Y is NaN go to slow case.
- jcc(Assembler::parity, slow_case);
- // get rid of duplicate arguments. Stack: X^Y
- if (num_fpu_regs_in_use > 0) {
- fxch(); fpop();
- fxch(); fpop();
- } else {
- ffree(2);
- ffree(1);
- }
- jmp(done);
-
- // X <= 0
- bind(x_negative);
-
- fld_s(1); // Stack: Y X Y
- frndint(); // Stack: int(Y) X Y
- fcmp(tmp, 2, false, false); // Stack: int(Y) X Y
- jcc(Assembler::notEqual, slow_case);
-
- subptr(rsp, 8);
-
- // For X^Y, when X < 0, Y has to be an integer and the final
- // result depends on whether it's odd or even. We just checked
- // that int(Y) == Y. We move int(Y) to gp registers as a 64 bit
- // integer to test its parity. If int(Y) is huge and doesn't fit
- // in the 64 bit integer range, the integer indefinite value will
- // end up in the gp registers. Huge numbers are all even, the
- // integer indefinite number is even so it's fine.
-
-#ifdef ASSERT
- // Let's check we don't end up with an integer indefinite number
- // when not expected. First test for huge numbers: check whether
- // int(Y)+1 == int(Y) which is true for very large numbers and
- // those are all even. A 64 bit integer is guaranteed to not
- // overflow for numbers where y+1 != y (when precision is set to
- // double precision).
- Label y_not_huge;
-
- fld1(); // Stack: 1 int(Y) X Y
- fadd(1); // Stack: 1+int(Y) int(Y) X Y
-
-#ifdef _LP64
- // trip to memory to force the precision down from double extended
- // precision
- fstp_d(Address(rsp, 0));
- fld_d(Address(rsp, 0));
-#endif
-
- fcmp(tmp, 1, true, false); // Stack: int(Y) X Y
-#endif
-
- // move int(Y) as 64 bit integer to thread's stack
- fistp_d(Address(rsp,0)); // Stack: X Y
-
-#ifdef ASSERT
- jcc(Assembler::notEqual, y_not_huge);
-
- // Y is huge so we know it's even. It may not fit in a 64 bit
- // integer and we don't want the debug code below to see the
- // integer indefinite value so overwrite int(Y) on the thread's
- // stack with 0.
- movl(Address(rsp, 0), 0);
- movl(Address(rsp, 4), 0);
-
- bind(y_not_huge);
-#endif
-
- fld_s(1); // duplicate arguments for runtime call. Stack: Y X Y
- fld_s(1); // Stack: X Y X Y
- fabs(); // Stack: abs(X) Y X Y
- fast_pow(); // Stack: abs(X)^Y X Y
- fcmp(tmp, 0, false, false); // Stack: abs(X)^Y X Y
- // abs(X)^Y not equal to itself: abs(X)^Y is NaN go to slow case.
-
- pop(tmp2);
- NOT_LP64(pop(tmp3));
- jcc(Assembler::parity, slow_case);
-
-#ifdef ASSERT
- // Check that int(Y) is not integer indefinite value (int
- // overflow). Shouldn't happen because for values that would
- // overflow, 1+int(Y)==Y which was tested earlier.
-#ifndef _LP64
- {
- Label integer;
- testl(tmp2, tmp2);
- jcc(Assembler::notZero, integer);
- cmpl(tmp3, 0x80000000);
- jcc(Assembler::notZero, integer);
- STOP("integer indefinite value shouldn't be seen here");
- bind(integer);
- }
-#else
- {
- Label integer;
- mov(tmp3, tmp2); // preserve tmp2 for parity check below
- shlq(tmp3, 1);
- jcc(Assembler::carryClear, integer);
- jcc(Assembler::notZero, integer);
- STOP("integer indefinite value shouldn't be seen here");
- bind(integer);
- }
-#endif
-#endif
-
- // get rid of duplicate arguments. Stack: X^Y
- if (num_fpu_regs_in_use > 0) {
- fxch(); fpop();
- fxch(); fpop();
- } else {
- ffree(2);
- ffree(1);
- }
-
- testl(tmp2, 1);
- jcc(Assembler::zero, done); // X <= 0, Y even: X^Y = abs(X)^Y
- // X <= 0, Y even: X^Y = -abs(X)^Y
-
- fchs(); // Stack: -abs(X)^Y Y
- jmp(done);
-
- // slow case: runtime call
- bind(slow_case);
-
- fpop(); // pop incorrect result or int(Y)
-
- fp_runtime_fallback(CAST_FROM_FN_PTR(address, SharedRuntime::dpow), 2, num_fpu_regs_in_use);
-
- // Come here with result in F-TOS
- bind(done);
-}
-
void MacroAssembler::fpop() {
ffree();
fincstp();