< prev index next >
src/cpu/x86/vm/macroAssembler_x86.cpp
Print this page
*** 3030,3039 ****
--- 3030,3048 ----
void MacroAssembler::fldcw(AddressLiteral src) {
Assembler::fldcw(as_Address(src));
}
+ void MacroAssembler::mulpd(XMMRegister dst, AddressLiteral src) {
+ if (reachable(src)) {
+ Assembler::mulpd(dst, as_Address(src));
+ } else {
+ lea(rscratch1, src);
+ Assembler::mulpd(dst, Address(rscratch1, 0));
+ }
+ }
+
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
*** 3102,3124 ****
pow_exp_core_encoding(); // Stack: exp(X) ...
restore_precision();
BLOCK_COMMENT("} fast_pow");
}
! 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) {
// 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()) {
--- 3111,3121 ----
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()) {
*** 3126,3151 ****
tmp = rdx;
}
Register tmp2 = rax;
Register tmp3 = rcx;
- if (is_exp) {
- // Stack: X
- fld_s(0); // duplicate argument for runtime call. Stack: X X
- fast_exp(); // Stack: exp(X) X
- fcmp(tmp, 0, false, false); // Stack: exp(X) X
- // exp(X) not equal to itself: exp(X) is NaN go to slow case.
- jcc(Assembler::parity, slow_case);
- // get rid of duplicate argument. Stack: exp(X)
- if (num_fpu_regs_in_use > 0) {
- fxch();
- fpop();
- } else {
- ffree(1);
- }
- jmp(done);
- } else {
// Stack: X Y
Label x_negative, y_not_2;
static double two = 2.0;
ExternalAddress two_addr((address)&two);
--- 3123,3132 ----
*** 3293,3311 ****
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(is_exp ? CAST_FROM_FN_PTR(address, SharedRuntime::dexp) : CAST_FROM_FN_PTR(address, SharedRuntime::dpow),
! is_exp ? 1 : 2, num_fpu_regs_in_use);
// Come here with result in F-TOS
bind(done);
}
--- 3274,3290 ----
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);
}
< prev index next >