105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
25c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Redistribution and use in source and binary forms, with or without
35c838251403b0be9a882540f1922577abba4c872ager@chromium.org// modification, are permitted provided that the following conditions are
45c838251403b0be9a882540f1922577abba4c872ager@chromium.org// met:
55c838251403b0be9a882540f1922577abba4c872ager@chromium.org//
65c838251403b0be9a882540f1922577abba4c872ager@chromium.org//     * Redistributions of source code must retain the above copyright
75c838251403b0be9a882540f1922577abba4c872ager@chromium.org//       notice, this list of conditions and the following disclaimer.
85c838251403b0be9a882540f1922577abba4c872ager@chromium.org//     * Redistributions in binary form must reproduce the above
95c838251403b0be9a882540f1922577abba4c872ager@chromium.org//       copyright notice, this list of conditions and the following
105c838251403b0be9a882540f1922577abba4c872ager@chromium.org//       disclaimer in the documentation and/or other materials provided
115c838251403b0be9a882540f1922577abba4c872ager@chromium.org//       with the distribution.
125c838251403b0be9a882540f1922577abba4c872ager@chromium.org//     * Neither the name of Google Inc. nor the names of its
135c838251403b0be9a882540f1922577abba4c872ager@chromium.org//       contributors may be used to endorse or promote products derived
145c838251403b0be9a882540f1922577abba4c872ager@chromium.org//       from this software without specific prior written permission.
155c838251403b0be9a882540f1922577abba4c872ager@chromium.org//
165c838251403b0be9a882540f1922577abba4c872ager@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
175c838251403b0be9a882540f1922577abba4c872ager@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
185c838251403b0be9a882540f1922577abba4c872ager@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
195c838251403b0be9a882540f1922577abba4c872ager@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
205c838251403b0be9a882540f1922577abba4c872ager@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
215c838251403b0be9a882540f1922577abba4c872ager@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
225c838251403b0be9a882540f1922577abba4c872ager@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
235c838251403b0be9a882540f1922577abba4c872ager@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
245c838251403b0be9a882540f1922577abba4c872ager@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
255c838251403b0be9a882540f1922577abba4c872ager@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
265c838251403b0be9a882540f1922577abba4c872ager@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
275c838251403b0be9a882540f1922577abba4c872ager@chromium.org
285c838251403b0be9a882540f1922577abba4c872ager@chromium.org#ifndef V8_MIPS_MACRO_ASSEMBLER_MIPS_H_
295c838251403b0be9a882540f1922577abba4c872ager@chromium.org#define V8_MIPS_MACRO_ASSEMBLER_MIPS_H_
305c838251403b0be9a882540f1922577abba4c872ager@chromium.org
315c838251403b0be9a882540f1922577abba4c872ager@chromium.org#include "assembler.h"
325c838251403b0be9a882540f1922577abba4c872ager@chromium.org#include "mips/assembler-mips.h"
3340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org#include "v8globals.h"
345c838251403b0be9a882540f1922577abba4c872ager@chromium.org
355c838251403b0be9a882540f1922577abba4c872ager@chromium.orgnamespace v8 {
365c838251403b0be9a882540f1922577abba4c872ager@chromium.orgnamespace internal {
375c838251403b0be9a882540f1922577abba4c872ager@chromium.org
385c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Forward declaration.
395c838251403b0be9a882540f1922577abba4c872ager@chromium.orgclass JumpTarget;
405c838251403b0be9a882540f1922577abba4c872ager@chromium.org
417516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// Reserved Register Usage Summary.
427516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org//
437516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// Registers t8, t9, and at are reserved for use by the MacroAssembler.
447516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org//
457516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// The programmer should know that the MacroAssembler may clobber these three,
467516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// but won't touch other registers except in special cases.
477516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org//
487516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// Per the MIPS ABI, register t9 must be used for indirect function call
497516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// via 'jalr t9' or 'jr t9' instructions. This is relied upon by gcc when
507516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// trying to update gp register for position-independent-code. Whenever
517516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// MIPS generated code calls C code, it must be via t9 register.
525c838251403b0be9a882540f1922577abba4c872ager@chromium.org
53c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org// Flags used for AllocateHeapNumber
5583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.orgenum TaggingMode {
5683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  // Tag the result.
5783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  TAG_RESULT,
5883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  // Don't tag
5983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  DONT_TAG_RESULT
6083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org};
6183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org
627516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// Flags used for the ObjectToDoubleFPURegister function.
637516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgenum ObjectToDoubleFlags {
647516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // No special flags.
657516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  NO_OBJECT_TO_DOUBLE_FLAGS = 0,
667516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Object is known to be a non smi.
677516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  OBJECT_NOT_SMI = 1 << 0,
687516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Don't load NaNs or infinities, branch to the non number case instead.
697516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  AVOID_NANS_AND_INFINITIES = 1 << 1
707516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org};
717516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
727516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// Allow programmer to use Branch Delay Slot of Branches, Jumps, Calls.
737516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgenum BranchDelaySlot {
747516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  USE_DELAY_SLOT,
757516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  PROTECT
767516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org};
777516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
7888aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org// Flags used for the li macro-assembler function.
7988aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.orgenum LiFlags {
8088aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org  // If the constant value can be represented in just 16 bits, then
8188aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org  // optimize the li to use a single instruction, rather than lui/ori pair.
8288aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org  OPTIMIZE_SIZE = 0,
8388aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org  // Always use 2 instructions (lui/ori pair), even if the constant could
8488aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org  // be loaded with just one, so that this value is patchable later.
8588aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org  CONSTANT_SIZE = 1
8688aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org};
8788aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org
88c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
89b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.orgenum RememberedSetAction { EMIT_REMEMBERED_SET, OMIT_REMEMBERED_SET };
90b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.orgenum SmiCheck { INLINE_SMI_CHECK, OMIT_SMI_CHECK };
91b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.orgenum RAStatus { kRAHasNotBeenSaved, kRAHasBeenSaved };
92b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
93b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.orgbool AreAliased(Register r1, Register r2, Register r3, Register r4);
94b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
95b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
96c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// -----------------------------------------------------------------------------
97c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Static helper functions.
98c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
991b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orginline MemOperand ContextOperand(Register context, int index) {
100c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  return MemOperand(context, Context::SlotOffset(index));
101c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
102c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
103c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1041b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orginline MemOperand GlobalObjectOperand()  {
10546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  return ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX);
106c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
107c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
108c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
109c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Generate a MemOperand for loading a field from an object.
1101b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orginline MemOperand FieldMemOperand(Register object, int offset) {
111c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  return MemOperand(object, offset - kHeapObjectTag);
112c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
113c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
114c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
115c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Generate a MemOperand for storing arguments 5..N on the stack
116c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// when calling CallCFunction().
1171b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orginline MemOperand CFunctionArgumentOperand(int index) {
118c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  ASSERT(index > kCArgSlotCount);
119c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Argument 5 takes the slot just past the four Arg-slots.
120c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  int offset = (index - 5) * kPointerSize + kCArgsSlotsSize;
121c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  return MemOperand(sp, offset);
122c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com}
123c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
124c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1255c838251403b0be9a882540f1922577abba4c872ager@chromium.org// MacroAssembler implements a collection of frequently used macros.
1265c838251403b0be9a882540f1922577abba4c872ager@chromium.orgclass MacroAssembler: public Assembler {
1275c838251403b0be9a882540f1922577abba4c872ager@chromium.org public:
12883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // The isolate parameter can be NULL if the macro assembler should
12983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // not use isolate-dependent functionality. In this case, it's the
13083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // responsibility of the caller to never invoke such function on the
13183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // macro assembler.
13283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  MacroAssembler(Isolate* isolate, void* buffer, int size);
1335c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1346db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  // Arguments macros.
1357516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#define COND_TYPED_ARGS Condition cond, Register r1, const Operand& r2
1367516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#define COND_ARGS cond, r1, r2
1377516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
1386db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  // Cases when relocation is not needed.
1397516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#define DECLARE_NORELOC_PROTOTYPE(Name, target_type) \
1407516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void Name(target_type target, BranchDelaySlot bd = PROTECT); \
1417516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  inline void Name(BranchDelaySlot bd, target_type target) { \
1427516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    Name(target, bd); \
1437516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  } \
1447516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void Name(target_type target, \
1457516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            COND_TYPED_ARGS, \
1467516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            BranchDelaySlot bd = PROTECT); \
1477516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  inline void Name(BranchDelaySlot bd, \
1487516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                   target_type target, \
1497516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                   COND_TYPED_ARGS) { \
1507516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    Name(target, COND_ARGS, bd); \
1517516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  }
1527516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
1537516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#define DECLARE_BRANCH_PROTOTYPES(Name) \
1547516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  DECLARE_NORELOC_PROTOTYPE(Name, Label*) \
1557516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  DECLARE_NORELOC_PROTOTYPE(Name, int16_t)
1567516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
1576db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  DECLARE_BRANCH_PROTOTYPES(Branch)
1586db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  DECLARE_BRANCH_PROTOTYPES(BranchAndLink)
1597516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
1606db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org#undef DECLARE_BRANCH_PROTOTYPES
1617516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#undef COND_TYPED_ARGS
1627516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#undef COND_ARGS
1635c838251403b0be9a882540f1922577abba4c872ager@chromium.org
16483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
1656db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  // Jump, Call, and Ret pseudo instructions implementing inter-working.
1666db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org#define COND_ARGS Condition cond = al, Register rs = zero_reg, \
1676db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  const Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT
1686db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org
1696db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  void Jump(Register target, COND_ARGS);
1706db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  void Jump(intptr_t target, RelocInfo::Mode rmode, COND_ARGS);
1716db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  void Jump(Address target, RelocInfo::Mode rmode, COND_ARGS);
1726db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  void Jump(Handle<Code> code, RelocInfo::Mode rmode, COND_ARGS);
173c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  static int CallSize(Register target, COND_ARGS);
1746db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  void Call(Register target, COND_ARGS);
175c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  static int CallSize(Address target, RelocInfo::Mode rmode, COND_ARGS);
1766db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  void Call(Address target, RelocInfo::Mode rmode, COND_ARGS);
17732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  int CallSize(Handle<Code> code,
17832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org               RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
17932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org               TypeFeedbackId ast_id = TypeFeedbackId::None(),
18032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org               COND_ARGS);
1816db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  void Call(Handle<Code> code,
1826db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org            RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
183471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org            TypeFeedbackId ast_id = TypeFeedbackId::None(),
1846db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org            COND_ARGS);
1856db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  void Ret(COND_ARGS);
186c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  inline void Ret(BranchDelaySlot bd, Condition cond = al,
187c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Register rs = zero_reg, const Operand& rt = Operand(zero_reg)) {
188c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Ret(cond, rs, rt, bd);
1896db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  }
1906db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org
19188aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org  void Branch(Label* L,
19288aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org              Condition cond,
19388aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org              Register rs,
19488aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org              Heap::RootListIndex index,
19588aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org              BranchDelaySlot bdslot = PROTECT);
19688aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org
1976db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org#undef COND_ARGS
19883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
1995c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Emit code to discard a non-negative number of pointer-sized elements
2005c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // from the stack, clobbering only the sp register.
2017516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void Drop(int count,
2027516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            Condition cond = cc_always,
2037516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            Register reg = no_reg,
2047516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org            const Operand& op = Operand(no_reg));
2057516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
2066ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org  // Trivial case of DropAndRet that utilizes the delay slot and only emits
2076ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org  // 2 instructions.
2086ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org  void DropAndRet(int drop);
2096ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org
2106ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org  void DropAndRet(int drop,
2116ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org                  Condition cond,
2126ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org                  Register reg,
2136ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org                  const Operand& op);
2147516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
2157516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Swap two registers.  If the scratch register is omitted then a slightly
2167516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // less efficient form using xor instead of mov is emitted.
2177516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void Swap(Register reg1, Register reg2, Register scratch = no_reg);
2185c838251403b0be9a882540f1922577abba4c872ager@chromium.org
2195c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void Call(Label* target);
2207516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
22140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  inline void Move(Register dst, Register src) {
22240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org    if (!dst.is(src)) {
22340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org      mov(dst, src);
22440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org    }
22540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  }
22640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org
22740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  inline void Move(FPURegister dst, FPURegister src) {
22840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org    if (!dst.is(src)) {
22940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org      mov_d(dst, src);
23040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org    }
23140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  }
23240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org
23340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  inline void Move(Register dst_low, Register dst_high, FPURegister src) {
23440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org    mfc1(dst_low, src);
23540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org    mfc1(dst_high, FPURegister::from_code(src.code() + 1));
23640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  }
23740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org
238c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com  inline void FmoveHigh(Register dst_high, FPURegister src) {
239c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com    mfc1(dst_high, FPURegister::from_code(src.code() + 1));
240c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com  }
241c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com
242c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com  inline void FmoveLow(Register dst_low, FPURegister src) {
243c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com    mfc1(dst_low, src);
244c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com  }
245c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com
24640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  inline void Move(FPURegister dst, Register src_low, Register src_high) {
24740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org    mtc1(src_low, dst);
24840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org    mtc1(src_high, FPURegister::from_code(dst.code() + 1));
24940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  }
2505c838251403b0be9a882540f1922577abba4c872ager@chromium.org
2513233d2f30cad1f77ff9f43fcbee12f182b18f6b6mstarzinger@chromium.org  // Conditional move.
252c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void Move(FPURegister dst, double imm);
2533233d2f30cad1f77ff9f43fcbee12f182b18f6b6mstarzinger@chromium.org  void Movz(Register rd, Register rs, Register rt);
2543233d2f30cad1f77ff9f43fcbee12f182b18f6b6mstarzinger@chromium.org  void Movn(Register rd, Register rs, Register rt);
2553233d2f30cad1f77ff9f43fcbee12f182b18f6b6mstarzinger@chromium.org  void Movt(Register rd, Register rs, uint16_t cc = 0);
2563233d2f30cad1f77ff9f43fcbee12f182b18f6b6mstarzinger@chromium.org  void Movf(Register rd, Register rs, uint16_t cc = 0);
2573233d2f30cad1f77ff9f43fcbee12f182b18f6b6mstarzinger@chromium.org
2583233d2f30cad1f77ff9f43fcbee12f182b18f6b6mstarzinger@chromium.org  void Clz(Register rd, Register rs);
259c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
2605c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Jump unconditionally to given label.
2615c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // We NEED a nop in the branch delay slot, as it used by v8, for example in
2625c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // CodeGenerator::ProcessDeferred().
2635d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  // Currently the branch delay slot is filled by the MacroAssembler.
2645c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Use rather b(Label) for code generation.
2655c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void jmp(Label* L) {
2667516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    Branch(L);
2675c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
2685c838251403b0be9a882540f1922577abba4c872ager@chromium.org
2695c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Load an object from the root table.
2705c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void LoadRoot(Register destination,
2715c838251403b0be9a882540f1922577abba4c872ager@chromium.org                Heap::RootListIndex index);
2725c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void LoadRoot(Register destination,
2735c838251403b0be9a882540f1922577abba4c872ager@chromium.org                Heap::RootListIndex index,
2745c838251403b0be9a882540f1922577abba4c872ager@chromium.org                Condition cond, Register src1, const Operand& src2);
2755c838251403b0be9a882540f1922577abba4c872ager@chromium.org
2767516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Store an object to the root table.
2777516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void StoreRoot(Register source,
2787516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                 Heap::RootListIndex index);
2797516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void StoreRoot(Register source,
2807516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                 Heap::RootListIndex index,
2817516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                 Condition cond, Register src1, const Operand& src2);
2827516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
28364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  void LoadHeapObject(Register dst, Handle<HeapObject> object);
2847516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
285fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org  void LoadObject(Register result, Handle<Object> object) {
28679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    AllowDeferredHandleDereference heap_object_check;
287fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org    if (object->IsHeapObject()) {
288fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org      LoadHeapObject(result, Handle<HeapObject>::cast(object));
289fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org    } else {
290fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org      li(result, object);
291fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org    }
292fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org  }
293fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org
294b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // ---------------------------------------------------------------------------
295b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // GC Support
296b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
297b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  void IncrementalMarkingRecordWriteHelper(Register object,
298b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                                           Register value,
299b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                                           Register address);
300b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
301b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  enum RememberedSetFinalAction {
302b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    kReturnAtEnd,
303b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    kFallThroughAtEnd
304b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  };
305b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
306b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
307b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // Record in the remembered set the fact that we have a pointer to new space
308b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // at the address pointed to by the addr register.  Only works if addr is not
309b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // in new space.
310b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  void RememberedSetHelper(Register object,  // Used for debug code.
311b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                           Register addr,
312b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                           Register scratch,
313b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                           SaveFPRegsMode save_fp,
314b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                           RememberedSetFinalAction and_then);
315b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
316b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  void CheckPageFlag(Register object,
317b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                     Register scratch,
318b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                     int mask,
319b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                     Condition cc,
320b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                     Label* condition_met);
321b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
322f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  void CheckMapDeprecated(Handle<Map> map,
323f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org                          Register scratch,
324f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org                          Label* if_deprecated);
325f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
326b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // Check if object is in new space.  Jumps if the object is not in new space.
327b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // The register scratch can be object itself, but it will be clobbered.
328b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  void JumpIfNotInNewSpace(Register object,
329b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                           Register scratch,
330b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                           Label* branch) {
331b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    InNewSpace(object, scratch, ne, branch);
332b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  }
333b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
334b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // Check if object is in new space.  Jumps if the object is in new space.
335b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // The register scratch can be object itself, but scratch will be clobbered.
336b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  void JumpIfInNewSpace(Register object,
337b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                        Register scratch,
338b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                        Label* branch) {
339b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    InNewSpace(object, scratch, eq, branch);
340b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  }
3417516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
342b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // Check if an object has a given incremental marking color.
343b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  void HasColor(Register object,
344b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                Register scratch0,
345b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                Register scratch1,
346b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                Label* has_color,
347b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                int first_bit,
348b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                int second_bit);
3497516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
350b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  void JumpIfBlack(Register object,
3517516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                   Register scratch0,
352b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                   Register scratch1,
353b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                   Label* on_black);
354b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
355b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // Checks the color of an object.  If the object is already grey or black
356b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // then we just fall through, since it is already live.  If it is white and
357b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // we can determine that it doesn't need to be scanned, then we just mark it
358b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // black and fall through.  For the rest we jump to the label so the
359b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // incremental marker can fix its assumptions.
360b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  void EnsureNotWhite(Register object,
361b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                      Register scratch1,
362b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                      Register scratch2,
363b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                      Register scratch3,
364b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                      Label* object_is_white_and_not_data);
3657516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
3662efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // Detects conservatively whether an object is data-only, i.e. it does need to
367b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // be scanned by the garbage collector.
368b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  void JumpIfDataObject(Register value,
369b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                        Register scratch,
370b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                        Label* not_data_object);
371b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
372b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // Notify the garbage collector that we wrote a pointer into an object.
373b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // |object| is the object being stored into, |value| is the object being
374b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // stored.  value and scratch registers are clobbered by the operation.
375b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // The offset is the offset from the start of the object, not the offset from
376b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // the tagged HeapObject pointer.  For use with FieldOperand(reg, off).
377b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  void RecordWriteField(
378b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      Register object,
379b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      int offset,
380b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      Register value,
381b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      Register scratch,
382b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      RAStatus ra_status,
383b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      SaveFPRegsMode save_fp,
384b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
385b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      SmiCheck smi_check = INLINE_SMI_CHECK);
386b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
387b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // As above, but the offset has the tag presubtracted.  For use with
388b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // MemOperand(reg, off).
389b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  inline void RecordWriteContextSlot(
390b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      Register context,
391b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      int offset,
392b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      Register value,
393b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      Register scratch,
394b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      RAStatus ra_status,
395b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      SaveFPRegsMode save_fp,
396b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
397b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      SmiCheck smi_check = INLINE_SMI_CHECK) {
398b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    RecordWriteField(context,
399b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                     offset + kHeapObjectTag,
400b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                     value,
401b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                     scratch,
402b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                     ra_status,
403b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                     save_fp,
404b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                     remembered_set_action,
405b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                     smi_check);
406b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  }
407b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
408b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // For a given |object| notify the garbage collector that the slot |address|
409b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // has been written.  |value| is the object being stored. The value and
410b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // address registers are clobbered by the operation.
411b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  void RecordWrite(
412b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      Register object,
413b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      Register address,
414b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      Register value,
415b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      RAStatus ra_status,
416b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      SaveFPRegsMode save_fp,
417b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
418b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      SmiCheck smi_check = INLINE_SMI_CHECK);
4197516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
4207516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
4217516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // ---------------------------------------------------------------------------
42283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Inline caching support.
4237516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
4247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Generate code for checking access rights - used for security checks
4257516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // on access to global objects across environments. The holder register
4267516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // is left untouched, whereas both scratch registers are clobbered.
4277516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void CheckAccessGlobalProxy(Register holder_reg,
4287516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                              Register scratch,
4297516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                              Label* miss);
4307516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
431f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  void GetNumberHash(Register reg0, Register scratch);
4326db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org
4336db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  void LoadFromNumberDictionary(Label* miss,
4346db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org                                Register elements,
4356db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org                                Register key,
4366db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org                                Register result,
4376db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org                                Register reg0,
4386db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org                                Register reg1,
4396db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org                                Register reg2);
4406db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org
4416db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org
4427516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  inline void MarkCode(NopMarkerTypes type) {
4437516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    nop(type);
4447516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  }
4457516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
4467516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Check if the given instruction is a 'type' marker.
4472efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // i.e. check if it is a sll zero_reg, zero_reg, <type> (referenced as
4487516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // nop(type)). These instructions are generated to mark special location in
4497516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // the code, like some special IC code.
4507516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  static inline bool IsMarkedCode(Instr instr, int type) {
4517516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    ASSERT((FIRST_IC_MARKER <= type) && (type < LAST_CODE_MARKER));
4527516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    return IsNop(instr, type);
4537516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  }
4547516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
4557516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
4567516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  static inline int GetCodeMarker(Instr instr) {
4577516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    uint32_t opcode = ((instr & kOpcodeMask));
4587516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    uint32_t rt = ((instr & kRtFieldMask) >> kRtShift);
4597516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    uint32_t rs = ((instr & kRsFieldMask) >> kRsShift);
4607516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    uint32_t sa = ((instr & kSaFieldMask) >> kSaShift);
4617516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
4627516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    // Return <n> if we have a sll zero_reg, zero_reg, n
4637516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    // else return -1.
4647516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    bool sllzz = (opcode == SLL &&
4657516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                  rt == static_cast<uint32_t>(ToNumber(zero_reg)) &&
4667516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                  rs == static_cast<uint32_t>(ToNumber(zero_reg)));
4677516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    int type =
4687516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org        (sllzz && FIRST_IC_MARKER <= sa && sa < LAST_CODE_MARKER) ? sa : -1;
4697516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    ASSERT((type == -1) ||
4707516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org           ((FIRST_IC_MARKER <= type) && (type < LAST_CODE_MARKER)));
4717516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    return type;
4725d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  }
4735d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
4745c838251403b0be9a882540f1922577abba4c872ager@chromium.org
4755c838251403b0be9a882540f1922577abba4c872ager@chromium.org
4765c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // ---------------------------------------------------------------------------
47783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Allocation support.
4787516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
4794c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org  // Allocate an object in new space or old pointer space. The object_size is
4804c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org  // specified either in bytes or in words if the allocation flag SIZE_IN_WORDS
4814c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org  // is passed. If the space is exhausted control continues at the gc_required
4824c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org  // label. The allocated object is returned in result. If the flag
4834c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org  // tag_allocated_object is true the result is tagged as as a heap object.
4844c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org  // All registers are clobbered also when control continues at the gc_required
4854c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org  // label.
4864c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org  void Allocate(int object_size,
4874c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org                Register result,
4884c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org                Register scratch1,
4894c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org                Register scratch2,
4904c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org                Label* gc_required,
4914c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org                AllocationFlags flags);
4924c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org
493f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  void Allocate(Register object_size,
494f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                Register result,
495f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                Register scratch1,
496f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                Register scratch2,
497f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                Label* gc_required,
498f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                AllocationFlags flags);
4997516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
5007516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Undo allocation in new space. The object passed and objects allocated after
5017516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // it will no longer be allocated. The caller must make sure that no pointers
5027516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // are left to the object(s) no longer allocated as they would be invalid when
5037516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // allocation is undone.
5047516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void UndoAllocationInNewSpace(Register object, Register scratch);
5057516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
5067516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
5077516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void AllocateTwoByteString(Register result,
5087516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                             Register length,
5097516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                             Register scratch1,
5107516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                             Register scratch2,
5117516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                             Register scratch3,
5127516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                             Label* gc_required);
5137516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void AllocateAsciiString(Register result,
5147516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                           Register length,
5157516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                           Register scratch1,
5167516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                           Register scratch2,
5177516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                           Register scratch3,
5187516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                           Label* gc_required);
5197516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void AllocateTwoByteConsString(Register result,
5207516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                                 Register length,
5217516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                                 Register scratch1,
5227516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                                 Register scratch2,
5237516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                                 Label* gc_required);
5247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void AllocateAsciiConsString(Register result,
5257516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                               Register length,
5267516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                               Register scratch1,
5277516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                               Register scratch2,
5287516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                               Label* gc_required);
5291805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  void AllocateTwoByteSlicedString(Register result,
5301805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org                                   Register length,
5311805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org                                   Register scratch1,
5321805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org                                   Register scratch2,
5331805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org                                   Label* gc_required);
5341805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  void AllocateAsciiSlicedString(Register result,
5351805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org                                 Register length,
5361805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org                                 Register scratch1,
5371805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org                                 Register scratch2,
5381805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org                                 Label* gc_required);
5397516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
5407516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Allocates a heap number or jumps to the gc_required label if the young
5417516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // space is full and a scavenge is needed. All registers are clobbered also
5427516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // when control continues at the gc_required label.
5437516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void AllocateHeapNumber(Register result,
5447516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                          Register scratch1,
5457516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                          Register scratch2,
5467516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                          Register heap_number_map,
54783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org                          Label* gc_required,
54883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org                          TaggingMode tagging_mode = TAG_RESULT);
5497516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void AllocateHeapNumberWithValue(Register result,
5507516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                                   FPURegister value,
5517516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                                   Register scratch1,
5527516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                                   Register scratch2,
5537516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                                   Label* gc_required);
5547516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
5557516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // ---------------------------------------------------------------------------
55683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Instruction macros.
5575c838251403b0be9a882540f1922577abba4c872ager@chromium.org
5587516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#define DEFINE_INSTRUCTION(instr)                                              \
5595c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void instr(Register rd, Register rs, const Operand& rt);                     \
5605c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void instr(Register rd, Register rs, Register rt) {                          \
5615c838251403b0be9a882540f1922577abba4c872ager@chromium.org    instr(rd, rs, Operand(rt));                                                \
5625c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }                                                                            \
5635c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void instr(Register rs, Register rt, int32_t j) {                            \
5645c838251403b0be9a882540f1922577abba4c872ager@chromium.org    instr(rs, rt, Operand(j));                                                 \
5655c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
5665c838251403b0be9a882540f1922577abba4c872ager@chromium.org
5677516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#define DEFINE_INSTRUCTION2(instr)                                             \
5685c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void instr(Register rs, const Operand& rt);                                  \
5695c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void instr(Register rs, Register rt) {                                       \
5705c838251403b0be9a882540f1922577abba4c872ager@chromium.org    instr(rs, Operand(rt));                                                    \
5715c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }                                                                            \
5725c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void instr(Register rs, int32_t j) {                                         \
5735c838251403b0be9a882540f1922577abba4c872ager@chromium.org    instr(rs, Operand(j));                                                     \
5745c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
5755c838251403b0be9a882540f1922577abba4c872ager@chromium.org
5765c838251403b0be9a882540f1922577abba4c872ager@chromium.org  DEFINE_INSTRUCTION(Addu);
5777516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  DEFINE_INSTRUCTION(Subu);
5785c838251403b0be9a882540f1922577abba4c872ager@chromium.org  DEFINE_INSTRUCTION(Mul);
5795c838251403b0be9a882540f1922577abba4c872ager@chromium.org  DEFINE_INSTRUCTION2(Mult);
5805c838251403b0be9a882540f1922577abba4c872ager@chromium.org  DEFINE_INSTRUCTION2(Multu);
5815c838251403b0be9a882540f1922577abba4c872ager@chromium.org  DEFINE_INSTRUCTION2(Div);
5825c838251403b0be9a882540f1922577abba4c872ager@chromium.org  DEFINE_INSTRUCTION2(Divu);
5835c838251403b0be9a882540f1922577abba4c872ager@chromium.org
5845c838251403b0be9a882540f1922577abba4c872ager@chromium.org  DEFINE_INSTRUCTION(And);
5855c838251403b0be9a882540f1922577abba4c872ager@chromium.org  DEFINE_INSTRUCTION(Or);
5865c838251403b0be9a882540f1922577abba4c872ager@chromium.org  DEFINE_INSTRUCTION(Xor);
5875c838251403b0be9a882540f1922577abba4c872ager@chromium.org  DEFINE_INSTRUCTION(Nor);
58883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  DEFINE_INSTRUCTION2(Neg);
5895c838251403b0be9a882540f1922577abba4c872ager@chromium.org
5905c838251403b0be9a882540f1922577abba4c872ager@chromium.org  DEFINE_INSTRUCTION(Slt);
5915c838251403b0be9a882540f1922577abba4c872ager@chromium.org  DEFINE_INSTRUCTION(Sltu);
5925c838251403b0be9a882540f1922577abba4c872ager@chromium.org
5937516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // MIPS32 R2 instruction macro.
5947516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  DEFINE_INSTRUCTION(Ror);
5957516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
5965c838251403b0be9a882540f1922577abba4c872ager@chromium.org#undef DEFINE_INSTRUCTION
5975c838251403b0be9a882540f1922577abba4c872ager@chromium.org#undef DEFINE_INSTRUCTION2
5985c838251403b0be9a882540f1922577abba4c872ager@chromium.org
5995c838251403b0be9a882540f1922577abba4c872ager@chromium.org
60083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // ---------------------------------------------------------------------------
60183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Pseudo-instructions.
6025c838251403b0be9a882540f1922577abba4c872ager@chromium.org
6035c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void mov(Register rd, Register rt) { or_(rd, rt, zero_reg); }
6045c838251403b0be9a882540f1922577abba4c872ager@chromium.org
60583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Load int32 in the rd register.
60688aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org  void li(Register rd, Operand j, LiFlags mode = OPTIMIZE_SIZE);
60788aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org  inline void li(Register rd, int32_t j, LiFlags mode = OPTIMIZE_SIZE) {
60888aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org    li(rd, Operand(j), mode);
6095c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
61088aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org  inline void li(Register dst, Handle<Object> value,
61188aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org                 LiFlags mode = OPTIMIZE_SIZE) {
61288aa058bdadfa79ae2836d12d6dd2d1c28aa490cdanno@chromium.org    li(dst, Operand(value), mode);
6137516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  }
6145c838251403b0be9a882540f1922577abba4c872ager@chromium.org
6155c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Push multiple registers on the stack.
616ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // Registers are saved in numerical order, with higher numbered registers
61783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // saved in higher memory addresses.
6185c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void MultiPush(RegList regs);
6195c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void MultiPushReversed(RegList regs);
6207516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
6211805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  void MultiPushFPU(RegList regs);
6221805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  void MultiPushReversedFPU(RegList regs);
6231805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org
62483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void push(Register src) {
6255c838251403b0be9a882540f1922577abba4c872ager@chromium.org    Addu(sp, sp, Operand(-kPointerSize));
6265c838251403b0be9a882540f1922577abba4c872ager@chromium.org    sw(src, MemOperand(sp, 0));
6275c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
628594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void Push(Register src) { push(src); }
6297516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
6306d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  // Push a handle.
6316d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  void Push(Handle<Object> handle);
63209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  void Push(Smi* smi) { Push(Handle<Smi>(smi, isolate())); }
6336d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
63483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Push two registers. Pushes leftmost register first (to highest address).
63583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void Push(Register src1, Register src2) {
6367516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    Subu(sp, sp, Operand(2 * kPointerSize));
6377516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    sw(src1, MemOperand(sp, 1 * kPointerSize));
6387516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    sw(src2, MemOperand(sp, 0 * kPointerSize));
6397516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  }
6407516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
64183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Push three registers. Pushes leftmost register first (to highest address).
64283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void Push(Register src1, Register src2, Register src3) {
64383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Subu(sp, sp, Operand(3 * kPointerSize));
6447516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    sw(src1, MemOperand(sp, 2 * kPointerSize));
6457516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    sw(src2, MemOperand(sp, 1 * kPointerSize));
6467516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    sw(src3, MemOperand(sp, 0 * kPointerSize));
6477516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  }
6487516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
64983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Push four registers. Pushes leftmost register first (to highest address).
65083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void Push(Register src1, Register src2, Register src3, Register src4) {
65183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Subu(sp, sp, Operand(4 * kPointerSize));
6527516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    sw(src1, MemOperand(sp, 3 * kPointerSize));
6537516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    sw(src2, MemOperand(sp, 2 * kPointerSize));
6547516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    sw(src3, MemOperand(sp, 1 * kPointerSize));
6557516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    sw(src4, MemOperand(sp, 0 * kPointerSize));
6567516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  }
6577516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
6585c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void Push(Register src, Condition cond, Register tst1, Register tst2) {
65983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    // Since we don't have conditional execution we use a Branch.
6607516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    Branch(3, cond, tst1, Operand(tst2));
66183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Subu(sp, sp, Operand(kPointerSize));
6625c838251403b0be9a882540f1922577abba4c872ager@chromium.org    sw(src, MemOperand(sp, 0));
6635c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
6645c838251403b0be9a882540f1922577abba4c872ager@chromium.org
6655c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Pops multiple values from the stack and load them in the
6665c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // registers specified in regs. Pop order is the opposite as in MultiPush.
6675c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void MultiPop(RegList regs);
6685c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void MultiPopReversed(RegList regs);
66983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
6701805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  void MultiPopFPU(RegList regs);
6711805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  void MultiPopReversedFPU(RegList regs);
6721805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org
67383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void pop(Register dst) {
6745c838251403b0be9a882540f1922577abba4c872ager@chromium.org    lw(dst, MemOperand(sp, 0));
6755c838251403b0be9a882540f1922577abba4c872ager@chromium.org    Addu(sp, sp, Operand(kPointerSize));
6765c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
677594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void Pop(Register dst) { pop(dst); }
67883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
67983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Pop two registers. Pops rightmost register first (from lower address).
68083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void Pop(Register src1, Register src2) {
68183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    ASSERT(!src1.is(src2));
68283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    lw(src2, MemOperand(sp, 0 * kPointerSize));
68383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    lw(src1, MemOperand(sp, 1 * kPointerSize));
68483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Addu(sp, sp, 2 * kPointerSize);
68583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
68683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
687c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Pop three registers. Pops rightmost register first (from lower address).
688c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void Pop(Register src1, Register src2, Register src3) {
689c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    lw(src3, MemOperand(sp, 0 * kPointerSize));
690c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    lw(src2, MemOperand(sp, 1 * kPointerSize));
691c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    lw(src1, MemOperand(sp, 2 * kPointerSize));
692c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Addu(sp, sp, 3 * kPointerSize);
693c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
694c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
6957516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void Pop(uint32_t count = 1) {
6967516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    Addu(sp, sp, Operand(count * kPointerSize));
6977516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  }
6987516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
6997516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Push and pop the registers that can hold pointers, as defined by the
7007516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // RegList constant kSafepointSavedRegisters.
70140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  void PushSafepointRegisters();
70240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  void PopSafepointRegisters();
70340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  void PushSafepointRegistersAndDoubles();
70440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  void PopSafepointRegistersAndDoubles();
70540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  // Store value in register src in the safepoint stack slot for
70640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  // register dst.
70740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  void StoreToSafepointRegisterSlot(Register src, Register dst);
70840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  void StoreToSafepointRegistersAndDoublesSlot(Register src, Register dst);
70940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  // Load the value of the src register from its safepoint stack slot
71040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  // into register dst.
71140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  void LoadFromSafepointRegisterSlot(Register dst, Register src);
7127516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
713c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Flush the I-cache from asm code. You should use CPU::FlushICache from C.
714c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Does not handle errors.
715c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void FlushICache(Register address, unsigned instructions);
716c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
7177516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // MIPS32 R2 instruction macro.
7187516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void Ins(Register rt, Register rs, uint16_t pos, uint16_t size);
7197516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void Ext(Register rt, Register rs, uint16_t pos, uint16_t size);
7207516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
721c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // ---------------------------------------------------------------------------
722c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // FPU macros. These do not handle special cases like NaN or +- inf.
723c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
7247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Convert unsigned word to double.
7254668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org  void Cvt_d_uw(FPURegister fd, FPURegister fs, FPURegister scratch);
7264668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org  void Cvt_d_uw(FPURegister fd, Register rs, FPURegister scratch);
7277516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
7287516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Convert double to unsigned word.
7294668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org  void Trunc_uw_d(FPURegister fd, FPURegister fs, FPURegister scratch);
7304668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org  void Trunc_uw_d(FPURegister fd, Register rs, FPURegister scratch);
7317516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
7323233d2f30cad1f77ff9f43fcbee12f182b18f6b6mstarzinger@chromium.org  void Trunc_w_d(FPURegister fd, FPURegister fs);
7333233d2f30cad1f77ff9f43fcbee12f182b18f6b6mstarzinger@chromium.org  void Round_w_d(FPURegister fd, FPURegister fs);
7343233d2f30cad1f77ff9f43fcbee12f182b18f6b6mstarzinger@chromium.org  void Floor_w_d(FPURegister fd, FPURegister fs);
7353233d2f30cad1f77ff9f43fcbee12f182b18f6b6mstarzinger@chromium.org  void Ceil_w_d(FPURegister fd, FPURegister fs);
736c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Wrapper function for the different cmp/branch types.
737c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void BranchF(Label* target,
738c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com               Label* nan,
739c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com               Condition cc,
740c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com               FPURegister cmp1,
741c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com               FPURegister cmp2,
742c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com               BranchDelaySlot bd = PROTECT);
743c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
744c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Alternate (inline) version for better readability with USE_DELAY_SLOT.
745c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  inline void BranchF(BranchDelaySlot bd,
746c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                      Label* target,
747c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                      Label* nan,
748c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                      Condition cc,
749c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                      FPURegister cmp1,
750c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                      FPURegister cmp2) {
751c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    BranchF(target, nan, cc, cmp1, cmp2, bd);
752c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  };
753c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
7547516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Convert the HeapNumber pointed to by source to a 32bits signed integer
7557516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // dest. If the HeapNumber does not fit into a 32bits signed integer branch
7567516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // to not_int32 label. If FPU is available double_scratch is used but not
7577516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // scratch2.
7587516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void ConvertToInt32(Register source,
7597516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                      Register dest,
7607516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                      Register scratch,
7617516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                      Register scratch2,
7627516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                      FPURegister double_scratch,
7637516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                      Label *not_int32);
7647516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
76583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  // Truncates a double using a specific rounding mode, and writes the value
76683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  // to the result register.
767c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // The except_flag will contain any exceptions caused by the instruction.
76883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  // If check_inexact is kDontCheckForInexactConversion, then the inexact
769c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // exception is masked.
770c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void EmitFPUTruncate(FPURoundingMode rounding_mode,
77183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org                       Register result,
772c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                       DoubleRegister double_input,
77383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org                       Register scratch,
77483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org                       DoubleRegister double_scratch,
775c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                       Register except_flag,
776c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                       CheckForInexactConversion check_inexact
777c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                           = kDontCheckForInexactConversion);
778c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
77983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Helper for EmitECMATruncate.
78083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // This will truncate a floating-point value outside of the singed 32bit
78183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // integer range to a 32bit signed integer.
78283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Expects the double value loaded in input_high and input_low.
78383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Exits with the answer in 'result'.
78483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Note that this code does not work for values in the 32bit range!
78583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void EmitOutOfInt32RangeTruncate(Register result,
78683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                   Register input_high,
78783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                   Register input_low,
78883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                   Register scratch);
78983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
790d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  // Performs a truncating conversion of a floating point number as used by
791d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  // the JS bitwise operations. See ECMA-262 9.5: ToInt32.
792d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  // Exits with 'result' holding the answer and all other registers clobbered.
793d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  void EmitECMATruncate(Register result,
794d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com                        FPURegister double_input,
795d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com                        FPURegister single_scratch,
796d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com                        Register scratch,
797d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com                        Register scratch2,
798d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com                        Register scratch3);
799d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com
8007516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Enter exit frame.
8017304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // argc - argument count to be dropped by LeaveExitFrame.
8027304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // save_doubles - saves FPU registers on stack, currently disabled.
8037304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // stack_space - extra stack space.
8047304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  void EnterExitFrame(bool save_doubles,
8057304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org                      int stack_space = 0);
8065d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
8077304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // Leave the current exit frame.
8086ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org  void LeaveExitFrame(bool save_doubles,
8096ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org                      Register arg_count,
8106ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org                      bool do_return = false);
8115d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
8127516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Get the actual activation frame alignment for target environment.
8137516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  static int ActivationFrameAlignment();
8145d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
8157304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // Make sure the stack is aligned. Only emits code in debug mode.
8167304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  void AssertStackIsAligned();
8177304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
8187516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void LoadContext(Register dst, int context_chain_length);
8195d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
82078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  // Conditionally load the cached Array transitioned map of type
82146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // transitioned_kind from the native context if the map in register
82246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // map_in_out is the cached Array map in the native context of
82378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  // expected_kind.
82478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  void LoadTransitionedArrayMapConditional(
82578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      ElementsKind expected_kind,
82678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      ElementsKind transitioned_kind,
82778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      Register map_in_out,
82878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      Register scratch,
82978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org      Label* no_map_match);
83078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org
83178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  // Load the initial map for new Arrays from a JSFunction.
83278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  void LoadInitialArrayMap(Register function_in,
83378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org                           Register scratch,
834830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org                           Register map_out,
835830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org                           bool can_have_holes);
836fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
8377516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void LoadGlobalFunction(int index, Register function);
838750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  void LoadArrayFunction(Register function);
8397516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
8407516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Load the initial map from the global function. The registers
8417516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // function and map can be the same, function is then overwritten.
8427516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void LoadGlobalFunctionInitialMap(Register function,
8437516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                                    Register map,
8447516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                                    Register scratch);
8457516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
846f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  void InitializeRootRegister() {
847f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    ExternalReference roots_array_start =
848f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com        ExternalReference::roots_array_start(isolate());
849f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    li(kRootRegister, Operand(roots_array_start));
850f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  }
851c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
8527516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // -------------------------------------------------------------------------
85383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // JavaScript invokes.
8545d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
855f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // Set up call kind marking in t1. The method takes t1 as an
85640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  // explicit first parameter to make the code more readable at the
85740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  // call sites.
85840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  void SetCallKind(Register dst, CallKind kind);
85940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org
8605d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  // Invoke the JavaScript function code by either calling or jumping.
8615d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  void InvokeCode(Register code,
8625d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                  const ParameterCount& expected,
8635d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                  const ParameterCount& actual,
8647516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                  InvokeFlag flag,
865d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com                  const CallWrapper& call_wrapper,
866d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com                  CallKind call_kind);
8675d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
8685d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  void InvokeCode(Handle<Code> code,
8695d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                  const ParameterCount& expected,
8705d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                  const ParameterCount& actual,
8715d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                  RelocInfo::Mode rmode,
87240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org                  InvokeFlag flag,
873d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com                  CallKind call_kind);
8745d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
8755d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  // Invoke the JavaScript function in the given register. Changes the
8765d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  // current context to the context in the function before invoking.
8775d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  void InvokeFunction(Register function,
8785d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                      const ParameterCount& actual,
8797516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                      InvokeFlag flag,
880d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com                      const CallWrapper& call_wrapper,
881d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com                      CallKind call_kind);
8827516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
883c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  void InvokeFunction(Handle<JSFunction> function,
88432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org                      const ParameterCount& expected,
8857516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                      const ParameterCount& actual,
886d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com                      InvokeFlag flag,
88705ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org                      const CallWrapper& call_wrapper,
888d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com                      CallKind call_kind);
8895d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
8905d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
8917516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void IsObjectJSObjectType(Register heap_object,
8927516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                            Register map,
8937516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                            Register scratch,
8947516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                            Label* fail);
8957516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
8967516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void IsInstanceJSObjectType(Register map,
8977516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                              Register scratch,
8987516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                              Label* fail);
8997516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
9007516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void IsObjectJSStringType(Register object,
9017516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                            Register scratch,
9027516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                            Label* fail);
9037516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
9049faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org  void IsObjectNameType(Register object,
9059faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org                        Register scratch,
9069faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org                        Label* fail);
9079faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org
908ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org#ifdef ENABLE_DEBUGGER_SUPPORT
9097516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // -------------------------------------------------------------------------
91083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Debugger Support.
911ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
912ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void DebugBreak();
913ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org#endif
914ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
915ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
9167516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // -------------------------------------------------------------------------
91783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Exception handling.
9185c838251403b0be9a882540f1922577abba4c872ager@chromium.org
9195c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Push a new try handler and link into try handler chain.
92078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  void PushTryHandler(StackHandler::Kind kind, int handler_index);
9215c838251403b0be9a882540f1922577abba4c872ager@chromium.org
9225c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Unlink the stack handler on top of the stack from the try handler chain.
9235c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Must preserve the result register.
9245c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void PopTryHandler();
9255c838251403b0be9a882540f1922577abba4c872ager@chromium.org
92665a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org  // Passes thrown value to the handler of top of the try handler chain.
9277304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  void Throw(Register value);
9287304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
9297304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // Propagates an uncatchable exception to the top of the current JS stack's
9307304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // handler chain.
93165a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org  void ThrowUncatchable(Register value);
9327304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
9337516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Copies a fixed number of fields of heap objects from src to dst.
9347516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void CopyFields(Register dst, Register src, RegList temps, int field_count);
9355c838251403b0be9a882540f1922577abba4c872ager@chromium.org
93683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Copies a number of bytes from src to dst. All registers are clobbered. On
93783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // exit src and dst will point to the place just after where the last byte was
93883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // read or written and length will be zero.
93983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void CopyBytes(Register src,
94083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                 Register dst,
94183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                 Register length,
94283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                 Register scratch);
94383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
944b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // Initialize fields with filler values.  Fields starting at |start_offset|
945b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // not including end_offset are overwritten with the value in |filler|.  At
946b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // the end the loop, |start_offset| takes the value of |end_offset|.
947b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  void InitializeFieldsWithFiller(Register start_offset,
948b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                                  Register end_offset,
949b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                                  Register filler);
950b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
9517516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // -------------------------------------------------------------------------
9525c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Support functions.
9535c838251403b0be9a882540f1922577abba4c872ager@chromium.org
9547516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Try to get function prototype of a function and puts the value in
9557516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // the result register. Checks that the function really is a
9567516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // function and jumps to the miss label if the fast checks fail. The
9577516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // function register will be untouched; the other registers may be
9587516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // clobbered.
9597516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void TryGetFunctionPrototype(Register function,
9607516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                               Register result,
9617516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                               Register scratch,
962394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                               Label* miss,
963394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                               bool miss_on_bound_function = false);
9647516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
9655d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  void GetObjectType(Register function,
9665d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                     Register map,
9675d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                     Register type_reg);
9685d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
969d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  // Check if a map for a JSObject indicates that the object has fast elements.
970d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  // Jump to the specified label if it does not.
971d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  void CheckFastElements(Register map,
972d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com                         Register scratch,
973d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com                         Label* fail);
974d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com
975b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // Check if a map for a JSObject indicates that the object can have both smi
976b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // and HeapObject elements.  Jump to the specified label if it does not.
977b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  void CheckFastObjectElements(Register map,
978b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                               Register scratch,
979b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                               Label* fail);
980b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
981b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // Check if a map for a JSObject indicates that the object has fast smi only
982b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // elements.  Jump to the specified label if it does not.
983830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  void CheckFastSmiElements(Register map,
984830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org                            Register scratch,
985830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org                            Label* fail);
986b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
987b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // Check to see if maybe_number can be stored as a double in
988b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // FastDoubleElements. If it can, store it at the index specified by key in
9892c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  // the FastDoubleElements array elements. Otherwise jump to fail, in which
9902c067b150f65db3e076b6b5a813e7f6f2492f770rossberg@chromium.org  // case scratch2, scratch3 and scratch4 are unmodified.
991b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  void StoreNumberToDoubleElements(Register value_reg,
992b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                                   Register key_reg,
99389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org                                   // All regs below here overwritten.
994b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                                   Register elements_reg,
995b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                                   Register scratch1,
996b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                                   Register scratch2,
997b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                                   Register scratch3,
998b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                                   Register scratch4,
9998e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org                                   Label* fail,
10008e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org                                   int elements_offset = 0);
1001b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
100205ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  // Compare an object's map with the specified map and its transitioned
100305ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  // elements maps if mode is ALLOW_ELEMENT_TRANSITION_MAPS. Jumps to
100405ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  // "branch_to" if the result of the comparison is "cond". If multiple map
100505ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  // compares are required, the compare sequences branches to early_success.
100605ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  void CompareMapAndBranch(Register obj,
100705ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org                           Register scratch,
100805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org                           Handle<Map> map,
100905ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org                           Label* early_success,
101005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org                           Condition cond,
1011a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org                           Label* branch_to);
101205ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
10137028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  // As above, but the map of the object is already loaded into the register
10147028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  // which is preserved by the code generated.
10157028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  void CompareMapAndBranch(Register obj_map,
10167028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                           Handle<Map> map,
10177028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                           Label* early_success,
10187028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                           Condition cond,
1019a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org                           Label* branch_to);
10207028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
102105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  // Check if the map of an object is equal to a specified map and branch to
102205ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  // label if not. Skip the smi check if not required (object is known to be a
102305ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  // heap object). If mode is ALLOW_ELEMENT_TRANSITION_MAPS, then also match
102405ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  // against maps that are ElementsKind transition maps of the specificed map.
10257516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void CheckMap(Register obj,
10267516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                Register scratch,
10277516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                Handle<Map> map,
10287516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                Label* fail,
1029a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org                SmiCheckType smi_check_type);
103005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
10317516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
10327516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void CheckMap(Register obj,
10337516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                Register scratch,
10347516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                Heap::RootListIndex index,
10357516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                Label* fail,
103640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org                SmiCheckType smi_check_type);
103740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org
103840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  // Check if the map of an object is equal to a specified map and branch to a
103940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  // specified target if equal. Skip the smi check if not required (object is
104040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  // known to be a heap object)
104140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  void DispatchMap(Register obj,
104240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org                   Register scratch,
104340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org                   Handle<Map> map,
104440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org                   Handle<Code> success,
104540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org                   SmiCheckType smi_check_type);
10465d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
10475d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  // Generates code for reporting that an illegal operation has
10485d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  // occurred.
10495d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  void IllegalOperation(int num_arguments);
10505d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
1051c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1052c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Load and check the instance type of an object for being a string.
1053c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Loads the type into the second argument register.
1054c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Returns a condition that will be enabled if the object was a string.
1055c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Condition IsObjectStringType(Register obj,
1056c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                               Register type,
1057c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                               Register result) {
1058c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    lw(type, FieldMemOperand(obj, HeapObject::kMapOffset));
1059c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    lbu(type, FieldMemOperand(type, Map::kInstanceTypeOffset));
1060c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    And(type, type, Operand(kIsNotStringMask));
1061c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ASSERT_EQ(0, kStringTag);
1062c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    return eq;
1063c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
1064c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1065c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
10667516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Picks out an array index from the hash field.
10677516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Register use:
10687516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  //   hash - holds the index's hash. Clobbered.
10697516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  //   index - holds the overwritten index on exit.
10707516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void IndexFromHash(Register hash, Register index);
10717516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
107283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Get the number of least significant bits from a register.
107383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void GetLeastBitsFromSmi(Register dst, Register src, int num_least_bits);
107483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void GetLeastBitsFromInt32(Register dst, Register src, int mun_least_bits);
107583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
10767516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Load the value of a number object into a FPU double register. If the
10777516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // object is not a number a jump to the label not_number is performed
10787516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // and the FPU double register is unchanged.
10797516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void ObjectToDoubleFPURegister(
10807516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      Register object,
10817516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      FPURegister value,
10827516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      Register scratch1,
10837516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      Register scratch2,
10847516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      Register heap_number_map,
10857516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      Label* not_number,
10867516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      ObjectToDoubleFlags flags = NO_OBJECT_TO_DOUBLE_FLAGS);
10877516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
10887516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Load the value of a smi object into a FPU double register. The register
10897516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // scratch1 can be the same register as smi in which case smi will hold the
10907516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // untagged value afterwards.
10917516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void SmiToDoubleFPURegister(Register smi,
10927516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                              FPURegister value,
10937516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                              Register scratch1);
10947516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
10957516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // -------------------------------------------------------------------------
109683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Overflow handling functions.
109783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Usage: first call the appropriate arithmetic function, then call one of the
109883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // jump functions with the overflow_dst register as the second parameter.
109983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
110083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void AdduAndCheckForOverflow(Register dst,
110183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                               Register left,
110283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                               Register right,
110383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                               Register overflow_dst,
110483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                               Register scratch = at);
110583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
110683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void SubuAndCheckForOverflow(Register dst,
110783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                               Register left,
110883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                               Register right,
110983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                               Register overflow_dst,
111083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                               Register scratch = at);
111183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
111283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void BranchOnOverflow(Label* label,
111383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                        Register overflow_check,
111483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                        BranchDelaySlot bd = PROTECT) {
111583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Branch(label, lt, overflow_check, Operand(zero_reg), bd);
111683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
111783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
111883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void BranchOnNoOverflow(Label* label,
111983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                          Register overflow_check,
112083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                          BranchDelaySlot bd = PROTECT) {
112183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Branch(label, ge, overflow_check, Operand(zero_reg), bd);
112283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
112383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
112483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void RetOnOverflow(Register overflow_check, BranchDelaySlot bd = PROTECT) {
112583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Ret(lt, overflow_check, Operand(zero_reg), bd);
112683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
112783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
112883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void RetOnNoOverflow(Register overflow_check, BranchDelaySlot bd = PROTECT) {
112983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    Ret(ge, overflow_check, Operand(zero_reg), bd);
113083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
113183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
113283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // -------------------------------------------------------------------------
113383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Runtime calls.
11345c838251403b0be9a882540f1922577abba4c872ager@chromium.org
11356ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org  // See comments at the beginning of CEntryStub::Generate.
11366ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org  inline void PrepareCEntryArgs(int num_args) {
11376ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org    li(s0, num_args);
11386ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org    li(s1, (num_args - 1) * kPointerSize);
11396ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org  }
11406ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org
11416ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org  inline void PrepareCEntryFunction(const ExternalReference& ref) {
11426ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org    li(s2, Operand(ref));
11436ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org  }
11446ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org
11455c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Call a code stub.
11466ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org  void CallStub(CodeStub* stub,
114759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org                TypeFeedbackId ast_id = TypeFeedbackId::None(),
11486ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org                Condition cond = cc_always,
11496ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org                Register r1 = zero_reg,
11506ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org                const Operand& r2 = Operand(zero_reg),
11516ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org                BranchDelaySlot bd = PROTECT);
11525c838251403b0be9a882540f1922577abba4c872ager@chromium.org
11537516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Tail call a code stub (jump).
11547516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void TailCallStub(CodeStub* stub);
11557516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
11567516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void CallJSExitStub(CodeStub* stub);
11575c838251403b0be9a882540f1922577abba4c872ager@chromium.org
11585c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Call a runtime routine.
11597516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void CallRuntime(const Runtime::Function* f, int num_arguments);
11607516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void CallRuntimeSaveDoubles(Runtime::FunctionId id);
11615c838251403b0be9a882540f1922577abba4c872ager@chromium.org
11625c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Convenience function: Same as above, but takes the fid instead.
11635c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void CallRuntime(Runtime::FunctionId fid, int num_arguments);
11645c838251403b0be9a882540f1922577abba4c872ager@chromium.org
11657516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Convenience function: call an external reference.
11667516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void CallExternalReference(const ExternalReference& ext,
11676ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org                             int num_arguments,
11686ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org                             BranchDelaySlot bd = PROTECT);
11697516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
11705c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Tail call of a runtime routine (jump).
1171ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // Like JumpToExternalReference, but also takes care of passing the number
11725c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // of parameters.
1173ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void TailCallExternalReference(const ExternalReference& ext,
1174ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org                                 int num_arguments,
1175ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org                                 int result_size);
1176ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
1177ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // Convenience function: tail call a runtime routine (jump).
1178ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void TailCallRuntime(Runtime::FunctionId fid,
11795c838251403b0be9a882540f1922577abba4c872ager@chromium.org                       int num_arguments,
11805c838251403b0be9a882540f1922577abba4c872ager@chromium.org                       int result_size);
11815c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1182c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  int CalculateStackPassedWords(int num_reg_arguments,
1183c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                int num_double_arguments);
1184c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
11857516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Before calling a C-function from generated code, align arguments on stack
11867516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // and add space for the four mips argument slots.
11877516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // After aligning the frame, non-register arguments must be stored on the
11887516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // stack, after the argument-slots using helper: CFunctionArgumentOperand().
11897516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // The argument count assumes all arguments are word sized.
11907516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Some compilers/platforms require the stack to be aligned when calling
11917516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // C++ code.
11927516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Needs a scratch register to do some arithmetic. This register will be
11937516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // trashed.
1194c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void PrepareCallCFunction(int num_reg_arguments,
1195c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                            int num_double_registers,
1196c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                            Register scratch);
1197c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void PrepareCallCFunction(int num_reg_arguments,
1198c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                            Register scratch);
11997516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
12007516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Arguments 1-4 are placed in registers a0 thru a3 respectively.
12017516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Arguments 5..n are stored to stack using following:
12027516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  //  sw(t0, CFunctionArgumentOperand(5));
12037516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
12047516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Calls a C function and cleans up the space for arguments allocated
12057516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // by PrepareCallCFunction. The called function is not allowed to trigger a
12067516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // garbage collection, since that might move the code and invalidate the
12077516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // return address (unless this is somehow accounted for by the called
12087516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // function).
12097516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void CallCFunction(ExternalReference function, int num_arguments);
1210b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  void CallCFunction(Register function, int num_arguments);
1211c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void CallCFunction(ExternalReference function,
1212c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     int num_reg_arguments,
1213c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     int num_double_arguments);
1214b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  void CallCFunction(Register function,
1215c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     int num_reg_arguments,
1216c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     int num_double_arguments);
121783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void GetCFunctionDoubleResult(const DoubleRegister dst);
121883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
121940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  // There are two ways of passing double arguments on MIPS, depending on
122040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  // whether soft or hard floating point ABI is used. These functions
122140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  // abstract parameter passing for the three different ways we call
122240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  // C functions from generated code.
122340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  void SetCallCDoubleArguments(DoubleRegister dreg);
122440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  void SetCallCDoubleArguments(DoubleRegister dreg1, DoubleRegister dreg2);
122540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  void SetCallCDoubleArguments(DoubleRegister dreg, Register reg);
122640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org
1227c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Calls an API function.  Allocates HandleScope, extracts returned value
1228c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // from handle and propagates exceptions.  Restores context.  stack_space
12292efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // - space to be unwound on exit (includes the call JS arguments space and
1230c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // the additional space allocated for the fast call).
1231bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  void CallApiFunctionAndReturn(ExternalReference function,
1232b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org                                Address function_address,
1233b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org                                ExternalReference thunk_ref,
1234b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org                                Register thunk_last_arg,
1235bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org                                int stack_space,
1236bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org                                bool returns_handle,
1237bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org                                int return_value_offset_from_fp);
12387304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
12395c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Jump to the builtin routine.
12406ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org  void JumpToExternalReference(const ExternalReference& builtin,
12416ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org                               BranchDelaySlot bd = PROTECT);
12425c838251403b0be9a882540f1922577abba4c872ager@chromium.org
12435c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Invoke specified builtin JavaScript function. Adds an entry to
12445c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // the unresolved list if the name does not resolve.
12457516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void InvokeBuiltin(Builtins::JavaScript id,
12468e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                     InvokeFlag flag,
1247fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org                     const CallWrapper& call_wrapper = NullCallWrapper());
12485c838251403b0be9a882540f1922577abba4c872ager@chromium.org
12495c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Store the code object for the given builtin in the target register and
12507516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // setup the function in a1.
12515c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void GetBuiltinEntry(Register target, Builtins::JavaScript id);
12525c838251403b0be9a882540f1922577abba4c872ager@chromium.org
12537516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Store the function for the given builtin in the target register.
12547516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void GetBuiltinFunction(Register target, Builtins::JavaScript id);
12557516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
12565c838251403b0be9a882540f1922577abba4c872ager@chromium.org  struct Unresolved {
12575c838251403b0be9a882540f1922577abba4c872ager@chromium.org    int pc;
125883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    uint32_t flags;  // See Bootstrapper::FixupFlags decoders/encoders.
12595c838251403b0be9a882540f1922577abba4c872ager@chromium.org    const char* name;
12605c838251403b0be9a882540f1922577abba4c872ager@chromium.org  };
12615c838251403b0be9a882540f1922577abba4c872ager@chromium.org
126283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  Handle<Object> CodeObject() {
126383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    ASSERT(!code_object_.is_null());
126483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    return code_object_;
126583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
12665c838251403b0be9a882540f1922577abba4c872ager@chromium.org
12677516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // -------------------------------------------------------------------------
126883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // StatsCounter support.
12695c838251403b0be9a882540f1922577abba4c872ager@chromium.org
12705c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void SetCounter(StatsCounter* counter, int value,
12715c838251403b0be9a882540f1922577abba4c872ager@chromium.org                  Register scratch1, Register scratch2);
12725c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void IncrementCounter(StatsCounter* counter, int value,
12735c838251403b0be9a882540f1922577abba4c872ager@chromium.org                        Register scratch1, Register scratch2);
12745c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void DecrementCounter(StatsCounter* counter, int value,
12755c838251403b0be9a882540f1922577abba4c872ager@chromium.org                        Register scratch1, Register scratch2);
12765c838251403b0be9a882540f1922577abba4c872ager@chromium.org
12775c838251403b0be9a882540f1922577abba4c872ager@chromium.org
12787516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // -------------------------------------------------------------------------
127983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Debugging.
12805c838251403b0be9a882540f1922577abba4c872ager@chromium.org
12815c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Calls Abort(msg) if the condition cc is not satisfied.
12825c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Use --debug_code to enable.
1283594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void Assert(Condition cc, BailoutReason reason, Register rs, Operand rt);
12847516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void AssertRegisterIsRoot(Register reg, Heap::RootListIndex index);
12857516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void AssertFastElements(Register elements);
12865c838251403b0be9a882540f1922577abba4c872ager@chromium.org
12875c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Like Assert(), but always enabled.
1288594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void Check(Condition cc, BailoutReason reason, Register rs, Operand rt);
12895c838251403b0be9a882540f1922577abba4c872ager@chromium.org
12905c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Print a message to stdout and abort execution.
1291594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void Abort(BailoutReason msg);
12925c838251403b0be9a882540f1922577abba4c872ager@chromium.org
12935c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Verify restrictions about code generated in stubs.
12945c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void set_generating_stub(bool value) { generating_stub_ = value; }
12955c838251403b0be9a882540f1922577abba4c872ager@chromium.org  bool generating_stub() { return generating_stub_; }
12965c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void set_allow_stub_calls(bool value) { allow_stub_calls_ = value; }
12975c838251403b0be9a882540f1922577abba4c872ager@chromium.org  bool allow_stub_calls() { return allow_stub_calls_; }
1298c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void set_has_frame(bool value) { has_frame_ = value; }
1299c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bool has_frame() { return has_frame_; }
1300c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  inline bool AllowThisStubCall(CodeStub* stub);
13015c838251403b0be9a882540f1922577abba4c872ager@chromium.org
13027516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // ---------------------------------------------------------------------------
130383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Number utilities.
13047516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
13057516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Check whether the value of reg is a power of two and not zero. If not
13067516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // control continues at the label not_power_of_two. If reg is a power of two
13077516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // the register scratch contains the value of (reg - 1) when control falls
13087516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // through.
13097516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void JumpIfNotPowerOfTwoOrZero(Register reg,
13107516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                                 Register scratch,
13117516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                                 Label* not_power_of_two_or_zero);
13127516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
13137516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // -------------------------------------------------------------------------
131483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Smi utilities.
13157516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
13167516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void SmiTag(Register reg) {
13177516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    Addu(reg, reg, reg);
13187516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  }
13197516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
1320c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Test for overflow < 0: use BranchOnOverflow() or BranchOnNoOverflow().
1321fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  void SmiTagCheckOverflow(Register reg, Register overflow);
1322fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  void SmiTagCheckOverflow(Register dst, Register src, Register overflow);
1323c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
13247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void SmiTag(Register dst, Register src) {
13257516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    Addu(dst, src, src);
13267516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  }
13277516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
13287516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void SmiUntag(Register reg) {
13297516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    sra(reg, reg, kSmiTagSize);
13307516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  }
13317516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
13327516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void SmiUntag(Register dst, Register src) {
13337516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    sra(dst, src, kSmiTagSize);
13347516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  }
13357516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
1336fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // Untag the source value into destination and jump if source is a smi.
1337fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // Souce and destination can be the same register.
1338fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  void UntagAndJumpIfSmi(Register dst, Register src, Label* smi_case);
1339fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
1340fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // Untag the source value into destination and jump if source is not a smi.
1341fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // Souce and destination can be the same register.
1342fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  void UntagAndJumpIfNotSmi(Register dst, Register src, Label* non_smi_case);
1343fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
13447516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Jump the register contains a smi.
1345fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  void JumpIfSmi(Register value,
1346fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org                 Label* smi_label,
1347fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org                 Register scratch = at,
1348fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org                 BranchDelaySlot bd = PROTECT);
13497516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
13507516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Jump if the register contains a non-smi.
1351fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  void JumpIfNotSmi(Register value,
1352fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org                    Label* not_smi_label,
1353fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org                    Register scratch = at,
1354fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org                    BranchDelaySlot bd = PROTECT);
13557516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
13567516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Jump if either of the registers contain a non-smi.
13577516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void JumpIfNotBothSmi(Register reg1, Register reg2, Label* on_not_both_smi);
13587516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Jump if either of the registers contain a smi.
13597516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void JumpIfEitherSmi(Register reg1, Register reg2, Label* on_either_smi);
13607516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
1361c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  // Abort execution if argument is a smi, enabled via --debug-code.
1362c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  void AssertNotSmi(Register object);
1363c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  void AssertSmi(Register object);
1364c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org
1365c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  // Abort execution if argument is not a string, enabled via --debug-code.
1366c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  void AssertString(Register object);
1367c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org
13689faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org  // Abort execution if argument is not a name, enabled via --debug-code.
13699faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org  void AssertName(Register object);
13709faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org
1371c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  // Abort execution if argument is not the root value with the given index,
1372c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  // enabled via --debug-code.
1373c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  void AssertRootValue(Register src,
1374c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org                       Heap::RootListIndex root_value_index,
1375594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                       BailoutReason reason);
13767516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
13777516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // ---------------------------------------------------------------------------
137883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // HeapNumber utilities.
13797516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
13807516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void JumpIfNotHeapNumber(Register object,
13817516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                           Register heap_number_map,
13827516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                           Register scratch,
13837516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                           Label* on_not_heap_number);
13847516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
13857516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // -------------------------------------------------------------------------
138683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // String utilities.
13877516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
13887516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Checks if both instance types are sequential ASCII strings and jumps to
13897516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // label if either is not.
13907516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void JumpIfBothInstanceTypesAreNotSequentialAscii(
13917516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      Register first_object_instance_type,
13927516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      Register second_object_instance_type,
13937516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      Register scratch1,
13947516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      Register scratch2,
13957516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      Label* failure);
13967516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
13977516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Check if instance type is sequential ASCII string and jump to label if
13987516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // it is not.
13997516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void JumpIfInstanceTypeIsNotSequentialAscii(Register type,
14007516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                                              Register scratch,
14017516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                                              Label* failure);
14027516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
14031510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  void JumpIfNotUniqueName(Register reg, Label* not_unique_name);
14041510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
14057516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Test that both first and second are sequential ASCII strings.
14067516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Assume that they are non-smis.
14077516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void JumpIfNonSmisNotBothSequentialAsciiStrings(Register first,
14087516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                                                  Register second,
14097516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                                                  Register scratch1,
14107516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                                                  Register scratch2,
14117516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                                                  Label* failure);
14127516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
14137516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Test that both first and second are sequential ASCII strings.
14147516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Check that they are non-smis.
14157516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void JumpIfNotBothSequentialAsciiStrings(Register first,
14167516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                                           Register second,
14177516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                                           Register scratch1,
14187516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                                           Register scratch2,
14197516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                                           Label* failure);
14207516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
1421c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void ClampUint8(Register output_reg, Register input_reg);
1422c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1423c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void ClampDoubleToUint8(Register result_reg,
1424c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                          DoubleRegister input_reg,
1425c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                          DoubleRegister temp_double_reg);
1426c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1427c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
142889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  void LoadInstanceDescriptors(Register map, Register descriptors);
142978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  void EnumLength(Register dst, Register map);
143033e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  void NumberOfOwnDescriptors(Register dst, Register map);
143133e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org
143233e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  template<typename Field>
143333e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  void DecodeField(Register reg) {
143433e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org    static const int shift = Field::kShift;
143533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org    static const int mask = (Field::kMask >> shift) << kSmiTagSize;
143633e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org    srl(reg, reg, shift);
143733e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org    And(reg, reg, Operand(mask));
143833e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  }
1439c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1440c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Activation support.
1441c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void EnterFrame(StackFrame::Type type);
1442c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void LeaveFrame(StackFrame::Type type);
1443c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1444c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Patch the relocated value (lui/ori pair).
1445c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void PatchRelocatedValue(Register li_location,
1446c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                           Register scratch,
1447c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                           Register new_value);
144805ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  // Get the relocatad value (loaded data) from the lui/ori pair.
144905ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org  void GetRelocatedValue(Register li_location,
145005ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org                         Register value,
145105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org                         Register scratch);
1452c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1453812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  // Expects object in a0 and returns map with validated enum cache
1454812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  // in a0.  Assumes that any other register can be used as a scratch.
1455812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  void CheckEnumCache(Register null_value, Label* call_runtime);
1456812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
1457ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // AllocationMemento support. Arrays may have an associated
1458ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // AllocationMemento object that can be checked for in order to pretransition
145959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  // to another type.
146059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  // On entry, receiver_reg should point to the array object.
146159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  // scratch_reg gets clobbered.
146259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  // If allocation info is present, jump to allocation_info_present
1463ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  void TestJSArrayForAllocationMemento(Register receiver_reg,
1464ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                       Register scratch_reg,
1465ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                       Condition cond,
1466ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org                                       Label* allocation_memento_present);
146759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
14685c838251403b0be9a882540f1922577abba4c872ager@chromium.org private:
14697516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void CallCFunctionHelper(Register function,
1470c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                           int num_reg_arguments,
1471c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                           int num_double_arguments);
14725d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
14733cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  void BranchShort(int16_t offset, BranchDelaySlot bdslot = PROTECT);
14743cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  void BranchShort(int16_t offset, Condition cond, Register rs,
14753cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org                   const Operand& rt,
14763cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org                   BranchDelaySlot bdslot = PROTECT);
14773cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  void BranchShort(Label* L, BranchDelaySlot bdslot = PROTECT);
14783cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  void BranchShort(Label* L, Condition cond, Register rs,
14793cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org                   const Operand& rt,
14803cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org                   BranchDelaySlot bdslot = PROTECT);
14813cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  void BranchAndLinkShort(int16_t offset, BranchDelaySlot bdslot = PROTECT);
14823cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  void BranchAndLinkShort(int16_t offset, Condition cond, Register rs,
14833cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org                          const Operand& rt,
14843cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org                          BranchDelaySlot bdslot = PROTECT);
14853cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  void BranchAndLinkShort(Label* L, BranchDelaySlot bdslot = PROTECT);
14863cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  void BranchAndLinkShort(Label* L, Condition cond, Register rs,
14873cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org                          const Operand& rt,
14883cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org                          BranchDelaySlot bdslot = PROTECT);
14893cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  void J(Label* L, BranchDelaySlot bdslot);
14903cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  void Jr(Label* L, BranchDelaySlot bdslot);
14913cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  void Jalr(Label* L, BranchDelaySlot bdslot);
14923cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org
14935d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  // Helper functions for generating invokes.
14945d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  void InvokePrologue(const ParameterCount& expected,
14955d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                      const ParameterCount& actual,
14965d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                      Handle<Code> code_constant,
14975d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                      Register code_reg,
14985d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                      Label* done,
149905ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org                      bool* definitely_mismatches,
15007516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                      InvokeFlag flag,
1501d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com                      const CallWrapper& call_wrapper,
1502d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com                      CallKind call_kind);
15035d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org
15045c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Get the code for the given builtin. Returns if able to resolve
15055c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // the function in the 'resolved' flag.
15065c838251403b0be9a882540f1922577abba4c872ager@chromium.org  Handle<Code> ResolveBuiltin(Builtins::JavaScript id, bool* resolved);
15075c838251403b0be9a882540f1922577abba4c872ager@chromium.org
15087516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void InitializeNewString(Register string,
15097516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                           Register length,
15107516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                           Heap::RootListIndex map_index,
15117516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                           Register scratch1,
15127516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                           Register scratch2);
15137516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
1514b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // Helper for implementing JumpIfNotInNewSpace and JumpIfInNewSpace.
1515b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  void InNewSpace(Register object,
1516b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                  Register scratch,
1517b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                  Condition cond,  // eq for new space, ne otherwise.
1518b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                  Label* branch);
1519b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
1520b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // Helper for finding the mark bits for an address.  Afterwards, the
1521b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // bitmap register points at the word with the mark bits and the mask
1522b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // the position of the first bit.  Leaves addr_reg unchanged.
1523b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  inline void GetMarkBits(Register addr_reg,
1524b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                          Register bitmap_reg,
1525b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                          Register mask_reg);
1526b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
1527f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org  // Helper for throwing exceptions.  Compute a handler address and jump to
1528f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org  // it.  See the implementation for register usage.
1529f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org  void JumpToHandlerEntry();
1530f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org
153140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  // Compute memory operands for safepoint stack slots.
153240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  static int SafepointRegisterStackIndex(int reg_code);
153340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  MemOperand SafepointRegisterSlot(Register reg);
153440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  MemOperand SafepointRegistersAndDoublesSlot(Register reg);
15357516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
15367516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  bool generating_stub_;
15377516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  bool allow_stub_calls_;
1538c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bool has_frame_;
15397516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // This handle will be patched with the code object on installation.
15407516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  Handle<Object> code_object_;
154140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org
154259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  // Needs access to SafepointRegisterStackIndex for compiled frame
154340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  // traversal.
154459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  friend class StandardFrame;
15457516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org};
15467516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
15477516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
15487516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// The code patcher is used to patch (typically) small parts of code e.g. for
15497516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// debugging and other types of instrumentation. When using the code patcher
15507516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// the exact number of bytes specified must be emitted. It is not legal to emit
15517516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// relocation information. If any of these constraints are violated it causes
15527516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// an assertion to fail.
15537516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgclass CodePatcher {
15547516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org public:
15557516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  CodePatcher(byte* address, int instructions);
15567516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  virtual ~CodePatcher();
15577516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
15587516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Macro assembler to emit code.
15597516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  MacroAssembler* masm() { return &masm_; }
15607516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
15617516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Emit an instruction directly.
156283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void Emit(Instr instr);
15637516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
15647516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Emit an address directly.
15657516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void Emit(Address addr);
15667516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
156783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Change the condition part of an instruction leaving the rest of the current
156883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // instruction unchanged.
156983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void ChangeBranchCondition(Condition cond);
157083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
15717516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org private:
15727516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  byte* address_;  // The address of the code being patched.
15737516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  int size_;  // Number of bytes of the expected patch size.
15747516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  MacroAssembler masm_;  // Macro assembler used to generate the code.
15757516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org};
15767516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
15777516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
15785c838251403b0be9a882540f1922577abba4c872ager@chromium.org
15795c838251403b0be9a882540f1922577abba4c872ager@chromium.org#ifdef GENERATED_CODE_COVERAGE
15805c838251403b0be9a882540f1922577abba4c872ager@chromium.org#define CODE_COVERAGE_STRINGIFY(x) #x
15815c838251403b0be9a882540f1922577abba4c872ager@chromium.org#define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x)
15825c838251403b0be9a882540f1922577abba4c872ager@chromium.org#define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__)
15835c838251403b0be9a882540f1922577abba4c872ager@chromium.org#define ACCESS_MASM(masm) masm->stop(__FILE_LINE__); masm->
15845c838251403b0be9a882540f1922577abba4c872ager@chromium.org#else
15855c838251403b0be9a882540f1922577abba4c872ager@chromium.org#define ACCESS_MASM(masm) masm->
15865c838251403b0be9a882540f1922577abba4c872ager@chromium.org#endif
15875c838251403b0be9a882540f1922577abba4c872ager@chromium.org
15885c838251403b0be9a882540f1922577abba4c872ager@chromium.org} }  // namespace v8::internal
15895c838251403b0be9a882540f1922577abba4c872ager@chromium.org
15905c838251403b0be9a882540f1922577abba4c872ager@chromium.org#endif  // V8_MIPS_MACRO_ASSEMBLER_MIPS_H_
1591