13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 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_IA32_MACRO_ASSEMBLER_IA32_H_
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_IA32_MACRO_ASSEMBLER_IA32_H_
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "assembler.h"
323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "frames.h"
33257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "v8globals.h"
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen// Flags used for the AllocateInNewSpace functions.
3925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsenenum AllocationFlags {
4025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  // No special flags.
4125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  NO_ALLOCATION_FLAGS = 0,
4225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  // Return the pointer to the allocated already tagged as a heap object.
4325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  TAG_OBJECT = 1 << 0,
4425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  // The content of the result register already contains the allocation top in
4525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  // new space.
4625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  RESULT_CONTAINS_TOP = 1 << 1
4725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen};
4825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
49257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
50e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Convenience for platform-independent signatures.  We do not normally
51e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// distinguish memory operands from other operands on ia32.
52e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarketypedef Operand MemOperand;
53e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochenum RememberedSetAction { EMIT_REMEMBERED_SET, OMIT_REMEMBERED_SET };
553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochenum SmiCheck { INLINE_SMI_CHECK, OMIT_SMI_CHECK };
563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool AreAliased(Register r1, Register r2, Register r3, Register r4);
593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// MacroAssembler implements a collection of frequently used macros.
62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass MacroAssembler: public Assembler {
63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
648b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // The isolate parameter can be NULL if the macro assembler should
658b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // not use isolate-dependent functionality. In this case, it's the
668b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // responsibility of the caller to never invoke such function on the
678b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // macro assembler.
688b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  MacroAssembler(Isolate* isolate, void* buffer, int size);
69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // GC Support
723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  enum RememberedSetFinalAction {
733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kReturnAtEnd,
743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kFallThroughAtEnd
753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  };
763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Record in the remembered set the fact that we have a pointer to new space
783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // at the address pointed to by the addr register.  Only works if addr is not
793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // in new space.
803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void RememberedSetHelper(Register object,  // Used for debug code.
813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                           Register addr,
823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                           Register scratch,
833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                           SaveFPRegsMode save_fp,
843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                           RememberedSetFinalAction and_then);
853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void CheckPageFlag(Register object,
873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     Register scratch,
883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     int mask,
893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     Condition cc,
903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     Label* condition_met,
913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     Label::Distance condition_met_distance = Label::kFar);
923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Check if object is in new space.  Jumps if the object is not in new space.
943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // The register scratch can be object itself, but scratch will be clobbered.
953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void JumpIfNotInNewSpace(Register object,
963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                           Register scratch,
973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                           Label* branch,
983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                           Label::Distance distance = Label::kFar) {
993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    InNewSpace(object, scratch, zero, branch, distance);
1003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Check if object is in new space.  Jumps if the object is in new space.
1033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // The register scratch can be object itself, but it will be clobbered.
1043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void JumpIfInNewSpace(Register object,
1053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                        Register scratch,
1063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                        Label* branch,
1073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                        Label::Distance distance = Label::kFar) {
1083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    InNewSpace(object, scratch, not_zero, branch, distance);
1093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Check if an object has a given incremental marking color.  Also uses ecx!
1123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void HasColor(Register object,
1133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                Register scratch0,
1143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                Register scratch1,
1153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                Label* has_color,
1163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                Label::Distance has_color_distance,
1173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                int first_bit,
1183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                int second_bit);
1193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void JumpIfBlack(Register object,
1213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                   Register scratch0,
1223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                   Register scratch1,
1233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                   Label* on_black,
1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                   Label::Distance on_black_distance = Label::kFar);
1253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Checks the color of an object.  If the object is already grey or black
1273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // then we just fall through, since it is already live.  If it is white and
1283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // we can determine that it doesn't need to be scanned, then we just mark it
1293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // black and fall through.  For the rest we jump to the label so the
1303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // incremental marker can fix its assumptions.
1313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void EnsureNotWhite(Register object,
1323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      Register scratch1,
1333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      Register scratch2,
1343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      Label* object_is_white_and_not_data,
1353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      Label::Distance distance);
1363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Notify the garbage collector that we wrote a pointer into an object.
1383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // |object| is the object being stored into, |value| is the object being
1393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // stored.  value and scratch registers are clobbered by the operation.
1403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // The offset is the offset from the start of the object, not the offset from
1413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // the tagged HeapObject pointer.  For use with FieldOperand(reg, off).
1423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void RecordWriteField(
1433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Register object,
1443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      int offset,
1453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Register value,
1463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Register scratch,
1473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      SaveFPRegsMode save_fp,
1483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
1493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      SmiCheck smi_check = INLINE_SMI_CHECK);
1503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // As above, but the offset has the tag presubtracted.  For use with
1523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Operand(reg, off).
1533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void RecordWriteContextSlot(
1543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Register context,
1553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      int offset,
1563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Register value,
1573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Register scratch,
1583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      SaveFPRegsMode save_fp,
1593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
1603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      SmiCheck smi_check = INLINE_SMI_CHECK) {
1613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    RecordWriteField(context,
1623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     offset + kHeapObjectTag,
1633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     value,
1643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     scratch,
1653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     save_fp,
1663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     remembered_set_action,
1673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     smi_check);
1683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Notify the garbage collector that we wrote a pointer into a fixed array.
1713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // |array| is the array being stored into, |value| is the
1723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // object being stored.  |index| is the array index represented as a
1733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Smi. All registers are clobbered by the operation RecordWriteArray
1748defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // filters out smis so it does not update the write barrier if the
1758defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // value is a smi.
1763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void RecordWriteArray(
1773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Register array,
1783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Register value,
1793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Register index,
1803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      SaveFPRegsMode save_fp,
1813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
1823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      SmiCheck smi_check = INLINE_SMI_CHECK);
183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1848defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // For page containing |object| mark region covering |address|
1858defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // dirty. |object| is the object being stored into, |value| is the
1863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // object being stored. The address and value registers are clobbered by the
1878defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // operation. RecordWrite filters out smis so it does not update the
1888defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // write barrier if the value is a smi.
1893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void RecordWrite(
1903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Register object,
1913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Register address,
1923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Register value,
1933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      SaveFPRegsMode save_fp,
1943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
1953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      SmiCheck smi_check = INLINE_SMI_CHECK);
1968defd9ff6930b4e24729971a61cf7469daf119beSteve Block
197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT
198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Debugger Support
200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
201402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  void DebugBreak();
202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
204b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Enter specific kind of exit frame. Expects the number of
205b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // arguments in register eax and sets up the number of arguments in
206b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // register edi and the pointer to the first argument in register
207b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // esi.
208b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void EnterExitFrame(bool save_doubles);
209d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
2108a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  void EnterApiExitFrame(int argc);
211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Leave the current exit frame. Expects the return value in
213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // register eax:edx (untouched) and the pointer to the first
214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // argument in register esi.
215b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void LeaveExitFrame(bool save_doubles);
216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2178a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // Leave the current exit frame. Expects the return value in
2188a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // register eax (untouched).
2198a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  void LeaveApiExitFrame();
2208a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
221d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Find the function context up the context chain.
222d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  void LoadContext(Register dst, int context_chain_length);
223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Conditionally load the cached Array transitioned map of type
2253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // transitioned_kind from the global context if the map in register
2263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // map_in_out is the cached Array map in the global context of
2273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // expected_kind.
2283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void LoadTransitionedArrayMapConditional(
2293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      ElementsKind expected_kind,
2303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      ElementsKind transitioned_kind,
2313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Register map_in_out,
2323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Register scratch,
2333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Label* no_map_match);
2343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Load the initial map for new Arrays from a JSFunction.
2363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void LoadInitialArrayMap(Register function_in,
2373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                           Register scratch,
2383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                           Register map_out);
2393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
24080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // Load the global function with the given index.
24180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  void LoadGlobalFunction(int index, Register function);
24280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
24380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // Load the initial map from the global function. The registers
24480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // function and map can be the same.
24580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  void LoadGlobalFunctionInitialMap(Register function, Register map);
24680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
247b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Push and pop the registers that can hold pointers.
248b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void PushSafepointRegisters() { pushad(); }
249b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void PopSafepointRegisters() { popad(); }
250e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // Store the value in register/immediate src in the safepoint
251e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // register stack slot for register dst.
252e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void StoreToSafepointRegisterSlot(Register dst, Register src);
253e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void StoreToSafepointRegisterSlot(Register dst, Immediate src);
254e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void LoadFromSafepointRegisterSlot(Register dst, Register src);
255b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void LoadHeapObject(Register result, Handle<HeapObject> object);
2573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void PushHeapObject(Handle<HeapObject> object);
2583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void LoadObject(Register result, Handle<Object> object) {
2603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (object->IsHeapObject()) {
2613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      LoadHeapObject(result, Handle<HeapObject>::cast(object));
2623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    } else {
2633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Set(result, Immediate(object));
2643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
2653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // JavaScript invokes
269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Set up call kind marking in ecx. The method takes ecx as an
271257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // explicit first parameter to make the code more readable at the
272257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // call sites.
273257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void SetCallKind(Register dst, CallKind kind);
274257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Invoke the JavaScript function code by either calling or jumping.
2763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void InvokeCode(Register code,
2773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                  const ParameterCount& expected,
2783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                  const ParameterCount& actual,
2793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                  InvokeFlag flag,
2803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                  const CallWrapper& call_wrapper,
2813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                  CallKind call_kind) {
2823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    InvokeCode(Operand(code), expected, actual, flag, call_wrapper, call_kind);
2833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void InvokeCode(const Operand& code,
286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                  const ParameterCount& expected,
287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                  const ParameterCount& actual,
288b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                  InvokeFlag flag,
289257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                  const CallWrapper& call_wrapper,
290257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                  CallKind call_kind);
291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void InvokeCode(Handle<Code> code,
293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                  const ParameterCount& expected,
294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                  const ParameterCount& actual,
295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                  RelocInfo::Mode rmode,
296b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                  InvokeFlag flag,
297257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                  const CallWrapper& call_wrapper,
298257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                  CallKind call_kind);
299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Invoke the JavaScript function in the given register. Changes the
301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // current context to the context in the function before invoking.
302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void InvokeFunction(Register function,
303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                      const ParameterCount& actual,
304b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                      InvokeFlag flag,
305257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                      const CallWrapper& call_wrapper,
306257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                      CallKind call_kind);
307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void InvokeFunction(Handle<JSFunction> function,
309402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu                      const ParameterCount& actual,
310b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                      InvokeFlag flag,
311257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                      const CallWrapper& call_wrapper,
312257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                      CallKind call_kind);
313402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Invoke specified builtin JavaScript function. Adds an entry to
315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the unresolved list if the name does not resolve.
316b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void InvokeBuiltin(Builtins::JavaScript id,
317b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                     InvokeFlag flag,
318257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                     const CallWrapper& call_wrapper = NullCallWrapper());
319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
320791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block  // Store the function for the given builtin in the target register.
321791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block  void GetBuiltinFunction(Register target, Builtins::JavaScript id);
322791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block
323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Store the code object for the given builtin in the target register.
324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void GetBuiltinEntry(Register target, Builtins::JavaScript id);
325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Expression support
327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Set(Register dst, const Immediate& x);
328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Set(const Operand& dst, const Immediate& x);
329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
330053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block  // Support for constant splitting.
331053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block  bool IsUnsafeImmediate(const Immediate& x);
332053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block  void SafeSet(Register dst, const Immediate& x);
333053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block  void SafePush(const Immediate& x);
334053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block
3353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Compare against a known root, e.g. undefined, null, true, ...
33669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  void CompareRoot(Register with, Heap::RootListIndex index);
3373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void CompareRoot(const Operand& with, Heap::RootListIndex index);
33869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compare object type for heap object.
340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Incoming register is heap_object and outgoing register is map.
341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void CmpObjectType(Register heap_object, InstanceType type, Register map);
342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compare instance type for map.
344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void CmpInstanceType(Register map, InstanceType type);
345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Check if a map for a JSObject indicates that the object has fast elements.
3473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Jump to the specified label if it does not.
3483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void CheckFastElements(Register map,
3493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                         Label* fail,
3503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                         Label::Distance distance = Label::kFar);
3513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
3523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Check if a map for a JSObject indicates that the object can have both smi
3533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // and HeapObject elements.  Jump to the specified label if it does not.
3543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void CheckFastObjectElements(Register map,
3553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               Label* fail,
3563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               Label::Distance distance = Label::kFar);
3573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Check if a map for a JSObject indicates that the object has fast smi only
3593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // elements.  Jump to the specified label if it does not.
3603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void CheckFastSmiOnlyElements(Register map,
3613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                Label* fail,
3623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                Label::Distance distance = Label::kFar);
3633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Check to see if maybe_number can be stored as a double in
3653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // FastDoubleElements. If it can, store it at the index specified by key in
3663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // the FastDoubleElements array elements, otherwise jump to fail.
3673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void StoreNumberToDoubleElements(Register maybe_number,
3683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Register elements,
3693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Register key,
3703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Register scratch1,
3713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   XMMRegister scratch2,
3723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Label* fail,
3733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   bool specialize_for_processor);
3743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Compare an object's map with the specified map and its transitioned
3763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // elements maps if mode is ALLOW_ELEMENT_TRANSITION_MAPS. FLAGS are set with
3773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // result of map compare. If multiple map compares are required, the compare
3783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // sequences branches to early_success.
3793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void CompareMap(Register obj,
3803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                  Handle<Map> map,
3813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                  Label* early_success,
3823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                  CompareMapMode mode = REQUIRE_EXACT_MAP);
3833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
384257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Check if the map of an object is equal to a specified map and branch to
385257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // label if not. Skip the smi check if not required (object is known to be a
3863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // heap object). If mode is ALLOW_ELEMENT_TRANSITION_MAPS, then also match
3873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // against maps that are ElementsKind transition maps of the specified map.
3883100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void CheckMap(Register obj,
3893100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                Handle<Map> map,
3903100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                Label* fail,
3913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                SmiCheckType smi_check_type,
3923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                CompareMapMode mode = REQUIRE_EXACT_MAP);
393257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
394257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Check if the map of an object is equal to a specified map and branch to a
395257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // specified target if equal. Skip the smi check if not required (object is
396257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // known to be a heap object)
397257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void DispatchMap(Register obj,
398257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                   Handle<Map> map,
399257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                   Handle<Code> success,
400257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                   SmiCheckType smi_check_type);
4013100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
402e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Check if the object in register heap_object is a string. Afterwards the
403e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // register map contains the object map and the register instance_type
404e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // contains the instance_type. The registers map and instance_type can be the
405e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // same in which case it contains the instance type afterwards. Either of the
406e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // registers map and instance_type can be the same as heap_object.
407e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  Condition IsObjectStringType(Register heap_object,
408e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke                               Register map,
409e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke                               Register instance_type);
410e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
4117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Check if a heap object's type is in the JSObject range, not including
4127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // JSFunction.  The object's map will be loaded in the map register.
4137f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Any or all of the three registers may be the same.
4147f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // The contents of the scratch register will always be overwritten.
4157f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  void IsObjectJSObjectType(Register heap_object,
4167f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                            Register map,
4177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                            Register scratch,
4187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                            Label* fail);
4197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
4207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // The contents of the scratch register will be overwritten.
4217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  void IsInstanceJSObjectType(Register map, Register scratch, Label* fail);
4227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // FCmp is similar to integer cmp, but requires unsigned
424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // jcc instructions (je, ja, jae, jb, jbe, je, and jz).
425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void FCmp();
426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
427257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void ClampUint8(Register reg);
428257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
429257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void ClampDoubleToUint8(XMMRegister input_reg,
430257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                          XMMRegister scratch_reg,
431257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                          Register result_reg);
432257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
433257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
434e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Smi tagging support.
435e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  void SmiTag(Register reg) {
43669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    STATIC_ASSERT(kSmiTag == 0);
43769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    STATIC_ASSERT(kSmiTagSize == 1);
4383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    add(reg, reg);
439e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
440e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  void SmiUntag(Register reg) {
441e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    sar(reg, kSmiTagSize);
442e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
443e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
444756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  // Modifies the register even if it does not contain a Smi!
445756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  void SmiUntag(Register reg, Label* is_smi) {
44669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    STATIC_ASSERT(kSmiTagSize == 1);
447756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    sar(reg, kSmiTagSize);
44869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    STATIC_ASSERT(kSmiTag == 0);
449756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    j(not_carry, is_smi);
450756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  }
451756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
4521e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Jump the register contains a smi.
4533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  inline void JumpIfSmi(Register value,
4543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                        Label* smi_label,
4553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                        Label::Distance distance = Label::kFar) {
4563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    test(value, Immediate(kSmiTagMask));
4573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    j(zero, smi_label, distance);
4583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
4593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Jump if the operand is a smi.
4603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  inline void JumpIfSmi(Operand value,
4613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                        Label* smi_label,
4623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                        Label::Distance distance = Label::kFar) {
4631e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    test(value, Immediate(kSmiTagMask));
4643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    j(zero, smi_label, distance);
4651e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
4661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Jump if register contain a non-smi.
4673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  inline void JumpIfNotSmi(Register value,
4683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                           Label* not_smi_label,
4693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                           Label::Distance distance = Label::kFar) {
4701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    test(value, Immediate(kSmiTagMask));
4713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    j(not_zero, not_smi_label, distance);
4721e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
4731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
474257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void LoadInstanceDescriptors(Register map, Register descriptors);
475756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
4760d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  void LoadPowerOf2(XMMRegister dst, Register scratch, int power);
4770d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
478402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // Abort execution if argument is not a number. Used in debug code.
4796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void AbortIfNotNumber(Register object);
4806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
4816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Abort execution if argument is not a smi. Used in debug code.
4826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void AbortIfNotSmi(Register object);
483402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
484756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  // Abort execution if argument is a smi. Used in debug code.
485756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  void AbortIfSmi(Register object);
486756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
48780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // Abort execution if argument is a string. Used in debug code.
48880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  void AbortIfNotString(Register object);
48980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Exception handling
492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Push a new try handler and link it into try handler chain.
4943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void PushTryHandler(StackHandler::Kind kind, int handler_index);
495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
496e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Unlink the stack handler on top of the stack from the try handler chain.
497e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  void PopTryHandler();
498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Throw to the top handler in the try hander chain.
500e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void Throw(Register value);
501e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
5023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Throw past all JS frames to the top JS entry frame.
5033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void ThrowUncatchable(Register value);
504e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Inline caching support
507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Generate code for checking access rights - used for security checks
509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // on access to global objects across environments. The holder register
510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // is left untouched, but the scratch register is clobbered.
511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void CheckAccessGlobalProxy(Register holder_reg,
512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                              Register scratch,
513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                              Label* miss);
514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
515c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  void GetNumberHash(Register r0, Register scratch);
516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void LoadFromNumberDictionary(Label* miss,
5183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                Register elements,
5193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                Register key,
5203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                Register r0,
5213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                Register r1,
5223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                Register r2,
5233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                Register result);
5243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
5253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Allocation support
528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Allocate an object in new space. If the new space is exhausted control
530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // continues at the gc_required label. The allocated object is returned in
531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // result and end of the new object is returned in result_end. The register
532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // scratch can be passed as no_reg in which case an additional object
533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // reference will be added to the reloc info. The returned pointers in result
534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // and result_end have not yet been tagged as heap objects. If
535d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // result_contains_top_on_entry is true the content of result is known to be
536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the allocation top on entry (could be result_end from a previous call to
537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // AllocateInNewSpace). If result_contains_top_on_entry is true scratch
538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // should be no_reg as it is never used.
539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void AllocateInNewSpace(int object_size,
540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Register result,
541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Register result_end,
542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Register scratch,
543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Label* gc_required,
544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          AllocationFlags flags);
545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void AllocateInNewSpace(int header_size,
547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          ScaleFactor element_size,
548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Register element_count,
549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Register result,
550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Register result_end,
551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Register scratch,
552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Label* gc_required,
553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          AllocationFlags flags);
554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void AllocateInNewSpace(Register object_size,
556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Register result,
557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Register result_end,
558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Register scratch,
559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Label* gc_required,
560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          AllocationFlags flags);
561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Undo allocation in new space. The object passed and objects allocated after
563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // it will no longer be allocated. Make sure that no pointers are left to the
564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // object(s) no longer allocated as they would be invalid when allocation is
565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // un-done.
566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void UndoAllocationInNewSpace(Register object);
567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5683ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Allocate a heap number in new space with undefined value. The
5693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // register scratch2 can be passed as no_reg; the others must be
5703ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // valid registers. Returns tagged pointer in result register, or
5713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // jumps to gc_required if new space is full.
5723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void AllocateHeapNumber(Register result,
5733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block                          Register scratch1,
5743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block                          Register scratch2,
5753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block                          Label* gc_required);
5763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
577d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Allocate a sequential string. All the header fields of the string object
578d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // are initialized.
579d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  void AllocateTwoByteString(Register result,
580d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                             Register length,
581d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                             Register scratch1,
582d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                             Register scratch2,
583d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                             Register scratch3,
584d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                             Label* gc_required);
585d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  void AllocateAsciiString(Register result,
586d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                           Register length,
587d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                           Register scratch1,
588d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                           Register scratch2,
589d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                           Register scratch3,
590d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                           Label* gc_required);
5919ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  void AllocateAsciiString(Register result,
5929ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick                           int length,
5939ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick                           Register scratch1,
5949ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick                           Register scratch2,
5959ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick                           Label* gc_required);
596d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
597d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Allocate a raw cons string object. Only the map field of the result is
598d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // initialized.
599589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  void AllocateTwoByteConsString(Register result,
600d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                          Register scratch1,
601d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                          Register scratch2,
602d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                          Label* gc_required);
603d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  void AllocateAsciiConsString(Register result,
604d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                               Register scratch1,
605d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                               Register scratch2,
606d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                               Label* gc_required);
607d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
60869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // Allocate a raw sliced string object. Only the map field of the result is
60969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // initialized.
610589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  void AllocateTwoByteSlicedString(Register result,
61169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch                            Register scratch1,
61269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch                            Register scratch2,
61369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch                            Label* gc_required);
61469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  void AllocateAsciiSlicedString(Register result,
61569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch                                 Register scratch1,
61669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch                                 Register scratch2,
61769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch                                 Label* gc_required);
61869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
619b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  // Copy memory, byte-by-byte, from source to destination.  Not optimized for
620b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  // long or aligned copies.
621b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  // The contents of index and scratch are destroyed.
622b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch  void CopyBytes(Register source,
623b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch                 Register destination,
624b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch                 Register length,
625b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch                 Register scratch);
6268a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
6273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Initialize fields with filler values.  Fields starting at |start_offset|
6283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // not including end_offset are overwritten with the value in |filler|.  At
6293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // the end the loop, |start_offset| takes the value of |end_offset|.
6303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void InitializeFieldsWithFiller(Register start_offset,
6313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                  Register end_offset,
6323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                  Register filler);
6333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Support functions.
636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Check a boolean-bit of a Smi field.
6383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void BooleanBitTest(Register object, int field_offset, int bit_index);
6393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check if result is zero and op is negative.
641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void NegativeZeroTest(Register result, Register op, Label* then_label);
642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check if result is zero and any of op1 and op2 are negative.
644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Register scratch is destroyed, and it must be different from op2.
645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void NegativeZeroTest(Register result, Register op1, Register op2,
646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                        Register scratch, Label* then_label);
647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Try to get function prototype of a function and puts the value in
649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the result register. Checks that the function really is a
650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // function and jumps to the miss label if the fast checks fail. The
651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // function register will be untouched; the other registers may be
652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // clobbered.
653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void TryGetFunctionPrototype(Register function,
654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Register result,
655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Register scratch,
6563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               Label* miss,
6573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               bool miss_on_bound_function = false);
658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Generates code for reporting that an illegal operation has
660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // occurred.
661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void IllegalOperation(int num_arguments);
662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
66380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // Picks out an array index from the hash field.
66480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // Register use:
66580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  //   hash - holds the index's hash. Clobbered.
66680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  //   index - holds the overwritten index on exit.
66780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  void IndexFromHash(Register hash, Register index);
66880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Runtime calls
671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
672e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Call a code stub.  Generate the code if necessary.
673257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void CallStub(CodeStub* stub, unsigned ast_id = kNoASTId);
674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
675e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Tail call a code stub (jump).  Generate the code if necessary.
676d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  void TailCallStub(CodeStub* stub);
677d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Return from a code stub after popping its arguments.
679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void StubReturn(int argc);
680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Call a runtime routine.
68244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void CallRuntime(const Runtime::Function* f, int num_arguments);
683b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void CallRuntimeSaveDoubles(Runtime::FunctionId id);
684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Convenience function: Same as above, but takes the fid instead.
686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void CallRuntime(Runtime::FunctionId id, int num_arguments);
687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
688bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  // Convenience function: call an external reference.
689bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  void CallExternalReference(ExternalReference ref, int num_arguments);
690bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch
691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Tail call of a runtime routine (jump).
6926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Like JumpToExternalReference, but also takes care of passing the number
6936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // of parameters.
6946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void TailCallExternalReference(const ExternalReference& ext,
6956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                 int num_arguments,
6966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                 int result_size);
6976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
6986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Convenience function: tail call a runtime routine (jump).
6996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void TailCallRuntime(Runtime::FunctionId fid,
700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                       int num_arguments,
701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                       int result_size);
702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Before calling a C-function from generated code, align arguments on stack.
7046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // After aligning the frame, arguments must be stored in esp[0], esp[4],
7056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // etc., not pushed. The argument count assumes all arguments are word sized.
7066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Some compilers/platforms require the stack to be aligned when calling
7076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // C++ code.
7086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Needs a scratch register to do some arithmetic. This register will be
7096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // trashed.
7106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void PrepareCallCFunction(int num_arguments, Register scratch);
7116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
7126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Calls a C function and cleans up the space for arguments allocated
7136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // by PrepareCallCFunction. The called function is not allowed to trigger a
7146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // garbage collection, since that might move the code and invalidate the
7156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // return address (unless this is somehow accounted for by the called
7166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // function).
7176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void CallCFunction(ExternalReference function, int num_arguments);
7186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void CallCFunction(Register function, int num_arguments);
7196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
7205913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  // Prepares stack to put arguments (aligns and so on). Reserves
7215913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  // space for return value if needed (assumes the return value is a handle).
7223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Arguments must be stored in ApiParameterOperand(0), ApiParameterOperand(1)
7233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // etc. Saves context (esi). If space was reserved for return value then
7243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // stores the pointer to the reserved slot into esi.
7253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void PrepareCallApiFunction(int argc);
726d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
7273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Calls an API function.  Allocates HandleScope, extracts returned value
7283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // from handle and propagates exceptions.  Clobbers ebx, edi and
7293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // caller-save registers.  Restores context.  On return removes
7303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // stack_space * kPointerSize (GCed).
7313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void CallApiFunctionAndReturn(Address function_address, int stack_space);
732e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Jump to a runtime routine.
7346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void JumpToExternalReference(const ExternalReference& ext);
735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Utilities
738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Ret();
740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Return and drop arguments from stack, where the number of arguments
7421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // may be bigger than 2^16 - 1.  Requires a scratch register.
7431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void Ret(int bytes_dropped, Register scratch);
7441e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
745e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Emit code to discard a non-negative number of pointer-sized elements
746e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // from the stack, clobbering only the esp register.
747e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  void Drop(int element_count);
748e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
749e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  void Call(Label* target) { call(target); }
750e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
751b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Emit call to the code we are currently generating.
752b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void CallSelf() {
753b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    Handle<Code> self(reinterpret_cast<Code**>(CodeObject().location()));
754b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    call(self, RelocInfo::CODE_TARGET);
755b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
756b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
7570d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // Move if the registers are not identical.
7580d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  void Move(Register target, Register source);
7590d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
7603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Push a handle value.
7613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void Push(Handle<Object> handle) { push(Immediate(handle)); }
7623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
7638b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Handle<Object> CodeObject() {
7648b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    ASSERT(!code_object_.is_null());
7658b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    return code_object_;
7668b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  }
767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // StatsCounter support
771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SetCounter(StatsCounter* counter, int value);
773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void IncrementCounter(StatsCounter* counter, int value);
774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void DecrementCounter(StatsCounter* counter, int value);
775d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void IncrementCounter(Condition cc, StatsCounter* counter, int value);
776d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void DecrementCounter(Condition cc, StatsCounter* counter, int value);
777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Debugging
781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Calls Abort(msg) if the condition cc is not satisfied.
783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Use --debug_code to enable.
784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Assert(Condition cc, const char* msg);
785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
786756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  void AssertFastElements(Register elements);
787756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Like Assert(), but always enabled.
789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Check(Condition cc, const char* msg);
790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Print a message to stdout and abort execution.
792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Abort(const char* msg);
793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Check that the stack is aligned.
7956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void CheckStackAlignment();
7966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Verify restrictions about code generated in stubs.
798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void set_generating_stub(bool value) { generating_stub_ = value; }
799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool generating_stub() { return generating_stub_; }
800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void set_allow_stub_calls(bool value) { allow_stub_calls_ = value; }
801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool allow_stub_calls() { return allow_stub_calls_; }
8023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void set_has_frame(bool value) { has_frame_ = value; }
8033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool has_frame() { return has_frame_; }
8043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline bool AllowThisStubCall(CodeStub* stub);
805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
806d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // ---------------------------------------------------------------------------
807d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // String utilities.
808d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
8093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Check whether the instance type represents a flat ASCII string. Jump to the
810402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // label if not. If the instance type can be scratched specify same register
811402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // for both instance type and scratch.
812402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  void JumpIfInstanceTypeIsNotSequentialAscii(Register instance_type,
813402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu                                              Register scratch,
8146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                              Label* on_not_flat_ascii_string);
815402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
816d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Checks if both objects are sequential ASCII strings, and jumps to label
817d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // if either is not.
818d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void JumpIfNotBothSequentialAsciiStrings(Register object1,
819d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                                           Register object2,
820d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                                           Register scratch1,
821d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                                           Register scratch2,
8226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                           Label* on_not_flat_ascii_strings);
823d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
8248b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  static int SafepointRegisterStackIndex(Register reg) {
8258b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    return SafepointRegisterStackIndex(reg.code());
8268b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  }
8278b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
8283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Activation support.
8293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void EnterFrame(StackFrame::Type type);
8303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void LeaveFrame(StackFrame::Type type);
8313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Expects object in eax and returns map with validated enum cache
8333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // in eax.  Assumes that any other register can be used as a scratch.
8343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void CheckEnumCache(Label* call_runtime);
8353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool generating_stub_;
838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool allow_stub_calls_;
8393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool has_frame_;
8403100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // This handle will be patched with the code object on installation.
8413100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  Handle<Object> code_object_;
842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Helper functions for generating invokes.
844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void InvokePrologue(const ParameterCount& expected,
845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                      const ParameterCount& actual,
846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                      Handle<Code> code_constant,
847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                      const Operand& code_operand,
848257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                      Label* done,
8493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      bool* definitely_mismatches,
850b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                      InvokeFlag flag,
8513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      Label::Distance done_distance,
852257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                      const CallWrapper& call_wrapper = NullCallWrapper(),
853257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                      CallKind call_kind = CALL_AS_METHOD);
854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
85580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  void EnterExitFramePrologue();
856b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void EnterExitFrameEpilogue(int argc, bool save_doubles);
857d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
8588a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  void LeaveExitFrameEpilogue();
8598a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Allocation support helpers.
861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void LoadAllocationTopHelper(Register result,
862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Register scratch,
863a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               AllocationFlags flags);
864a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void UpdateAllocationTopHelper(Register result_end, Register scratch);
865e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
866e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Helper for PopHandleScope.  Allowed to perform a GC and returns
867e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // NULL if gc_allowed.  Does not perform a GC if !gc_allowed, and
868e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // possibly returns a failure object indicating an allocation failure.
8695913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* PopHandleScopeHelper(Register saved,
8705913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                                    Register scratch,
8715913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                                    bool gc_allowed);
872e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
8733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Helper for implementing JumpIfNotInNewSpace and JumpIfInNewSpace.
8743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void InNewSpace(Register object,
8753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                  Register scratch,
8763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                  Condition cc,
8773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                  Label* condition_met,
8783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                  Label::Distance condition_met_distance = Label::kFar);
8793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Helper for finding the mark bits for an address.  Afterwards, the
8813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // bitmap register points at the word with the mark bits and the mask
8823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // the position of the first bit.  Uses ecx as scratch and leaves addr_reg
8833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // unchanged.
8843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void GetMarkBits(Register addr_reg,
8853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                          Register bitmap_reg,
8863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                          Register mask_reg);
8873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Helper for throwing exceptions.  Compute a handler address and jump to
8893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // it.  See the implementation for register usage.
8903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void JumpToHandlerEntry();
891e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
892e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // Compute memory operands for safepoint stack slots.
893e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  Operand SafepointRegisterSlot(Register reg);
894e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  static int SafepointRegisterStackIndex(int reg_code);
895e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
896e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // Needs access to SafepointRegisterStackIndex for optimized frame
897e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // traversal.
898e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  friend class OptimizedFrame;
899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The code patcher is used to patch (typically) small parts of code e.g. for
903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// debugging and other types of instrumentation. When using the code patcher
904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// the exact number of bytes specified must be emitted. Is not legal to emit
905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// relocation information. If any of these constraints are violated it causes
906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// an assertion.
907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass CodePatcher {
908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CodePatcher(byte* address, int size);
910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  virtual ~CodePatcher();
911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Macro assembler to emit code.
913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  MacroAssembler* masm() { return &masm_; }
914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  byte* address_;  // The address of the code being patched.
917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int size_;  // Number of bytes of the expected patch size.
918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  MacroAssembler masm_;  // Macro assembler used to generate the code.
919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// -----------------------------------------------------------------------------
923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Static helper functions.
924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Generate an Operand for loading a field from an object.
9263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochinline Operand FieldOperand(Register object, int offset) {
927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Operand(object, offset - kHeapObjectTag);
928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Generate an Operand for loading an indexed field from an object.
9323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochinline Operand FieldOperand(Register object,
9333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                            Register index,
9343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                            ScaleFactor scale,
9353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                            int offset) {
936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Operand(object, index, scale, offset - kHeapObjectTag);
937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
9398a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
9403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochinline Operand ContextOperand(Register context, int index) {
9418a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  return Operand(context, Context::SlotOffset(index));
9428a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
9438a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
9448a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
9453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochinline Operand GlobalObjectOperand() {
9468a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  return ContextOperand(esi, Context::GLOBAL_INDEX);
9478a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
9488a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
9498a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
9505913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck// Generates an Operand for saving parameters after PrepareCallApiFunction.
9515913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckOperand ApiParameterOperand(int index);
9525913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck
953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef GENERATED_CODE_COVERAGE
955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockextern void LogGeneratedCodeCoverage(const char* file_line);
956a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CODE_COVERAGE_STRINGIFY(x) #x
957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x)
958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__)
959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define ACCESS_MASM(masm) {                                               \
960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    byte* ia32_coverage_function =                                        \
961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        reinterpret_cast<byte*>(FUNCTION_ADDR(LogGeneratedCodeCoverage)); \
962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    masm->pushfd();                                                       \
963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    masm->pushad();                                                       \
964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    masm->push(Immediate(reinterpret_cast<int>(&__FILE_LINE__)));         \
965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    masm->call(ia32_coverage_function, RelocInfo::RUNTIME_ENTRY);         \
966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    masm->pop(eax);                                                       \
967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    masm->popad();                                                        \
968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    masm->popfd();                                                        \
969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }                                                                       \
970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  masm->
971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#else
972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define ACCESS_MASM(masm) masm->
973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif  // V8_IA32_MACRO_ASSEMBLER_IA32_H_
979