1fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
25c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Redistribution and use in source and binary forms, with or without
35c838251403b0be9a882540f1922577abba4c872ager@chromium.org// modification, are permitted provided that the following conditions are
45c838251403b0be9a882540f1922577abba4c872ager@chromium.org// met:
55c838251403b0be9a882540f1922577abba4c872ager@chromium.org//
65c838251403b0be9a882540f1922577abba4c872ager@chromium.org//     * Redistributions of source code must retain the above copyright
75c838251403b0be9a882540f1922577abba4c872ager@chromium.org//       notice, this list of conditions and the following disclaimer.
85c838251403b0be9a882540f1922577abba4c872ager@chromium.org//     * Redistributions in binary form must reproduce the above
95c838251403b0be9a882540f1922577abba4c872ager@chromium.org//       copyright notice, this list of conditions and the following
105c838251403b0be9a882540f1922577abba4c872ager@chromium.org//       disclaimer in the documentation and/or other materials provided
115c838251403b0be9a882540f1922577abba4c872ager@chromium.org//       with the distribution.
125c838251403b0be9a882540f1922577abba4c872ager@chromium.org//     * Neither the name of Google Inc. nor the names of its
135c838251403b0be9a882540f1922577abba4c872ager@chromium.org//       contributors may be used to endorse or promote products derived
145c838251403b0be9a882540f1922577abba4c872ager@chromium.org//       from this software without specific prior written permission.
155c838251403b0be9a882540f1922577abba4c872ager@chromium.org//
165c838251403b0be9a882540f1922577abba4c872ager@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
175c838251403b0be9a882540f1922577abba4c872ager@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
185c838251403b0be9a882540f1922577abba4c872ager@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
195c838251403b0be9a882540f1922577abba4c872ager@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
205c838251403b0be9a882540f1922577abba4c872ager@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
215c838251403b0be9a882540f1922577abba4c872ager@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
225c838251403b0be9a882540f1922577abba4c872ager@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
235c838251403b0be9a882540f1922577abba4c872ager@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
245c838251403b0be9a882540f1922577abba4c872ager@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
255c838251403b0be9a882540f1922577abba4c872ager@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
265c838251403b0be9a882540f1922577abba4c872ager@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
275c838251403b0be9a882540f1922577abba4c872ager@chromium.org
285c838251403b0be9a882540f1922577abba4c872ager@chromium.org#include "v8.h"
295c838251403b0be9a882540f1922577abba4c872ager@chromium.org
3093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_MIPS
319dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
3283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org#include "codegen.h"
33394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com#include "macro-assembler.h"
3483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org#include "simulator-mips.h"
355c838251403b0be9a882540f1922577abba4c872ager@chromium.org
365c838251403b0be9a882540f1922577abba4c872ager@chromium.orgnamespace v8 {
375c838251403b0be9a882540f1922577abba4c872ager@chromium.orgnamespace internal {
385c838251403b0be9a882540f1922577abba4c872ager@chromium.org
39394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
40154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgUnaryMathFunction CreateTranscendentalFunction(TranscendentalCache::Type type) {
419a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org  switch (type) {
429a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org    case TranscendentalCache::SIN: return &sin;
439a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org    case TranscendentalCache::COS: return &cos;
449a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org    case TranscendentalCache::TAN: return &tan;
459a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org    case TranscendentalCache::LOG: return &log;
469a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org    default: UNIMPLEMENTED();
479a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org  }
489a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org  return NULL;
499a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org}
509a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org
519a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org
5283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org#define __ masm.
5383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
5483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
5583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org#if defined(USE_SIMULATOR)
5683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.orgbyte* fast_exp_mips_machine_code = NULL;
5783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.orgdouble fast_exp_simulator(double x) {
5883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  return Simulator::current(Isolate::Current())->CallFP(
5983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org      fast_exp_mips_machine_code, x, 0);
6083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org}
6183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org#endif
6283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
6383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
6483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.orgUnaryMathFunction CreateExpFunction() {
6583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  if (!FLAG_fast_math) return &exp;
6683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  size_t actual_size;
6783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  byte* buffer = static_cast<byte*>(OS::Allocate(1 * KB, &actual_size, true));
6883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  if (buffer == NULL) return &exp;
6983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  ExternalReference::InitializeMathExpData();
7083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
7183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size));
7283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
7383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  {
7483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    DoubleRegister input = f12;
7583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    DoubleRegister result = f0;
7683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    DoubleRegister double_scratch1 = f4;
7783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    DoubleRegister double_scratch2 = f6;
7883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    Register temp1 = t0;
7983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    Register temp2 = t1;
8083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    Register temp3 = t2;
8183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
8283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    if (!IsMipsSoftFloatABI) {
8383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org      // Input value is in f12 anyway, nothing to do.
8483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    } else {
8583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org      __ Move(input, a0, a1);
8683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    }
8783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    __ Push(temp3, temp2, temp1);
8883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    MathExpGenerator::EmitMathExp(
8983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org        &masm, input, result, double_scratch1, double_scratch2,
9083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org        temp1, temp2, temp3);
9183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    __ Pop(temp3, temp2, temp1);
9283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    if (!IsMipsSoftFloatABI) {
9383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org      // Result is already in f0, nothing to do.
9483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    } else {
95e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      __ Move(v0, v1, result);
9683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    }
9783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    __ Ret();
9883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  }
9983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
10083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  CodeDesc desc;
10183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  masm.GetCode(&desc);
1022e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  ASSERT(!RelocInfo::RequiresRelocation(desc));
10383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
10483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  CPU::FlushICache(buffer, actual_size);
10583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  OS::ProtectCode(buffer, actual_size);
10683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
10783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org#if !defined(USE_SIMULATOR)
10883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  return FUNCTION_CAST<UnaryMathFunction>(buffer);
10983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org#else
11083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  fast_exp_mips_machine_code = buffer;
11183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  return &fast_exp_simulator;
11283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org#endif
11383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org}
11483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
11583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
11683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org#undef __
11783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
11883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
119154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgUnaryMathFunction CreateSqrtFunction() {
120154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org  return &sqrt;
121154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org}
122154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org
123e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
1247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// -------------------------------------------------------------------------
1257516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// Platform-specific RuntimeCallHelper functions.
1267516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
1277516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid StubRuntimeCallHelper::BeforeCall(MacroAssembler* masm) const {
128c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  masm->EnterFrame(StackFrame::INTERNAL);
129c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSERT(!masm->has_frame());
130c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  masm->set_has_frame(true);
1317516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org}
1327516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
1337516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
1347516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid StubRuntimeCallHelper::AfterCall(MacroAssembler* masm) const {
135c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  masm->LeaveFrame(StackFrame::INTERNAL);
136c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSERT(masm->has_frame());
137c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  masm->set_has_frame(false);
1385c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
1395c838251403b0be9a882540f1922577abba4c872ager@chromium.org
140e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
141394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com// -------------------------------------------------------------------------
142394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com// Code generators
143394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
14483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org#define __ ACCESS_MASM(masm)
14583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
146830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.orgvoid ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
14728381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org    MacroAssembler* masm, AllocationSiteMode mode,
148ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    Label* allocation_memento_found) {
149394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // ----------- S t a t e -------------
150394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //  -- a0    : value
151394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //  -- a1    : key
152394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //  -- a2    : receiver
153394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //  -- ra    : return address
154394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //  -- a3    : target map, scratch for subsequent call
155394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //  -- t0    : scratch (elements)
156394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // -----------------------------------
15728381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org  if (mode == TRACK_ALLOCATION_SITE) {
158ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    ASSERT(allocation_memento_found != NULL);
159ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    masm->TestJSArrayForAllocationMemento(a2, t0, eq,
160ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                          allocation_memento_found);
16128381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org  }
16228381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org
163394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Set transitioned map.
164394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ sw(a3, FieldMemOperand(a2, HeapObject::kMapOffset));
165394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ RecordWriteField(a2,
166394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      HeapObject::kMapOffset,
167394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      a3,
168394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      t5,
169394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      kRAHasNotBeenSaved,
170394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      kDontSaveFPRegs,
171394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      EMIT_REMEMBERED_SET,
172394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      OMIT_SMI_CHECK);
173394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
174394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
175394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
176830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.orgvoid ElementsTransitionGenerator::GenerateSmiToDouble(
17728381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org    MacroAssembler* masm, AllocationSiteMode mode, Label* fail) {
178394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // ----------- S t a t e -------------
179394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //  -- a0    : value
180394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //  -- a1    : key
181394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //  -- a2    : receiver
182394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //  -- ra    : return address
183394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //  -- a3    : target map, scratch for subsequent call
184394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //  -- t0    : scratch (elements)
185394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // -----------------------------------
18656454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  Label loop, entry, convert_hole, gc_required, only_change_map, done;
187394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
188394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Register scratch = t6;
189394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
19028381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org  if (mode == TRACK_ALLOCATION_SITE) {
191ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    masm->TestJSArrayForAllocationMemento(a2, t0, eq, fail);
19259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  }
19359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
19456454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  // Check for empty arrays, which only require a map transition and no changes
19556454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  // to the backing store.
196394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ lw(t0, FieldMemOperand(a2, JSObject::kElementsOffset));
19756454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  __ LoadRoot(at, Heap::kEmptyFixedArrayRootIndex);
19856454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  __ Branch(&only_change_map, eq, at, Operand(t0));
19956454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org
20056454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  __ push(ra);
201394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ lw(t1, FieldMemOperand(t0, FixedArray::kLengthOffset));
202394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // t0: source FixedArray
203394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // t1: number of elements (smi-tagged)
204394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
205394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Allocate new FixedDoubleArray.
206394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ sll(scratch, t1, 2);
207394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Addu(scratch, scratch, FixedDoubleArray::kHeaderSize);
208594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  __ Allocate(scratch, t2, t3, t5, &gc_required, DOUBLE_ALIGNMENT);
209394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // t2: destination FixedDoubleArray, not tagged as heap object
210f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
211fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // Set destination FixedDoubleArray's length and map.
212394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ LoadRoot(t5, Heap::kFixedDoubleArrayMapRootIndex);
213394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ sw(t1, MemOperand(t2, FixedDoubleArray::kLengthOffset));
214fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  __ sw(t5, MemOperand(t2, HeapObject::kMapOffset));
215394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Update receiver's map.
216394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
217394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ sw(a3, FieldMemOperand(a2, HeapObject::kMapOffset));
218394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ RecordWriteField(a2,
219394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      HeapObject::kMapOffset,
220394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      a3,
221394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      t5,
222394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      kRAHasBeenSaved,
223394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      kDontSaveFPRegs,
22456454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org                      OMIT_REMEMBERED_SET,
225394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      OMIT_SMI_CHECK);
226394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Replace receiver's backing store with newly created FixedDoubleArray.
227394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Addu(a3, t2, Operand(kHeapObjectTag));
228394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ sw(a3, FieldMemOperand(a2, JSObject::kElementsOffset));
229394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ RecordWriteField(a2,
230394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      JSObject::kElementsOffset,
231394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      a3,
232394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      t5,
233394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      kRAHasBeenSaved,
234394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      kDontSaveFPRegs,
235394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      EMIT_REMEMBERED_SET,
236394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      OMIT_SMI_CHECK);
237394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
238394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
239394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Prepare for conversion loop.
240394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Addu(a3, t0, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
241394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Addu(t3, t2, Operand(FixedDoubleArray::kHeaderSize));
242394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ sll(t2, t1, 2);
243394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Addu(t2, t2, t3);
244394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ li(t0, Operand(kHoleNanLower32));
245394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ li(t1, Operand(kHoleNanUpper32));
246394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // t0: kHoleNanLower32
247394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // t1: kHoleNanUpper32
248394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // t2: end of destination FixedDoubleArray, not tagged
249394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // t3: begin of FixedDoubleArray element fields, not tagged
250394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
251394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Branch(&entry);
252394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
25356454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  __ bind(&only_change_map);
25456454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  __ sw(a3, FieldMemOperand(a2, HeapObject::kMapOffset));
25556454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  __ RecordWriteField(a2,
25656454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org                      HeapObject::kMapOffset,
25756454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org                      a3,
25856454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org                      t5,
259a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                      kRAHasNotBeenSaved,
26056454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org                      kDontSaveFPRegs,
26156454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org                      OMIT_REMEMBERED_SET,
26256454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org                      OMIT_SMI_CHECK);
26356454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  __ Branch(&done);
26456454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org
265394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Call into runtime if GC is required.
266394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ bind(&gc_required);
267394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ pop(ra);
268394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Branch(fail);
269394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
270394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Convert and copy elements.
271394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ bind(&loop);
272394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ lw(t5, MemOperand(a3));
273394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Addu(a3, a3, kIntSize);
274394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // t5: current element
275fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  __ UntagAndJumpIfNotSmi(t5, t5, &convert_hole);
276394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
277394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Normal smi, convert to double and store.
278e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ mtc1(t5, f0);
279e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ cvt_d_w(f0, f0);
280e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ sdc1(f0, MemOperand(t3));
281e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ Addu(t3, t3, kDoubleSize);
282e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
283394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Branch(&entry);
284394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
285394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Hole found, store the-hole NaN.
286394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ bind(&convert_hole);
287c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  if (FLAG_debug_code) {
288fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    // Restore a "smi-untagged" heap object.
289fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    __ SmiTag(t5);
290fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    __ Or(t5, t5, Operand(1));
291c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org    __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
292594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    __ Assert(eq, kObjectFoundInSmiOnlyArray, at, Operand(t5));
293c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  }
294394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ sw(t0, MemOperand(t3));  // mantissa
295394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ sw(t1, MemOperand(t3, kIntSize));  // exponent
296394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Addu(t3, t3, kDoubleSize);
297394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
298394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ bind(&entry);
299394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Branch(&loop, lt, t3, Operand(t2));
300394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
301394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ pop(ra);
30256454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  __ bind(&done);
303394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
304394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
305394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
306394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comvoid ElementsTransitionGenerator::GenerateDoubleToObject(
30728381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org    MacroAssembler* masm, AllocationSiteMode mode, Label* fail) {
308394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // ----------- S t a t e -------------
309394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //  -- a0    : value
310394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //  -- a1    : key
311394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //  -- a2    : receiver
312394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //  -- ra    : return address
313394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //  -- a3    : target map, scratch for subsequent call
314394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //  -- t0    : scratch (elements)
315394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // -----------------------------------
31656454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  Label entry, loop, convert_hole, gc_required, only_change_map;
317394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
31828381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org  if (mode == TRACK_ALLOCATION_SITE) {
319ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    masm->TestJSArrayForAllocationMemento(a2, t0, eq, fail);
32028381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org  }
32128381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org
32256454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  // Check for empty arrays, which only require a map transition and no changes
32356454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  // to the backing store.
324394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ lw(t0, FieldMemOperand(a2, JSObject::kElementsOffset));
32556454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  __ LoadRoot(at, Heap::kEmptyFixedArrayRootIndex);
32656454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  __ Branch(&only_change_map, eq, at, Operand(t0));
32756454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org
32856454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  __ MultiPush(a0.bit() | a1.bit() | a2.bit() | a3.bit() | ra.bit());
32956454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org
330394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ lw(t1, FieldMemOperand(t0, FixedArray::kLengthOffset));
331394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // t0: source FixedArray
332394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // t1: number of elements (smi-tagged)
333394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
334394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Allocate new FixedArray.
335394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ sll(a0, t1, 1);
336394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Addu(a0, a0, FixedDoubleArray::kHeaderSize);
337f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  __ Allocate(a0, t2, t3, t5, &gc_required, NO_ALLOCATION_FLAGS);
338394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // t2: destination FixedArray, not tagged as heap object
339fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // Set destination FixedDoubleArray's length and map.
340394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ LoadRoot(t5, Heap::kFixedArrayMapRootIndex);
341394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ sw(t1, MemOperand(t2, FixedDoubleArray::kLengthOffset));
342fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  __ sw(t5, MemOperand(t2, HeapObject::kMapOffset));
343394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
344394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Prepare for conversion loop.
345394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Addu(t0, t0, Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag + 4));
346394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Addu(a3, t2, Operand(FixedArray::kHeaderSize));
347394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Addu(t2, t2, Operand(kHeapObjectTag));
348394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ sll(t1, t1, 1);
349394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Addu(t1, a3, t1);
350394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ LoadRoot(t3, Heap::kTheHoleValueRootIndex);
351394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ LoadRoot(t5, Heap::kHeapNumberMapRootIndex);
352394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Using offsetted addresses.
353394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // a3: begin of destination FixedArray element fields, not tagged
354394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // t0: begin of source FixedDoubleArray element fields, not tagged, +4
355394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // t1: end of destination FixedArray, not tagged
356394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // t2: destination FixedArray
357394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // t3: the-hole pointer
358394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // t5: heap number map
359394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Branch(&entry);
360394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
361394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Call into runtime if GC is required.
362394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ bind(&gc_required);
363394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ MultiPop(a0.bit() | a1.bit() | a2.bit() | a3.bit() | ra.bit());
364394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
365394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Branch(fail);
366394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
367394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ bind(&loop);
368394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ lw(a1, MemOperand(t0));
369394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Addu(t0, t0, kDoubleSize);
370394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // a1: current element's upper 32 bit
371394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // t0: address of next element's upper 32 bit
372394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Branch(&convert_hole, eq, a1, Operand(kHoleNanUpper32));
373394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
374394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Non-hole double, copy value into a heap number.
375394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ AllocateHeapNumber(a2, a0, t6, t5, &gc_required);
376394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // a2: new heap number
377394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ lw(a0, MemOperand(t0, -12));
378394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ sw(a0, FieldMemOperand(a2, HeapNumber::kMantissaOffset));
379394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ sw(a1, FieldMemOperand(a2, HeapNumber::kExponentOffset));
380394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ mov(a0, a3);
381394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ sw(a2, MemOperand(a3));
382394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Addu(a3, a3, kIntSize);
383394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ RecordWrite(t2,
384394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                 a0,
385394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                 a2,
386394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                 kRAHasBeenSaved,
387394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                 kDontSaveFPRegs,
388394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                 EMIT_REMEMBERED_SET,
389394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                 OMIT_SMI_CHECK);
390394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Branch(&entry);
391394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
392394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Replace the-hole NaN with the-hole pointer.
393394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ bind(&convert_hole);
394394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ sw(t3, MemOperand(a3));
395394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Addu(a3, a3, kIntSize);
396394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
397394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ bind(&entry);
398394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Branch(&loop, lt, a3, Operand(t1));
399394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
400394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ MultiPop(a2.bit() | a3.bit() | a0.bit() | a1.bit());
401394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Replace receiver's backing store with newly created and filled FixedArray.
402394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ sw(t2, FieldMemOperand(a2, JSObject::kElementsOffset));
403394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ RecordWriteField(a2,
404394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      JSObject::kElementsOffset,
405394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      t2,
406394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      t5,
407394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      kRAHasBeenSaved,
408394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      kDontSaveFPRegs,
409394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      EMIT_REMEMBERED_SET,
410394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      OMIT_SMI_CHECK);
411394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ pop(ra);
41256454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org
41356454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  __ bind(&only_change_map);
41456454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  // Update receiver's map.
41556454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  __ sw(a3, FieldMemOperand(a2, HeapObject::kMapOffset));
41656454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  __ RecordWriteField(a2,
41756454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org                      HeapObject::kMapOffset,
41856454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org                      a3,
41956454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org                      t5,
42056454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org                      kRAHasNotBeenSaved,
42156454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org                      kDontSaveFPRegs,
42256454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org                      OMIT_REMEMBERED_SET,
42356454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org                      OMIT_SMI_CHECK);
424394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
425394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
42664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
42764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.orgvoid StringCharLoadGenerator::Generate(MacroAssembler* masm,
42864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org                                       Register string,
42964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org                                       Register index,
43064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org                                       Register result,
43164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org                                       Label* call_runtime) {
43264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Fetch the instance type of the receiver into result register.
43364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ lw(result, FieldMemOperand(string, HeapObject::kMapOffset));
43464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ lbu(result, FieldMemOperand(result, Map::kInstanceTypeOffset));
43564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
43664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // We need special handling for indirect strings.
43764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  Label check_sequential;
43864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ And(at, result, Operand(kIsIndirectStringMask));
43964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ Branch(&check_sequential, eq, at, Operand(zero_reg));
44064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
44164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Dispatch on the indirect string shape: slice or cons.
44264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  Label cons_string;
44364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ And(at, result, Operand(kSlicedNotConsMask));
44464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ Branch(&cons_string, eq, at, Operand(zero_reg));
44564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
44664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Handle slices.
44764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  Label indirect_string_loaded;
44864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ lw(result, FieldMemOperand(string, SlicedString::kOffsetOffset));
449fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  __ lw(string, FieldMemOperand(string, SlicedString::kParentOffset));
45064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ sra(at, result, kSmiTagSize);
45164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ Addu(index, index, at);
45264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ jmp(&indirect_string_loaded);
45364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
45464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Handle cons strings.
45564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Check whether the right hand side is the empty string (i.e. if
45664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // this is really a flat string in a cons string). If that is not
45764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // the case we would rather go to the runtime system now to flatten
45864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // the string.
45964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ bind(&cons_string);
46064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ lw(result, FieldMemOperand(string, ConsString::kSecondOffset));
461750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  __ LoadRoot(at, Heap::kempty_stringRootIndex);
46264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ Branch(call_runtime, ne, result, Operand(at));
46364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Get the first of the two strings and load its instance type.
46464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ lw(string, FieldMemOperand(string, ConsString::kFirstOffset));
46564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
46664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ bind(&indirect_string_loaded);
46764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ lw(result, FieldMemOperand(string, HeapObject::kMapOffset));
46864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ lbu(result, FieldMemOperand(result, Map::kInstanceTypeOffset));
46964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
47064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Distinguish sequential and external strings. Only these two string
47164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // representations can reach here (slices and flat cons strings have been
47264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // reduced to the underlying sequential or external string).
47364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  Label external_string, check_encoding;
47464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ bind(&check_sequential);
47564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  STATIC_ASSERT(kSeqStringTag == 0);
47664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ And(at, result, Operand(kStringRepresentationMask));
47764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ Branch(&external_string, ne, at, Operand(zero_reg));
47864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
47964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Prepare sequential strings
480fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize);
48164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ Addu(string,
48264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org          string,
48364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org          SeqTwoByteString::kHeaderSize - kHeapObjectTag);
48464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ jmp(&check_encoding);
48564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
48664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Handle external strings.
48764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ bind(&external_string);
48864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  if (FLAG_debug_code) {
48964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    // Assert that we do not have a cons or slice (indirect strings) here.
49064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    // Sequential strings have already been ruled out.
49164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    __ And(at, result, Operand(kIsIndirectStringMask));
492594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    __ Assert(eq, kExternalStringExpectedButNotFound,
49364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org        at, Operand(zero_reg));
49464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  }
49564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Rule out short external strings.
49664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  STATIC_CHECK(kShortExternalStringTag != 0);
49764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ And(at, result, Operand(kShortExternalStringMask));
49864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ Branch(call_runtime, ne, at, Operand(zero_reg));
49964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ lw(string, FieldMemOperand(string, ExternalString::kResourceDataOffset));
50064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
50164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  Label ascii, done;
50264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ bind(&check_encoding);
50364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  STATIC_ASSERT(kTwoByteStringTag == 0);
50464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ And(at, result, Operand(kStringEncodingMask));
50564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ Branch(&ascii, ne, at, Operand(zero_reg));
50664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Two-byte string.
50764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ sll(at, index, 1);
50864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ Addu(at, string, at);
50964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ lhu(result, MemOperand(at));
51064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ jmp(&done);
51164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ bind(&ascii);
51264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Ascii string.
51364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ Addu(at, string, index);
51464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ lbu(result, MemOperand(at));
51564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ bind(&done);
51664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org}
51764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
51883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
51983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.orgstatic MemOperand ExpConstant(int index, Register base) {
52083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  return MemOperand(base, index * kDoubleSize);
52183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org}
52283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
52383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
52483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.orgvoid MathExpGenerator::EmitMathExp(MacroAssembler* masm,
52583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org                                   DoubleRegister input,
52683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org                                   DoubleRegister result,
52783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org                                   DoubleRegister double_scratch1,
52883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org                                   DoubleRegister double_scratch2,
52983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org                                   Register temp1,
53083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org                                   Register temp2,
53183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org                                   Register temp3) {
53283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  ASSERT(!input.is(result));
53383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  ASSERT(!input.is(double_scratch1));
53483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  ASSERT(!input.is(double_scratch2));
53583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  ASSERT(!result.is(double_scratch1));
53683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  ASSERT(!result.is(double_scratch2));
53783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  ASSERT(!double_scratch1.is(double_scratch2));
53883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  ASSERT(!temp1.is(temp2));
53983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  ASSERT(!temp1.is(temp3));
54083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  ASSERT(!temp2.is(temp3));
54183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  ASSERT(ExternalReference::math_exp_constants(0).address() != NULL);
54283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
54383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  Label done;
54483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
54583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ li(temp3, Operand(ExternalReference::math_exp_constants(0)));
54683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
54783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ ldc1(double_scratch1, ExpConstant(0, temp3));
54883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ Move(result, kDoubleRegZero);
54983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ BranchF(&done, NULL, ge, double_scratch1, input);
55083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ ldc1(double_scratch2, ExpConstant(1, temp3));
55183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ ldc1(result, ExpConstant(2, temp3));
55283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ BranchF(&done, NULL, ge, input, double_scratch2);
55383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ ldc1(double_scratch1, ExpConstant(3, temp3));
55483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ ldc1(result, ExpConstant(4, temp3));
55583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ mul_d(double_scratch1, double_scratch1, input);
55683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ add_d(double_scratch1, double_scratch1, result);
55783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ Move(temp2, temp1, double_scratch1);
55883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ sub_d(double_scratch1, double_scratch1, result);
55983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ ldc1(result, ExpConstant(6, temp3));
56083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ ldc1(double_scratch2, ExpConstant(5, temp3));
56183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ mul_d(double_scratch1, double_scratch1, double_scratch2);
56283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ sub_d(double_scratch1, double_scratch1, input);
56383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ sub_d(result, result, double_scratch1);
56483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ mul_d(input, double_scratch1, double_scratch1);
56583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ mul_d(result, result, input);
56683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ srl(temp1, temp2, 11);
56783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ ldc1(double_scratch2, ExpConstant(7, temp3));
56883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ mul_d(result, result, double_scratch2);
56983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ sub_d(result, result, double_scratch1);
57083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ ldc1(double_scratch2, ExpConstant(8, temp3));
57183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ add_d(result, result, double_scratch2);
57283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ li(at, 0x7ff);
57383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ And(temp2, temp2, at);
57483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ Addu(temp1, temp1, Operand(0x3ff));
57583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ sll(temp1, temp1, 20);
57683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
57783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  // Must not call ExpConstant() after overwriting temp3!
57883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ li(temp3, Operand(ExternalReference::math_exp_log_table()));
57983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ sll(at, temp2, 3);
58083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ addu(at, at, temp3);
58183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ lw(at, MemOperand(at));
58283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ Addu(temp3, temp3, Operand(kPointerSize));
58383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ sll(temp2, temp2, 3);
58483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ addu(temp2, temp2, temp3);
58583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ lw(temp2, MemOperand(temp2));
58683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ Or(temp1, temp1, temp2);
58783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ Move(input, at, temp1);
58883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ mul_d(result, result, input);
58983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ bind(&done);
59083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org}
59183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
59283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
593fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org// nop(CODE_AGE_MARKER_NOP)
594fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.orgstatic const uint32_t kCodeAgePatchFirstInstruction = 0x00010180;
595fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
596fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.orgstatic byte* GetNoCodeAgeSequence(uint32_t* length) {
597fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  // The sequence of instructions that is patched out for aging code is the
598fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  // following boilerplate stack-building prologue that is found in FUNCTIONS
599fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  static bool initialized = false;
600fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  static uint32_t sequence[kNoCodeAgeSequenceLength];
601fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  byte* byte_sequence = reinterpret_cast<byte*>(sequence);
602fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  *length = kNoCodeAgeSequenceLength * Assembler::kInstrSize;
603fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  if (!initialized) {
604fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    CodePatcher patcher(byte_sequence, kNoCodeAgeSequenceLength);
605fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    patcher.masm()->Push(ra, fp, cp, a1);
606ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    patcher.masm()->nop(Assembler::CODE_AGE_SEQUENCE_NOP);
607fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    patcher.masm()->Addu(fp, sp, Operand(2 * kPointerSize));
608fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    initialized = true;
609fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  }
610fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  return byte_sequence;
611fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org}
612fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
613fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
614fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.orgbool Code::IsYoungSequence(byte* sequence) {
615fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  uint32_t young_length;
616fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  byte* young_sequence = GetNoCodeAgeSequence(&young_length);
617fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  bool result = !memcmp(sequence, young_sequence, young_length);
618fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  ASSERT(result ||
619fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org         Memory::uint32_at(sequence) == kCodeAgePatchFirstInstruction);
620fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  return result;
621fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org}
622fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
623fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
624fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.orgvoid Code::GetCodeAgeAndParity(byte* sequence, Age* age,
625fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                               MarkingParity* parity) {
626fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  if (IsYoungSequence(sequence)) {
627fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    *age = kNoAge;
628fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    *parity = NO_MARKING_PARITY;
629fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  } else {
630fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    Address target_address = Memory::Address_at(
631fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        sequence + Assembler::kInstrSize * (kNoCodeAgeSequenceLength - 1));
632fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    Code* stub = GetCodeFromTargetAddress(target_address);
633fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    GetCodeAgeAndParity(stub, age, parity);
634fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  }
635fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org}
636fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
637fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
638fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.orgvoid Code::PatchPlatformCodeAge(byte* sequence,
639fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                                Code::Age age,
640fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                                MarkingParity parity) {
641fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  uint32_t young_length;
642fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  byte* young_sequence = GetNoCodeAgeSequence(&young_length);
643fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  if (age == kNoAge) {
644c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org    CopyBytes(sequence, young_sequence, young_length);
645fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    CPU::FlushICache(sequence, young_length);
646fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  } else {
647fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    Code* stub = GetCodeAgeStub(age, parity);
648fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    CodePatcher patcher(sequence, young_length / Assembler::kInstrSize);
649fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    // Mark this code sequence for FindPlatformCodeAgeSequence()
650fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    patcher.masm()->nop(Assembler::CODE_AGE_MARKER_NOP);
651fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    // Save the function's original return address
652fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    // (it will be clobbered by Call(t9))
653fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    patcher.masm()->mov(at, ra);
654fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    // Load the stub address to t9 and call it
655fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    patcher.masm()->li(t9,
656fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        Operand(reinterpret_cast<uint32_t>(stub->instruction_start())));
657fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    patcher.masm()->Call(t9);
658fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    // Record the stub address in the empty space for GetCodeAgeAndParity()
659fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    patcher.masm()->dd(reinterpret_cast<uint32_t>(stub->instruction_start()));
660fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  }
661fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org}
662fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
663fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
664394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com#undef __
6655c838251403b0be9a882540f1922577abba4c872ager@chromium.org
6665c838251403b0be9a882540f1922577abba4c872ager@chromium.org} }  // namespace v8::internal
6679dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
6689dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#endif  // V8_TARGET_ARCH_MIPS
669