| Index: src/mips/codegen-mips.cc
|
| diff --git a/src/mips/codegen-mips.cc b/src/mips/codegen-mips.cc
|
| index 51ad4743de1ee0feada8f6aabeb8a7226a3fd631..963778ef113f50652edcb381a12cd24610924ee2 100644
|
| --- a/src/mips/codegen-mips.cc
|
| +++ b/src/mips/codegen-mips.cc
|
| @@ -31,11 +31,11 @@
|
|
|
| #include "codegen.h"
|
| #include "macro-assembler.h"
|
| +#include "simulator-mips.h"
|
|
|
| namespace v8 {
|
| namespace internal {
|
|
|
| -#define __ ACCESS_MASM(masm)
|
|
|
| UnaryMathFunction CreateTranscendentalFunction(TranscendentalCache::Type type) {
|
| switch (type) {
|
| @@ -49,6 +49,74 @@ UnaryMathFunction CreateTranscendentalFunction(TranscendentalCache::Type type) {
|
| }
|
|
|
|
|
| +#define __ masm.
|
| +
|
| +
|
| +#if defined(USE_SIMULATOR)
|
| +byte* fast_exp_mips_machine_code = NULL;
|
| +double fast_exp_simulator(double x) {
|
| + return Simulator::current(Isolate::Current())->CallFP(
|
| + fast_exp_mips_machine_code, x, 0);
|
| +}
|
| +#endif
|
| +
|
| +
|
| +UnaryMathFunction CreateExpFunction() {
|
| + if (!CpuFeatures::IsSupported(FPU)) return &exp;
|
| + 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));
|
| +
|
| + {
|
| + CpuFeatures::Scope use_fpu(FPU);
|
| + DoubleRegister input = f12;
|
| + DoubleRegister result = f0;
|
| + DoubleRegister double_scratch1 = f4;
|
| + DoubleRegister double_scratch2 = f6;
|
| + Register temp1 = t0;
|
| + Register temp2 = t1;
|
| + Register temp3 = t2;
|
| +
|
| + if (!IsMipsSoftFloatABI) {
|
| + // Input value is in f12 anyway, nothing to do.
|
| + } else {
|
| + __ Move(input, a0, a1);
|
| + }
|
| + __ Push(temp3, temp2, temp1);
|
| + MathExpGenerator::EmitMathExp(
|
| + &masm, input, result, double_scratch1, double_scratch2,
|
| + temp1, temp2, temp3);
|
| + __ Pop(temp3, temp2, temp1);
|
| + if (!IsMipsSoftFloatABI) {
|
| + // Result is already in f0, nothing to do.
|
| + } else {
|
| + __ Move(a0, a1, result);
|
| + }
|
| + __ Ret();
|
| + }
|
| +
|
| + CodeDesc desc;
|
| + masm.GetCode(&desc);
|
| +
|
| + CPU::FlushICache(buffer, actual_size);
|
| + OS::ProtectCode(buffer, actual_size);
|
| +
|
| +#if !defined(USE_SIMULATOR)
|
| + return FUNCTION_CAST<UnaryMathFunction>(buffer);
|
| +#else
|
| + fast_exp_mips_machine_code = buffer;
|
| + return &fast_exp_simulator;
|
| +#endif
|
| +}
|
| +
|
| +
|
| +#undef __
|
| +
|
| +
|
| UnaryMathFunction CreateSqrtFunction() {
|
| return &sqrt;
|
| }
|
| @@ -72,6 +140,8 @@ void StubRuntimeCallHelper::AfterCall(MacroAssembler* masm) const {
|
| // -------------------------------------------------------------------------
|
| // Code generators
|
|
|
| +#define __ ACCESS_MASM(masm)
|
| +
|
| void ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
|
| MacroAssembler* masm) {
|
| // ----------- S t a t e -------------
|
| @@ -446,6 +516,81 @@ void StringCharLoadGenerator::Generate(MacroAssembler* masm,
|
| __ bind(&done);
|
| }
|
|
|
| +
|
| +static MemOperand ExpConstant(int index, Register base) {
|
| + return MemOperand(base, index * kDoubleSize);
|
| +}
|
| +
|
| +
|
| +void MathExpGenerator::EmitMathExp(MacroAssembler* masm,
|
| + DoubleRegister input,
|
| + DoubleRegister result,
|
| + DoubleRegister double_scratch1,
|
| + DoubleRegister double_scratch2,
|
| + Register temp1,
|
| + Register temp2,
|
| + Register temp3) {
|
| + ASSERT(!input.is(result));
|
| + ASSERT(!input.is(double_scratch1));
|
| + ASSERT(!input.is(double_scratch2));
|
| + ASSERT(!result.is(double_scratch1));
|
| + ASSERT(!result.is(double_scratch2));
|
| + ASSERT(!double_scratch1.is(double_scratch2));
|
| + ASSERT(!temp1.is(temp2));
|
| + ASSERT(!temp1.is(temp3));
|
| + ASSERT(!temp2.is(temp3));
|
| + ASSERT(ExternalReference::math_exp_constants(0).address() != NULL);
|
| +
|
| + Label done;
|
| +
|
| + __ li(temp3, Operand(ExternalReference::math_exp_constants(0)));
|
| +
|
| + __ ldc1(double_scratch1, ExpConstant(0, temp3));
|
| + __ Move(result, kDoubleRegZero);
|
| + __ BranchF(&done, NULL, ge, double_scratch1, input);
|
| + __ ldc1(double_scratch2, ExpConstant(1, temp3));
|
| + __ ldc1(result, ExpConstant(2, temp3));
|
| + __ BranchF(&done, NULL, ge, input, double_scratch2);
|
| + __ ldc1(double_scratch1, ExpConstant(3, temp3));
|
| + __ ldc1(result, ExpConstant(4, temp3));
|
| + __ mul_d(double_scratch1, double_scratch1, input);
|
| + __ add_d(double_scratch1, double_scratch1, result);
|
| + __ Move(temp2, temp1, double_scratch1);
|
| + __ sub_d(double_scratch1, double_scratch1, result);
|
| + __ ldc1(result, ExpConstant(6, temp3));
|
| + __ ldc1(double_scratch2, ExpConstant(5, temp3));
|
| + __ mul_d(double_scratch1, double_scratch1, double_scratch2);
|
| + __ sub_d(double_scratch1, double_scratch1, input);
|
| + __ sub_d(result, result, double_scratch1);
|
| + __ mul_d(input, double_scratch1, double_scratch1);
|
| + __ mul_d(result, result, input);
|
| + __ srl(temp1, temp2, 11);
|
| + __ ldc1(double_scratch2, ExpConstant(7, temp3));
|
| + __ mul_d(result, result, double_scratch2);
|
| + __ sub_d(result, result, double_scratch1);
|
| + __ ldc1(double_scratch2, ExpConstant(8, temp3));
|
| + __ add_d(result, result, double_scratch2);
|
| + __ li(at, 0x7ff);
|
| + __ And(temp2, temp2, at);
|
| + __ Addu(temp1, temp1, Operand(0x3ff));
|
| + __ sll(temp1, temp1, 20);
|
| +
|
| + // Must not call ExpConstant() after overwriting temp3!
|
| + __ li(temp3, Operand(ExternalReference::math_exp_log_table()));
|
| + __ sll(at, temp2, 3);
|
| + __ addu(at, at, temp3);
|
| + __ lw(at, MemOperand(at));
|
| + __ Addu(temp3, temp3, Operand(kPointerSize));
|
| + __ sll(temp2, temp2, 3);
|
| + __ addu(temp2, temp2, temp3);
|
| + __ lw(temp2, MemOperand(temp2));
|
| + __ Or(temp1, temp1, temp2);
|
| + __ Move(input, at, temp1);
|
| + __ mul_d(result, result, input);
|
| + __ bind(&done);
|
| +}
|
| +
|
| +
|
| // nop(CODE_AGE_MARKER_NOP)
|
| static const uint32_t kCodeAgePatchFirstInstruction = 0x00010180;
|
|
|
|
|