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_X64_MACRO_ASSEMBLER_X64_H_
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_X64_MACRO_ASSEMBLER_X64_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
50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Default scratch register used by MacroAssembler (and other code that needs
51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// a spare register). The register isn't callee save, and not used by the
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// function calling convention.
533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst Register kScratchRegister = { 10 };      // r10.
543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst Register kSmiConstantRegister = { 12 };  // r12 (callee save).
553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst Register kRootRegister = { 13 };         // r13 (callee save).
568defd9ff6930b4e24729971a61cf7469daf119beSteve Block// Value of smi in kSmiConstantRegister.
573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kSmiConstantRegisterValue = 1;
58e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// Actual value of root register is offset from the root array's start
59e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// to take advantage of negitive 8-bit displacement values.
603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int kRootRegisterBias = 128;
61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
62e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Convenience for platform-independent signatures.
63e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarketypedef Operand MemOperand;
64e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochenum RememberedSetAction { EMIT_REMEMBERED_SET, OMIT_REMEMBERED_SET };
663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochenum SmiCheck { INLINE_SMI_CHECK, OMIT_SMI_CHECK };
673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool AreAliased(Register r1, Register r2, Register r3, Register r4);
693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Forward declaration.
71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass JumpTarget;
72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstruct SmiIndex {
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  SmiIndex(Register index_register, ScaleFactor scale)
75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      : reg(index_register),
76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        scale(scale) {}
77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Register reg;
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ScaleFactor scale;
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// MacroAssembler implements a collection of frequently used macros.
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass MacroAssembler: public Assembler {
84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
858b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // The isolate parameter can be NULL if the macro assembler should
868b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // not use isolate-dependent functionality. In this case, it's the
878b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // responsibility of the caller to never invoke such function on the
888b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // macro assembler.
898b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  MacroAssembler(Isolate* isolate, void* buffer, int size);
90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
9144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Prevent the use of the RootArray during the lifetime of this
9244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // scope object.
9344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  class NoRootArrayScope BASE_EMBEDDED {
9444f0eee88ff00398ff7f715fab053374d808c90dSteve Block   public:
9544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    explicit NoRootArrayScope(MacroAssembler* assembler)
9644f0eee88ff00398ff7f715fab053374d808c90dSteve Block        : variable_(&assembler->root_array_available_),
9744f0eee88ff00398ff7f715fab053374d808c90dSteve Block          old_value_(assembler->root_array_available_) {
9844f0eee88ff00398ff7f715fab053374d808c90dSteve Block      assembler->root_array_available_ = false;
9944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    }
10044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ~NoRootArrayScope() {
10144f0eee88ff00398ff7f715fab053374d808c90dSteve Block      *variable_ = old_value_;
10244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    }
10344f0eee88ff00398ff7f715fab053374d808c90dSteve Block   private:
10444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    bool* variable_;
10544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    bool old_value_;
10644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  };
10744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
10844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Operand pointing to an external reference.
10944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // May emit code to set up the scratch register. The operand is
11044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // only guaranteed to be correct as long as the scratch register
11144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // isn't changed.
11244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // If the operand is used more than once, use a scratch register
11344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // that is guaranteed not to be clobbered.
11444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Operand ExternalOperand(ExternalReference reference,
11544f0eee88ff00398ff7f715fab053374d808c90dSteve Block                          Register scratch = kScratchRegister);
11644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Loads and stores the value of an external reference.
11744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Special case code for load and store to take advantage of
11844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // load_rax/store_rax if possible/necessary.
11944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // For other operations, just use:
12044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  //   Operand operand = ExternalOperand(extref);
12144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  //   operation(operand, ..);
12244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void Load(Register destination, ExternalReference source);
12344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void Store(ExternalReference destination, Register source);
12444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Loads the address of the external reference into the destination
12544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // register.
12644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void LoadAddress(Register destination, ExternalReference source);
12744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Returns the size of the code generated by LoadAddress.
12844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Used by CallSize(ExternalReference) to find the size of a call.
12944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int LoadAddressSize(ExternalReference source);
13044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
13144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Operations on roots in the root-array.
132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void LoadRoot(Register destination, Heap::RootListIndex index);
13344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void StoreRoot(Register source, Heap::RootListIndex index);
134e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // Load a root value where the index (or part of it) is variable.
135e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // The variable_offset register is added to the fixed_offset value
136e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // to get the index into the root-array.
137e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void LoadRootIndexed(Register destination,
138e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                       Register variable_offset,
139e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                       int fixed_offset);
140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void CompareRoot(Register with, Heap::RootListIndex index);
1411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void CompareRoot(const Operand& with, Heap::RootListIndex index);
142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void PushRoot(Heap::RootListIndex index);
143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // These functions do not arrange the registers in any particular order so
1453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // they are not useful for calls that can cause a GC.  The caller can
1463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // exclude up to 3 registers that do not need to be saved and restored.
1473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void PushCallerSaved(SaveFPRegsMode fp_mode,
1483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                       Register exclusion1 = no_reg,
1493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                       Register exclusion2 = no_reg,
1503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                       Register exclusion3 = no_reg);
1513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void PopCallerSaved(SaveFPRegsMode fp_mode,
1523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      Register exclusion1 = no_reg,
1533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      Register exclusion2 = no_reg,
1543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      Register exclusion3 = no_reg);
1553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// ---------------------------------------------------------------------------
1573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// GC Support
1583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  enum RememberedSetFinalAction {
1613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kReturnAtEnd,
1623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    kFallThroughAtEnd
1633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  };
164592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch
1653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Record in the remembered set the fact that we have a pointer to new space
1663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // at the address pointed to by the addr register.  Only works if addr is not
1673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // in new space.
1683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void RememberedSetHelper(Register object,  // Used for debug code.
1693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                           Register addr,
1703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                           Register scratch,
1713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                           SaveFPRegsMode save_fp,
1723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                           RememberedSetFinalAction and_then);
1733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void CheckPageFlag(Register object,
1753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     Register scratch,
1763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     int mask,
1773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     Condition cc,
1783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     Label* condition_met,
1793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     Label::Distance condition_met_distance = Label::kFar);
1803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Check if object is in new space.  Jumps if the object is not in new space.
1823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // The register scratch can be object itself, but scratch will be clobbered.
1833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void JumpIfNotInNewSpace(Register object,
1843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                           Register scratch,
1853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                           Label* branch,
1863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                           Label::Distance distance = Label::kFar) {
1873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    InNewSpace(object, scratch, not_equal, branch, distance);
1883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Check if object is in new space.  Jumps if the object is in new space.
1913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // The register scratch can be object itself, but it will be clobbered.
1923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void JumpIfInNewSpace(Register object,
1933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                        Register scratch,
1943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                        Label* branch,
1953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                        Label::Distance distance = Label::kFar) {
1963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    InNewSpace(object, scratch, equal, branch, distance);
1973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Check if an object has the black incremental marking color.  Also uses rcx!
2003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void JumpIfBlack(Register object,
2013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                   Register scratch0,
2023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                   Register scratch1,
2033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                   Label* on_black,
2043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                   Label::Distance on_black_distance = Label::kFar);
2053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Detects conservatively whether an object is data-only, i.e. it does need to
2073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // be scanned by the garbage collector.
2083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void JumpIfDataObject(Register value,
2093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                        Register scratch,
2103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                        Label* not_data_object,
2113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                        Label::Distance not_data_object_distance);
2123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Checks the color of an object.  If the object is already grey or black
2143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // then we just fall through, since it is already live.  If it is white and
2153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // we can determine that it doesn't need to be scanned, then we just mark it
2163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // black and fall through.  For the rest we jump to the label so the
2173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // incremental marker can fix its assumptions.
2183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void EnsureNotWhite(Register object,
2193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      Register scratch1,
2203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      Register scratch2,
2213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      Label* object_is_white_and_not_data,
2223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      Label::Distance distance);
2233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Notify the garbage collector that we wrote a pointer into an object.
2253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // |object| is the object being stored into, |value| is the object being
2263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // stored.  value and scratch registers are clobbered by the operation.
2273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // The offset is the offset from the start of the object, not the offset from
2283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // the tagged HeapObject pointer.  For use with FieldOperand(reg, off).
2293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void RecordWriteField(
2303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Register object,
2313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      int offset,
2323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Register value,
2333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Register scratch,
2343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      SaveFPRegsMode save_fp,
2353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
2363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      SmiCheck smi_check = INLINE_SMI_CHECK);
2373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // As above, but the offset has the tag presubtracted.  For use with
2393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Operand(reg, off).
2403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void RecordWriteContextSlot(
2413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Register context,
2423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      int offset,
2433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Register value,
2443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Register scratch,
2453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      SaveFPRegsMode save_fp,
2463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
2473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      SmiCheck smi_check = INLINE_SMI_CHECK) {
2483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    RecordWriteField(context,
2493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     offset + kHeapObjectTag,
2503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     value,
2513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     scratch,
2523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     save_fp,
2533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     remembered_set_action,
2543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     smi_check);
2553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Notify the garbage collector that we wrote a pointer into a fixed array.
2583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // |array| is the array being stored into, |value| is the
2593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // object being stored.  |index| is the array index represented as a non-smi.
2603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // All registers are clobbered by the operation RecordWriteArray
2613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // filters out smis so it does not update the write barrier if the
2623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // value is a smi.
2633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void RecordWriteArray(
2643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Register array,
2653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Register value,
2663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Register index,
2673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      SaveFPRegsMode save_fp,
2683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
2693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      SmiCheck smi_check = INLINE_SMI_CHECK);
2703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // For page containing |object| mark region covering |address|
27285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  // dirty. |object| is the object being stored into, |value| is the
2733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // object being stored. The address and value registers are clobbered by the
2748defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // operation.  RecordWrite filters out smis so it does not update
2758defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // the write barrier if the value is a smi.
2763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void RecordWrite(
2773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Register object,
2783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Register address,
2793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Register value,
2803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      SaveFPRegsMode save_fp,
2813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
2823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      SmiCheck smi_check = INLINE_SMI_CHECK);
2833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT
285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Debugger Support
287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
288402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  void DebugBreak();
289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
291d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Enter specific kind of exit frame; either in normal or
292d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // debug mode. Expects the number of arguments in register rax and
293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // sets up the number of arguments in register rdi and the pointer
294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // to the first argument in register rsi.
2958a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  //
2968a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // Allocates arg_stack_space * kPointerSize memory (not GCed) on the stack
2978a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // accessible via StackSpaceOperand.
2981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void EnterExitFrame(int arg_stack_space = 0, bool save_doubles = false);
299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3008a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // Enter specific kind of exit frame. Allocates arg_stack_space * kPointerSize
3018a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // memory (not GCed) on the stack accessible via StackSpaceOperand.
3028a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  void EnterApiExitFrame(int arg_stack_space);
303bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch
304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Leave the current exit frame. Expects/provides the return value in
305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // register rax:rdx (untouched) and the pointer to the first
306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // argument in register rsi.
3071e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void LeaveExitFrame(bool save_doubles = false);
308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3098a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // Leave the current exit frame. Expects/provides the return value in
3108a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // register rax (untouched).
3118a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  void LeaveApiExitFrame();
312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
313b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Push and pop the registers that can hold pointers.
3141e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void PushSafepointRegisters() { Pushad(); }
3151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void PopSafepointRegisters() { Popad(); }
316e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // Store the value in register src in the safepoint register stack
317e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // slot for register dst.
318e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void StoreToSafepointRegisterSlot(Register dst, Register src);
319e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void LoadFromSafepointRegisterSlot(Register dst, Register src);
320e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
321e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void InitializeRootRegister() {
3223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ExternalReference roots_array_start =
3233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        ExternalReference::roots_array_start(isolate());
3243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    movq(kRootRegister, roots_array_start);
325e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    addq(kRootRegister, Immediate(kRootRegisterBias));
326b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
327b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // JavaScript invokes
330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Set up call kind marking in rcx. The method takes rcx as an
332257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // explicit first parameter to make the code more readable at the
333257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // call sites.
334257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void SetCallKind(Register dst, CallKind kind);
335257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Invoke the JavaScript function code by either calling or jumping.
337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void InvokeCode(Register code,
338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                  const ParameterCount& expected,
339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                  const ParameterCount& actual,
340e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                  InvokeFlag flag,
341257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                  const CallWrapper& call_wrapper,
342257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                  CallKind call_kind);
343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void InvokeCode(Handle<Code> code,
345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                  const ParameterCount& expected,
346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                  const ParameterCount& actual,
347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                  RelocInfo::Mode rmode,
348e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                  InvokeFlag flag,
349257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                  const CallWrapper& call_wrapper,
350257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                  CallKind call_kind);
351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Invoke the JavaScript function in the given register. Changes the
353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // current context to the context in the function before invoking.
354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void InvokeFunction(Register function,
355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                      const ParameterCount& actual,
356e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                      InvokeFlag flag,
357257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                      const CallWrapper& call_wrapper,
358257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                      CallKind call_kind);
359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void InvokeFunction(Handle<JSFunction> function,
361402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu                      const ParameterCount& actual,
362e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                      InvokeFlag flag,
363257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                      const CallWrapper& call_wrapper,
364257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                      CallKind call_kind);
365402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Invoke specified builtin JavaScript function. Adds an entry to
367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the unresolved list if the name does not resolve.
368e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void InvokeBuiltin(Builtins::JavaScript id,
369e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                     InvokeFlag flag,
370257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                     const CallWrapper& call_wrapper = NullCallWrapper());
371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
372791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block  // Store the function for the given builtin in the target register.
373791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block  void GetBuiltinFunction(Register target, Builtins::JavaScript id);
374791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block
375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Store the code object for the given builtin in the target register.
376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void GetBuiltinEntry(Register target, Builtins::JavaScript id);
377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Smi tagging, untagging and operations on tagged smis.
381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3828defd9ff6930b4e24729971a61cf7469daf119beSteve Block  void InitializeSmiConstantRegister() {
3838defd9ff6930b4e24729971a61cf7469daf119beSteve Block    movq(kSmiConstantRegister,
3848defd9ff6930b4e24729971a61cf7469daf119beSteve Block         reinterpret_cast<uint64_t>(Smi::FromInt(kSmiConstantRegisterValue)),
3858defd9ff6930b4e24729971a61cf7469daf119beSteve Block         RelocInfo::NONE);
3868defd9ff6930b4e24729971a61cf7469daf119beSteve Block  }
3878defd9ff6930b4e24729971a61cf7469daf119beSteve Block
388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Conversions between tagged smi values and non-tagged integer values.
389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Tag an integer value. The result must be known to be a valid smi value.
3914515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  // Only uses the low 32 bits of the src register. Sets the N and Z flags
3920d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // based on the value of the resulting smi.
393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Integer32ToSmi(Register dst, Register src);
394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3959dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  // Stores an integer32 value into a memory field that already holds a smi.
3969dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  void Integer32ToSmiField(const Operand& dst, Register src);
3979dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Adds constant to src and tags the result as a smi.
399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Result must be a valid smi.
4003ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void Integer64PlusConstantToSmi(Register dst, Register src, int constant);
401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Convert smi to 32-bit integer. I.e., not sign extended into
403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // high 32 bits of destination.
404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SmiToInteger32(Register dst, Register src);
4057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  void SmiToInteger32(Register dst, const Operand& src);
406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Convert smi to 64-bit integer (sign extended if necessary).
408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SmiToInteger64(Register dst, Register src);
4099dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  void SmiToInteger64(Register dst, const Operand& src);
410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Multiply a positive smi's integer value by a power of two.
412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Provides result as 64-bit integer value.
413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void PositiveSmiTimesPowerOfTwoToInteger64(Register dst,
414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                             Register src,
415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                             int power);
416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Divide a positive smi's integer value by a power of two.
4187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Provides result as 32-bit integer value.
4197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  void PositiveSmiDivPowerOfTwoToInteger32(Register dst,
4207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                                           Register src,
4217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                                           int power);
4227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
4238b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // Perform the logical or of two smi values and return a smi value.
4248b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // If either argument is not a smi, jump to on_not_smis and retain
4258b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // the original values of source registers. The destination register
4268b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // may be changed if it's not one of the source registers.
4278b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  void SmiOrIfSmis(Register dst,
4288b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch                   Register src1,
4298b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch                   Register src2,
430257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                   Label* on_not_smis,
431257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                   Label::Distance near_jump = Label::kFar);
4328b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
4337f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
43444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Simple comparison of smis.  Both sides must be known smis to use these,
43544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // otherwise use Cmp.
43644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void SmiCompare(Register smi1, Register smi2);
4373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void SmiCompare(Register dst, Smi* src);
4386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void SmiCompare(Register dst, const Operand& src);
4393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void SmiCompare(const Operand& dst, Register src);
4403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void SmiCompare(const Operand& dst, Smi* src);
4419dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  // Compare the int32 in src register to the value of the smi stored at dst.
4429dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  void SmiCompareInteger32(const Operand& dst, Register src);
4433ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Sets sign and zero flags depending on value of smi in register.
4443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void SmiTest(Register src);
4453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Functions performing a check on a known or potential smi. Returns
447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // a condition that is satisfied if the check is successful.
448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Is the value a tagged smi.
450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Condition CheckSmi(Register src);
4511e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  Condition CheckSmi(const Operand& src);
452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
453f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  // Is the value a non-negative tagged smi.
454f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  Condition CheckNonNegativeSmi(Register src);
455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
456e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Are both values tagged smis.
457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Condition CheckBothSmi(Register first, Register second);
458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
459f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  // Are both values non-negative tagged smis.
460f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  Condition CheckBothNonNegativeSmi(Register first, Register second);
461d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
462e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Are either value a tagged smi.
463bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  Condition CheckEitherSmi(Register first,
464bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch                           Register second,
465bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch                           Register scratch = kScratchRegister);
466e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Is the value the minimum smi value (since we are using
468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // two's complement numbers, negating the value is known to yield
469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // a non-smi value).
470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Condition CheckIsMinSmi(Register src);
471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Checks whether an 32-bit integer value is a valid for conversion
473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // to a smi.
474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Condition CheckInteger32ValidSmiValue(Register src);
475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Checks whether an 32-bit unsigned integer value is a valid for
4773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // conversion to a smi.
4783ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  Condition CheckUInteger32ValidSmiValue(Register src);
4793ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
4801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Check whether src is a Smi, and set dst to zero if it is a smi,
4811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // and to one if it isn't.
4821e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void CheckSmiToIndicator(Register dst, Register src);
4831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void CheckSmiToIndicator(Register dst, const Operand& src);
4841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Test-and-jump functions. Typically combines a check function
486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // above with a conditional jump.
487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Jump if the value cannot be represented by a smi.
489257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void JumpIfNotValidSmiValue(Register src, Label* on_invalid,
490257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                              Label::Distance near_jump = Label::kFar);
491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Jump if the unsigned integer value cannot be represented by a smi.
493257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void JumpIfUIntNotValidSmiValue(Register src, Label* on_invalid,
494257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                  Label::Distance near_jump = Label::kFar);
4953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Jump to label if the value is a tagged smi.
497257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void JumpIfSmi(Register src,
498257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                 Label* on_smi,
499257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                 Label::Distance near_jump = Label::kFar);
500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Jump to label if the value is not a tagged smi.
502257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void JumpIfNotSmi(Register src,
503257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                    Label* on_not_smi,
504257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                    Label::Distance near_jump = Label::kFar);
505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
506f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  // Jump to label if the value is not a non-negative tagged smi.
507257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void JumpUnlessNonNegativeSmi(Register src,
508257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                Label* on_not_smi,
509257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                Label::Distance near_jump = Label::kFar);
510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5113ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Jump to label if the value, which must be a tagged smi, has value equal
512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // to the constant.
5130d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  void JumpIfSmiEqualsConstant(Register src,
5140d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                               Smi* constant,
515257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                               Label* on_equals,
516257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                               Label::Distance near_jump = Label::kFar);
517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Jump if either or both register are not smi values.
5190d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  void JumpIfNotBothSmi(Register src1,
5200d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                        Register src2,
521257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                        Label* on_not_both_smi,
522257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                        Label::Distance near_jump = Label::kFar);
523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
524f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  // Jump if either or both register are not non-negative smi values.
525f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  void JumpUnlessBothNonNegativeSmi(Register src1, Register src2,
526257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                    Label* on_not_both_smi,
527257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                    Label::Distance near_jump = Label::kFar);
528d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Operations on tagged smi values.
530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Smis represent a subset of integers. The subset is always equivalent to
532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // a two's complement interpretation of a fixed number of bits.
533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Optimistically adds an integer constant to a supposed smi.
535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If the src is not a smi, or the result is not a smi, jump to
536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the label.
537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SmiTryAddConstant(Register dst,
538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                         Register src,
5393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block                         Smi* constant,
540257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                         Label* on_not_smi_result,
541257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                         Label::Distance near_jump = Label::kFar);
542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5433ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Add an integer constant to a tagged smi, giving a tagged smi as result.
5443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // No overflow testing on the result is done.
5453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void SmiAddConstant(Register dst, Register src, Smi* constant);
5463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
547f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // Add an integer constant to a tagged smi, giving a tagged smi as result.
548f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  // No overflow testing on the result is done.
549f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void SmiAddConstant(const Operand& dst, Smi* constant);
550f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Add an integer constant to a tagged smi, giving a tagged smi as result,
552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // or jumping to a label if the result cannot be represented by a smi.
553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SmiAddConstant(Register dst,
554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                      Register src,
5553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block                      Smi* constant,
556257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                      Label* on_not_smi_result,
557257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                      Label::Distance near_jump = Label::kFar);
558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Subtract an integer constant from a tagged smi, giving a tagged smi as
5606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // result. No testing on the result is done. Sets the N and Z flags
5616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // based on the value of the resulting integer.
5623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void SmiSubConstant(Register dst, Register src, Smi* constant);
5633ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
5643ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Subtract an integer constant from a tagged smi, giving a tagged smi as
565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // result, or jumping to a label if the result cannot be represented by a smi.
566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SmiSubConstant(Register dst,
567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                      Register src,
5683ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block                      Smi* constant,
569257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                      Label* on_not_smi_result,
570257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                      Label::Distance near_jump = Label::kFar);
571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Negating a smi can give a negative zero or too large positive value.
5733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // NOTICE: This operation jumps on success, not failure!
574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SmiNeg(Register dst,
575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block              Register src,
576257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch              Label* on_smi_result,
577257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch              Label::Distance near_jump = Label::kFar);
578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Adds smi values and return the result as a smi.
580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If dst is src1, then src1 will be destroyed, even if
581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the operation is unsuccessful.
582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SmiAdd(Register dst,
583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block              Register src1,
584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block              Register src2,
585257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch              Label* on_not_smi_result,
586257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch              Label::Distance near_jump = Label::kFar);
58744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void SmiAdd(Register dst,
58844f0eee88ff00398ff7f715fab053374d808c90dSteve Block              Register src1,
58944f0eee88ff00398ff7f715fab053374d808c90dSteve Block              const Operand& src2,
590257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch              Label* on_not_smi_result,
591257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch              Label::Distance near_jump = Label::kFar);
5920d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
5930d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  void SmiAdd(Register dst,
5940d5e116f6aee03185f237311a943491bb079a768Kristian Monsen              Register src1,
5950d5e116f6aee03185f237311a943491bb079a768Kristian Monsen              Register src2);
596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Subtracts smi values and return the result as a smi.
598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If dst is src1, then src1 will be destroyed, even if
599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the operation is unsuccessful.
600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SmiSub(Register dst,
601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block              Register src1,
602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block              Register src2,
603257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch              Label* on_not_smi_result,
604257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch              Label::Distance near_jump = Label::kFar);
6050d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
6060d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  void SmiSub(Register dst,
6070d5e116f6aee03185f237311a943491bb079a768Kristian Monsen              Register src1,
6080d5e116f6aee03185f237311a943491bb079a768Kristian Monsen              Register src2);
609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void SmiSub(Register dst,
6116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block              Register src1,
612f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke              const Operand& src2,
613257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch              Label* on_not_smi_result,
614257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch              Label::Distance near_jump = Label::kFar);
6150d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
6160d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  void SmiSub(Register dst,
6170d5e116f6aee03185f237311a943491bb079a768Kristian Monsen              Register src1,
6180d5e116f6aee03185f237311a943491bb079a768Kristian Monsen              const Operand& src2);
6196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Multiplies smi values and return the result as a smi,
621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // if possible.
622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If dst is src1, then src1 will be destroyed, even if
623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the operation is unsuccessful.
624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SmiMul(Register dst,
625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block              Register src1,
626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block              Register src2,
627257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch              Label* on_not_smi_result,
628257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch              Label::Distance near_jump = Label::kFar);
629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Divides one smi by another and returns the quotient.
631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Clobbers rax and rdx registers.
632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SmiDiv(Register dst,
633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block              Register src1,
634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block              Register src2,
635257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch              Label* on_not_smi_result,
636257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch              Label::Distance near_jump = Label::kFar);
637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Divides one smi by another and returns the remainder.
639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Clobbers rax and rdx registers.
640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SmiMod(Register dst,
641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block              Register src1,
642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block              Register src2,
643257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch              Label* on_not_smi_result,
644257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch              Label::Distance near_jump = Label::kFar);
645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Bitwise operations.
647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SmiNot(Register dst, Register src);
648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SmiAnd(Register dst, Register src1, Register src2);
649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SmiOr(Register dst, Register src1, Register src2);
650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SmiXor(Register dst, Register src1, Register src2);
6513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void SmiAndConstant(Register dst, Register src1, Smi* constant);
6523ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void SmiOrConstant(Register dst, Register src1, Smi* constant);
6533ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void SmiXorConstant(Register dst, Register src1, Smi* constant);
654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SmiShiftLeftConstant(Register dst,
656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            Register src,
65725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen                            int shift_value);
658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SmiShiftLogicalRightConstant(Register dst,
659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                  Register src,
660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                  int shift_value,
661257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                  Label* on_not_smi_result,
662257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                  Label::Distance near_jump = Label::kFar);
663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SmiShiftArithmeticRightConstant(Register dst,
664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                       Register src,
665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                       int shift_value);
666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Shifts a smi value to the left, and returns the result if that is a smi.
668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Uses and clobbers rcx, so dst may not be rcx.
669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SmiShiftLeft(Register dst,
670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                    Register src1,
67125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen                    Register src2);
672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Shifts a smi value to the right, shifting in zero bits at the top, and
673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // returns the unsigned intepretation of the result if that is a smi.
674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Uses and clobbers rcx, so dst may not be rcx.
675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SmiShiftLogicalRight(Register dst,
6760d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                            Register src1,
6770d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                            Register src2,
678257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                            Label* on_not_smi_result,
679257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                            Label::Distance near_jump = Label::kFar);
680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Shifts a smi value to the right, sign extending the top, and
681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // returns the signed intepretation of the result. That will always
682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // be a valid smi value, since it's numerically smaller than the
683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // original.
684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Uses and clobbers rcx, so dst may not be rcx.
685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SmiShiftArithmeticRight(Register dst,
686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Register src1,
687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Register src2);
688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Specialized operations
690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Select the non-smi register of two registers where exactly one is a
692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // smi. If neither are smis, jump to the failure label.
693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SelectNonSmi(Register dst,
694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                    Register src1,
695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                    Register src2,
696257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                    Label* on_not_smis,
697257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                    Label::Distance near_jump = Label::kFar);
698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Converts, if necessary, a smi to a combination of number and
700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // multiplier to be used as a scaled index.
701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The src register contains a *positive* smi value. The shift is the
702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // power of two to multiply the index value by (e.g.
703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // to index by smi-value * kPointerSize, pass the smi and kPointerSizeLog2).
704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The returned index register may be either src or dst, depending
705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // on what is most efficient. If src and dst are different registers,
706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // src is always unchanged.
707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  SmiIndex SmiToIndex(Register dst, Register src, int shift);
708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Converts a positive smi to a negative index.
710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  SmiIndex SmiToNegativeIndex(Register dst, Register src, int shift);
711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
71244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Add the value of a smi in memory to an int32 register.
71344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Sets flags as a normal add.
71444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void AddSmiField(Register dst, const Operand& src);
71544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
7163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Basic Smi operations.
7173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void Move(Register dst, Smi* source) {
7188defd9ff6930b4e24729971a61cf7469daf119beSteve Block    LoadSmiConstant(dst, source);
7193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
7203ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
7213ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void Move(const Operand& dst, Smi* source) {
7228defd9ff6930b4e24729971a61cf7469daf119beSteve Block    Register constant = GetSmiConstant(source);
7238defd9ff6930b4e24729971a61cf7469daf119beSteve Block    movq(dst, constant);
7243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
7253ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
7263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void Push(Smi* smi);
7273ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void Test(const Operand& dst, Smi* source);
7283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
7293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
731e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // String macros.
7321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
7331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // If object is a string, its map is loaded into object_map.
7341e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void JumpIfNotString(Register object,
7351e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block                       Register object_map,
736257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                       Label* not_string,
737257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                       Label::Distance near_jump = Label::kFar);
7381e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
7391e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
740257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void JumpIfNotBothSequentialAsciiStrings(
741257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Register first_object,
742257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Register second_object,
743257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Register scratch1,
744257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Register scratch2,
745257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Label* on_not_both_flat_ascii,
746257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Label::Distance near_jump = Label::kFar);
747e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
7483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Check whether the instance type represents a flat ASCII string. Jump to the
7496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // label if not. If the instance type can be scratched specify same register
7506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // for both instance type and scratch.
7510d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  void JumpIfInstanceTypeIsNotSequentialAscii(
7520d5e116f6aee03185f237311a943491bb079a768Kristian Monsen      Register instance_type,
7530d5e116f6aee03185f237311a943491bb079a768Kristian Monsen      Register scratch,
754257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Label*on_not_flat_ascii_string,
755257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Label::Distance near_jump = Label::kFar);
7566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
7576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void JumpIfBothInstanceTypesAreNotSequentialAscii(
7586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      Register first_object_instance_type,
7596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      Register second_object_instance_type,
7606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      Register scratch1,
7616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      Register scratch2,
762257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Label* on_fail,
763257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Label::Distance near_jump = Label::kFar);
7646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
765e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // ---------------------------------------------------------------------------
766e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Macro instructions.
767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7683ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Load a register with a long value as efficiently as possible.
769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Set(Register dst, int64_t x);
770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Set(const Operand& dst, int64_t x);
771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7720d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // Move if the registers are not identical.
7730d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  void Move(Register target, Register source);
7740d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
7753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Bit-field support.
7763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void TestBit(const Operand& dst, int bit_index);
7773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Handle support
779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Move(Register dst, Handle<Object> source);
780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Move(const Operand& dst, Handle<Object> source);
781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Cmp(Register dst, Handle<Object> source);
782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Cmp(const Operand& dst, Handle<Object> source);
78344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void Cmp(Register dst, Smi* src);
78444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void Cmp(const Operand& dst, Smi* src);
785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Push(Handle<Object> source);
786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Load a heap object and handle the case of new-space objects by
7883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // indirecting via a global cell.
7893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void LoadHeapObject(Register result, Handle<HeapObject> object);
7903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void PushHeapObject(Handle<HeapObject> object);
7913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void LoadObject(Register result, Handle<Object> object) {
7933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (object->IsHeapObject()) {
7943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      LoadHeapObject(result, Handle<HeapObject>::cast(object));
7953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    } else {
7963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Move(result, object);
7973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
7983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
7993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Load a global cell into a register.
8013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void LoadGlobalCell(Register dst, Handle<JSGlobalPropertyCell> cell);
8023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
803e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Emit code to discard a non-negative number of pointer-sized elements
804e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // from the stack, clobbering only the rsp register.
805e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  void Drop(int stack_elements);
806e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
807e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  void Call(Label* target) { call(target); }
808e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Control Flow
810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Jump(Address destination, RelocInfo::Mode rmode);
811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Jump(ExternalReference ext);
812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Jump(Handle<Code> code_object, RelocInfo::Mode rmode);
813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Call(Address destination, RelocInfo::Mode rmode);
815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Call(ExternalReference ext);
816257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void Call(Handle<Code> code_object,
817257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch            RelocInfo::Mode rmode,
818257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch            unsigned ast_id = kNoASTId);
819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
82044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // The size of the code generated for different call instructions.
82144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int CallSize(Address destination, RelocInfo::Mode rmode) {
82244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return kCallInstructionLength;
82344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
82444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int CallSize(ExternalReference ext);
82544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int CallSize(Handle<Code> code_object) {
82644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // Code calls use 32-bit relative addressing.
82744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return kShortCallInstructionLength;
82844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
82944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int CallSize(Register target) {
83044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // Opcode: REX_opt FF /2 m64
83144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return (target.high_bit() != 0) ? 3 : 2;
83244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
83344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int CallSize(const Operand& target) {
83444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // Opcode: REX_opt FF /2 m64
83544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return (target.requires_rex() ? 2 : 1) + target.operand_size();
83644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
83744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
8381e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Emit call to the code we are currently generating.
8391e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void CallSelf() {
8401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    Handle<Code> self(reinterpret_cast<Code**>(CodeObject().location()));
8411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    Call(self, RelocInfo::CODE_TARGET);
8421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
8431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
8441e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Non-x64 instructions.
8451e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Push/pop all general purpose registers.
8461e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Does not push rsp/rbp nor any of the assembler's special purpose registers
8471e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // (kScratchRegister, kSmiConstantRegister, kRootRegister).
8481e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void Pushad();
8491e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void Popad();
8501e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Sets the stack as after performing Popad, without actually loading the
8511e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // registers.
8521e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void Dropad();
8531e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compare object type for heap object.
855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Always use unsigned comparisons: above and below, not less and greater.
856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Incoming register is heap_object and outgoing register is map.
857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // They may be the same register, and may be kScratchRegister.
858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void CmpObjectType(Register heap_object, InstanceType type, Register map);
859a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compare instance type for map.
861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Always use unsigned comparisons: above and below, not less and greater.
862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void CmpInstanceType(Register map, InstanceType type);
863a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
8643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Check if a map for a JSObject indicates that the object has fast elements.
8653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Jump to the specified label if it does not.
8663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void CheckFastElements(Register map,
8673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                         Label* fail,
8683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                         Label::Distance distance = Label::kFar);
8693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
8703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Check if a map for a JSObject indicates that the object can have both smi
8713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // and HeapObject elements.  Jump to the specified label if it does not.
8723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void CheckFastObjectElements(Register map,
8733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               Label* fail,
8743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               Label::Distance distance = Label::kFar);
8753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Check if a map for a JSObject indicates that the object has fast smi only
8773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // elements.  Jump to the specified label if it does not.
8783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void CheckFastSmiOnlyElements(Register map,
8793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                Label* fail,
8803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                Label::Distance distance = Label::kFar);
8813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Check to see if maybe_number can be stored as a double in
8833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // FastDoubleElements. If it can, store it at the index specified by index in
8843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // the FastDoubleElements array elements, otherwise jump to fail.  Note that
8853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // index must not be smi-tagged.
8863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void StoreNumberToDoubleElements(Register maybe_number,
8873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Register elements,
8883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Register index,
8893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   XMMRegister xmm_scratch,
8903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                   Label* fail);
8913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Compare an object's map with the specified map and its transitioned
8933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // elements maps if mode is ALLOW_ELEMENT_TRANSITION_MAPS. FLAGS are set with
8943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // result of map compare. If multiple map compares are required, the compare
8953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // sequences branches to early_success.
8963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void CompareMap(Register obj,
8973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                  Handle<Map> map,
8983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                  Label* early_success,
8993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                  CompareMapMode mode = REQUIRE_EXACT_MAP);
9003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
9013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Check if the map of an object is equal to a specified map and branch to
9023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // label if not. Skip the smi check if not required (object is known to be a
9033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // heap object). If mode is ALLOW_ELEMENT_TRANSITION_MAPS, then also match
9043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // against maps that are ElementsKind transition maps of the specified map.
9053100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void CheckMap(Register obj,
9063100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                Handle<Map> map,
9073100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                Label* fail,
9083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                SmiCheckType smi_check_type,
9093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                CompareMapMode mode = REQUIRE_EXACT_MAP);
910257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
911257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Check if the map of an object is equal to a specified map and branch to a
912257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // specified target if equal. Skip the smi check if not required (object is
913257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // known to be a heap object)
914257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void DispatchMap(Register obj,
915257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                   Handle<Map> map,
916257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                   Handle<Code> success,
917257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                   SmiCheckType smi_check_type);
9183100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
919d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Check if the object in register heap_object is a string. Afterwards the
920d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // register map contains the object map and the register instance_type
921d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // contains the instance_type. The registers map and instance_type can be the
922d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // same in which case it contains the instance type afterwards. Either of the
923d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // registers map and instance_type can be the same as heap_object.
924d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  Condition IsObjectStringType(Register heap_object,
925d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                               Register map,
926d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                               Register instance_type);
927d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
9288defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // FCmp compares and pops the two values on top of the FPU stack.
9298defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // The flag results are similar to integer cmp, but requires unsigned
930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // jcc instructions (je, ja, jae, jb, jbe, je, and jz).
931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void FCmp();
932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
933257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void ClampUint8(Register reg);
934257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
935257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void ClampDoubleToUint8(XMMRegister input_reg,
936257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                          XMMRegister temp_xmm_reg,
937257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                          Register result_reg,
938257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                          Register temp_reg);
939257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
940257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void LoadInstanceDescriptors(Register map, Register descriptors);
941257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
942402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // Abort execution if argument is not a number. Used in debug code.
943f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void AbortIfNotNumber(Register object);
944402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
945756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  // Abort execution if argument is a smi. Used in debug code.
946756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  void AbortIfSmi(Register object);
947756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
9486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Abort execution if argument is not a smi. Used in debug code.
949f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  void AbortIfNotSmi(Register object);
95044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void AbortIfNotSmi(const Operand& object);
9516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
9523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Abort execution if a 64 bit register containing a 32 bit payload does not
9533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // have zeros in the top 32 bits.
9543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void AbortIfNotZeroExtended(Register reg);
9553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
956e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // Abort execution if argument is a string. Used in debug code.
957e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void AbortIfNotString(Register object);
958e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
9599dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  // Abort execution if argument is not the root value with the given index.
9609dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  void AbortIfNotRootValue(Register src,
9619dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen                           Heap::RootListIndex root_value_index,
9629dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen                           const char* message);
9639dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Exception handling
966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
9673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Push a new try handler and link it into try handler chain.
9683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void PushTryHandler(StackHandler::Kind kind, int handler_index);
969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
970e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Unlink the stack handler on top of the stack from the try handler chain.
971e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  void PopTryHandler();
972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
973e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // Activate the top handler in the try hander chain and pass the
974e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // thrown value.
975e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  void Throw(Register value);
976e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
977e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // Propagate an uncatchable exception out of the current JS stack.
9783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void ThrowUncatchable(Register value);
979e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Inline caching support
982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Generate code for checking access rights - used for security checks
984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // on access to global objects across environments. The holder register
985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // is left untouched, but the scratch register and kScratchRegister,
986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // which must be different, are clobbered.
987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void CheckAccessGlobalProxy(Register holder_reg,
988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                              Register scratch,
989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                              Label* miss);
990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
991c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  void GetNumberHash(Register r0, Register scratch);
992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
9933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void LoadFromNumberDictionary(Label* miss,
9943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                Register elements,
9953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                Register key,
9963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                Register r0,
9973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                Register r1,
9983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                Register r2,
9993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                Register result);
10003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
10013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
1003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Allocation support
1004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Allocate an object in new space. If the new space is exhausted control
1006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // continues at the gc_required label. The allocated object is returned in
1007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // result and end of the new object is returned in result_end. The register
1008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // scratch can be passed as no_reg in which case an additional object
1009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // reference will be added to the reloc info. The returned pointers in result
1010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // and result_end have not yet been tagged as heap objects. If
1011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // result_contains_top_on_entry is true the content of result is known to be
1012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the allocation top on entry (could be result_end from a previous call to
1013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // AllocateInNewSpace). If result_contains_top_on_entry is true scratch
1014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // should be no_reg as it is never used.
1015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void AllocateInNewSpace(int object_size,
1016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Register result,
1017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Register result_end,
1018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Register scratch,
1019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Label* gc_required,
1020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          AllocationFlags flags);
1021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void AllocateInNewSpace(int header_size,
1023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          ScaleFactor element_size,
1024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Register element_count,
1025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Register result,
1026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Register result_end,
1027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Register scratch,
1028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Label* gc_required,
1029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          AllocationFlags flags);
1030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void AllocateInNewSpace(Register object_size,
1032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Register result,
1033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Register result_end,
1034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Register scratch,
1035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Label* gc_required,
1036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          AllocationFlags flags);
1037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Undo allocation in new space. The object passed and objects allocated after
1039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // it will no longer be allocated. Make sure that no pointers are left to the
1040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // object(s) no longer allocated as they would be invalid when allocation is
1041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // un-done.
1042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void UndoAllocationInNewSpace(Register object);
1043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
10443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Allocate a heap number in new space with undefined value. Returns
10453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // tagged pointer in result register, or jumps to gc_required if new
10463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // space is full.
10473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void AllocateHeapNumber(Register result,
10483ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block                          Register scratch,
10493ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block                          Label* gc_required);
10503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
1051e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Allocate a sequential string. All the header fields of the string object
1052e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // are initialized.
1053e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  void AllocateTwoByteString(Register result,
1054e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke                             Register length,
1055e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke                             Register scratch1,
1056e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke                             Register scratch2,
1057e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke                             Register scratch3,
1058e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke                             Label* gc_required);
1059e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  void AllocateAsciiString(Register result,
1060e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke                           Register length,
1061e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke                           Register scratch1,
1062e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke                           Register scratch2,
1063e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke                           Register scratch3,
1064e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke                           Label* gc_required);
1065e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
1066e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Allocate a raw cons string object. Only the map field of the result is
1067e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // initialized.
1068589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  void AllocateTwoByteConsString(Register result,
1069e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke                          Register scratch1,
1070e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke                          Register scratch2,
1071e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke                          Label* gc_required);
1072e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  void AllocateAsciiConsString(Register result,
1073e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke                               Register scratch1,
1074e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke                               Register scratch2,
1075e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke                               Label* gc_required);
1076e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
1077589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Allocate a raw sliced string object. Only the map field of the result is
1078589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // initialized.
1079589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  void AllocateTwoByteSlicedString(Register result,
1080589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                            Register scratch1,
1081589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                            Register scratch2,
1082589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                            Label* gc_required);
1083589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  void AllocateAsciiSlicedString(Register result,
1084589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                                 Register scratch1,
1085589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                                 Register scratch2,
1086589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                                 Label* gc_required);
1087589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
1088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
1089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Support functions.
1090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check if result is zero and op is negative.
1092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void NegativeZeroTest(Register result, Register op, Label* then_label);
1093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check if result is zero and op is negative in code using jump targets.
1095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void NegativeZeroTest(CodeGenerator* cgen,
1096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                        Register result,
1097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                        Register op,
1098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                        JumpTarget* then_target);
1099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check if result is zero and any of op1 and op2 are negative.
1101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Register scratch is destroyed, and it must be different from op2.
1102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void NegativeZeroTest(Register result, Register op1, Register op2,
1103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                        Register scratch, Label* then_label);
1104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Try to get function prototype of a function and puts the value in
1106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the result register. Checks that the function really is a
1107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // function and jumps to the miss label if the fast checks fail. The
1108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // function register will be untouched; the other register may be
1109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // clobbered.
1110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void TryGetFunctionPrototype(Register function,
1111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Register result,
11123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               Label* miss,
11133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                               bool miss_on_bound_function = false);
1114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Generates code for reporting that an illegal operation has
1116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // occurred.
1117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void IllegalOperation(int num_arguments);
1118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
111980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // Picks out an array index from the hash field.
112080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // Register use:
112180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  //   hash - holds the index's hash. Clobbered.
112280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  //   index - holds the overwritten index on exit.
112380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  void IndexFromHash(Register hash, Register index);
112480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
1125d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Find the function context up the context chain.
1126d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  void LoadContext(Register dst, int context_chain_length);
1127d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
11283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Conditionally load the cached Array transitioned map of type
11293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // transitioned_kind from the global context if the map in register
11303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // map_in_out is the cached Array map in the global context of
11313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // expected_kind.
11323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void LoadTransitionedArrayMapConditional(
11333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      ElementsKind expected_kind,
11343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      ElementsKind transitioned_kind,
11353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Register map_in_out,
11363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Register scratch,
11373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Label* no_map_match);
11383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
11393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Load the initial map for new Arrays from a JSFunction.
11403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void LoadInitialArrayMap(Register function_in,
11413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                           Register scratch,
11423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                           Register map_out);
11433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1144b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Load the global function with the given index.
1145b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void LoadGlobalFunction(int index, Register function);
1146b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1147b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Load the initial map from the global function. The registers
1148b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // function and map can be the same.
1149b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void LoadGlobalFunctionInitialMap(Register function, Register map);
1150b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
1152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Runtime calls
1153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Call a code stub.
1155257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void CallStub(CodeStub* stub, unsigned ast_id = kNoASTId);
1156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1157e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Tail call a code stub (jump).
1158e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  void TailCallStub(CodeStub* stub);
1159e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
1160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Return from a code stub after popping its arguments.
1161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void StubReturn(int argc);
1162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Call a runtime routine.
116444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void CallRuntime(const Runtime::Function* f, int num_arguments);
1165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
11661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Call a runtime function and save the value of XMM registers.
11671e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void CallRuntimeSaveDoubles(Runtime::FunctionId id);
11681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
1169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Convenience function: Same as above, but takes the fid instead.
1170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void CallRuntime(Runtime::FunctionId id, int num_arguments);
1171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1172402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // Convenience function: call an external reference.
1173402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  void CallExternalReference(const ExternalReference& ext,
1174402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu                             int num_arguments);
1175402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
1176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Tail call of a runtime routine (jump).
11776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Like JumpToExternalReference, but also takes care of passing the number
11786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // of parameters.
11796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void TailCallExternalReference(const ExternalReference& ext,
11806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                 int num_arguments,
11816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                 int result_size);
11826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
11836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Convenience function: tail call a runtime routine (jump).
11846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void TailCallRuntime(Runtime::FunctionId fid,
1185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                       int num_arguments,
1186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                       int result_size);
1187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Jump to a runtime routine.
11896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void JumpToExternalReference(const ExternalReference& ext, int result_size);
1190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
11913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Prepares stack to put arguments (aligns and so on).  WIN64 calling
11923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // convention requires to put the pointer to the return value slot into
11933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // rcx (rcx must be preserverd until CallApiFunctionAndReturn).  Saves
11943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // context (rsi).  Clobbers rax.  Allocates arg_stack_space * kPointerSize
11958a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // inside the exit frame (not GCed) accessible via StackSpaceOperand.
11968a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  void PrepareCallApiFunction(int arg_stack_space);
11978a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
11983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Calls an API function.  Allocates HandleScope, extracts returned value
11993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // from handle and propagates exceptions.  Clobbers r14, r15, rbx and
12003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // caller-save registers.  Restores context.  On return removes
12013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // stack_space * kPointerSize (GCed).
12023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void CallApiFunctionAndReturn(Address function_address, int stack_space);
12035913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck
12044515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  // Before calling a C-function from generated code, align arguments on stack.
12054515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  // After aligning the frame, arguments must be stored in esp[0], esp[4],
12064515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  // etc., not pushed. The argument count assumes all arguments are word sized.
12074515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  // The number of slots reserved for arguments depends on platform. On Windows
12084515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  // stack slots are reserved for the arguments passed in registers. On other
12094515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  // platforms stack slots are only reserved for the arguments actually passed
12104515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  // on the stack.
12114515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  void PrepareCallCFunction(int num_arguments);
12124515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke
12134515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  // Calls a C function and cleans up the space for arguments allocated
12144515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  // by PrepareCallCFunction. The called function is not allowed to trigger a
12154515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  // garbage collection, since that might move the code and invalidate the
12164515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  // return address (unless this is somehow accounted for by the called
12174515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  // function).
12184515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  void CallCFunction(ExternalReference function, int num_arguments);
12194515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  void CallCFunction(Register function, int num_arguments);
12204515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke
12214515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  // Calculate the number of stack slots to reserve for arguments when calling a
12224515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  // C function.
12234515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  int ArgumentStackSlotsForCFunctionCall(int num_arguments);
1224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
1226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Utilities
1227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Ret();
1229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
12301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Return and drop arguments from stack, where the number of arguments
12311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // may be bigger than 2^16 - 1.  Requires a scratch register.
12321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void Ret(int bytes_dropped, Register scratch);
12331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
12348b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Handle<Object> CodeObject() {
12358b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    ASSERT(!code_object_.is_null());
12368b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    return code_object_;
12378b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  }
1238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
123944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Copy length bytes from source to destination.
124044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Uses scratch register internally (if you have a low-eight register
124144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // free, do use it, otherwise kScratchRegister will be used).
124244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // The min_length is a minimum limit on the value that length will have.
124344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // The algorithm has some special cases that might be omitted if the string
124444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // is known to always be long.
124544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  void CopyBytes(Register destination,
124644f0eee88ff00398ff7f715fab053374d808c90dSteve Block                 Register source,
124744f0eee88ff00398ff7f715fab053374d808c90dSteve Block                 Register length,
124844f0eee88ff00398ff7f715fab053374d808c90dSteve Block                 int min_length = 0,
124944f0eee88ff00398ff7f715fab053374d808c90dSteve Block                 Register scratch = kScratchRegister);
125044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
12513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Initialize fields with filler values.  Fields starting at |start_offset|
12523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // not including end_offset are overwritten with the value in |filler|.  At
12533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // the end the loop, |start_offset| takes the value of |end_offset|.
12543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void InitializeFieldsWithFiller(Register start_offset,
12553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                  Register end_offset,
12563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                  Register filler);
12573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
1260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // StatsCounter support
1261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SetCounter(StatsCounter* counter, int value);
1263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void IncrementCounter(StatsCounter* counter, int value);
1264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void DecrementCounter(StatsCounter* counter, int value);
1265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
1268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Debugging
1269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Calls Abort(msg) if the condition cc is not satisfied.
1271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Use --debug_code to enable.
1272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Assert(Condition cc, const char* msg);
1273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1274756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  void AssertFastElements(Register elements);
1275756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
1276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Like Assert(), but always enabled.
1277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Check(Condition cc, const char* msg);
1278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Print a message to stdout and abort execution.
1280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Abort(const char* msg);
1281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
12826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Check that the stack is aligned.
12836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void CheckStackAlignment();
12846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Verify restrictions about code generated in stubs.
1286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void set_generating_stub(bool value) { generating_stub_ = value; }
1287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool generating_stub() { return generating_stub_; }
1288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void set_allow_stub_calls(bool value) { allow_stub_calls_ = value; }
1289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool allow_stub_calls() { return allow_stub_calls_; }
12903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void set_has_frame(bool value) { has_frame_ = value; }
12913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool has_frame() { return has_frame_; }
12923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline bool AllowThisStubCall(CodeStub* stub);
1293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
12948b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  static int SafepointRegisterStackIndex(Register reg) {
12958b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    return SafepointRegisterStackIndex(reg.code());
12968b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  }
12978b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
12983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Activation support.
12993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void EnterFrame(StackFrame::Type type);
13003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void LeaveFrame(StackFrame::Type type);
13013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
13023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Expects object in rax and returns map with validated enum cache
13033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // in rax.  Assumes that any other register can be used as a scratch.
13043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void CheckEnumCache(Register null_value,
13053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      Label* call_runtime);
13063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
13081e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Order general registers are pushed by Pushad.
130944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // rax, rcx, rdx, rbx, rsi, rdi, r8, r9, r11, r14, r15.
13103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  static const int kSafepointPushRegisterIndices[Register::kNumRegisters];
1311e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  static const int kNumSafepointSavedRegisters = 11;
1312257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  static const int kSmiShift = kSmiTagSize + kSmiShiftSize;
1313e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool generating_stub_;
1315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool allow_stub_calls_;
13163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool has_frame_;
131744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  bool root_array_available_;
13188defd9ff6930b4e24729971a61cf7469daf119beSteve Block
13198defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // Returns a register holding the smi value. The register MUST NOT be
13208defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // modified. It may be the "smi 1 constant" register.
13218defd9ff6930b4e24729971a61cf7469daf119beSteve Block  Register GetSmiConstant(Smi* value);
13228defd9ff6930b4e24729971a61cf7469daf119beSteve Block
13238defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // Moves the smi value to the destination register.
13248defd9ff6930b4e24729971a61cf7469daf119beSteve Block  void LoadSmiConstant(Register dst, Smi* value);
13258defd9ff6930b4e24729971a61cf7469daf119beSteve Block
13263100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // This handle will be patched with the code object on installation.
13273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  Handle<Object> code_object_;
1328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Helper functions for generating invokes.
1330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void InvokePrologue(const ParameterCount& expected,
1331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                      const ParameterCount& actual,
1332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                      Handle<Code> code_constant,
1333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                      Register code_register,
1334257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                      Label* done,
13353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      bool* definitely_mismatches,
1336e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                      InvokeFlag flag,
1337257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                      Label::Distance near_jump = Label::kFar,
1338257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                      const CallWrapper& call_wrapper = NullCallWrapper(),
1339257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                      CallKind call_kind = CALL_AS_METHOD);
1340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
134180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  void EnterExitFramePrologue(bool save_rax);
13428a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
13438a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // Allocates arg_stack_space * kPointerSize memory (not GCed) on the stack
13448a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // accessible via StackSpaceOperand.
13451e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  void EnterExitFrameEpilogue(int arg_stack_space, bool save_doubles);
13468a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
13478a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  void LeaveExitFrameEpilogue();
1348bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch
1349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Allocation support helpers.
13506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Loads the top of new-space into the result register.
13516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Otherwise the address of the new-space top is loaded into scratch (if
13526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // scratch is valid), and the new-space top is loaded into result.
1353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void LoadAllocationTopHelper(Register result,
1354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Register scratch,
1355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               AllocationFlags flags);
13566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Update allocation top with value in result_end register.
13576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // If scratch is valid, it contains the address of the allocation top.
1358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void UpdateAllocationTopHelper(Register result_end, Register scratch);
1359bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch
1360bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  // Helper for PopHandleScope.  Allowed to perform a GC and returns
1361bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  // NULL if gc_allowed.  Does not perform a GC if !gc_allowed, and
1362bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  // possibly returns a failure object indicating an allocation failure.
1363bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  Object* PopHandleScopeHelper(Register saved,
1364bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch                               Register scratch,
1365bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch                               bool gc_allowed);
1366e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
13673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Helper for implementing JumpIfNotInNewSpace and JumpIfInNewSpace.
13683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void InNewSpace(Register object,
13693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                  Register scratch,
13703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                  Condition cc,
13713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                  Label* branch,
13723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                  Label::Distance distance = Label::kFar);
13733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
13743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Helper for finding the mark bits for an address.  Afterwards, the
13753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // bitmap register points at the word with the mark bits and the mask
13763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // the position of the first bit.  Uses rcx as scratch and leaves addr_reg
13773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // unchanged.
13783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  inline void GetMarkBits(Register addr_reg,
13793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                          Register bitmap_reg,
13803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                          Register mask_reg);
13813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
13823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Helper for throwing exceptions.  Compute a handler address and jump to
13833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // it.  See the implementation for register usage.
13843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void JumpToHandlerEntry();
1385e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1386e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // Compute memory operands for safepoint stack slots.
1387e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  Operand SafepointRegisterSlot(Register reg);
1388e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  static int SafepointRegisterStackIndex(int reg_code) {
1389e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    return kNumSafepointRegisters - kSafepointPushRegisterIndices[reg_code] - 1;
1390e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
1391e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
1392e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // Needs access to SafepointRegisterStackIndex for optimized frame
1393e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // traversal.
1394e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  friend class OptimizedFrame;
1395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
1396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The code patcher is used to patch (typically) small parts of code e.g. for
1399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// debugging and other types of instrumentation. When using the code patcher
1400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// the exact number of bytes specified must be emitted. Is not legal to emit
1401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// relocation information. If any of these constraints are violated it causes
1402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// an assertion.
1403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass CodePatcher {
1404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
1405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CodePatcher(byte* address, int size);
1406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  virtual ~CodePatcher();
1407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Macro assembler to emit code.
1409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  MacroAssembler* masm() { return &masm_; }
1410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
1412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  byte* address_;  // The address of the code being patched.
1413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int size_;  // Number of bytes of the expected patch size.
1414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  MacroAssembler masm_;  // Macro assembler used to generate the code.
1415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
1416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// -----------------------------------------------------------------------------
1419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Static helper functions.
1420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Generate an Operand for loading a field from an object.
14223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochinline Operand FieldOperand(Register object, int offset) {
1423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Operand(object, offset - kHeapObjectTag);
1424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Generate an Operand for loading an indexed field from an object.
14283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochinline Operand FieldOperand(Register object,
14293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                            Register index,
14303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                            ScaleFactor scale,
14313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                            int offset) {
1432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Operand(object, index, scale, offset - kHeapObjectTag);
1433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
14363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochinline Operand ContextOperand(Register context, int index) {
14378a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  return Operand(context, Context::SlotOffset(index));
14388a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
14398a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
14408a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
14413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochinline Operand GlobalObjectOperand() {
14428a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  return ContextOperand(rsi, Context::GLOBAL_INDEX);
14438a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
14448a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
14458a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
14468a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang// Provides access to exit frame stack space (not GCed).
14473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochinline Operand StackSpaceOperand(int index) {
14488a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang#ifdef _WIN64
14498a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  const int kShaddowSpace = 4;
14508a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  return Operand(rsp, (index + kShaddowSpace) * kPointerSize);
14518a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang#else
14528a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  return Operand(rsp, index * kPointerSize);
14538a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang#endif
14548a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
14558a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
14568a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
14578a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
1458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef GENERATED_CODE_COVERAGE
1459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockextern void LogGeneratedCodeCoverage(const char* file_line);
1460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CODE_COVERAGE_STRINGIFY(x) #x
1461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x)
1462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__)
1463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define ACCESS_MASM(masm) {                                               \
1464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    byte* x64_coverage_function =                                         \
1465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        reinterpret_cast<byte*>(FUNCTION_ADDR(LogGeneratedCodeCoverage)); \
1466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    masm->pushfd();                                                       \
1467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    masm->pushad();                                                       \
1468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    masm->push(Immediate(reinterpret_cast<int>(&__FILE_LINE__)));         \
1469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    masm->call(x64_coverage_function, RelocInfo::RUNTIME_ENTRY);          \
1470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    masm->pop(rax);                                                       \
1471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    masm->popad();                                                        \
1472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    masm->popfd();                                                        \
1473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }                                                                       \
1474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  masm->
1475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#else
1476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define ACCESS_MASM(masm) masm->
1477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
1478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
1480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif  // V8_X64_MACRO_ASSEMBLER_X64_H_
1482