| Index: src/x64/codegen-x64.cc
|
| diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc
|
| index aa777baf50ecf36e194474c9c79fa7ca96abcc58..e2471e69cc726d69c1eed338ac333558a8be6b9f 100644
|
| --- a/src/x64/codegen-x64.cc
|
| +++ b/src/x64/codegen-x64.cc
|
| @@ -99,6 +99,36 @@ UnaryMathFunction CreateTranscendentalFunction(TranscendentalCache::Type type) {
|
| }
|
|
|
|
|
| +UnaryMathFunction CreateExpFunction() {
|
| + if (!FLAG_fast_math) return &exp;
|
| + size_t actual_size;
|
| + byte* buffer = static_cast<byte*>(OS::Allocate(1 * KB, &actual_size, true));
|
| + if (buffer == NULL) return &exp;
|
| + ExternalReference::InitializeMathExpData();
|
| +
|
| + MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size));
|
| + // xmm0: raw double input.
|
| + XMMRegister input = xmm0;
|
| + XMMRegister result = xmm1;
|
| + __ push(rax);
|
| + __ push(rbx);
|
| +
|
| + MathExpGenerator::EmitMathExp(&masm, input, result, xmm2, rax, rbx);
|
| +
|
| + __ pop(rbx);
|
| + __ pop(rax);
|
| + __ movsd(xmm0, result);
|
| + __ Ret();
|
| +
|
| + CodeDesc desc;
|
| + masm.GetCode(&desc);
|
| +
|
| + CPU::FlushICache(buffer, actual_size);
|
| + OS::ProtectCode(buffer, actual_size);
|
| + return FUNCTION_CAST<UnaryMathFunction>(buffer);
|
| +}
|
| +
|
| +
|
| UnaryMathFunction CreateSqrtFunction() {
|
| size_t actual_size;
|
| // Allocate buffer in executable space.
|
| @@ -575,6 +605,58 @@ void StringCharLoadGenerator::Generate(MacroAssembler* masm,
|
| __ bind(&done);
|
| }
|
|
|
| +
|
| +void MathExpGenerator::EmitMathExp(MacroAssembler* masm,
|
| + XMMRegister input,
|
| + XMMRegister result,
|
| + XMMRegister double_scratch,
|
| + Register temp1,
|
| + Register temp2) {
|
| + ASSERT(!input.is(result));
|
| + ASSERT(!input.is(double_scratch));
|
| + ASSERT(!result.is(double_scratch));
|
| + ASSERT(!temp1.is(temp2));
|
| + ASSERT(ExternalReference::math_exp_constants(0).address() != NULL);
|
| +
|
| + Label done;
|
| +
|
| + __ movq(kScratchRegister, ExternalReference::math_exp_constants(0));
|
| + __ movsd(double_scratch, Operand(kScratchRegister, 0 * kDoubleSize));
|
| + __ xorpd(result, result);
|
| + __ ucomisd(double_scratch, input);
|
| + __ j(above_equal, &done);
|
| + __ ucomisd(input, Operand(kScratchRegister, 1 * kDoubleSize));
|
| + __ movsd(result, Operand(kScratchRegister, 2 * kDoubleSize));
|
| + __ j(above_equal, &done);
|
| + __ movsd(double_scratch, Operand(kScratchRegister, 3 * kDoubleSize));
|
| + __ movsd(result, Operand(kScratchRegister, 4 * kDoubleSize));
|
| + __ mulsd(double_scratch, input);
|
| + __ addsd(double_scratch, result);
|
| + __ movq(temp2, double_scratch);
|
| + __ subsd(double_scratch, result);
|
| + __ movsd(result, Operand(kScratchRegister, 6 * kDoubleSize));
|
| + __ lea(temp1, Operand(temp2, 0x1ff800));
|
| + __ and_(temp2, Immediate(0x7ff));
|
| + __ shr(temp1, Immediate(11));
|
| + __ mulsd(double_scratch, Operand(kScratchRegister, 5 * kDoubleSize));
|
| + __ movq(kScratchRegister, ExternalReference::math_exp_log_table());
|
| + __ shl(temp1, Immediate(52));
|
| + __ or_(temp1, Operand(kScratchRegister, temp2, times_8, 0));
|
| + __ movq(kScratchRegister, ExternalReference::math_exp_constants(0));
|
| + __ subsd(double_scratch, input);
|
| + __ movsd(input, double_scratch);
|
| + __ subsd(result, double_scratch);
|
| + __ mulsd(input, double_scratch);
|
| + __ mulsd(result, input);
|
| + __ movq(input, temp1);
|
| + __ mulsd(result, Operand(kScratchRegister, 7 * kDoubleSize));
|
| + __ subsd(result, double_scratch);
|
| + __ addsd(result, Operand(kScratchRegister, 8 * kDoubleSize));
|
| + __ mulsd(result, input);
|
| +
|
| + __ bind(&done);
|
| +}
|
| +
|
| #undef __
|
|
|
|
|
|
|