macro-assembler-arm.h revision 25f6136652d8341ed047e7fc1a450af5bd218ea9
1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2006-2009 the V8 project authors. All rights reserved.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions of source code must retain the above copyright
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       notice, this list of conditions and the following disclaimer.
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions in binary form must reproduce the above
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       copyright notice, this list of conditions and the following
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       disclaimer in the documentation and/or other materials provided
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       with the distribution.
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Neither the name of Google Inc. nor the names of its
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       contributors may be used to endorse or promote products derived
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       from this software without specific prior written permission.
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_ARM_MACRO_ASSEMBLER_ARM_H_
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_ARM_MACRO_ASSEMBLER_ARM_H_
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "assembler.h"
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// ----------------------------------------------------------------------------
373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Static helper functions
383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// Generate a MemOperand for loading a field from an object.
403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescustatic inline MemOperand FieldMemOperand(Register object, int offset) {
413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  return MemOperand(object, offset - kHeapObjectTag);
423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Give alias names to registers
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst Register cp = { 8 };  // JavaScript context pointer
473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuconst Register roots = { 10 };  // Roots array pointer.
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockenum InvokeJSFlags {
50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CALL_JS,
51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  JUMP_JS
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen// Flags used for the AllocateInNewSpace functions.
5625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsenenum AllocationFlags {
5725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  // No special flags.
5825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  NO_ALLOCATION_FLAGS = 0,
5925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  // Return the pointer to the allocated already tagged as a heap object.
6025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  TAG_OBJECT = 1 << 0,
6125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  // The content of the result register already contains the allocation top in
6225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  // new space.
6325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  RESULT_CONTAINS_TOP = 1 << 1,
6425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  // Specify that the requested size of the space to allocate is specified in
6525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  // words instead of bytes.
6625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  SIZE_IN_WORDS = 1 << 2
6725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen};
6825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
6925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// MacroAssembler implements a collection of frequently used macros.
71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass MacroAssembler: public Assembler {
72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  MacroAssembler(void* buffer, int size);
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
753100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // Jump, Call, and Ret pseudo instructions implementing inter-working.
76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Jump(Register target, Condition cond = al);
77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Jump(byte* target, RelocInfo::Mode rmode, Condition cond = al);
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Jump(Handle<Code> code, RelocInfo::Mode rmode, Condition cond = al);
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Call(Register target, Condition cond = al);
80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Call(byte* target, RelocInfo::Mode rmode, Condition cond = al);
81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Call(Handle<Code> code, RelocInfo::Mode rmode, Condition cond = al);
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Ret(Condition cond = al);
83e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
84e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Emit code to discard a non-negative number of pointer-sized elements
85e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // from the stack, clobbering only the sp register.
86e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  void Drop(int count, Condition cond = al);
87e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Swap two registers.  If the scratch register is omitted then a slightly
906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // less efficient form using xor instead of mov is emitted.
916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void Swap(Register reg1, Register reg2, Register scratch = no_reg);
926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
93e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  void Call(Label* target);
94e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  void Move(Register dst, Handle<Object> value);
956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // May do nothing if the registers are identical.
966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void Move(Register dst, Register src);
97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Jumps to the label at the index given by the Smi in "index".
98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SmiJumpTable(Register index, Vector<Label*> targets);
99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Load an object from the root table.
100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void LoadRoot(Register destination,
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                Heap::RootListIndex index,
102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                Condition cond = al);
10325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  // Store an object to the root table.
10425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  void StoreRoot(Register source,
10525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen                 Heap::RootListIndex index,
10625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen                 Condition cond = al);
107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Check if object is in new space.
1106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // scratch can be object itself, but it will be clobbered.
1116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void InNewSpace(Register object,
1126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                  Register scratch,
1136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                  Condition cc,  // eq for new space, ne otherwise
1146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                  Label* branch);
1156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Set the remebered set bit for an offset into an
1186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // object. RecordWriteHelper only works if the object is not in new
1196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // space.
1206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void RecordWriteHelper(Register object, Register offset, Register scracth);
1216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Sets the remembered set bit for [address+offset], where address is the
123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // address of the heap object 'object'.  The address must be in the first 8K
124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // of an allocated page. The 'scratch' register is used in the
125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // implementation and all 3 registers are clobbered by the operation, as
126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // well as the ip register.
127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void RecordWrite(Register object, Register offset, Register scratch);
128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Push two registers.  Pushes leftmost register first (to highest address).
1306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void Push(Register src1, Register src2, Condition cond = al) {
1316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    ASSERT(!src1.is(src2));
1326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    if (src1.code() > src2.code()) {
1336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      stm(db_w, sp, src1.bit() | src2.bit(), cond);
1346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    } else {
1356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      str(src1, MemOperand(sp, 4, NegPreIndex), cond);
1366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      str(src2, MemOperand(sp, 4, NegPreIndex), cond);
1376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    }
1386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
1396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Push three registers.  Pushes leftmost register first (to highest address).
1416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void Push(Register src1, Register src2, Register src3, Condition cond = al) {
1426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    ASSERT(!src1.is(src2));
1436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    ASSERT(!src2.is(src3));
1446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    ASSERT(!src1.is(src3));
1456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    if (src1.code() > src2.code()) {
1466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      if (src2.code() > src3.code()) {
1476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        stm(db_w, sp, src1.bit() | src2.bit() | src3.bit(), cond);
1486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      } else {
1496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        stm(db_w, sp, src1.bit() | src2.bit(), cond);
1506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        str(src3, MemOperand(sp, 4, NegPreIndex), cond);
1516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      }
1526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    } else {
1536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      str(src1, MemOperand(sp, 4, NegPreIndex), cond);
1546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      Push(src2, src3, cond);
1556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    }
1566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
1576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Push four registers.  Pushes leftmost register first (to highest address).
1596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void Push(Register src1, Register src2,
1606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block            Register src3, Register src4, Condition cond = al) {
1616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    ASSERT(!src1.is(src2));
1626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    ASSERT(!src2.is(src3));
1636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    ASSERT(!src1.is(src3));
1646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    ASSERT(!src1.is(src4));
1656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    ASSERT(!src2.is(src4));
1666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    ASSERT(!src3.is(src4));
1676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    if (src1.code() > src2.code()) {
1686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      if (src2.code() > src3.code()) {
1696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        if (src3.code() > src4.code()) {
1706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block          stm(db_w,
1716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block              sp,
1726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block              src1.bit() | src2.bit() | src3.bit() | src4.bit(),
1736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block              cond);
1746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        } else {
1756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block          stm(db_w, sp, src1.bit() | src2.bit() | src3.bit(), cond);
1766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block          str(src4, MemOperand(sp, 4, NegPreIndex), cond);
1776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        }
1786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      } else {
1796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        stm(db_w, sp, src1.bit() | src2.bit(), cond);
1806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block        Push(src3, src4, cond);
1816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      }
1826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    } else {
1836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      str(src1, MemOperand(sp, 4, NegPreIndex), cond);
1846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      Push(src2, src3, src4, cond);
1856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    }
1866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
1876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
189d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Stack limit support
190d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
191d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  void StackLimitCheck(Label* on_stack_limit_hit);
192d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
193d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // ---------------------------------------------------------------------------
194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Activation frames
195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void EnterInternalFrame() { EnterFrame(StackFrame::INTERNAL); }
197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void LeaveInternalFrame() { LeaveFrame(StackFrame::INTERNAL); }
198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void EnterConstructFrame() { EnterFrame(StackFrame::CONSTRUCT); }
200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void LeaveConstructFrame() { LeaveFrame(StackFrame::CONSTRUCT); }
201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
202d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Enter specific kind of exit frame; either normal or debug mode.
203d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Expects the number of arguments in register r0 and
204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the builtin function to call in register r1. Exits with argc in
205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // r4, argv in r6, and and the builtin function to call in r5.
206d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  void EnterExitFrame(ExitFrame::Mode mode);
207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Leave the current exit frame. Expects the return value in r0.
209d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  void LeaveExitFrame(ExitFrame::Mode mode);
210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Get the actual activation frame alignment for target environment.
2126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  static int ActivationFrameAlignment();
213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
214d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  void LoadContext(Register dst, int context_chain_length);
215d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // JavaScript invokes
218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Invoke the JavaScript function code by either calling or jumping.
220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void InvokeCode(Register code,
221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                  const ParameterCount& expected,
222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                  const ParameterCount& actual,
223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                  InvokeFlag flag);
224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void InvokeCode(Handle<Code> code,
226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                  const ParameterCount& expected,
227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                  const ParameterCount& actual,
228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                  RelocInfo::Mode rmode,
229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                  InvokeFlag flag);
230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Invoke the JavaScript function in the given register. Changes the
232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // current context to the context in the function before invoking.
233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void InvokeFunction(Register function,
234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                      const ParameterCount& actual,
235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                      InvokeFlag flag);
236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
237402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  void InvokeFunction(JSFunction* function,
238402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu                      const ParameterCount& actual,
239402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu                      InvokeFlag flag);
240402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT
243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Debugger Support
245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SaveRegistersToMemory(RegList regs);
247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void RestoreRegistersFromMemory(RegList regs);
248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void CopyRegistersFromMemoryToStack(Register base, RegList regs);
249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void CopyRegistersFromStackToMemory(Register base,
250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                      Register scratch,
251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                      RegList regs);
252402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  void DebugBreak();
253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Exception handling
257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Push a new try handler and link into try handler chain.
259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The return address must be passed in register lr.
260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // On exit, r0 contains TOS (code slot).
261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void PushTryHandler(CodeLocation try_location, HandlerType type);
262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
263e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Unlink the stack handler on top of the stack from the try handler chain.
264e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Must preserve the result register.
265e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  void PopTryHandler();
266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Inline caching support
269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Generates code that verifies that the maps of objects in the
271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // prototype chain of object hasn't changed since the code was
272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // generated and branches to the miss label if any map has. If
273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // necessary the function also generates code for security check
274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // in case of global object holders. The scratch and holder
275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // registers are always clobbered, but the object register is only
276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // clobbered if it the same as the holder register. The function
277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // returns a register containing the holder - either object_reg or
278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // holder_reg.
2796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // The function can optionally (when save_at_depth !=
2806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // kInvalidProtoDepth) save the object at the given depth by moving
2816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // it to [sp].
282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Register CheckMaps(JSObject* object, Register object_reg,
283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     JSObject* holder, Register holder_reg,
2846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                     Register scratch,
2856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                     int save_at_depth,
2866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                     Label* miss);
287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Generate code for checking access rights - used for security checks
289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // on access to global objects across environments. The holder register
290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // is left untouched, whereas both scratch registers are clobbered.
291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void CheckAccessGlobalProxy(Register holder_reg,
292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                              Register scratch,
293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                              Label* miss);
294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Allocation support
298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Allocate an object in new space. The object_size is specified in words (not
300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // bytes). If the new space is exhausted control continues at the gc_required
301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // label. The allocated object is returned in result. If the flag
30225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  // tag_allocated_object is true the result is tagged as as a heap object. All
30325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  // registers are clobbered also when control continues at the gc_required
30425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  // label.
305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void AllocateInNewSpace(int object_size,
306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Register result,
307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Register scratch1,
308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Register scratch2,
309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Label* gc_required,
310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          AllocationFlags flags);
311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void AllocateInNewSpace(Register object_size,
312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Register result,
313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Register scratch1,
314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Register scratch2,
315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Label* gc_required,
316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          AllocationFlags flags);
317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Undo allocation in new space. The object passed and objects allocated after
319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // it will no longer be allocated. The caller must make sure that no pointers
320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // are left to the object(s) no longer allocated as they would be invalid when
321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // allocation is undone.
322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void UndoAllocationInNewSpace(Register object, Register scratch);
323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3243100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
3253100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void AllocateTwoByteString(Register result,
3263100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                             Register length,
3273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                             Register scratch1,
3283100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                             Register scratch2,
3293100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                             Register scratch3,
3303100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                             Label* gc_required);
3313100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void AllocateAsciiString(Register result,
3323100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                           Register length,
3333100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                           Register scratch1,
3343100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                           Register scratch2,
3353100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                           Register scratch3,
3363100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                           Label* gc_required);
3373100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void AllocateTwoByteConsString(Register result,
3383100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                                 Register length,
3393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                                 Register scratch1,
3403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                                 Register scratch2,
3413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                                 Label* gc_required);
3423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void AllocateAsciiConsString(Register result,
3433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                               Register length,
3443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                               Register scratch1,
3453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                               Register scratch2,
3463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                               Label* gc_required);
3473100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
34825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  // Allocates a heap number or jumps to the gc_required label if the young
34925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  // space is full and a scavenge is needed. All registers are clobbered also
35025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  // when control continues at the gc_required label.
3516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void AllocateHeapNumber(Register result,
3526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                          Register scratch1,
3536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                          Register scratch2,
3546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                          Label* gc_required);
3553100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Support functions.
358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Try to get function prototype of a function and puts the value in
360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the result register. Checks that the function really is a
361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // function and jumps to the miss label if the fast checks fail. The
362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // function register will be untouched; the other registers may be
363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // clobbered.
364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void TryGetFunctionPrototype(Register function,
365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Register result,
366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Register scratch,
367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Label* miss);
368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compare object type for heap object.  heap_object contains a non-Smi
370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // whose object type should be compared with the given type.  This both
371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // sets the flags and leaves the object type in the type_reg register.
372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // It leaves the map in the map register (unless the type_reg and map register
373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // are the same register).  It leaves the heap object in the heap_object
374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // register unless the heap_object register is the same register as one of the
375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // other registers.
376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void CompareObjectType(Register heap_object,
377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                         Register map,
378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                         Register type_reg,
379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                         InstanceType type);
380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compare instance type in a map.  map contains a valid map object whose
382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // object type should be compared with the given type.  This both
383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // sets the flags and leaves the object type in the type_reg register.  It
384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // leaves the heap object in the heap_object register unless the heap_object
385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // register is the same register as type_reg.
386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void CompareInstanceType(Register map,
387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                           Register type_reg,
388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                           InstanceType type);
389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3903100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
3913100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // Check if the map of an object is equal to a specified map and
3923100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // branch to label if not. Skip the smi check if not required
3933100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // (object is known to be a heap object)
3943100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void CheckMap(Register obj,
3953100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                Register scratch,
3963100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                Handle<Map> map,
3973100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                Label* fail,
3983100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                bool is_heap_object);
3993100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
4003100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // Load and check the instance type of an object for being a string.
4013100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // Loads the type into the second argument register.
4023100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // Returns a condition that will be enabled if the object was a string.
4033100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  Condition IsObjectStringType(Register obj,
4043100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                               Register type) {
4053100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    ldr(type, FieldMemOperand(obj, HeapObject::kMapOffset));
4063100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    ldrb(type, FieldMemOperand(type, Map::kInstanceTypeOffset));
4073100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    tst(type, Operand(kIsNotStringMask));
4083100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    ASSERT_EQ(0, kStringTag);
4093100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    return eq;
4103100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  }
4113100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
4123100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void BranchOnSmi(Register value, Label* smi_label) {
414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    tst(value, Operand(kSmiTagMask));
415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    b(eq, smi_label);
416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  inline void BranchOnNotSmi(Register value, Label* not_smi_label) {
419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    tst(value, Operand(kSmiTagMask));
420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    b(ne, not_smi_label);
421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Generates code for reporting that an illegal operation has
424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // occurred.
425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void IllegalOperation(int num_arguments);
426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // Get the number of least significant bits from a register
4283100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void GetLeastBitsFromSmi(Register dst, Register src, int num_least_bits);
4293100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
430d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Uses VFP instructions to Convert a Smi to a double.
431d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  void IntegerToDoubleConversionWithVFP3(Register inReg,
432d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                         Register outHighReg,
433d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                         Register outLowReg);
434d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
4356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Count leading zeros in a 32 bit word.  On ARM5 and later it uses the clz
4366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // instruction.  On pre-ARM5 hardware this routine gives the wrong answer
4376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // for 0 (31 instead of 32).
4386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void CountLeadingZeros(Register source,
4396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                         Register scratch,
4406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                         Register zeros);
441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Runtime calls
444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Call a code stub.
446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void CallStub(CodeStub* stub, Condition cond = al);
447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4483100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // Call a code stub.
4493100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void TailCallStub(CodeStub* stub, Condition cond = al);
4503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Return from a code stub after popping its arguments.
452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void StubReturn(int argc);
453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Call a runtime routine.
455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void CallRuntime(Runtime::Function* f, int num_arguments);
456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Convenience function: Same as above, but takes the fid instead.
458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void CallRuntime(Runtime::FunctionId fid, int num_arguments);
459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
460402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // Convenience function: call an external reference.
461402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  void CallExternalReference(const ExternalReference& ext,
462402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu                             int num_arguments);
463402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Tail call of a runtime routine (jump).
4656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Like JumpToExternalReference, but also takes care of passing the number
466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // of parameters.
4676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void TailCallExternalReference(const ExternalReference& ext,
4686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                 int num_arguments,
4696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                 int result_size);
4706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
4716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Convenience function: tail call a runtime routine (jump).
4726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void TailCallRuntime(Runtime::FunctionId fid,
473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                       int num_arguments,
474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                       int result_size);
475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Before calling a C-function from generated code, align arguments on stack.
4776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // After aligning the frame, non-register arguments must be stored in
4786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // sp[0], sp[4], etc., not pushed. The argument count assumes all arguments
4796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // are word sized.
4806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Some compilers/platforms require the stack to be aligned when calling
4816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // C++ code.
4826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Needs a scratch register to do some arithmetic. This register will be
4836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // trashed.
4846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void PrepareCallCFunction(int num_arguments, Register scratch);
4856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
4866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Calls a C function and cleans up the space for arguments allocated
4876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // by PrepareCallCFunction. The called function is not allowed to trigger a
4886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // garbage collection, since that might move the code and invalidate the
4896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // return address (unless this is somehow accounted for by the called
4906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // function).
4916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void CallCFunction(ExternalReference function, int num_arguments);
4926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void CallCFunction(Register function, int num_arguments);
4936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Jump to a runtime routine.
4956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void JumpToExternalReference(const ExternalReference& builtin);
496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Invoke specified builtin JavaScript function. Adds an entry to
498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the unresolved list if the name does not resolve.
499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void InvokeBuiltin(Builtins::JavaScript id, InvokeJSFlags flags);
500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Store the code object for the given builtin in the target register and
502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // setup the function in r1.
503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void GetBuiltinEntry(Register target, Builtins::JavaScript id);
504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Object> CodeObject() { return code_object_; }
506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // StatsCounter support
510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SetCounter(StatsCounter* counter, int value,
512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                  Register scratch1, Register scratch2);
513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void IncrementCounter(StatsCounter* counter, int value,
514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                        Register scratch1, Register scratch2);
515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void DecrementCounter(StatsCounter* counter, int value,
516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                        Register scratch1, Register scratch2);
517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Debugging
521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Calls Abort(msg) if the condition cc is not satisfied.
523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Use --debug_code to enable.
524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Assert(Condition cc, const char* msg);
525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Like Assert(), but always enabled.
527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Check(Condition cc, const char* msg);
528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Print a message to stdout and abort execution.
530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Abort(const char* msg);
531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Verify restrictions about code generated in stubs.
533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void set_generating_stub(bool value) { generating_stub_ = value; }
534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool generating_stub() { return generating_stub_; }
535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void set_allow_stub_calls(bool value) { allow_stub_calls_ = value; }
536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool allow_stub_calls() { return allow_stub_calls_; }
537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
538d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // ---------------------------------------------------------------------------
5393100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // Smi utilities
5403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
5413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // Jump if either of the registers contain a non-smi.
5423100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void JumpIfNotBothSmi(Register reg1, Register reg2, Label* on_not_both_smi);
5433100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // Jump if either of the registers contain a smi.
5443100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void JumpIfEitherSmi(Register reg1, Register reg2, Label* on_either_smi);
5453100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
5463100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // ---------------------------------------------------------------------------
547d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // String utilities
548d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
549d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Checks if both objects are sequential ASCII strings and jumps to label
550d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // if either is not. Assumes that neither object is a smi.
551d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void JumpIfNonSmisNotBothSequentialAsciiStrings(Register object1,
552d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                                                  Register object2,
553d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                                                  Register scratch1,
554d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                                                  Register scratch2,
5556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                                  Label* failure);
556d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
557d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Checks if both objects are sequential ASCII strings and jumps to label
558d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // if either is not.
559d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void JumpIfNotBothSequentialAsciiStrings(Register first,
560d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                                           Register second,
561d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                                           Register scratch1,
562d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                                           Register scratch2,
563d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                                           Label* not_flat_ascii_strings);
564d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
5656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Checks if both instance types are sequential ASCII strings and jumps to
5666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // label if either is not.
5676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void JumpIfBothInstanceTypesAreNotSequentialAscii(
5686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      Register first_object_instance_type,
5696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      Register second_object_instance_type,
5706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      Register scratch1,
5716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      Register scratch2,
5726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      Label* failure);
5736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
5746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Check if instance type is sequential ASCII string and jump to label if
5756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // it is not.
5766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void JumpIfInstanceTypeIsNotSequentialAscii(Register type,
5776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                              Register scratch,
5786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                              Label* failure);
5796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
5806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
5823100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void Jump(intptr_t target, RelocInfo::Mode rmode, Condition cond = al);
5833100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void Call(intptr_t target, RelocInfo::Mode rmode, Condition cond = al);
584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Helper functions for generating invokes.
586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void InvokePrologue(const ParameterCount& expected,
587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                      const ParameterCount& actual,
588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                      Handle<Code> code_constant,
589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                      Register code_reg,
590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                      Label* done,
591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                      InvokeFlag flag);
592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Activation support.
594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void EnterFrame(StackFrame::Type type);
595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void LeaveFrame(StackFrame::Type type);
5963100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
5976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void InitializeNewString(Register string,
5986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                           Register length,
5996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                           Heap::RootListIndex map_index,
6006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                           Register scratch1,
6016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                           Register scratch2);
6026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
6033100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  bool generating_stub_;
6043100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  bool allow_stub_calls_;
6053100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // This handle will be patched with the code object on installation.
6063100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  Handle<Object> code_object_;
607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT
611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The code patcher is used to patch (typically) small parts of code e.g. for
612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// debugging and other types of instrumentation. When using the code patcher
613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// the exact number of bytes specified must be emitted. It is not legal to emit
614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// relocation information. If any of these constraints are violated it causes
615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// an assertion to fail.
616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass CodePatcher {
617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CodePatcher(byte* address, int instructions);
619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  virtual ~CodePatcher();
620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Macro assembler to emit code.
622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  MacroAssembler* masm() { return &masm_; }
623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emit an instruction directly.
625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Emit(Instr x);
626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Emit an address directly.
628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Emit(Address addr);
629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  byte* address_;  // The address of the code being patched.
632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int instructions_;  // Number of instructions of the expected patch size.
633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int size_;  // Number of bytes of the expected patch size.
634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  MacroAssembler masm_;  // Macro assembler used to generate the code.
635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif  // ENABLE_DEBUGGER_SUPPORT
637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// -----------------------------------------------------------------------------
640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Static helper functions.
641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef GENERATED_CODE_COVERAGE
643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CODE_COVERAGE_STRINGIFY(x) #x
644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x)
645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__)
646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define ACCESS_MASM(masm) masm->stop(__FILE_LINE__); masm->
647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#else
648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define ACCESS_MASM(masm) masm->
649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif  // V8_ARM_MACRO_ASSEMBLER_ARM_H_
655