| Index: src/arm64/codegen-arm64.cc
|
| diff --git a/src/arm64/codegen-arm64.cc b/src/arm64/codegen-arm64.cc
|
| index 990dd4101fe04ba51a07af6af6732b367c42157b..edd289900e978d6d63ce8bb13f076bb272f1fd8f 100644
|
| --- a/src/arm64/codegen-arm64.cc
|
| +++ b/src/arm64/codegen-arm64.cc
|
| @@ -15,66 +15,6 @@ namespace internal {
|
|
|
| #define __ ACCESS_MASM(masm)
|
|
|
| -#if defined(USE_SIMULATOR)
|
| -byte* fast_exp_arm64_machine_code = nullptr;
|
| -double fast_exp_simulator(double x, Isolate* isolate) {
|
| - Simulator * simulator = Simulator::current(isolate);
|
| - Simulator::CallArgument args[] = {
|
| - Simulator::CallArgument(x),
|
| - Simulator::CallArgument::End()
|
| - };
|
| - return simulator->CallDouble(fast_exp_arm64_machine_code, args);
|
| -}
|
| -#endif
|
| -
|
| -
|
| -UnaryMathFunctionWithIsolate CreateExpFunction(Isolate* isolate) {
|
| - // Use the Math.exp implemetation in MathExpGenerator::EmitMathExp() to create
|
| - // an AAPCS64-compliant exp() function. This will be faster than the C
|
| - // library's exp() function, but probably less accurate.
|
| - size_t actual_size;
|
| - byte* buffer =
|
| - static_cast<byte*>(base::OS::Allocate(1 * KB, &actual_size, true));
|
| - if (buffer == nullptr) return nullptr;
|
| -
|
| - ExternalReference::InitializeMathExpData();
|
| - MacroAssembler masm(isolate, buffer, static_cast<int>(actual_size),
|
| - CodeObjectRequired::kNo);
|
| - masm.SetStackPointer(csp);
|
| -
|
| - // The argument will be in d0 on entry.
|
| - DoubleRegister input = d0;
|
| - // Use other caller-saved registers for all other values.
|
| - DoubleRegister result = d1;
|
| - DoubleRegister double_temp1 = d2;
|
| - DoubleRegister double_temp2 = d3;
|
| - Register temp1 = x10;
|
| - Register temp2 = x11;
|
| - Register temp3 = x12;
|
| -
|
| - MathExpGenerator::EmitMathExp(&masm, input, result,
|
| - double_temp1, double_temp2,
|
| - temp1, temp2, temp3);
|
| - // Move the result to the return register.
|
| - masm.Fmov(d0, result);
|
| - masm.Ret();
|
| -
|
| - CodeDesc desc;
|
| - masm.GetCode(&desc);
|
| - DCHECK(!RelocInfo::RequiresRelocation(desc));
|
| -
|
| - Assembler::FlushICache(isolate, buffer, actual_size);
|
| - base::OS::ProtectCode(buffer, actual_size);
|
| -
|
| -#if !defined(USE_SIMULATOR)
|
| - return FUNCTION_CAST<UnaryMathFunctionWithIsolate>(buffer);
|
| -#else
|
| - fast_exp_arm64_machine_code = buffer;
|
| - return &fast_exp_simulator;
|
| -#endif
|
| -}
|
| -
|
| -
|
| UnaryMathFunctionWithIsolate CreateSqrtFunction(Isolate* isolate) {
|
| return nullptr;
|
| }
|
| @@ -510,127 +450,6 @@ void StringCharLoadGenerator::Generate(MacroAssembler* masm,
|
| __ Bind(&done);
|
| }
|
|
|
| -
|
| -static MemOperand ExpConstant(Register base, int index) {
|
| - return MemOperand(base, index * kDoubleSize);
|
| -}
|
| -
|
| -
|
| -void MathExpGenerator::EmitMathExp(MacroAssembler* masm,
|
| - DoubleRegister input,
|
| - DoubleRegister result,
|
| - DoubleRegister double_temp1,
|
| - DoubleRegister double_temp2,
|
| - Register temp1,
|
| - Register temp2,
|
| - Register temp3) {
|
| - // TODO(jbramley): There are several instances where fnmsub could be used
|
| - // instead of fmul and fsub. Doing this changes the result, but since this is
|
| - // an estimation anyway, does it matter?
|
| -
|
| - DCHECK(!AreAliased(input, result,
|
| - double_temp1, double_temp2,
|
| - temp1, temp2, temp3));
|
| - DCHECK(ExternalReference::math_exp_constants(0).address() != NULL);
|
| - DCHECK(!masm->serializer_enabled()); // External references not serializable.
|
| -
|
| - Label done;
|
| - DoubleRegister double_temp3 = result;
|
| - Register constants = temp3;
|
| -
|
| - // The algorithm used relies on some magic constants which are initialized in
|
| - // ExternalReference::InitializeMathExpData().
|
| -
|
| - // Load the address of the start of the array.
|
| - __ Mov(constants, ExternalReference::math_exp_constants(0));
|
| -
|
| - // We have to do a four-way split here:
|
| - // - If input <= about -708.4, the output always rounds to zero.
|
| - // - If input >= about 709.8, the output always rounds to +infinity.
|
| - // - If the input is NaN, the output is NaN.
|
| - // - Otherwise, the result needs to be calculated.
|
| - Label result_is_finite_non_zero;
|
| - // Assert that we can load offset 0 (the small input threshold) and offset 1
|
| - // (the large input threshold) with a single ldp.
|
| - DCHECK(kDRegSize == (ExpConstant(constants, 1).offset() -
|
| - ExpConstant(constants, 0).offset()));
|
| - __ Ldp(double_temp1, double_temp2, ExpConstant(constants, 0));
|
| -
|
| - __ Fcmp(input, double_temp1);
|
| - __ Fccmp(input, double_temp2, NoFlag, hi);
|
| - // At this point, the condition flags can be in one of five states:
|
| - // NZCV
|
| - // 1000 -708.4 < input < 709.8 result = exp(input)
|
| - // 0110 input == 709.8 result = +infinity
|
| - // 0010 input > 709.8 result = +infinity
|
| - // 0011 input is NaN result = input
|
| - // 0000 input <= -708.4 result = +0.0
|
| -
|
| - // Continue the common case first. 'mi' tests N == 1.
|
| - __ B(&result_is_finite_non_zero, mi);
|
| -
|
| - // TODO(jbramley): Consider adding a +infinity register for ARM64.
|
| - __ Ldr(double_temp2, ExpConstant(constants, 2)); // Synthesize +infinity.
|
| -
|
| - // Select between +0.0 and +infinity. 'lo' tests C == 0.
|
| - __ Fcsel(result, fp_zero, double_temp2, lo);
|
| - // Select between {+0.0 or +infinity} and input. 'vc' tests V == 0.
|
| - __ Fcsel(result, result, input, vc);
|
| - __ B(&done);
|
| -
|
| - // The rest is magic, as described in InitializeMathExpData().
|
| - __ Bind(&result_is_finite_non_zero);
|
| -
|
| - // Assert that we can load offset 3 and offset 4 with a single ldp.
|
| - DCHECK(kDRegSize == (ExpConstant(constants, 4).offset() -
|
| - ExpConstant(constants, 3).offset()));
|
| - __ Ldp(double_temp1, double_temp3, ExpConstant(constants, 3));
|
| - __ Fmadd(double_temp1, double_temp1, input, double_temp3);
|
| - __ Fmov(temp2.W(), double_temp1.S());
|
| - __ Fsub(double_temp1, double_temp1, double_temp3);
|
| -
|
| - // Assert that we can load offset 5 and offset 6 with a single ldp.
|
| - DCHECK(kDRegSize == (ExpConstant(constants, 6).offset() -
|
| - ExpConstant(constants, 5).offset()));
|
| - __ Ldp(double_temp2, double_temp3, ExpConstant(constants, 5));
|
| - // TODO(jbramley): Consider using Fnmsub here.
|
| - __ Fmul(double_temp1, double_temp1, double_temp2);
|
| - __ Fsub(double_temp1, double_temp1, input);
|
| -
|
| - __ Fmul(double_temp2, double_temp1, double_temp1);
|
| - __ Fsub(double_temp3, double_temp3, double_temp1);
|
| - __ Fmul(double_temp3, double_temp3, double_temp2);
|
| -
|
| - __ Mov(temp1.W(), Operand(temp2.W(), LSR, 11));
|
| -
|
| - __ Ldr(double_temp2, ExpConstant(constants, 7));
|
| - // TODO(jbramley): Consider using Fnmsub here.
|
| - __ Fmul(double_temp3, double_temp3, double_temp2);
|
| - __ Fsub(double_temp3, double_temp3, double_temp1);
|
| -
|
| - // The 8th constant is 1.0, so use an immediate move rather than a load.
|
| - // We can't generate a runtime assertion here as we would need to call Abort
|
| - // in the runtime and we don't have an Isolate when we generate this code.
|
| - __ Fmov(double_temp2, 1.0);
|
| - __ Fadd(double_temp3, double_temp3, double_temp2);
|
| -
|
| - __ And(temp2, temp2, 0x7ff);
|
| - __ Add(temp1, temp1, 0x3ff);
|
| -
|
| - // Do the final table lookup.
|
| - __ Mov(temp3, ExternalReference::math_exp_log_table());
|
| -
|
| - __ Add(temp3, temp3, Operand(temp2, LSL, kDRegSizeLog2));
|
| - __ Ldp(temp2.W(), temp3.W(), MemOperand(temp3));
|
| - __ Orr(temp1.W(), temp3.W(), Operand(temp1.W(), LSL, 20));
|
| - __ Bfi(temp2, temp1, 32, 32);
|
| - __ Fmov(double_temp1, temp2);
|
| -
|
| - __ Fmul(result, double_temp3, double_temp1);
|
| -
|
| - __ Bind(&done);
|
| -}
|
| -
|
| #undef __
|
|
|
| } // namespace internal
|
|
|