1fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file.
45c838251403b0be9a882540f1922577abba4c872ager@chromium.org
5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h"
65c838251403b0be9a882540f1922577abba4c872ager@chromium.org
793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_MIPS
89dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/codegen.h"
10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/macro-assembler.h"
11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/mips/simulator-mips.h"
125c838251403b0be9a882540f1922577abba4c872ager@chromium.org
135c838251403b0be9a882540f1922577abba4c872ager@chromium.orgnamespace v8 {
145c838251403b0be9a882540f1922577abba4c872ager@chromium.orgnamespace internal {
155c838251403b0be9a882540f1922577abba4c872ager@chromium.org
16394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org#define __ masm.
1883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
1983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
2083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org#if defined(USE_SIMULATOR)
2183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.orgbyte* fast_exp_mips_machine_code = NULL;
2283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.orgdouble fast_exp_simulator(double x) {
2383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  return Simulator::current(Isolate::Current())->CallFP(
2483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org      fast_exp_mips_machine_code, x, 0);
2583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org}
2683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org#endif
2783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
2883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
2983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.orgUnaryMathFunction CreateExpFunction() {
30e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org  if (!FLAG_fast_math) return &std::exp;
3183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  size_t actual_size;
3283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  byte* buffer = static_cast<byte*>(OS::Allocate(1 * KB, &actual_size, true));
33e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org  if (buffer == NULL) return &std::exp;
3483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  ExternalReference::InitializeMathExpData();
3583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
3683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size));
3783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
3883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  {
3983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    DoubleRegister input = f12;
4083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    DoubleRegister result = f0;
4183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    DoubleRegister double_scratch1 = f4;
4283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    DoubleRegister double_scratch2 = f6;
4383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    Register temp1 = t0;
4483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    Register temp2 = t1;
4583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    Register temp3 = t2;
4683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
47731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org    __ MovFromFloatParameter(input);
4883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    __ Push(temp3, temp2, temp1);
4983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    MathExpGenerator::EmitMathExp(
5083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org        &masm, input, result, double_scratch1, double_scratch2,
5183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org        temp1, temp2, temp3);
5283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    __ Pop(temp3, temp2, temp1);
53731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org    __ MovToFloatResult(result);
5483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    __ Ret();
5583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  }
5683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
5783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  CodeDesc desc;
5883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  masm.GetCode(&desc);
592e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org  ASSERT(!RelocInfo::RequiresRelocation(desc));
6083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
6183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  CPU::FlushICache(buffer, actual_size);
6283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  OS::ProtectCode(buffer, actual_size);
6383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
6483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org#if !defined(USE_SIMULATOR)
6583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  return FUNCTION_CAST<UnaryMathFunction>(buffer);
6683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org#else
6783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  fast_exp_mips_machine_code = buffer;
6883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  return &fast_exp_simulator;
6983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org#endif
7083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org}
7183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
7283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
73afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org#if defined(V8_HOST_ARCH_MIPS)
74d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgMemCopyUint8Function CreateMemCopyUint8Function(MemCopyUint8Function stub) {
75afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org#if defined(USE_SIMULATOR)
76afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org  return stub;
77afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org#else
78afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org  size_t actual_size;
79afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org  byte* buffer = static_cast<byte*>(OS::Allocate(3 * KB, &actual_size, true));
80afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org  if (buffer == NULL) return stub;
81afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
82afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org  // This code assumes that cache lines are 32 bytes and if the cache line is
83afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org  // larger it will not work correctly.
84afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org  MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size));
85afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
86afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org  {
87afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    Label lastb, unaligned, aligned, chkw,
88afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org          loop16w, chk1w, wordCopy_loop, skip_pref, lastbloop,
89afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org          leave, ua_chk16w, ua_loop16w, ua_skip_pref, ua_chkw,
90afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org          ua_chk1w, ua_wordCopy_loop, ua_smallCopy, ua_smallCopy_loop;
91afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
92afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // The size of each prefetch.
93afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    uint32_t pref_chunk = 32;
94afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // The maximum size of a prefetch, it must not be less then pref_chunk.
95afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // If the real size of a prefetch is greater then max_pref_size and
96afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // the kPrefHintPrepareForStore hint is used, the code will not work
97afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // correctly.
98afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    uint32_t max_pref_size = 128;
99afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    ASSERT(pref_chunk < max_pref_size);
100afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
101afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // pref_limit is set based on the fact that we never use an offset
102afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // greater then 5 on a store pref and that a single pref can
103afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // never be larger then max_pref_size.
104afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    uint32_t pref_limit = (5 * pref_chunk) + max_pref_size;
105afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    int32_t pref_hint_load = kPrefHintLoadStreamed;
106afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    int32_t pref_hint_store = kPrefHintPrepareForStore;
107afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    uint32_t loadstore_chunk = 4;
108afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
109afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // The initial prefetches may fetch bytes that are before the buffer being
110afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // copied. Start copies with an offset of 4 so avoid this situation when
111afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // using kPrefHintPrepareForStore.
112afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    ASSERT(pref_hint_store != kPrefHintPrepareForStore ||
113afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org           pref_chunk * 4 >= max_pref_size);
114afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
115afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // If the size is less than 8, go to lastb. Regardless of size,
116afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // copy dst pointer to v0 for the retuen value.
117afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ slti(t2, a2, 2 * loadstore_chunk);
118afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ bne(t2, zero_reg, &lastb);
119afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ mov(v0, a0);  // In delay slot.
120afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
121afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // If src and dst have different alignments, go to unaligned, if they
122afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // have the same alignment (but are not actually aligned) do a partial
123afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // load/store to make them aligned. If they are both already aligned
124afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // we can start copying at aligned.
125afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ xor_(t8, a1, a0);
126afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ andi(t8, t8, loadstore_chunk - 1);  // t8 is a0/a1 word-displacement.
127afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ bne(t8, zero_reg, &unaligned);
128afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ subu(a3, zero_reg, a0);  // In delay slot.
129afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
130afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ andi(a3, a3, loadstore_chunk - 1);  // Copy a3 bytes to align a0/a1.
131afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ beq(a3, zero_reg, &aligned);  // Already aligned.
132afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ subu(a2, a2, a3);  // In delay slot. a2 is the remining bytes count.
133afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
134731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org    if (kArchEndian == kLittle) {
135731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t8, MemOperand(a1));
136731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ addu(a1, a1, a3);
137731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ swr(t8, MemOperand(a0));
138731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ addu(a0, a0, a3);
139731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org    } else {
140731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t8, MemOperand(a1));
141731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ addu(a1, a1, a3);
142731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ swl(t8, MemOperand(a0));
143731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ addu(a0, a0, a3);
144731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org    }
145afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // Now dst/src are both aligned to (word) aligned addresses. Set a2 to
146afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // count how many bytes we have to copy after all the 64 byte chunks are
147afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // copied and a3 to the dst pointer after all the 64 byte chunks have been
148afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // copied. We will loop, incrementing a0 and a1 until a0 equals a3.
149afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ bind(&aligned);
150afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ andi(t8, a2, 0x3f);
151afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ beq(a2, t8, &chkw);  // Less than 64?
152afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ subu(a3, a2, t8);  // In delay slot.
153afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ addu(a3, a0, a3);  // Now a3 is the final dst after loop.
154afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
155afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // When in the loop we prefetch with kPrefHintPrepareForStore hint,
156afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // in this case the a0+x should be past the "t0-32" address. This means:
157afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // for x=128 the last "safe" a0 address is "t0-160". Alternatively, for
158afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // x=64 the last "safe" a0 address is "t0-96". In the current version we
159afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // will use "pref hint, 128(a0)", so "t0-160" is the limit.
160afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    if (pref_hint_store == kPrefHintPrepareForStore) {
161afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org      __ addu(t0, a0, a2);  // t0 is the "past the end" address.
162afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org      __ Subu(t9, t0, pref_limit);  // t9 is the "last safe pref" address.
163afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    }
164afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
165afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ Pref(pref_hint_load, MemOperand(a1, 0 * pref_chunk));
166afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ Pref(pref_hint_load, MemOperand(a1, 1 * pref_chunk));
167afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ Pref(pref_hint_load, MemOperand(a1, 2 * pref_chunk));
168afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ Pref(pref_hint_load, MemOperand(a1, 3 * pref_chunk));
169afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
170afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    if (pref_hint_store != kPrefHintPrepareForStore) {
171afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org      __ Pref(pref_hint_store, MemOperand(a0, 1 * pref_chunk));
172afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org      __ Pref(pref_hint_store, MemOperand(a0, 2 * pref_chunk));
173afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org      __ Pref(pref_hint_store, MemOperand(a0, 3 * pref_chunk));
174afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    }
175afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ bind(&loop16w);
176afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ lw(t0, MemOperand(a1));
177afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
178afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    if (pref_hint_store == kPrefHintPrepareForStore) {
179afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org      __ sltu(v1, t9, a0);  // If a0 > t9, don't use next prefetch.
180afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org      __ Branch(USE_DELAY_SLOT, &skip_pref, gt, v1, Operand(zero_reg));
181afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    }
182afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ lw(t1, MemOperand(a1, 1, loadstore_chunk));  // Maybe in delay slot.
183afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
184afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ Pref(pref_hint_store, MemOperand(a0, 4 * pref_chunk));
185afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ Pref(pref_hint_store, MemOperand(a0, 5 * pref_chunk));
186afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
187afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ bind(&skip_pref);
188afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ lw(t2, MemOperand(a1, 2, loadstore_chunk));
189afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ lw(t3, MemOperand(a1, 3, loadstore_chunk));
190afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ lw(t4, MemOperand(a1, 4, loadstore_chunk));
191afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ lw(t5, MemOperand(a1, 5, loadstore_chunk));
192afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ lw(t6, MemOperand(a1, 6, loadstore_chunk));
193afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ lw(t7, MemOperand(a1, 7, loadstore_chunk));
194afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ Pref(pref_hint_load, MemOperand(a1, 4 * pref_chunk));
195afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
196afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t0, MemOperand(a0));
197afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t1, MemOperand(a0, 1, loadstore_chunk));
198afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t2, MemOperand(a0, 2, loadstore_chunk));
199afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t3, MemOperand(a0, 3, loadstore_chunk));
200afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t4, MemOperand(a0, 4, loadstore_chunk));
201afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t5, MemOperand(a0, 5, loadstore_chunk));
202afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t6, MemOperand(a0, 6, loadstore_chunk));
203afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t7, MemOperand(a0, 7, loadstore_chunk));
204afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
205afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ lw(t0, MemOperand(a1, 8, loadstore_chunk));
206afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ lw(t1, MemOperand(a1, 9, loadstore_chunk));
207afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ lw(t2, MemOperand(a1, 10, loadstore_chunk));
208afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ lw(t3, MemOperand(a1, 11, loadstore_chunk));
209afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ lw(t4, MemOperand(a1, 12, loadstore_chunk));
210afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ lw(t5, MemOperand(a1, 13, loadstore_chunk));
211afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ lw(t6, MemOperand(a1, 14, loadstore_chunk));
212afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ lw(t7, MemOperand(a1, 15, loadstore_chunk));
213afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ Pref(pref_hint_load, MemOperand(a1, 5 * pref_chunk));
214afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
215afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t0, MemOperand(a0, 8, loadstore_chunk));
216afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t1, MemOperand(a0, 9, loadstore_chunk));
217afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t2, MemOperand(a0, 10, loadstore_chunk));
218afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t3, MemOperand(a0, 11, loadstore_chunk));
219afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t4, MemOperand(a0, 12, loadstore_chunk));
220afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t5, MemOperand(a0, 13, loadstore_chunk));
221afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t6, MemOperand(a0, 14, loadstore_chunk));
222afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t7, MemOperand(a0, 15, loadstore_chunk));
223afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ addiu(a0, a0, 16 * loadstore_chunk);
224afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ bne(a0, a3, &loop16w);
225afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ addiu(a1, a1, 16 * loadstore_chunk);  // In delay slot.
226afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ mov(a2, t8);
227afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
228afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // Here we have src and dest word-aligned but less than 64-bytes to go.
229afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // Check for a 32 bytes chunk and copy if there is one. Otherwise jump
230afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // down to chk1w to handle the tail end of the copy.
231afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ bind(&chkw);
232afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ Pref(pref_hint_load, MemOperand(a1, 0 * pref_chunk));
233afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ andi(t8, a2, 0x1f);
234afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ beq(a2, t8, &chk1w);  // Less than 32?
235afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ nop();  // In delay slot.
236afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ lw(t0, MemOperand(a1));
237afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ lw(t1, MemOperand(a1, 1, loadstore_chunk));
238afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ lw(t2, MemOperand(a1, 2, loadstore_chunk));
239afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ lw(t3, MemOperand(a1, 3, loadstore_chunk));
240afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ lw(t4, MemOperand(a1, 4, loadstore_chunk));
241afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ lw(t5, MemOperand(a1, 5, loadstore_chunk));
242afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ lw(t6, MemOperand(a1, 6, loadstore_chunk));
243afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ lw(t7, MemOperand(a1, 7, loadstore_chunk));
244afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ addiu(a1, a1, 8 * loadstore_chunk);
245afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t0, MemOperand(a0));
246afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t1, MemOperand(a0, 1, loadstore_chunk));
247afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t2, MemOperand(a0, 2, loadstore_chunk));
248afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t3, MemOperand(a0, 3, loadstore_chunk));
249afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t4, MemOperand(a0, 4, loadstore_chunk));
250afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t5, MemOperand(a0, 5, loadstore_chunk));
251afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t6, MemOperand(a0, 6, loadstore_chunk));
252afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t7, MemOperand(a0, 7, loadstore_chunk));
253afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ addiu(a0, a0, 8 * loadstore_chunk);
254afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
255afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // Here we have less than 32 bytes to copy. Set up for a loop to copy
256afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // one word at a time. Set a2 to count how many bytes we have to copy
257afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // after all the word chunks are copied and a3 to the dst pointer after
258afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // all the word chunks have been copied. We will loop, incrementing a0
259afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // and a1 untill a0 equals a3.
260afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ bind(&chk1w);
261afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ andi(a2, t8, loadstore_chunk - 1);
262afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ beq(a2, t8, &lastb);
263afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ subu(a3, t8, a2);  // In delay slot.
264afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ addu(a3, a0, a3);
265afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
266afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ bind(&wordCopy_loop);
267afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ lw(t3, MemOperand(a1));
268afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ addiu(a0, a0, loadstore_chunk);
269afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ addiu(a1, a1, loadstore_chunk);
270afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ bne(a0, a3, &wordCopy_loop);
271afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t3, MemOperand(a0, -1, loadstore_chunk));  // In delay slot.
272afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
273afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ bind(&lastb);
274afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ Branch(&leave, le, a2, Operand(zero_reg));
275afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ addu(a3, a0, a2);
276afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
277afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ bind(&lastbloop);
278afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ lb(v1, MemOperand(a1));
279afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ addiu(a0, a0, 1);
280afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ addiu(a1, a1, 1);
281afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ bne(a0, a3, &lastbloop);
282afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sb(v1, MemOperand(a0, -1));  // In delay slot.
283afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
284afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ bind(&leave);
285afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ jr(ra);
286afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ nop();
287afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
288afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // Unaligned case. Only the dst gets aligned so we need to do partial
289afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // loads of the source followed by normal stores to the dst (once we
290afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // have aligned the destination).
291afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ bind(&unaligned);
292afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ andi(a3, a3, loadstore_chunk - 1);  // Copy a3 bytes to align a0/a1.
293afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ beq(a3, zero_reg, &ua_chk16w);
294afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ subu(a2, a2, a3);  // In delay slot.
295afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
296731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org    if (kArchEndian == kLittle) {
297731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(v1, MemOperand(a1));
298731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(v1,
299731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
300731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ addu(a1, a1, a3);
301731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ swr(v1, MemOperand(a0));
302731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ addu(a0, a0, a3);
303731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org    } else {
304731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(v1, MemOperand(a1));
305731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(v1,
306731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
307731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ addu(a1, a1, a3);
308731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ swl(v1, MemOperand(a0));
309731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ addu(a0, a0, a3);
310731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org    }
311afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
312afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // Now the dst (but not the source) is aligned. Set a2 to count how many
313afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // bytes we have to copy after all the 64 byte chunks are copied and a3 to
314afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // the dst pointer after all the 64 byte chunks have been copied. We will
315afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // loop, incrementing a0 and a1 until a0 equals a3.
316afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ bind(&ua_chk16w);
317afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ andi(t8, a2, 0x3f);
318afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ beq(a2, t8, &ua_chkw);
319afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ subu(a3, a2, t8);  // In delay slot.
320afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ addu(a3, a0, a3);
321afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
322afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    if (pref_hint_store == kPrefHintPrepareForStore) {
323afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org      __ addu(t0, a0, a2);
324afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org      __ Subu(t9, t0, pref_limit);
325afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    }
326afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
327afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ Pref(pref_hint_load, MemOperand(a1, 0 * pref_chunk));
328afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ Pref(pref_hint_load, MemOperand(a1, 1 * pref_chunk));
329afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ Pref(pref_hint_load, MemOperand(a1, 2 * pref_chunk));
330afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
331afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    if (pref_hint_store != kPrefHintPrepareForStore) {
332afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org      __ Pref(pref_hint_store, MemOperand(a0, 1 * pref_chunk));
333afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org      __ Pref(pref_hint_store, MemOperand(a0, 2 * pref_chunk));
334afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org      __ Pref(pref_hint_store, MemOperand(a0, 3 * pref_chunk));
335afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    }
336afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
337afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ bind(&ua_loop16w);
338afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ Pref(pref_hint_load, MemOperand(a1, 3 * pref_chunk));
339731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org    if (kArchEndian == kLittle) {
340731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t0, MemOperand(a1));
341731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t1, MemOperand(a1, 1, loadstore_chunk));
342731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t2, MemOperand(a1, 2, loadstore_chunk));
343731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org
344731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      if (pref_hint_store == kPrefHintPrepareForStore) {
345731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org        __ sltu(v1, t9, a0);
346731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org        __ Branch(USE_DELAY_SLOT, &ua_skip_pref, gt, v1, Operand(zero_reg));
347731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      }
348731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t3, MemOperand(a1, 3, loadstore_chunk));  // Maybe in delay slot.
349731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org
350731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ Pref(pref_hint_store, MemOperand(a0, 4 * pref_chunk));
351731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ Pref(pref_hint_store, MemOperand(a0, 5 * pref_chunk));
352731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org
353731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ bind(&ua_skip_pref);
354731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t4, MemOperand(a1, 4, loadstore_chunk));
355731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t5, MemOperand(a1, 5, loadstore_chunk));
356731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t6, MemOperand(a1, 6, loadstore_chunk));
357731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t7, MemOperand(a1, 7, loadstore_chunk));
358731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t0,
359731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
360731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t1,
361731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 2, loadstore_chunk, MemOperand::offset_minus_one));
362731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t2,
363731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 3, loadstore_chunk, MemOperand::offset_minus_one));
364731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t3,
365731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 4, loadstore_chunk, MemOperand::offset_minus_one));
366731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t4,
367731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 5, loadstore_chunk, MemOperand::offset_minus_one));
368731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t5,
369731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 6, loadstore_chunk, MemOperand::offset_minus_one));
370731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t6,
371731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 7, loadstore_chunk, MemOperand::offset_minus_one));
372731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t7,
373731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 8, loadstore_chunk, MemOperand::offset_minus_one));
374731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org    } else {
375731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t0, MemOperand(a1));
376731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t1, MemOperand(a1, 1, loadstore_chunk));
377731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t2, MemOperand(a1, 2, loadstore_chunk));
378731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org
379731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      if (pref_hint_store == kPrefHintPrepareForStore) {
380731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org        __ sltu(v1, t9, a0);
381731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org        __ Branch(USE_DELAY_SLOT, &ua_skip_pref, gt, v1, Operand(zero_reg));
382731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      }
383731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t3, MemOperand(a1, 3, loadstore_chunk));  // Maybe in delay slot.
384731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org
385731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ Pref(pref_hint_store, MemOperand(a0, 4 * pref_chunk));
386731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ Pref(pref_hint_store, MemOperand(a0, 5 * pref_chunk));
387731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org
388731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ bind(&ua_skip_pref);
389731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t4, MemOperand(a1, 4, loadstore_chunk));
390731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t5, MemOperand(a1, 5, loadstore_chunk));
391731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t6, MemOperand(a1, 6, loadstore_chunk));
392731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t7, MemOperand(a1, 7, loadstore_chunk));
393731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t0,
394731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
395731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t1,
396731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 2, loadstore_chunk, MemOperand::offset_minus_one));
397731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t2,
398731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 3, loadstore_chunk, MemOperand::offset_minus_one));
399731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t3,
400731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 4, loadstore_chunk, MemOperand::offset_minus_one));
401731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t4,
402731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 5, loadstore_chunk, MemOperand::offset_minus_one));
403731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t5,
404731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 6, loadstore_chunk, MemOperand::offset_minus_one));
405731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t6,
406731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 7, loadstore_chunk, MemOperand::offset_minus_one));
407731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t7,
408731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 8, loadstore_chunk, MemOperand::offset_minus_one));
409afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    }
410afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ Pref(pref_hint_load, MemOperand(a1, 4 * pref_chunk));
411afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t0, MemOperand(a0));
412afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t1, MemOperand(a0, 1, loadstore_chunk));
413afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t2, MemOperand(a0, 2, loadstore_chunk));
414afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t3, MemOperand(a0, 3, loadstore_chunk));
415afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t4, MemOperand(a0, 4, loadstore_chunk));
416afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t5, MemOperand(a0, 5, loadstore_chunk));
417afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t6, MemOperand(a0, 6, loadstore_chunk));
418afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t7, MemOperand(a0, 7, loadstore_chunk));
419731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org    if (kArchEndian == kLittle) {
420731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t0, MemOperand(a1, 8, loadstore_chunk));
421731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t1, MemOperand(a1, 9, loadstore_chunk));
422731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t2, MemOperand(a1, 10, loadstore_chunk));
423731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t3, MemOperand(a1, 11, loadstore_chunk));
424731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t4, MemOperand(a1, 12, loadstore_chunk));
425731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t5, MemOperand(a1, 13, loadstore_chunk));
426731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t6, MemOperand(a1, 14, loadstore_chunk));
427731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t7, MemOperand(a1, 15, loadstore_chunk));
428731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t0,
429731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 9, loadstore_chunk, MemOperand::offset_minus_one));
430731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t1,
431731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 10, loadstore_chunk, MemOperand::offset_minus_one));
432731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t2,
433731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 11, loadstore_chunk, MemOperand::offset_minus_one));
434731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t3,
435731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 12, loadstore_chunk, MemOperand::offset_minus_one));
436731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t4,
437731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 13, loadstore_chunk, MemOperand::offset_minus_one));
438731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t5,
439731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 14, loadstore_chunk, MemOperand::offset_minus_one));
440731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t6,
441731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 15, loadstore_chunk, MemOperand::offset_minus_one));
442731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t7,
443731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 16, loadstore_chunk, MemOperand::offset_minus_one));
444731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org    } else {
445731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t0, MemOperand(a1, 8, loadstore_chunk));
446731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t1, MemOperand(a1, 9, loadstore_chunk));
447731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t2, MemOperand(a1, 10, loadstore_chunk));
448731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t3, MemOperand(a1, 11, loadstore_chunk));
449731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t4, MemOperand(a1, 12, loadstore_chunk));
450731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t5, MemOperand(a1, 13, loadstore_chunk));
451731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t6, MemOperand(a1, 14, loadstore_chunk));
452731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t7, MemOperand(a1, 15, loadstore_chunk));
453731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t0,
454731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 9, loadstore_chunk, MemOperand::offset_minus_one));
455731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t1,
456731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 10, loadstore_chunk, MemOperand::offset_minus_one));
457731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t2,
458731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 11, loadstore_chunk, MemOperand::offset_minus_one));
459731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t3,
460731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 12, loadstore_chunk, MemOperand::offset_minus_one));
461731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t4,
462731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 13, loadstore_chunk, MemOperand::offset_minus_one));
463731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t5,
464731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 14, loadstore_chunk, MemOperand::offset_minus_one));
465731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t6,
466731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 15, loadstore_chunk, MemOperand::offset_minus_one));
467731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t7,
468731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 16, loadstore_chunk, MemOperand::offset_minus_one));
469731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org    }
470afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ Pref(pref_hint_load, MemOperand(a1, 5 * pref_chunk));
471afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t0, MemOperand(a0, 8, loadstore_chunk));
472afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t1, MemOperand(a0, 9, loadstore_chunk));
473afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t2, MemOperand(a0, 10, loadstore_chunk));
474afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t3, MemOperand(a0, 11, loadstore_chunk));
475afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t4, MemOperand(a0, 12, loadstore_chunk));
476afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t5, MemOperand(a0, 13, loadstore_chunk));
477afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t6, MemOperand(a0, 14, loadstore_chunk));
478afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t7, MemOperand(a0, 15, loadstore_chunk));
479afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ addiu(a0, a0, 16 * loadstore_chunk);
480afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ bne(a0, a3, &ua_loop16w);
481afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ addiu(a1, a1, 16 * loadstore_chunk);  // In delay slot.
482afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ mov(a2, t8);
483afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
484afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // Here less than 64-bytes. Check for
485afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // a 32 byte chunk and copy if there is one. Otherwise jump down to
486afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // ua_chk1w to handle the tail end of the copy.
487afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ bind(&ua_chkw);
488afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ Pref(pref_hint_load, MemOperand(a1));
489afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ andi(t8, a2, 0x1f);
490afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
491afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ beq(a2, t8, &ua_chk1w);
492afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ nop();  // In delay slot.
493731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org    if (kArchEndian == kLittle) {
494731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t0, MemOperand(a1));
495731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t1, MemOperand(a1, 1, loadstore_chunk));
496731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t2, MemOperand(a1, 2, loadstore_chunk));
497731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t3, MemOperand(a1, 3, loadstore_chunk));
498731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t4, MemOperand(a1, 4, loadstore_chunk));
499731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t5, MemOperand(a1, 5, loadstore_chunk));
500731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t6, MemOperand(a1, 6, loadstore_chunk));
501731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t7, MemOperand(a1, 7, loadstore_chunk));
502731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t0,
503731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
504731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t1,
505731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 2, loadstore_chunk, MemOperand::offset_minus_one));
506731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t2,
507731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 3, loadstore_chunk, MemOperand::offset_minus_one));
508731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t3,
509731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 4, loadstore_chunk, MemOperand::offset_minus_one));
510731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t4,
511731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 5, loadstore_chunk, MemOperand::offset_minus_one));
512731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t5,
513731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 6, loadstore_chunk, MemOperand::offset_minus_one));
514731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t6,
515731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 7, loadstore_chunk, MemOperand::offset_minus_one));
516731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t7,
517731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 8, loadstore_chunk, MemOperand::offset_minus_one));
518731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org    } else {
519731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t0, MemOperand(a1));
520731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t1, MemOperand(a1, 1, loadstore_chunk));
521731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t2, MemOperand(a1, 2, loadstore_chunk));
522731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t3, MemOperand(a1, 3, loadstore_chunk));
523731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t4, MemOperand(a1, 4, loadstore_chunk));
524731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t5, MemOperand(a1, 5, loadstore_chunk));
525731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t6, MemOperand(a1, 6, loadstore_chunk));
526731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(t7, MemOperand(a1, 7, loadstore_chunk));
527731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t0,
528731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
529731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t1,
530731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 2, loadstore_chunk, MemOperand::offset_minus_one));
531731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t2,
532731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 3, loadstore_chunk, MemOperand::offset_minus_one));
533731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t3,
534731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 4, loadstore_chunk, MemOperand::offset_minus_one));
535731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t4,
536731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 5, loadstore_chunk, MemOperand::offset_minus_one));
537731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t5,
538731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 6, loadstore_chunk, MemOperand::offset_minus_one));
539731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t6,
540731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 7, loadstore_chunk, MemOperand::offset_minus_one));
541731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(t7,
542731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 8, loadstore_chunk, MemOperand::offset_minus_one));
543731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org    }
544afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ addiu(a1, a1, 8 * loadstore_chunk);
545afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t0, MemOperand(a0));
546afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t1, MemOperand(a0, 1, loadstore_chunk));
547afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t2, MemOperand(a0, 2, loadstore_chunk));
548afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t3, MemOperand(a0, 3, loadstore_chunk));
549afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t4, MemOperand(a0, 4, loadstore_chunk));
550afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t5, MemOperand(a0, 5, loadstore_chunk));
551afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t6, MemOperand(a0, 6, loadstore_chunk));
552afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(t7, MemOperand(a0, 7, loadstore_chunk));
553afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ addiu(a0, a0, 8 * loadstore_chunk);
554afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
555afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // Less than 32 bytes to copy. Set up for a loop to
556afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // copy one word at a time.
557afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ bind(&ua_chk1w);
558afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ andi(a2, t8, loadstore_chunk - 1);
559afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ beq(a2, t8, &ua_smallCopy);
560afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ subu(a3, t8, a2);  // In delay slot.
561afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ addu(a3, a0, a3);
562afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
563afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ bind(&ua_wordCopy_loop);
564731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org    if (kArchEndian == kLittle) {
565731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(v1, MemOperand(a1));
566731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(v1,
567731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
568731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org    } else {
569731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwl(v1, MemOperand(a1));
570731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      __ lwr(v1,
571731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org             MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
572731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org    }
573afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ addiu(a0, a0, loadstore_chunk);
574afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ addiu(a1, a1, loadstore_chunk);
575afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ bne(a0, a3, &ua_wordCopy_loop);
576afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sw(v1, MemOperand(a0, -1, loadstore_chunk));  // In delay slot.
577afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
578afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    // Copy the last 8 bytes.
579afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ bind(&ua_smallCopy);
580afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ beq(a2, zero_reg, &leave);
581afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ addu(a3, a0, a2);  // In delay slot.
582afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
583afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ bind(&ua_smallCopy_loop);
584afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ lb(v1, MemOperand(a1));
585afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ addiu(a0, a0, 1);
586afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ addiu(a1, a1, 1);
587afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ bne(a0, a3, &ua_smallCopy_loop);
588afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ sb(v1, MemOperand(a0, -1));  // In delay slot.
589afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
590afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ jr(ra);
591afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org    __ nop();
592afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org  }
593afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org  CodeDesc desc;
594afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org  masm.GetCode(&desc);
595afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org  ASSERT(!RelocInfo::RequiresRelocation(desc));
596afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
597afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org  CPU::FlushICache(buffer, actual_size);
598afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org  OS::ProtectCode(buffer, actual_size);
599d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  return FUNCTION_CAST<MemCopyUint8Function>(buffer);
600afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org#endif
601afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org}
602afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org#endif
603afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org
604034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.orgUnaryMathFunction CreateSqrtFunction() {
605034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org#if defined(USE_SIMULATOR)
606034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  return &std::sqrt;
607034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org#else
608034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  size_t actual_size;
609034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  byte* buffer = static_cast<byte*>(OS::Allocate(1 * KB, &actual_size, true));
610034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  if (buffer == NULL) return &std::sqrt;
61183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
612034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size));
61383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
6144ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org  __ MovFromFloatParameter(f12);
615034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  __ sqrt_d(f0, f12);
6164ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org  __ MovToFloatResult(f0);
617034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  __ Ret();
618034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org
619034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  CodeDesc desc;
620034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  masm.GetCode(&desc);
621034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  ASSERT(!RelocInfo::RequiresRelocation(desc));
622034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org
623034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  CPU::FlushICache(buffer, actual_size);
624034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  OS::ProtectCode(buffer, actual_size);
625034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org  return FUNCTION_CAST<UnaryMathFunction>(buffer);
626034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org#endif
627154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org}
628154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org
629034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org#undef __
630034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org
631e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
6327516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// -------------------------------------------------------------------------
6337516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// Platform-specific RuntimeCallHelper functions.
6347516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
6357516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid StubRuntimeCallHelper::BeforeCall(MacroAssembler* masm) const {
636c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  masm->EnterFrame(StackFrame::INTERNAL);
637c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSERT(!masm->has_frame());
638c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  masm->set_has_frame(true);
6397516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org}
6407516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
6417516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
6427516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid StubRuntimeCallHelper::AfterCall(MacroAssembler* masm) const {
643c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  masm->LeaveFrame(StackFrame::INTERNAL);
644c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSERT(masm->has_frame());
645c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  masm->set_has_frame(false);
6465c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
6475c838251403b0be9a882540f1922577abba4c872ager@chromium.org
648e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
649394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com// -------------------------------------------------------------------------
650394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com// Code generators
651394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
65283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org#define __ ACCESS_MASM(masm)
65383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
654830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.orgvoid ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
65528381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org    MacroAssembler* masm, AllocationSiteMode mode,
656ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    Label* allocation_memento_found) {
657394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // ----------- S t a t e -------------
658394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //  -- a0    : value
659394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //  -- a1    : key
660394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //  -- a2    : receiver
661394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //  -- ra    : return address
662394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //  -- a3    : target map, scratch for subsequent call
663394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //  -- t0    : scratch (elements)
664394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // -----------------------------------
66528381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org  if (mode == TRACK_ALLOCATION_SITE) {
666ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org    ASSERT(allocation_memento_found != NULL);
667b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    __ JumpIfJSArrayHasAllocationMemento(a2, t0, allocation_memento_found);
66828381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org  }
66928381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org
670394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Set transitioned map.
671394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ sw(a3, FieldMemOperand(a2, HeapObject::kMapOffset));
672394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ RecordWriteField(a2,
673394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      HeapObject::kMapOffset,
674394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      a3,
675394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      t5,
676394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      kRAHasNotBeenSaved,
677394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      kDontSaveFPRegs,
678394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      EMIT_REMEMBERED_SET,
679394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      OMIT_SMI_CHECK);
680394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
681394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
682394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
683830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.orgvoid ElementsTransitionGenerator::GenerateSmiToDouble(
68428381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org    MacroAssembler* masm, AllocationSiteMode mode, Label* fail) {
685394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // ----------- S t a t e -------------
686394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //  -- a0    : value
687394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //  -- a1    : key
688394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //  -- a2    : receiver
689394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //  -- ra    : return address
690394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //  -- a3    : target map, scratch for subsequent call
691394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //  -- t0    : scratch (elements)
692394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // -----------------------------------
69356454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  Label loop, entry, convert_hole, gc_required, only_change_map, done;
694394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
695394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Register scratch = t6;
696394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
69728381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org  if (mode == TRACK_ALLOCATION_SITE) {
698b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    __ JumpIfJSArrayHasAllocationMemento(a2, t0, fail);
69959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  }
70059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
70156454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  // Check for empty arrays, which only require a map transition and no changes
70256454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  // to the backing store.
703394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ lw(t0, FieldMemOperand(a2, JSObject::kElementsOffset));
70456454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  __ LoadRoot(at, Heap::kEmptyFixedArrayRootIndex);
70556454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  __ Branch(&only_change_map, eq, at, Operand(t0));
70656454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org
70756454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  __ push(ra);
708394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ lw(t1, FieldMemOperand(t0, FixedArray::kLengthOffset));
709394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // t0: source FixedArray
710394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // t1: number of elements (smi-tagged)
711394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
712394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Allocate new FixedDoubleArray.
713394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ sll(scratch, t1, 2);
714394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Addu(scratch, scratch, FixedDoubleArray::kHeaderSize);
715594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  __ Allocate(scratch, t2, t3, t5, &gc_required, DOUBLE_ALIGNMENT);
716394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // t2: destination FixedDoubleArray, not tagged as heap object
717f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
718fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // Set destination FixedDoubleArray's length and map.
719394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ LoadRoot(t5, Heap::kFixedDoubleArrayMapRootIndex);
720394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ sw(t1, MemOperand(t2, FixedDoubleArray::kLengthOffset));
721fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  __ sw(t5, MemOperand(t2, HeapObject::kMapOffset));
722394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Update receiver's map.
723394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
724394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ sw(a3, FieldMemOperand(a2, HeapObject::kMapOffset));
725394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ RecordWriteField(a2,
726394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      HeapObject::kMapOffset,
727394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      a3,
728394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      t5,
729394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      kRAHasBeenSaved,
730394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      kDontSaveFPRegs,
73156454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org                      OMIT_REMEMBERED_SET,
732394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      OMIT_SMI_CHECK);
733394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Replace receiver's backing store with newly created FixedDoubleArray.
734394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Addu(a3, t2, Operand(kHeapObjectTag));
735394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ sw(a3, FieldMemOperand(a2, JSObject::kElementsOffset));
736394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ RecordWriteField(a2,
737394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      JSObject::kElementsOffset,
738394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      a3,
739394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      t5,
740394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      kRAHasBeenSaved,
741394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      kDontSaveFPRegs,
742394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      EMIT_REMEMBERED_SET,
743394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      OMIT_SMI_CHECK);
744394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
745394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
746394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Prepare for conversion loop.
747394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Addu(a3, t0, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
748394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Addu(t3, t2, Operand(FixedDoubleArray::kHeaderSize));
749394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ sll(t2, t1, 2);
750394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Addu(t2, t2, t3);
751394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ li(t0, Operand(kHoleNanLower32));
752394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ li(t1, Operand(kHoleNanUpper32));
753394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // t0: kHoleNanLower32
754394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // t1: kHoleNanUpper32
755394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // t2: end of destination FixedDoubleArray, not tagged
756394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // t3: begin of FixedDoubleArray element fields, not tagged
757394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
758394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Branch(&entry);
759394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
76056454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  __ bind(&only_change_map);
76156454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  __ sw(a3, FieldMemOperand(a2, HeapObject::kMapOffset));
76256454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  __ RecordWriteField(a2,
76356454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org                      HeapObject::kMapOffset,
76456454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org                      a3,
76556454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org                      t5,
766a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                      kRAHasNotBeenSaved,
76756454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org                      kDontSaveFPRegs,
76856454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org                      OMIT_REMEMBERED_SET,
76956454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org                      OMIT_SMI_CHECK);
77056454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  __ Branch(&done);
77156454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org
772394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Call into runtime if GC is required.
773394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ bind(&gc_required);
774394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ pop(ra);
775394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Branch(fail);
776394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
777394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Convert and copy elements.
778394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ bind(&loop);
779394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ lw(t5, MemOperand(a3));
780394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Addu(a3, a3, kIntSize);
781394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // t5: current element
782fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  __ UntagAndJumpIfNotSmi(t5, t5, &convert_hole);
783394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
784394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Normal smi, convert to double and store.
785e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ mtc1(t5, f0);
786e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ cvt_d_w(f0, f0);
787e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ sdc1(f0, MemOperand(t3));
788e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ Addu(t3, t3, kDoubleSize);
789e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
790394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Branch(&entry);
791394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
792394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Hole found, store the-hole NaN.
793394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ bind(&convert_hole);
794c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  if (FLAG_debug_code) {
795fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    // Restore a "smi-untagged" heap object.
796fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    __ SmiTag(t5);
797fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    __ Or(t5, t5, Operand(1));
798c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org    __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
799594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    __ Assert(eq, kObjectFoundInSmiOnlyArray, at, Operand(t5));
800c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  }
801731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org  __ sw(t0, MemOperand(t3, Register::kMantissaOffset));  // mantissa
802731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org  __ sw(t1, MemOperand(t3, Register::kExponentOffset));  // exponent
803394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Addu(t3, t3, kDoubleSize);
804394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
805394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ bind(&entry);
806394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Branch(&loop, lt, t3, Operand(t2));
807394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
808394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ pop(ra);
80956454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  __ bind(&done);
810394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
811394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
812394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
813394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comvoid ElementsTransitionGenerator::GenerateDoubleToObject(
81428381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org    MacroAssembler* masm, AllocationSiteMode mode, Label* fail) {
815394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // ----------- S t a t e -------------
816394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //  -- a0    : value
817394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //  -- a1    : key
818394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //  -- a2    : receiver
819394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //  -- ra    : return address
820394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //  -- a3    : target map, scratch for subsequent call
821394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  //  -- t0    : scratch (elements)
822394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // -----------------------------------
82356454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  Label entry, loop, convert_hole, gc_required, only_change_map;
824394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
82528381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org  if (mode == TRACK_ALLOCATION_SITE) {
826b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    __ JumpIfJSArrayHasAllocationMemento(a2, t0, fail);
82728381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org  }
82828381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org
82956454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  // Check for empty arrays, which only require a map transition and no changes
83056454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  // to the backing store.
831394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ lw(t0, FieldMemOperand(a2, JSObject::kElementsOffset));
83256454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  __ LoadRoot(at, Heap::kEmptyFixedArrayRootIndex);
83356454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  __ Branch(&only_change_map, eq, at, Operand(t0));
83456454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org
83556454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  __ MultiPush(a0.bit() | a1.bit() | a2.bit() | a3.bit() | ra.bit());
83656454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org
837394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ lw(t1, FieldMemOperand(t0, FixedArray::kLengthOffset));
838394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // t0: source FixedArray
839394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // t1: number of elements (smi-tagged)
840394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
841394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Allocate new FixedArray.
842394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ sll(a0, t1, 1);
843394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Addu(a0, a0, FixedDoubleArray::kHeaderSize);
844f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  __ Allocate(a0, t2, t3, t5, &gc_required, NO_ALLOCATION_FLAGS);
845394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // t2: destination FixedArray, not tagged as heap object
846fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // Set destination FixedDoubleArray's length and map.
847394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ LoadRoot(t5, Heap::kFixedArrayMapRootIndex);
848394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ sw(t1, MemOperand(t2, FixedDoubleArray::kLengthOffset));
849fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  __ sw(t5, MemOperand(t2, HeapObject::kMapOffset));
850394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
851394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Prepare for conversion loop.
852731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org  __ Addu(t0, t0, Operand(
853731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org        FixedDoubleArray::kHeaderSize - kHeapObjectTag
854731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org        + Register::kExponentOffset));
855394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Addu(a3, t2, Operand(FixedArray::kHeaderSize));
856394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Addu(t2, t2, Operand(kHeapObjectTag));
857394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ sll(t1, t1, 1);
858394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Addu(t1, a3, t1);
859394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ LoadRoot(t3, Heap::kTheHoleValueRootIndex);
860394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ LoadRoot(t5, Heap::kHeapNumberMapRootIndex);
861394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Using offsetted addresses.
862394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // a3: begin of destination FixedArray element fields, not tagged
863731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org  // t0: begin of source FixedDoubleArray element fields, not tagged,
864731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org  //     points to the exponent
865394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // t1: end of destination FixedArray, not tagged
866394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // t2: destination FixedArray
867394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // t3: the-hole pointer
868394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // t5: heap number map
869394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Branch(&entry);
870394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
871394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Call into runtime if GC is required.
872394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ bind(&gc_required);
873394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ MultiPop(a0.bit() | a1.bit() | a2.bit() | a3.bit() | ra.bit());
874394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
875394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Branch(fail);
876394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
877394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ bind(&loop);
878394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ lw(a1, MemOperand(t0));
879394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Addu(t0, t0, kDoubleSize);
880394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // a1: current element's upper 32 bit
881394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // t0: address of next element's upper 32 bit
882394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Branch(&convert_hole, eq, a1, Operand(kHoleNanUpper32));
883394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
884394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Non-hole double, copy value into a heap number.
885394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ AllocateHeapNumber(a2, a0, t6, t5, &gc_required);
886394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // a2: new heap number
887731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org  // Load mantissa of current element, t0 point to exponent of next element.
888731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org  __ lw(a0, MemOperand(t0, (Register::kMantissaOffset
889731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org      - Register::kExponentOffset - kDoubleSize)));
890394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ sw(a0, FieldMemOperand(a2, HeapNumber::kMantissaOffset));
891394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ sw(a1, FieldMemOperand(a2, HeapNumber::kExponentOffset));
892394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ mov(a0, a3);
893394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ sw(a2, MemOperand(a3));
894394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Addu(a3, a3, kIntSize);
895394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ RecordWrite(t2,
896394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                 a0,
897394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                 a2,
898394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                 kRAHasBeenSaved,
899394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                 kDontSaveFPRegs,
900394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                 EMIT_REMEMBERED_SET,
901394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                 OMIT_SMI_CHECK);
902394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Branch(&entry);
903394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
904394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Replace the-hole NaN with the-hole pointer.
905394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ bind(&convert_hole);
906394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ sw(t3, MemOperand(a3));
907394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Addu(a3, a3, kIntSize);
908394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
909394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ bind(&entry);
910394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Branch(&loop, lt, a3, Operand(t1));
911394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
912394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ MultiPop(a2.bit() | a3.bit() | a0.bit() | a1.bit());
913394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Replace receiver's backing store with newly created and filled FixedArray.
914394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ sw(t2, FieldMemOperand(a2, JSObject::kElementsOffset));
915394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ RecordWriteField(a2,
916394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      JSObject::kElementsOffset,
917394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      t2,
918394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      t5,
919394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      kRAHasBeenSaved,
920394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      kDontSaveFPRegs,
921394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      EMIT_REMEMBERED_SET,
922394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                      OMIT_SMI_CHECK);
923394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ pop(ra);
92456454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org
92556454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  __ bind(&only_change_map);
92656454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  // Update receiver's map.
92756454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  __ sw(a3, FieldMemOperand(a2, HeapObject::kMapOffset));
92856454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org  __ RecordWriteField(a2,
92956454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org                      HeapObject::kMapOffset,
93056454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org                      a3,
93156454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org                      t5,
93256454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org                      kRAHasNotBeenSaved,
93356454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org                      kDontSaveFPRegs,
93456454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org                      OMIT_REMEMBERED_SET,
93556454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org                      OMIT_SMI_CHECK);
936394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
937394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
93864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
93964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.orgvoid StringCharLoadGenerator::Generate(MacroAssembler* masm,
94064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org                                       Register string,
94164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org                                       Register index,
94264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org                                       Register result,
94364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org                                       Label* call_runtime) {
94464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Fetch the instance type of the receiver into result register.
94564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ lw(result, FieldMemOperand(string, HeapObject::kMapOffset));
94664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ lbu(result, FieldMemOperand(result, Map::kInstanceTypeOffset));
94764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
94864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // We need special handling for indirect strings.
94964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  Label check_sequential;
95064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ And(at, result, Operand(kIsIndirectStringMask));
95164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ Branch(&check_sequential, eq, at, Operand(zero_reg));
95264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
95364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Dispatch on the indirect string shape: slice or cons.
95464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  Label cons_string;
95564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ And(at, result, Operand(kSlicedNotConsMask));
95664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ Branch(&cons_string, eq, at, Operand(zero_reg));
95764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
95864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Handle slices.
95964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  Label indirect_string_loaded;
96064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ lw(result, FieldMemOperand(string, SlicedString::kOffsetOffset));
961fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  __ lw(string, FieldMemOperand(string, SlicedString::kParentOffset));
96264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ sra(at, result, kSmiTagSize);
96364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ Addu(index, index, at);
96464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ jmp(&indirect_string_loaded);
96564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
96664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Handle cons strings.
96764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Check whether the right hand side is the empty string (i.e. if
96864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // this is really a flat string in a cons string). If that is not
96964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // the case we would rather go to the runtime system now to flatten
97064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // the string.
97164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ bind(&cons_string);
97264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ lw(result, FieldMemOperand(string, ConsString::kSecondOffset));
973750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  __ LoadRoot(at, Heap::kempty_stringRootIndex);
97464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ Branch(call_runtime, ne, result, Operand(at));
97564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Get the first of the two strings and load its instance type.
97664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ lw(string, FieldMemOperand(string, ConsString::kFirstOffset));
97764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
97864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ bind(&indirect_string_loaded);
97964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ lw(result, FieldMemOperand(string, HeapObject::kMapOffset));
98064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ lbu(result, FieldMemOperand(result, Map::kInstanceTypeOffset));
98164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
98264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Distinguish sequential and external strings. Only these two string
98364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // representations can reach here (slices and flat cons strings have been
98464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // reduced to the underlying sequential or external string).
98564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  Label external_string, check_encoding;
98664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ bind(&check_sequential);
98764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  STATIC_ASSERT(kSeqStringTag == 0);
98864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ And(at, result, Operand(kStringRepresentationMask));
98964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ Branch(&external_string, ne, at, Operand(zero_reg));
99064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
99164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Prepare sequential strings
992fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize);
99364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ Addu(string,
99464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org          string,
99564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org          SeqTwoByteString::kHeaderSize - kHeapObjectTag);
99664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ jmp(&check_encoding);
99764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
99864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Handle external strings.
99964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ bind(&external_string);
100064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  if (FLAG_debug_code) {
100164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    // Assert that we do not have a cons or slice (indirect strings) here.
100264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    // Sequential strings have already been ruled out.
100364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    __ And(at, result, Operand(kIsIndirectStringMask));
1004594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    __ Assert(eq, kExternalStringExpectedButNotFound,
100564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org        at, Operand(zero_reg));
100664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  }
100764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Rule out short external strings.
1008d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  STATIC_ASSERT(kShortExternalStringTag != 0);
100964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ And(at, result, Operand(kShortExternalStringMask));
101064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ Branch(call_runtime, ne, at, Operand(zero_reg));
101164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ lw(string, FieldMemOperand(string, ExternalString::kResourceDataOffset));
101264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
101364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  Label ascii, done;
101464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ bind(&check_encoding);
101564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  STATIC_ASSERT(kTwoByteStringTag == 0);
101664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ And(at, result, Operand(kStringEncodingMask));
101764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ Branch(&ascii, ne, at, Operand(zero_reg));
101864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Two-byte string.
101964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ sll(at, index, 1);
102064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ Addu(at, string, at);
102164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ lhu(result, MemOperand(at));
102264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ jmp(&done);
102364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ bind(&ascii);
102464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Ascii string.
102564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ Addu(at, string, index);
102664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ lbu(result, MemOperand(at));
102764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  __ bind(&done);
102864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org}
102964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
103083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
103183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.orgstatic MemOperand ExpConstant(int index, Register base) {
103283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  return MemOperand(base, index * kDoubleSize);
103383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org}
103483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
103583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
103683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.orgvoid MathExpGenerator::EmitMathExp(MacroAssembler* masm,
103783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org                                   DoubleRegister input,
103883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org                                   DoubleRegister result,
103983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org                                   DoubleRegister double_scratch1,
104083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org                                   DoubleRegister double_scratch2,
104183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org                                   Register temp1,
104283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org                                   Register temp2,
104383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org                                   Register temp3) {
104483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  ASSERT(!input.is(result));
104583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  ASSERT(!input.is(double_scratch1));
104683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  ASSERT(!input.is(double_scratch2));
104783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  ASSERT(!result.is(double_scratch1));
104883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  ASSERT(!result.is(double_scratch2));
104983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  ASSERT(!double_scratch1.is(double_scratch2));
105083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  ASSERT(!temp1.is(temp2));
105183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  ASSERT(!temp1.is(temp3));
105283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  ASSERT(!temp2.is(temp3));
105383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  ASSERT(ExternalReference::math_exp_constants(0).address() != NULL);
105483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
10558e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  Label zero, infinity, done;
105683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
105783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ li(temp3, Operand(ExternalReference::math_exp_constants(0)));
105883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
105983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ ldc1(double_scratch1, ExpConstant(0, temp3));
10608e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  __ BranchF(&zero, NULL, ge, double_scratch1, input);
10618e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org
106283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ ldc1(double_scratch2, ExpConstant(1, temp3));
10638e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  __ BranchF(&infinity, NULL, ge, input, double_scratch2);
10648e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org
106583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ ldc1(double_scratch1, ExpConstant(3, temp3));
106683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ ldc1(result, ExpConstant(4, temp3));
106783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ mul_d(double_scratch1, double_scratch1, input);
106883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ add_d(double_scratch1, double_scratch1, result);
10698e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  __ FmoveLow(temp2, double_scratch1);
107083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ sub_d(double_scratch1, double_scratch1, result);
107183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ ldc1(result, ExpConstant(6, temp3));
107283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ ldc1(double_scratch2, ExpConstant(5, temp3));
107383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ mul_d(double_scratch1, double_scratch1, double_scratch2);
107483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ sub_d(double_scratch1, double_scratch1, input);
107583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ sub_d(result, result, double_scratch1);
10768e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  __ mul_d(double_scratch2, double_scratch1, double_scratch1);
10778e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  __ mul_d(result, result, double_scratch2);
107883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ ldc1(double_scratch2, ExpConstant(7, temp3));
107983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ mul_d(result, result, double_scratch2);
108083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ sub_d(result, result, double_scratch1);
10818e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  // Mov 1 in double_scratch2 as math_exp_constants_array[8] == 1.
10828e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  ASSERT(*reinterpret_cast<double*>
10838e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org         (ExternalReference::math_exp_constants(8).address()) == 1);
10848e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  __ Move(double_scratch2, 1);
108583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ add_d(result, result, double_scratch2);
10868e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  __ srl(temp1, temp2, 11);
10878e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  __ Ext(temp2, temp2, 0, 11);
108883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ Addu(temp1, temp1, Operand(0x3ff));
108983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
109083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  // Must not call ExpConstant() after overwriting temp3!
109183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ li(temp3, Operand(ExternalReference::math_exp_log_table()));
109283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ sll(at, temp2, 3);
10938e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  __ Addu(temp3, temp3, Operand(at));
1094731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org  __ lw(temp2, MemOperand(temp3, Register::kMantissaOffset));
1095731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org  __ lw(temp3, MemOperand(temp3, Register::kExponentOffset));
10968e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  // The first word is loaded is the lower number register.
10978e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  if (temp2.code() < temp3.code()) {
10988e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org    __ sll(at, temp1, 20);
10998e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org    __ Or(temp1, temp3, at);
11008e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org    __ Move(double_scratch1, temp2, temp1);
11018e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  } else {
11028e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org    __ sll(at, temp1, 20);
11038e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org    __ Or(temp1, temp2, at);
11048e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org    __ Move(double_scratch1, temp3, temp1);
11058e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  }
11068e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  __ mul_d(result, result, double_scratch1);
110725530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org  __ BranchShort(&done);
11088e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org
11098e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  __ bind(&zero);
11108e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  __ Move(result, kDoubleRegZero);
111125530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org  __ BranchShort(&done);
11128e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org
11138e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  __ bind(&infinity);
11148e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  __ ldc1(result, ExpConstant(2, temp3));
11158e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org
111683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  __ bind(&done);
111783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org}
111883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
1119afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org#ifdef DEBUG
1120fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org// nop(CODE_AGE_MARKER_NOP)
1121fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.orgstatic const uint32_t kCodeAgePatchFirstInstruction = 0x00010180;
1122afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org#endif
1123fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
11245924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org
11255924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.orgCodeAgingHelper::CodeAgingHelper() {
11265924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org  ASSERT(young_sequence_.length() == kNoCodeAgeSequenceLength);
11275924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org  // Since patcher is a large object, allocate it dynamically when needed,
11285924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org  // to avoid overloading the stack in stress conditions.
11295924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org  // DONT_FLUSH is used because the CodeAgingHelper is initialized early in
11305924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org  // the process, before MIPS simulator ICache is setup.
11315924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org  SmartPointer<CodePatcher> patcher(
11325924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org      new CodePatcher(young_sequence_.start(),
11335924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org                      young_sequence_.length() / Assembler::kInstrSize,
11345924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org                      CodePatcher::DONT_FLUSH));
11355924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org  PredictableCodeSizeScope scope(patcher->masm(), young_sequence_.length());
11365924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org  patcher->masm()->Push(ra, fp, cp, a1);
11375924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org  patcher->masm()->nop(Assembler::CODE_AGE_SEQUENCE_NOP);
11385924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org  patcher->masm()->Addu(
11395924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org      fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
1140fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org}
1141fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
1142fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
11435924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org#ifdef DEBUG
11445924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.orgbool CodeAgingHelper::IsOld(byte* candidate) const {
11455924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org  return Memory::uint32_at(candidate) == kCodeAgePatchFirstInstruction;
11465924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org}
11475924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org#endif
11485924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org
11495924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org
11505924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.orgbool Code::IsYoungSequence(Isolate* isolate, byte* sequence) {
11515924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org  bool result = isolate->code_aging_helper()->IsYoung(sequence);
11525924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org  ASSERT(result || isolate->code_aging_helper()->IsOld(sequence));
1153fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  return result;
1154fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org}
1155fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
1156fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
11575924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.orgvoid Code::GetCodeAgeAndParity(Isolate* isolate, byte* sequence, Age* age,
1158fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                               MarkingParity* parity) {
11595924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org  if (IsYoungSequence(isolate, sequence)) {
1160e94b5ff1e1e95fb2c8ef6bce66ce8533786d9792bmeurer@chromium.org    *age = kNoAgeCodeAge;
1161fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    *parity = NO_MARKING_PARITY;
1162fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  } else {
1163f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    Address target_address = Assembler::target_address_at(
1164f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org        sequence + Assembler::kInstrSize);
1165fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    Code* stub = GetCodeFromTargetAddress(target_address);
1166fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    GetCodeAgeAndParity(stub, age, parity);
1167fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  }
1168fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org}
1169fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
1170fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
1171528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid Code::PatchPlatformCodeAge(Isolate* isolate,
1172528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                byte* sequence,
1173fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                                Code::Age age,
1174fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                                MarkingParity parity) {
11755924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org  uint32_t young_length = isolate->code_aging_helper()->young_sequence_length();
1176e94b5ff1e1e95fb2c8ef6bce66ce8533786d9792bmeurer@chromium.org  if (age == kNoAgeCodeAge) {
11775924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org    isolate->code_aging_helper()->CopyYoungSequenceTo(sequence);
1178fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    CPU::FlushICache(sequence, young_length);
1179fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  } else {
1180528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    Code* stub = GetCodeAgeStub(isolate, age, parity);
1181fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    CodePatcher patcher(sequence, young_length / Assembler::kInstrSize);
1182f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    // Mark this code sequence for FindPlatformCodeAgeSequence().
1183fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    patcher.masm()->nop(Assembler::CODE_AGE_MARKER_NOP);
1184f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    // Load the stub address to t9 and call it,
1185f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    // GetCodeAgeAndParity() extracts the stub address from this instruction.
1186f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    patcher.masm()->li(
1187f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org        t9,
1188f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org        Operand(reinterpret_cast<uint32_t>(stub->instruction_start())),
1189f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org        CONSTANT_SIZE);
1190f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    patcher.masm()->nop();  // Prevent jalr to jal optimization.
1191f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    patcher.masm()->jalr(t9, a0);
1192f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    patcher.masm()->nop();  // Branch delay slot nop.
1193f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    patcher.masm()->nop();  // Pad the empty space.
1194fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  }
1195fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org}
1196fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
1197fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
1198394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com#undef __
11995c838251403b0be9a882540f1922577abba4c872ager@chromium.org
12005c838251403b0be9a882540f1922577abba4c872ager@chromium.org} }  // namespace v8::internal
12019dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
12029dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#endif  // V8_TARGET_ARCH_MIPS
1203