1f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com// Copyright 2012 the V8 project authors. All rights reserved.
25ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// Redistribution and use in source and binary forms, with or without
35ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// modification, are permitted provided that the following conditions are
45ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// met:
55ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org//
65ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org//     * Redistributions of source code must retain the above copyright
75ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org//       notice, this list of conditions and the following disclaimer.
85ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org//     * Redistributions in binary form must reproduce the above
95ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org//       copyright notice, this list of conditions and the following
105ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org//       disclaimer in the documentation and/or other materials provided
115ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org//       with the distribution.
125ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org//     * Neither the name of Google Inc. nor the names of its
135ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org//       contributors may be used to endorse or promote products derived
145ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org//       from this software without specific prior written permission.
155ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org//
165ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
175ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
185ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
195ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
205ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
215ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
225ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
235ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
245ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
255ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
265ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
275ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
289085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#ifndef V8_X64_MACRO_ASSEMBLER_X64_H_
299085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#define V8_X64_MACRO_ASSEMBLER_X64_H_
309085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
319085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#include "assembler.h"
32c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#include "frames.h"
33c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org#include "v8globals.h"
349085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
3571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 {
3671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal {
379085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
38e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org// Default scratch register used by MacroAssembler (and other code that needs
39e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org// a spare register). The register isn't callee save, and not used by the
40e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org// function calling convention.
411b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgconst Register kScratchRegister = { 10 };      // r10.
421b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgconst Register kSmiConstantRegister = { 12 };  // r12 (callee save).
431b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgconst Register kRootRegister = { 13 };         // r13 (callee save).
4469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org// Value of smi in kSmiConstantRegister.
451b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgconst int kSmiConstantRegisterValue = 1;
468f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org// Actual value of root register is offset from the root array's start
478f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org// to take advantage of negitive 8-bit displacement values.
481b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgconst int kRootRegisterBias = 128;
49e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org
500c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org// Convenience for platform-independent signatures.
510c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.orgtypedef Operand MemOperand;
520c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
53c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comenum RememberedSetAction { EMIT_REMEMBERED_SET, OMIT_REMEMBERED_SET };
54c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comenum SmiCheck { INLINE_SMI_CHECK, OMIT_SMI_CHECK };
55c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
56e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.orgenum SmiOperationConstraint {
57e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  PRESERVE_SOURCE_REGISTER,
58e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  BAILOUT_ON_NO_OVERFLOW,
59e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  BAILOUT_ON_OVERFLOW,
60e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  NUMBER_OF_CONSTRAINTS
61e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org};
62e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org
63e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.orgSTATIC_ASSERT(NUMBER_OF_CONSTRAINTS <= 8);
64e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org
65e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.orgclass SmiOperationExecutionMode : public EnumSet<SmiOperationConstraint, byte> {
66e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org public:
67e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  SmiOperationExecutionMode() : EnumSet<SmiOperationConstraint, byte>(0) { }
68e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  explicit SmiOperationExecutionMode(byte bits)
69e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org      : EnumSet<SmiOperationConstraint, byte>(bits) { }
70e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org};
71e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org
72c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool AreAliased(Register r1, Register r2, Register r3, Register r4);
73c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
749085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// Forward declaration.
759085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.orgclass JumpTarget;
769085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
774af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgstruct SmiIndex {
784af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  SmiIndex(Register index_register, ScaleFactor scale)
794af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org      : reg(index_register),
804af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org        scale(scale) {}
814af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  Register reg;
824af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  ScaleFactor scale;
834af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org};
849085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
85c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
869085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// MacroAssembler implements a collection of frequently used macros.
879085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.orgclass MacroAssembler: public Assembler {
889085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org public:
89c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  // The isolate parameter can be NULL if the macro assembler should
90c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  // not use isolate-dependent functionality. In this case, it's the
91c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  // responsibility of the caller to never invoke such function on the
92c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  // macro assembler.
93c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  MacroAssembler(Isolate* isolate, void* buffer, int size);
949085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
95ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // Prevent the use of the RootArray during the lifetime of this
96ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // scope object.
97ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  class NoRootArrayScope BASE_EMBEDDED {
98ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org   public:
99ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    explicit NoRootArrayScope(MacroAssembler* assembler)
100ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        : variable_(&assembler->root_array_available_),
101ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          old_value_(assembler->root_array_available_) {
102ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      assembler->root_array_available_ = false;
103ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    }
104ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    ~NoRootArrayScope() {
105ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      *variable_ = old_value_;
106ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    }
107ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org   private:
108ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    bool* variable_;
109ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    bool old_value_;
110ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  };
111ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
112ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // Operand pointing to an external reference.
113ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // May emit code to set up the scratch register. The operand is
114ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // only guaranteed to be correct as long as the scratch register
115ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // isn't changed.
116ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // If the operand is used more than once, use a scratch register
117ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // that is guaranteed not to be clobbered.
118ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Operand ExternalOperand(ExternalReference reference,
119ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                          Register scratch = kScratchRegister);
120ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // Loads and stores the value of an external reference.
121ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // Special case code for load and store to take advantage of
122ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // load_rax/store_rax if possible/necessary.
123ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // For other operations, just use:
124ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  //   Operand operand = ExternalOperand(extref);
125ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  //   operation(operand, ..);
126ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  void Load(Register destination, ExternalReference source);
127ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  void Store(ExternalReference destination, Register source);
128ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // Loads the address of the external reference into the destination
129ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // register.
130ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  void LoadAddress(Register destination, ExternalReference source);
131ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // Returns the size of the code generated by LoadAddress.
132ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // Used by CallSize(ExternalReference) to find the size of a call.
133ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  int LoadAddressSize(ExternalReference source);
134ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  // Pushes the address of the external reference onto the stack.
135ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com  void PushAddress(ExternalReference source);
136ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
137ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // Operations on roots in the root-array.
13818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  void LoadRoot(Register destination, Heap::RootListIndex index);
139ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  void StoreRoot(Register source, Heap::RootListIndex index);
1408f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  // Load a root value where the index (or part of it) is variable.
1418f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  // The variable_offset register is added to the fixed_offset value
1428f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  // to get the index into the root-array.
1438f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  void LoadRootIndexed(Register destination,
1448f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                       Register variable_offset,
1458f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                       int fixed_offset);
14618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  void CompareRoot(Register with, Heap::RootListIndex index);
14783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  void CompareRoot(const Operand& with, Heap::RootListIndex index);
14818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  void PushRoot(Heap::RootListIndex index);
14918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
150c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // These functions do not arrange the registers in any particular order so
151c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // they are not useful for calls that can cause a GC.  The caller can
152c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // exclude up to 3 registers that do not need to be saved and restored.
153c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void PushCallerSaved(SaveFPRegsMode fp_mode,
154c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                       Register exclusion1 = no_reg,
155c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                       Register exclusion2 = no_reg,
156c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                       Register exclusion3 = no_reg);
157c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void PopCallerSaved(SaveFPRegsMode fp_mode,
158c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                      Register exclusion1 = no_reg,
159c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                      Register exclusion2 = no_reg,
160c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                      Register exclusion3 = no_reg);
161c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
162c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// ---------------------------------------------------------------------------
163c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// GC Support
164c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
165c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
166c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  enum RememberedSetFinalAction {
167c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    kReturnAtEnd,
168c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    kFallThroughAtEnd
169c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  };
1704111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org
171c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Record in the remembered set the fact that we have a pointer to new space
172c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // at the address pointed to by the addr register.  Only works if addr is not
173c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // in new space.
174c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void RememberedSetHelper(Register object,  // Used for debug code.
175c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                           Register addr,
176c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                           Register scratch,
177c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                           SaveFPRegsMode save_fp,
178c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                           RememberedSetFinalAction and_then);
179c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
180c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void CheckPageFlag(Register object,
181c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     Register scratch,
182c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     int mask,
183c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     Condition cc,
184c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     Label* condition_met,
185c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     Label::Distance condition_met_distance = Label::kFar);
186c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
187f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  void CheckMapDeprecated(Handle<Map> map,
188f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org                          Register scratch,
189f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org                          Label* if_deprecated);
190f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
191c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Check if object is in new space.  Jumps if the object is not in new space.
192c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // The register scratch can be object itself, but scratch will be clobbered.
193c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void JumpIfNotInNewSpace(Register object,
194c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                           Register scratch,
195c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                           Label* branch,
196c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                           Label::Distance distance = Label::kFar) {
197c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    InNewSpace(object, scratch, not_equal, branch, distance);
198c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
199c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
200c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Check if object is in new space.  Jumps if the object is in new space.
201c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // The register scratch can be object itself, but it will be clobbered.
202c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void JumpIfInNewSpace(Register object,
203c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                        Register scratch,
204c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                        Label* branch,
205c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                        Label::Distance distance = Label::kFar) {
206c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    InNewSpace(object, scratch, equal, branch, distance);
207c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
208c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
209c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Check if an object has the black incremental marking color.  Also uses rcx!
210c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void JumpIfBlack(Register object,
211c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                   Register scratch0,
212c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                   Register scratch1,
213c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                   Label* on_black,
214c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                   Label::Distance on_black_distance = Label::kFar);
215c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
2162efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // Detects conservatively whether an object is data-only, i.e. it does need to
217c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // be scanned by the garbage collector.
218c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void JumpIfDataObject(Register value,
219c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                        Register scratch,
220c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                        Label* not_data_object,
221c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                        Label::Distance not_data_object_distance);
222c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
223c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Checks the color of an object.  If the object is already grey or black
224c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // then we just fall through, since it is already live.  If it is white and
225c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // we can determine that it doesn't need to be scanned, then we just mark it
226c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // black and fall through.  For the rest we jump to the label so the
227c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // incremental marker can fix its assumptions.
228c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void EnsureNotWhite(Register object,
229c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                      Register scratch1,
230c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                      Register scratch2,
231c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                      Label* object_is_white_and_not_data,
232c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                      Label::Distance distance);
233c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
234c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Notify the garbage collector that we wrote a pointer into an object.
235c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // |object| is the object being stored into, |value| is the object being
236c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // stored.  value and scratch registers are clobbered by the operation.
237c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // The offset is the offset from the start of the object, not the offset from
238c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // the tagged HeapObject pointer.  For use with FieldOperand(reg, off).
239c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void RecordWriteField(
240c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Register object,
241c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      int offset,
242c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Register value,
243c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Register scratch,
244c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      SaveFPRegsMode save_fp,
245c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
246c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      SmiCheck smi_check = INLINE_SMI_CHECK);
247c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
248c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // As above, but the offset has the tag presubtracted.  For use with
249c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Operand(reg, off).
250c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void RecordWriteContextSlot(
251c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Register context,
252c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      int offset,
253c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Register value,
254c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Register scratch,
255c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      SaveFPRegsMode save_fp,
256c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
257c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      SmiCheck smi_check = INLINE_SMI_CHECK) {
258c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    RecordWriteField(context,
259c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     offset + kHeapObjectTag,
260c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     value,
261c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     scratch,
262c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     save_fp,
263c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     remembered_set_action,
264c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     smi_check);
265c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
266c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
267c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Notify the garbage collector that we wrote a pointer into a fixed array.
268c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // |array| is the array being stored into, |value| is the
269394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // object being stored.  |index| is the array index represented as a non-smi.
270394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // All registers are clobbered by the operation RecordWriteArray
271c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // filters out smis so it does not update the write barrier if the
272c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // value is a smi.
273c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void RecordWriteArray(
274c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Register array,
275c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Register value,
276c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Register index,
277c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      SaveFPRegsMode save_fp,
278c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
279c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      SmiCheck smi_check = INLINE_SMI_CHECK);
280c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
281c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // For page containing |object| mark region covering |address|
28269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  // dirty. |object| is the object being stored into, |value| is the
283c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // object being stored. The address and value registers are clobbered by the
28469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  // operation.  RecordWrite filters out smis so it does not update
28569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  // the write barrier if the value is a smi.
286c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void RecordWrite(
287c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Register object,
288c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Register address,
289c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Register value,
290c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      SaveFPRegsMode save_fp,
291c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
292c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      SmiCheck smi_check = INLINE_SMI_CHECK);
2939d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com
2949085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#ifdef ENABLE_DEBUGGER_SUPPORT
2959085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // ---------------------------------------------------------------------------
2969085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // Debugger Support
2979085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
2985c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void DebugBreak();
2999085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#endif
3009085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
301c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  // Generates function and stub prologue code.
302c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  void Prologue(PrologueFrameMode frame_mode);
303c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org
304c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // Enter specific kind of exit frame; either in normal or
305c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  // debug mode. Expects the number of arguments in register rax and
306a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  // sets up the number of arguments in register rdi and the pointer
307a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  // to the first argument in register rsi.
3084a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  //
3094a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // Allocates arg_stack_space * kPointerSize memory (not GCed) on the stack
3104a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // accessible via StackSpaceOperand.
3110ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  void EnterExitFrame(int arg_stack_space = 0, bool save_doubles = false);
3129085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
3134a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // Enter specific kind of exit frame. Allocates arg_stack_space * kPointerSize
3144a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // memory (not GCed) on the stack accessible via StackSpaceOperand.
3154a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  void EnterApiExitFrame(int arg_stack_space);
316e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org
317a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  // Leave the current exit frame. Expects/provides the return value in
318a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  // register rax:rdx (untouched) and the pointer to the first
319a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  // argument in register rsi.
3200ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  void LeaveExitFrame(bool save_doubles = false);
3219085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
3224a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // Leave the current exit frame. Expects/provides the return value in
3234a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // register rax (untouched).
324528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  void LeaveApiExitFrame(bool restore_context);
3259085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
326a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Push and pop the registers that can hold pointers.
3270ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  void PushSafepointRegisters() { Pushad(); }
3280ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  void PopSafepointRegisters() { Popad(); }
3293a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  // Store the value in register src in the safepoint register stack
3303a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  // slot for register dst.
33146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  void StoreToSafepointRegisterSlot(Register dst, const Immediate& imm);
3323a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  void StoreToSafepointRegisterSlot(Register dst, Register src);
3335d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org  void LoadFromSafepointRegisterSlot(Register dst, Register src);
3340ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org
3358f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  void InitializeRootRegister() {
336394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    ExternalReference roots_array_start =
337394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        ExternalReference::roots_array_start(isolate());
338e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    Move(kRootRegister, roots_array_start);
3398f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    addq(kRootRegister, Immediate(kRootRegisterBias));
3408f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  }
3418f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
3429085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // ---------------------------------------------------------------------------
3439085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // JavaScript invokes
3449085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
345f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // Set up call kind marking in rcx. The method takes rcx as an
34640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  // explicit first parameter to make the code more readable at the
34740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  // call sites.
34840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  void SetCallKind(Register dst, CallKind kind);
34940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org
3509085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // Invoke the JavaScript function code by either calling or jumping.
351eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  void InvokeCode(Register code,
3529085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org                  const ParameterCount& expected,
3539085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org                  const ParameterCount& actual,
3543a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                  InvokeFlag flag,
355d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org                  const CallWrapper& call_wrapper,
356d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org                  CallKind call_kind);
3579085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
3589085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  void InvokeCode(Handle<Code> code,
3599085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org                  const ParameterCount& expected,
3609085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org                  const ParameterCount& actual,
3619085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org                  RelocInfo::Mode rmode,
3623a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                  InvokeFlag flag,
363d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org                  const CallWrapper& call_wrapper,
364d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org                  CallKind call_kind);
3659085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
3669085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // Invoke the JavaScript function in the given register. Changes the
3679085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // current context to the context in the function before invoking.
3689085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  void InvokeFunction(Register function,
3699085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org                      const ParameterCount& actual,
3703a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                      InvokeFlag flag,
371d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org                      const CallWrapper& call_wrapper,
372d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org                      CallKind call_kind);
3739085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
3748a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org  void InvokeFunction(Register function,
3758a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org                      const ParameterCount& expected,
3768a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org                      const ParameterCount& actual,
3778a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org                      InvokeFlag flag,
3788a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org                      const CallWrapper& call_wrapper,
3798a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org                      CallKind call_kind);
3808a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org
381c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  void InvokeFunction(Handle<JSFunction> function,
38232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org                      const ParameterCount& expected,
3835c838251403b0be9a882540f1922577abba4c872ager@chromium.org                      const ParameterCount& actual,
3843a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                      InvokeFlag flag,
385d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org                      const CallWrapper& call_wrapper,
386d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org                      CallKind call_kind);
3875c838251403b0be9a882540f1922577abba4c872ager@chromium.org
3889085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // Invoke specified builtin JavaScript function. Adds an entry to
3899085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // the unresolved list if the name does not resolve.
3903a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  void InvokeBuiltin(Builtins::JavaScript id,
3913a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                     InvokeFlag flag,
392fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org                     const CallWrapper& call_wrapper = NullCallWrapper());
3939085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
394145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com  // Store the function for the given builtin in the target register.
395145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com  void GetBuiltinFunction(Register target, Builtins::JavaScript id);
396145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com
3979085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // Store the code object for the given builtin in the target register.
3989085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  void GetBuiltinEntry(Register target, Builtins::JavaScript id);
3999085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
4004af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
4014af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // ---------------------------------------------------------------------------
4024af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Smi tagging, untagging and operations on tagged smis.
4034af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
404dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  // Support for constant splitting.
405dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  bool IsUnsafeInt(const int32_t x);
406dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  void SafeMove(Register dst, Smi* src);
407dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org  void SafePush(Smi* src);
408dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
40969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  void InitializeSmiConstantRegister() {
410e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    movq(kSmiConstantRegister, Smi::FromInt(kSmiConstantRegisterValue),
4114cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org         RelocInfo::NONE64);
41269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  }
41369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org
4144af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Conversions between tagged smi values and non-tagged integer values.
4154af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
4164af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Tag an integer value. The result must be known to be a valid smi value.
417b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // Only uses the low 32 bits of the src register. Sets the N and Z flags
418c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org  // based on the value of the resulting smi.
4194af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  void Integer32ToSmi(Register dst, Register src);
4204af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
4215ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  // Stores an integer32 value into a memory field that already holds a smi.
4225ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  void Integer32ToSmiField(const Operand& dst, Register src);
4235ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
4244af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Adds constant to src and tags the result as a smi.
4254af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Result must be a valid smi.
4269d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  void Integer64PlusConstantToSmi(Register dst, Register src, int constant);
4274af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
4284af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Convert smi to 32-bit integer. I.e., not sign extended into
4294af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // high 32 bits of destination.
4304af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  void SmiToInteger32(Register dst, Register src);
43130ce411529579186181838984710b0b0980857aaricow@chromium.org  void SmiToInteger32(Register dst, const Operand& src);
4324af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
4334af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Convert smi to 64-bit integer (sign extended if necessary).
4344af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  void SmiToInteger64(Register dst, Register src);
4355ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  void SmiToInteger64(Register dst, const Operand& src);
4364af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
4374af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Multiply a positive smi's integer value by a power of two.
4384af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Provides result as 64-bit integer value.
4394af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  void PositiveSmiTimesPowerOfTwoToInteger64(Register dst,
4404af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org                                             Register src,
4414af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org                                             int power);
4424af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
44330ce411529579186181838984710b0b0980857aaricow@chromium.org  // Divide a positive smi's integer value by a power of two.
44430ce411529579186181838984710b0b0980857aaricow@chromium.org  // Provides result as 32-bit integer value.
44530ce411529579186181838984710b0b0980857aaricow@chromium.org  void PositiveSmiDivPowerOfTwoToInteger32(Register dst,
44630ce411529579186181838984710b0b0980857aaricow@chromium.org                                           Register src,
44730ce411529579186181838984710b0b0980857aaricow@chromium.org                                           int power);
44830ce411529579186181838984710b0b0980857aaricow@chromium.org
44944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  // Perform the logical or of two smi values and return a smi value.
45044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  // If either argument is not a smi, jump to on_not_smis and retain
45144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  // the original values of source registers. The destination register
45244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  // may be changed if it's not one of the source registers.
45344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  void SmiOrIfSmis(Register dst,
45444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org                   Register src1,
45544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org                   Register src2,
45683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                   Label* on_not_smis,
45783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                   Label::Distance near_jump = Label::kFar);
45844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
45930ce411529579186181838984710b0b0980857aaricow@chromium.org
460badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  // Simple comparison of smis.  Both sides must be known smis to use these,
461badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  // otherwise use Cmp.
462badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  void SmiCompare(Register smi1, Register smi2);
4639d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  void SmiCompare(Register dst, Smi* src);
464ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org  void SmiCompare(Register dst, const Operand& src);
4659d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  void SmiCompare(const Operand& dst, Register src);
4669d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  void SmiCompare(const Operand& dst, Smi* src);
4675ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  // Compare the int32 in src register to the value of the smi stored at dst.
4685ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org  void SmiCompareInteger32(const Operand& dst, Register src);
4699d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  // Sets sign and zero flags depending on value of smi in register.
4709d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  void SmiTest(Register src);
4719d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com
4724af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Functions performing a check on a known or potential smi. Returns
4734af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // a condition that is satisfied if the check is successful.
4744af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
4754af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Is the value a tagged smi.
4764af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  Condition CheckSmi(Register src);
4770a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  Condition CheckSmi(const Operand& src);
4784af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
479eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org  // Is the value a non-negative tagged smi.
480eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org  Condition CheckNonNegativeSmi(Register src);
4814af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
482b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // Are both values tagged smis.
4834af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  Condition CheckBothSmi(Register first, Register second);
4844af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
485eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org  // Are both values non-negative tagged smis.
486eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org  Condition CheckBothNonNegativeSmi(Register first, Register second);
487b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
488b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // Are either value a tagged smi.
489c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org  Condition CheckEitherSmi(Register first,
490c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org                           Register second,
491c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org                           Register scratch = kScratchRegister);
492b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
4934af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Is the value the minimum smi value (since we are using
4944af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // two's complement numbers, negating the value is known to yield
4954af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // a non-smi value).
4964af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  Condition CheckIsMinSmi(Register src);
4974af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
4984af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Checks whether an 32-bit integer value is a valid for conversion
4994af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // to a smi.
5004af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  Condition CheckInteger32ValidSmiValue(Register src);
5014af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
5023811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  // Checks whether an 32-bit unsigned integer value is a valid for
5033811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  // conversion to a smi.
5043811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  Condition CheckUInteger32ValidSmiValue(Register src);
5053811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
5060ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  // Check whether src is a Smi, and set dst to zero if it is a smi,
5070ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  // and to one if it isn't.
5080ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  void CheckSmiToIndicator(Register dst, Register src);
5090ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  void CheckSmiToIndicator(Register dst, const Operand& src);
5100ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org
5114af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Test-and-jump functions. Typically combines a check function
5124af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // above with a conditional jump.
5134af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
5144af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Jump if the value cannot be represented by a smi.
51583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void JumpIfNotValidSmiValue(Register src, Label* on_invalid,
51683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                              Label::Distance near_jump = Label::kFar);
5174af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
5183811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  // Jump if the unsigned integer value cannot be represented by a smi.
51983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void JumpIfUIntNotValidSmiValue(Register src, Label* on_invalid,
52083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                  Label::Distance near_jump = Label::kFar);
5213811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
5224af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Jump to label if the value is a tagged smi.
52383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void JumpIfSmi(Register src,
52483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                 Label* on_smi,
52583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                 Label::Distance near_jump = Label::kFar);
5264af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
5274af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Jump to label if the value is not a tagged smi.
52883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void JumpIfNotSmi(Register src,
52983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                    Label* on_not_smi,
53083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                    Label::Distance near_jump = Label::kFar);
5314af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
532eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org  // Jump to label if the value is not a non-negative tagged smi.
53383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void JumpUnlessNonNegativeSmi(Register src,
53483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                Label* on_not_smi,
53583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                Label::Distance near_jump = Label::kFar);
5364af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
5379d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  // Jump to label if the value, which must be a tagged smi, has value equal
5384af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // to the constant.
539c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org  void JumpIfSmiEqualsConstant(Register src,
540c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org                               Smi* constant,
54183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                               Label* on_equals,
54283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                               Label::Distance near_jump = Label::kFar);
543c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
5444af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Jump if either or both register are not smi values.
545c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org  void JumpIfNotBothSmi(Register src1,
546c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org                        Register src2,
54783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                        Label* on_not_both_smi,
54883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                        Label::Distance near_jump = Label::kFar);
5494af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
550eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org  // Jump if either or both register are not non-negative smi values.
551eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org  void JumpUnlessBothNonNegativeSmi(Register src1, Register src2,
55283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                    Label* on_not_both_smi,
55383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                    Label::Distance near_jump = Label::kFar);
554b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
5554af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Operations on tagged smi values.
5564af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
5574af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Smis represent a subset of integers. The subset is always equivalent to
5584af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // a two's complement interpretation of a fixed number of bits.
5594af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
5609d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  // Add an integer constant to a tagged smi, giving a tagged smi as result.
5619d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  // No overflow testing on the result is done.
5629d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  void SmiAddConstant(Register dst, Register src, Smi* constant);
5639d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com
5649dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  // Add an integer constant to a tagged smi, giving a tagged smi as result.
5659dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  // No overflow testing on the result is done.
5669dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com  void SmiAddConstant(const Operand& dst, Smi* constant);
5679dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
5684af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Add an integer constant to a tagged smi, giving a tagged smi as result,
5694af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // or jumping to a label if the result cannot be represented by a smi.
5704af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  void SmiAddConstant(Register dst,
5714af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org                      Register src,
5729d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com                      Smi* constant,
573e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org                      SmiOperationExecutionMode mode,
574e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org                      Label* bailout_label,
57583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                      Label::Distance near_jump = Label::kFar);
5764af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
5774af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Subtract an integer constant from a tagged smi, giving a tagged smi as
578ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org  // result. No testing on the result is done. Sets the N and Z flags
579ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org  // based on the value of the resulting integer.
5809d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  void SmiSubConstant(Register dst, Register src, Smi* constant);
5819d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com
5829d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  // Subtract an integer constant from a tagged smi, giving a tagged smi as
5834af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // result, or jumping to a label if the result cannot be represented by a smi.
5844af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  void SmiSubConstant(Register dst,
5854af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org                      Register src,
5869d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com                      Smi* constant,
587e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org                      SmiOperationExecutionMode mode,
588e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org                      Label* bailout_label,
58983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                      Label::Distance near_jump = Label::kFar);
5904af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
5914af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Negating a smi can give a negative zero or too large positive value.
5929d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  // NOTICE: This operation jumps on success, not failure!
5934af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  void SmiNeg(Register dst,
5944af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org              Register src,
59583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org              Label* on_smi_result,
59683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org              Label::Distance near_jump = Label::kFar);
5974af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
5984af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Adds smi values and return the result as a smi.
599d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  // If dst is src1, then src1 will be destroyed if the operation is
600d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  // successful, otherwise kept intact.
6014af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  void SmiAdd(Register dst,
6024af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org              Register src1,
6034af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org              Register src2,
60483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org              Label* on_not_smi_result,
60583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org              Label::Distance near_jump = Label::kFar);
6067979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  void SmiAdd(Register dst,
6077979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org              Register src1,
6087979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org              const Operand& src2,
60983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org              Label* on_not_smi_result,
61083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org              Label::Distance near_jump = Label::kFar);
611c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org
612c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org  void SmiAdd(Register dst,
613c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org              Register src1,
614c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org              Register src2);
6154af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
6164af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Subtracts smi values and return the result as a smi.
617c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org  // If dst is src1, then src1 will be destroyed if the operation is
618c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org  // successful, otherwise kept intact.
6194af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  void SmiSub(Register dst,
6204af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org              Register src1,
6214af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org              Register src2,
62283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org              Label* on_not_smi_result,
62383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org              Label::Distance near_jump = Label::kFar);
624ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org  void SmiSub(Register dst,
625ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org              Register src1,
6269dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com              const Operand& src2,
62783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org              Label* on_not_smi_result,
62883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org              Label::Distance near_jump = Label::kFar);
629c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org
630c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org  void SmiSub(Register dst,
631c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org              Register src1,
632c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org              Register src2);
633c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org
634c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org  void SmiSub(Register dst,
635c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org              Register src1,
636c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org              const Operand& src2);
637ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org
6384af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Multiplies smi values and return the result as a smi,
6394af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // if possible.
6404af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // If dst is src1, then src1 will be destroyed, even if
6414af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // the operation is unsuccessful.
6424af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  void SmiMul(Register dst,
6434af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org              Register src1,
6444af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org              Register src2,
64583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org              Label* on_not_smi_result,
64683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org              Label::Distance near_jump = Label::kFar);
6474af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
6484af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Divides one smi by another and returns the quotient.
6494af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Clobbers rax and rdx registers.
6504af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  void SmiDiv(Register dst,
6514af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org              Register src1,
6524af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org              Register src2,
65383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org              Label* on_not_smi_result,
65483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org              Label::Distance near_jump = Label::kFar);
6554af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
6564af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Divides one smi by another and returns the remainder.
6574af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Clobbers rax and rdx registers.
6584af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  void SmiMod(Register dst,
6594af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org              Register src1,
6604af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org              Register src2,
66183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org              Label* on_not_smi_result,
66283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org              Label::Distance near_jump = Label::kFar);
6634af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
6644af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Bitwise operations.
6654af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  void SmiNot(Register dst, Register src);
6664af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  void SmiAnd(Register dst, Register src1, Register src2);
6674af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  void SmiOr(Register dst, Register src1, Register src2);
6684af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  void SmiXor(Register dst, Register src1, Register src2);
6699d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  void SmiAndConstant(Register dst, Register src1, Smi* constant);
6709d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  void SmiOrConstant(Register dst, Register src1, Smi* constant);
6719d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  void SmiXorConstant(Register dst, Register src1, Smi* constant);
6724af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
6734af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  void SmiShiftLeftConstant(Register dst,
6744af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org                            Register src,
675720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org                            int shift_value);
6764af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  void SmiShiftLogicalRightConstant(Register dst,
6774af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org                                  Register src,
6784af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org                                  int shift_value,
67983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                  Label* on_not_smi_result,
68083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                  Label::Distance near_jump = Label::kFar);
6814af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  void SmiShiftArithmeticRightConstant(Register dst,
6824af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org                                       Register src,
6834af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org                                       int shift_value);
6844af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
6854af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Shifts a smi value to the left, and returns the result if that is a smi.
6864af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Uses and clobbers rcx, so dst may not be rcx.
6874af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  void SmiShiftLeft(Register dst,
6884af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org                    Register src1,
689720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org                    Register src2);
6904af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Shifts a smi value to the right, shifting in zero bits at the top, and
6914af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // returns the unsigned intepretation of the result if that is a smi.
6924af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Uses and clobbers rcx, so dst may not be rcx.
6934af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  void SmiShiftLogicalRight(Register dst,
694c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org                            Register src1,
695c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org                            Register src2,
69683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                            Label* on_not_smi_result,
69783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                            Label::Distance near_jump = Label::kFar);
6984af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Shifts a smi value to the right, sign extending the top, and
6994af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // returns the signed intepretation of the result. That will always
7004af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // be a valid smi value, since it's numerically smaller than the
7014af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // original.
7024af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Uses and clobbers rcx, so dst may not be rcx.
7034af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  void SmiShiftArithmeticRight(Register dst,
7044af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org                               Register src1,
7054af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org                               Register src2);
7064af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
7074af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Specialized operations
7084af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
7094af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Select the non-smi register of two registers where exactly one is a
7104af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // smi. If neither are smis, jump to the failure label.
7114af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  void SelectNonSmi(Register dst,
7124af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org                    Register src1,
7134af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org                    Register src2,
71483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                    Label* on_not_smis,
71583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                    Label::Distance near_jump = Label::kFar);
7164af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
7174af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Converts, if necessary, a smi to a combination of number and
7184af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // multiplier to be used as a scaled index.
7194af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // The src register contains a *positive* smi value. The shift is the
7204af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // power of two to multiply the index value by (e.g.
7214af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // to index by smi-value * kPointerSize, pass the smi and kPointerSizeLog2).
7224af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // The returned index register may be either src or dst, depending
7234af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // on what is most efficient. If src and dst are different registers,
7244af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // src is always unchanged.
7254af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  SmiIndex SmiToIndex(Register dst, Register src, int shift);
7264af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
7274af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Converts a positive smi to a negative index.
7284af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  SmiIndex SmiToNegativeIndex(Register dst, Register src, int shift);
7294af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
7307979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  // Add the value of a smi in memory to an int32 register.
7317979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  // Sets flags as a normal add.
7327979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  void AddSmiField(Register dst, const Operand& src);
7337979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org
7349d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  // Basic Smi operations.
7353811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  void Move(Register dst, Smi* source) {
73669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org    LoadSmiConstant(dst, source);
7373811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  }
7383811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
7393811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  void Move(const Operand& dst, Smi* source) {
74069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org    Register constant = GetSmiConstant(source);
74169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org    movq(dst, constant);
7423811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  }
7433811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
7449d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  void Push(Smi* smi);
745662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
746662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  // Save away a 64-bit integer on the stack as two 32-bit integers
747662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  // masquerading as smis so that the garbage collector skips visiting them.
748662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  void PushInt64AsTwoSmis(Register src, Register scratch = kScratchRegister);
749662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  // Reconstruct a 64-bit integer from two 32-bit integers masquerading as
750662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  // smis on the top of stack.
751662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  void PopInt64AsTwoSmis(Register dst, Register scratch = kScratchRegister);
752662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org
7539d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  void Test(const Operand& dst, Smi* source);
7549d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com
755394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
756eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // ---------------------------------------------------------------------------
757b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // String macros.
75883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
759528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // Generate code to do a lookup in the number string cache. If the number in
760528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // the register object is found in the cache the generated code falls through
761528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // with the result in the result register. The object and the result register
762528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // can be the same. If the number is not found in the cache the code jumps to
763528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // the label not_found with only the content of register object unchanged.
764528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  void LookupNumberStringCache(Register object,
765528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                               Register result,
766528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                               Register scratch1,
767528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                               Register scratch2,
768528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                               Label* not_found);
769528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
77083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  // If object is a string, its map is loaded into object_map.
77183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  void JumpIfNotString(Register object,
77283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org                       Register object_map,
77383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                       Label* not_string,
77483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                       Label::Distance near_jump = Label::kFar);
77583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
77683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
77783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void JumpIfNotBothSequentialAsciiStrings(
77883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Register first_object,
77983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Register second_object,
78083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Register scratch1,
78183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Register scratch2,
78283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Label* on_not_both_flat_ascii,
78383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Label::Distance near_jump = Label::kFar);
784b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
7852efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // Check whether the instance type represents a flat ASCII string. Jump to the
786ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // label if not. If the instance type can be scratched specify same register
787ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // for both instance type and scratch.
788c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org  void JumpIfInstanceTypeIsNotSequentialAscii(
789c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org      Register instance_type,
790c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org      Register scratch,
79183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Label*on_not_flat_ascii_string,
79283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Label::Distance near_jump = Label::kFar);
793ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
794ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void JumpIfBothInstanceTypesAreNotSequentialAscii(
795ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org      Register first_object_instance_type,
796ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org      Register second_object_instance_type,
797ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org      Register scratch1,
798ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org      Register scratch2,
79983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Label* on_fail,
80083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      Label::Distance near_jump = Label::kFar);
801ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
8029af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  void EmitSeqStringSetCharCheck(Register string,
8039af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org                                 Register index,
8049af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org                                 Register value,
8059af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org                                 uint32_t encoding_mask);
8069af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org
8071510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  // Checks if the given register or operand is a unique name
8081510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  void JumpIfNotUniqueName(Register reg, Label* not_unique_name,
8091510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                           Label::Distance distance = Label::kFar);
8101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  void JumpIfNotUniqueName(Operand operand, Label* not_unique_name,
8111510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                           Label::Distance distance = Label::kFar);
8121510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
813b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // ---------------------------------------------------------------------------
81413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // Macro instructions.
815eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
816d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  // Load/store with specific representation.
817d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  void Load(Register dst, const Operand& src, Representation r);
818d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  void Store(const Operand& dst, Register src, Representation r);
819d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org
8209d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com  // Load a register with a long value as efficiently as possible.
821e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org  void Set(Register dst, int64_t x);
822e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org  void Set(const Operand& dst, int64_t x);
8239085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
824528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // cvtsi2sd instruction only writes to the low 64-bit of dst register, which
825528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // hinders register renaming and makes dependence chains longer. So we use
826528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // xorps to clear the dst register before cvtsi2sd to solve this issue.
827528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  void Cvtlsi2sd(XMMRegister dst, Register src);
828528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  void Cvtlsi2sd(XMMRegister dst, const Operand& src);
829528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
8304a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  // Move if the registers are not identical.
8314a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org  void Move(Register target, Register source);
8324a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org
833394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Bit-field support.
834394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  void TestBit(const Operand& dst, int bit_index);
835394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
8365aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  // Handle support
8375aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  void Move(Register dst, Handle<Object> source);
8385aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  void Move(const Operand& dst, Handle<Object> source);
8395aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  void Cmp(Register dst, Handle<Object> source);
8403e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org  void Cmp(const Operand& dst, Handle<Object> source);
841badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  void Cmp(Register dst, Smi* src);
842badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  void Cmp(const Operand& dst, Smi* src);
8435aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  void Push(Handle<Object> source);
8440c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
84564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Load a heap object and handle the case of new-space objects by
84664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // indirecting via a global cell.
847c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  void MoveHeapObject(Register result, Handle<Object> object);
848a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org
84964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Load a global cell into a register.
85041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  void LoadGlobalCell(Register dst, Handle<Cell> cell);
85164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
8520c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  // Emit code to discard a non-negative number of pointer-sized elements
8530c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  // from the stack, clobbering only the rsp register.
85413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  void Drop(int stack_elements);
8550c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
85613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  void Call(Label* target) { call(target); }
857594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void Push(Register src) { push(src); }
858594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void Pop(Register dst) { pop(dst); }
859594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void PushReturnAddressFrom(Register src) { push(src); }
860594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void PopReturnAddressTo(Register dst) { pop(dst); }
861e94b5ff1e1e95fb2c8ef6bce66ce8533786d9792bmeurer@chromium.org  void MoveDouble(Register dst, const Operand& src) { movq(dst, src); }
862e94b5ff1e1e95fb2c8ef6bce66ce8533786d9792bmeurer@chromium.org  void MoveDouble(const Operand& dst, Register src) { movq(dst, src); }
863e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  void Move(Register dst, ExternalReference ext) {
864e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org    movq(dst, reinterpret_cast<Address>(ext.address()),
865e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org         RelocInfo::EXTERNAL_REFERENCE);
866e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  }
8675aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
868eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Control Flow
869eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  void Jump(Address destination, RelocInfo::Mode rmode);
870eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  void Jump(ExternalReference ext);
8715aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org  void Jump(Handle<Code> code_object, RelocInfo::Mode rmode);
8725aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org
873eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  void Call(Address destination, RelocInfo::Mode rmode);
874eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  void Call(ExternalReference ext);
8758e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  void Call(Handle<Code> code_object,
8768e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org            RelocInfo::Mode rmode,
877471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org            TypeFeedbackId ast_id = TypeFeedbackId::None());
878eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
879eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org  // The size of the code generated for different call instructions.
880eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org  int CallSize(Address destination, RelocInfo::Mode rmode) {
881594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    return kCallSequenceLength;
882eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org  }
883ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  int CallSize(ExternalReference ext);
884eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org  int CallSize(Handle<Code> code_object) {
885eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org    // Code calls use 32-bit relative addressing.
886eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org    return kShortCallInstructionLength;
887eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org  }
888eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org  int CallSize(Register target) {
889eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org    // Opcode: REX_opt FF /2 m64
890eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org    return (target.high_bit() != 0) ? 3 : 2;
891eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org  }
892eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org  int CallSize(const Operand& target) {
893eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org    // Opcode: REX_opt FF /2 m64
894eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org    return (target.requires_rex() ? 2 : 1) + target.operand_size();
895eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org  }
896eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org
89783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  // Emit call to the code we are currently generating.
89883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  void CallSelf() {
89983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org    Handle<Code> self(reinterpret_cast<Code**>(CodeObject().location()));
90083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org    Call(self, RelocInfo::CODE_TARGET);
90183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  }
90283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
9030a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  // Non-x64 instructions.
9040a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  // Push/pop all general purpose registers.
9050a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  // Does not push rsp/rbp nor any of the assembler's special purpose registers
9060a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  // (kScratchRegister, kSmiConstantRegister, kRootRegister).
9070a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  void Pushad();
9080a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  void Popad();
9090ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  // Sets the stack as after performing Popad, without actually loading the
9100ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  // registers.
9110ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  void Dropad();
9120a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
9139085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // Compare object type for heap object.
914e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org  // Always use unsigned comparisons: above and below, not less and greater.
9159085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // Incoming register is heap_object and outgoing register is map.
91686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  // They may be the same register, and may be kScratchRegister.
9179085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  void CmpObjectType(Register heap_object, InstanceType type, Register map);
9189085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
9199085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // Compare instance type for map.
920e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org  // Always use unsigned comparisons: above and below, not less and greater.
9219085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  void CmpInstanceType(Register map, InstanceType type);
9229085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
923d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  // Check if a map for a JSObject indicates that the object has fast elements.
924d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  // Jump to the specified label if it does not.
925d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  void CheckFastElements(Register map,
926d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com                         Label* fail,
927d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com                         Label::Distance distance = Label::kFar);
928d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com
929c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Check if a map for a JSObject indicates that the object can have both smi
930c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // and HeapObject elements.  Jump to the specified label if it does not.
931c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void CheckFastObjectElements(Register map,
932c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                               Label* fail,
933c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                               Label::Distance distance = Label::kFar);
934c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
935c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Check if a map for a JSObject indicates that the object has fast smi only
936c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // elements.  Jump to the specified label if it does not.
937830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  void CheckFastSmiElements(Register map,
938830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org                            Label* fail,
939830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org                            Label::Distance distance = Label::kFar);
940c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
941c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Check to see if maybe_number can be stored as a double in
942394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // FastDoubleElements. If it can, store it at the index specified by index in
943394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // the FastDoubleElements array elements, otherwise jump to fail.  Note that
944394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // index must not be smi-tagged.
945c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void StoreNumberToDoubleElements(Register maybe_number,
946c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                   Register elements,
947394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                   Register index,
948c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                   XMMRegister xmm_scratch,
949fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                                   Label* fail,
950fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                                   int elements_offset = 0);
951c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
952935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  // Compare an object's map with the specified map.
953935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  void CompareMap(Register obj, Handle<Map> map);
954f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
955f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // Check if the map of an object is equal to a specified map and branch to
956f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // label if not. Skip the smi check if not required (object is known to be a
957f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // heap object). If mode is ALLOW_ELEMENT_TRANSITION_MAPS, then also match
9582efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // against maps that are ElementsKind transition maps of the specified map.
9595c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void CheckMap(Register obj,
9605c838251403b0be9a882540f1922577abba4c872ager@chromium.org                Handle<Map> map,
9615c838251403b0be9a882540f1922577abba4c872ager@chromium.org                Label* fail,
962a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org                SmiCheckType smi_check_type);
9635c838251403b0be9a882540f1922577abba4c872ager@chromium.org
964ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  // Check if the map of an object is equal to a specified map and branch to a
965ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  // specified target if equal. Skip the smi check if not required (object is
966ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  // known to be a heap object)
967ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  void DispatchMap(Register obj,
9682bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org                   Register unused,
969ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org                   Handle<Map> map,
970ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org                   Handle<Code> success,
971ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org                   SmiCheckType smi_check_type);
972ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
973b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // Check if the object in register heap_object is a string. Afterwards the
974b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // register map contains the object map and the register instance_type
975b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // contains the instance_type. The registers map and instance_type can be the
976b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // same in which case it contains the instance type afterwards. Either of the
977b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // registers map and instance_type can be the same as heap_object.
978b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  Condition IsObjectStringType(Register heap_object,
979b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org                               Register map,
980b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org                               Register instance_type);
981b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
982750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // Check if the object in register heap_object is a name. Afterwards the
983750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // register map contains the object map and the register instance_type
984750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // contains the instance_type. The registers map and instance_type can be the
985750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // same in which case it contains the instance type afterwards. Either of the
986750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // registers map and instance_type can be the same as heap_object.
987750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  Condition IsObjectNameType(Register heap_object,
988750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                             Register map,
989750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                             Register instance_type);
990750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
99140b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org  // FCmp compares and pops the two values on top of the FPU stack.
99240b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org  // The flag results are similar to integer cmp, but requires unsigned
9939085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // jcc instructions (je, ja, jae, jb, jbe, je, and jz).
9949085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  void FCmp();
9959085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
996c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  void ClampUint8(Register reg);
997c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
998c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  void ClampDoubleToUint8(XMMRegister input_reg,
999c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org                          XMMRegister temp_xmm_reg,
100089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org                          Register result_reg);
1001c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
1002c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  void SlowTruncateToI(Register result_reg, Register input_reg,
1003c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org      int offset = HeapNumber::kValueOffset - kHeapObjectTag);
1004c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org
1005c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  void TruncateHeapNumberToI(Register result_reg, Register input_reg);
1006c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  void TruncateDoubleToI(Register result_reg, XMMRegister input_reg);
1007c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org
1008c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  void DoubleToI(Register result_reg, XMMRegister input_reg,
1009c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org      XMMRegister scratch, MinusZeroMode minus_zero_mode,
1010c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org      Label* conversion_failed, Label::Distance dst = Label::kFar);
1011c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org
1012c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  void TaggedToI(Register result_reg, Register input_reg, XMMRegister temp,
1013c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org      MinusZeroMode minus_zero_mode, Label* lost_precision,
1014c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org      Label::Distance dst = Label::kFar);
1015c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org
101646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  void LoadUint32(XMMRegister dst, Register src, XMMRegister scratch);
101746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
101840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  void LoadInstanceDescriptors(Register map, Register descriptors);
1019355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  void EnumLength(Register dst, Register map);
102006ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  void NumberOfOwnDescriptors(Register dst, Register map);
1021355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org
1022355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  template<typename Field>
1023355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  void DecodeField(Register reg) {
102406ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org    static const int shift = Field::kShift + kSmiShift;
102506ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org    static const int mask = Field::kMask >> Field::kShift;
102606ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org    shr(reg, Immediate(shift));
102706ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org    and_(reg, Immediate(mask));
102806ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org    shl(reg, Immediate(kSmiShift));
1029355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  }
103040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org
1031c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  // Abort execution if argument is not a number, enabled via --debug-code.
1032c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  void AssertNumber(Register object);
10335c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1034c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  // Abort execution if argument is a smi, enabled via --debug-code.
1035c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  void AssertNotSmi(Register object);
1036ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
1037c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  // Abort execution if argument is not a smi, enabled via --debug-code.
1038c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  void AssertSmi(Register object);
1039c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  void AssertSmi(const Operand& object);
104025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
1041f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  // Abort execution if a 64 bit register containing a 32 bit payload does not
1042c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  // have zeros in the top 32 bits, enabled via --debug-code.
1043c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  void AssertZeroExtended(Register reg);
1044f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org
1045c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  // Abort execution if argument is not a string, enabled via --debug-code.
1046c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  void AssertString(Register object);
104749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
1048750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // Abort execution if argument is not a name, enabled via --debug-code.
1049750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  void AssertName(Register object);
1050750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
1051c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  // Abort execution if argument is not the root value with the given index,
1052c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  // enabled via --debug-code.
1053c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  void AssertRootValue(Register src,
1054c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org                       Heap::RootListIndex root_value_index,
1055594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                       BailoutReason reason);
10565ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org
10579085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // ---------------------------------------------------------------------------
10589085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // Exception handling
10599085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
106004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  // Push a new try handler and link it into try handler chain.
106178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  void PushTryHandler(StackHandler::Kind kind, int handler_index);
10629085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
106313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // Unlink the stack handler on top of the stack from the try handler chain.
106413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  void PopTryHandler();
10659085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
106649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  // Activate the top handler in the try hander chain and pass the
106749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  // thrown value.
106849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  void Throw(Register value);
106949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
107049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  // Propagate an uncatchable exception out of the current JS stack.
107165a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org  void ThrowUncatchable(Register value);
107249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
10739af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  // Throw a message string as an exception.
10749af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  void Throw(BailoutReason reason);
10759af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org
10769af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  // Throw a message string as an exception if a condition is not true.
10779af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  void ThrowIf(Condition cc, BailoutReason reason);
10789af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org
10799085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // ---------------------------------------------------------------------------
10809085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // Inline caching support
10819085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
10829085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // Generate code for checking access rights - used for security checks
10839085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // on access to global objects across environments. The holder register
1084e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org  // is left untouched, but the scratch register and kScratchRegister,
1085e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org  // which must be different, are clobbered.
10869085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  void CheckAccessGlobalProxy(Register holder_reg,
10879085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org                              Register scratch,
10889085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org                              Label* miss);
10899085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
1090f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  void GetNumberHash(Register r0, Register scratch);
10919085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
10926db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  void LoadFromNumberDictionary(Label* miss,
10936db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org                                Register elements,
10946db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org                                Register key,
10956db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org                                Register r0,
10966db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org                                Register r1,
10976db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org                                Register r2,
10986db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org                                Register result);
10996db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org
11006db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org
11019085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // ---------------------------------------------------------------------------
110218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // Allocation support
110318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
11042bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  // Allocate an object in new space or old pointer space. If the given space
11052bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  // is exhausted control continues at the gc_required label. The allocated
11062bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  // object is returned in result and end of the new object is returned in
11072bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  // result_end. The register scratch can be passed as no_reg in which case
11082bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  // an additional object reference will be added to the reloc info. The
11092bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  // returned pointers in result and result_end have not yet been tagged as
11102bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  // heap objects. If result_contains_top_on_entry is true the content of
11112bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  // result is known to be the allocation top on entry (could be result_end
11122bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  // from a previous call). If result_contains_top_on_entry is true scratch
111318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // should be no_reg as it is never used.
11142bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  void Allocate(int object_size,
11152bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org                Register result,
11162bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org                Register result_end,
11172bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org                Register scratch,
11182bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org                Label* gc_required,
11192bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org                AllocationFlags flags);
1120c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org
1121f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  void Allocate(int header_size,
1122f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                ScaleFactor element_size,
1123f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                Register element_count,
1124f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                Register result,
1125f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                Register result_end,
1126f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                Register scratch,
1127f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                Label* gc_required,
1128f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                AllocationFlags flags);
1129f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org
1130f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  void Allocate(Register object_size,
1131f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                Register result,
1132f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                Register result_end,
1133f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                Register scratch,
1134f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                Label* gc_required,
1135f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                AllocationFlags flags);
113618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
113718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // Undo allocation in new space. The object passed and objects allocated after
113818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // it will no longer be allocated. Make sure that no pointers are left to the
113918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // object(s) no longer allocated as they would be invalid when allocation is
114018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // un-done.
114118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  void UndoAllocationInNewSpace(Register object);
114218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
11433811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  // Allocate a heap number in new space with undefined value. Returns
11443811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  // tagged pointer in result register, or jumps to gc_required if new
11453811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  // space is full.
11463811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org  void AllocateHeapNumber(Register result,
11473811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org                          Register scratch,
11483811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org                          Label* gc_required);
11493811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org
115013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // Allocate a sequential string. All the header fields of the string object
115113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // are initialized.
115213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  void AllocateTwoByteString(Register result,
115313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                             Register length,
115413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                             Register scratch1,
115513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                             Register scratch2,
115613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                             Register scratch3,
115713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                             Label* gc_required);
115813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  void AllocateAsciiString(Register result,
115913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                           Register length,
116013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                           Register scratch1,
116113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                           Register scratch2,
116213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                           Register scratch3,
116313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                           Label* gc_required);
116413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
116513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // Allocate a raw cons string object. Only the map field of the result is
116613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // initialized.
11671805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  void AllocateTwoByteConsString(Register result,
116813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                          Register scratch1,
116913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                          Register scratch2,
117013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                          Label* gc_required);
117113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  void AllocateAsciiConsString(Register result,
117213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                               Register scratch1,
117313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                               Register scratch2,
117413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org                               Label* gc_required);
117513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
11761805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  // Allocate a raw sliced string object. Only the map field of the result is
11771805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  // initialized.
11781805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  void AllocateTwoByteSlicedString(Register result,
11791805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org                            Register scratch1,
11801805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org                            Register scratch2,
11811805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org                            Label* gc_required);
11821805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  void AllocateAsciiSlicedString(Register result,
11831805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org                                 Register scratch1,
11841805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org                                 Register scratch2,
11851805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org                                 Label* gc_required);
11861805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org
118718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // ---------------------------------------------------------------------------
11889085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // Support functions.
11899085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
11909085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // Check if result is zero and op is negative.
11919085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  void NegativeZeroTest(Register result, Register op, Label* then_label);
11929085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
11939085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // Check if result is zero and op is negative in code using jump targets.
11949085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  void NegativeZeroTest(CodeGenerator* cgen,
11959085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org                        Register result,
11969085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org                        Register op,
11979085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org                        JumpTarget* then_target);
11989085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
11999085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // Check if result is zero and any of op1 and op2 are negative.
12009085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // Register scratch is destroyed, and it must be different from op2.
12019085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  void NegativeZeroTest(Register result, Register op1, Register op2,
12029085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org                        Register scratch, Label* then_label);
12039085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
12049085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // Try to get function prototype of a function and puts the value in
12059085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // the result register. Checks that the function really is a
12069085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // function and jumps to the miss label if the fast checks fail. The
120786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  // function register will be untouched; the other register may be
12089085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // clobbered.
12099085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  void TryGetFunctionPrototype(Register function,
12109085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org                               Register result,
1211394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                               Label* miss,
1212394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                               bool miss_on_bound_function = false);
12139085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
12149085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // Generates code for reporting that an illegal operation has
12159085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // occurred.
12169085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  void IllegalOperation(int num_arguments);
12179085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
1218d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  // Picks out an array index from the hash field.
1219d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  // Register use:
1220d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  //   hash - holds the index's hash. Clobbered.
1221d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  //   index - holds the overwritten index on exit.
1222d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  void IndexFromHash(Register hash, Register index);
1223d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org
1224ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  // Find the function context up the context chain.
1225ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  void LoadContext(Register dst, int context_chain_length);
1226ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org
12271145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org  // Conditionally load the cached Array transitioned map of type
122846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // transitioned_kind from the native context if the map in register
122946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // map_in_out is the cached Array map in the native context of
12301145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org  // expected_kind.
12311145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org  void LoadTransitionedArrayMapConditional(
12321145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org      ElementsKind expected_kind,
12331145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org      ElementsKind transitioned_kind,
12341145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org      Register map_in_out,
12351145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org      Register scratch,
12361145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org      Label* no_map_match);
12371145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org
12381145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org  // Load the initial map for new Arrays from a JSFunction.
12391145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org  void LoadInitialArrayMap(Register function_in,
12401145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org                           Register scratch,
1241830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org                           Register map_out,
1242830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org                           bool can_have_holes);
1243fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
12445f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // Load the global function with the given index.
12455f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  void LoadGlobalFunction(int index, Register function);
12464a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  void LoadArrayFunction(Register function);
12475f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
12485f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // Load the initial map from the global function. The registers
12495f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // function and map can be the same.
12505f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  void LoadGlobalFunctionInitialMap(Register function, Register map);
12515f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
12529085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // ---------------------------------------------------------------------------
12539085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // Runtime calls
12549085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
12559085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // Call a code stub.
1256471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  void CallStub(CodeStub* stub, TypeFeedbackId ast_id = TypeFeedbackId::None());
12579085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
125813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // Tail call a code stub (jump).
125913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  void TailCallStub(CodeStub* stub);
126013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org
12619085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // Return from a code stub after popping its arguments.
12629085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  void StubReturn(int argc);
12639085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
12649085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // Call a runtime routine.
1265fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  void CallRuntime(const Runtime::Function* f,
1266fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org                   int num_arguments,
1267fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org                   SaveFPRegsMode save_doubles = kDontSaveFPRegs);
12689085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
12690ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  // Call a runtime function and save the value of XMM registers.
1270fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  void CallRuntimeSaveDoubles(Runtime::FunctionId id) {
1271fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    const Runtime::Function* function = Runtime::FunctionForId(id);
1272fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    CallRuntime(function, function->nargs, kSaveFPRegs);
1273fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  }
12740ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org
12759085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // Convenience function: Same as above, but takes the fid instead.
1276f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  void CallRuntime(Runtime::FunctionId id,
1277f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                   int num_arguments,
1278f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                   SaveFPRegsMode save_doubles = kDontSaveFPRegs) {
1279f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    CallRuntime(Runtime::FunctionForId(id), num_arguments, save_doubles);
1280fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  }
12819085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
12825c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Convenience function: call an external reference.
12835c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void CallExternalReference(const ExternalReference& ext,
12845c838251403b0be9a882540f1922577abba4c872ager@chromium.org                             int num_arguments);
12855c838251403b0be9a882540f1922577abba4c872ager@chromium.org
12869085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // Tail call of a runtime routine (jump).
1287ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // Like JumpToExternalReference, but also takes care of passing the number
1288ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // of parameters.
1289ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void TailCallExternalReference(const ExternalReference& ext,
1290ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org                                 int num_arguments,
1291ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org                                 int result_size);
1292ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
1293ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // Convenience function: tail call a runtime routine (jump).
1294ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void TailCallRuntime(Runtime::FunctionId fid,
1295a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org                       int num_arguments,
1296a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org                       int result_size);
12979085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
1298c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  // Jump to a runtime routine.
1299ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void JumpToExternalReference(const ExternalReference& ext, int result_size);
13009085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
1301c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Prepares stack to put arguments (aligns and so on).  WIN64 calling
1302c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // convention requires to put the pointer to the return value slot into
1303c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // rcx (rcx must be preserverd until CallApiFunctionAndReturn).  Saves
1304c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // context (rsi).  Clobbers rax.  Allocates arg_stack_space * kPointerSize
13054a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // inside the exit frame (not GCed) accessible via StackSpaceOperand.
1306662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  void PrepareCallApiFunction(int arg_stack_space);
13074a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
1308c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Calls an API function.  Allocates HandleScope, extracts returned value
1309c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // from handle and propagates exceptions.  Clobbers r14, r15, rbx and
1310c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // caller-save registers.  Restores context.  On return removes
1311c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // stack_space * kPointerSize (GCed).
1312bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  void CallApiFunctionAndReturn(Address function_address,
1313b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org                                Address thunk_address,
1314b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org                                Register thunk_last_arg,
1315bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org                                int stack_space,
1316528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                Operand return_value_operand,
1317528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                Operand* context_restore_operand);
1318303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org
1319b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // Before calling a C-function from generated code, align arguments on stack.
1320c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org  // After aligning the frame, arguments must be stored in rsp[0], rsp[8],
1321b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // etc., not pushed. The argument count assumes all arguments are word sized.
1322b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // The number of slots reserved for arguments depends on platform. On Windows
1323b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // stack slots are reserved for the arguments passed in registers. On other
1324b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // platforms stack slots are only reserved for the arguments actually passed
1325b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // on the stack.
1326b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  void PrepareCallCFunction(int num_arguments);
1327b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
1328b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // Calls a C function and cleans up the space for arguments allocated
1329b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // by PrepareCallCFunction. The called function is not allowed to trigger a
1330b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // garbage collection, since that might move the code and invalidate the
1331b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // return address (unless this is somehow accounted for by the called
1332b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // function).
1333b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  void CallCFunction(ExternalReference function, int num_arguments);
1334b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  void CallCFunction(Register function, int num_arguments);
1335b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
1336b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // Calculate the number of stack slots to reserve for arguments when calling a
1337b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // C function.
1338b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  int ArgumentStackSlotsForCFunctionCall(int num_arguments);
13399085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
13409085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // ---------------------------------------------------------------------------
13419085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // Utilities
13429085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
13439085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  void Ret();
13449085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
1345d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  // Return and drop arguments from stack, where the number of arguments
1346d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  // may be bigger than 2^16 - 1.  Requires a scratch register.
1347d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com  void Ret(int bytes_dropped, Register scratch);
1348d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com
1349c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  Handle<Object> CodeObject() {
1350c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    ASSERT(!code_object_.is_null());
1351c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    return code_object_;
1352c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  }
13539085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
13547979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  // Copy length bytes from source to destination.
13557979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  // Uses scratch register internally (if you have a low-eight register
13567979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  // free, do use it, otherwise kScratchRegister will be used).
13577979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  // The min_length is a minimum limit on the value that length will have.
13587979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  // The algorithm has some special cases that might be omitted if the string
13597979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  // is known to always be long.
13607979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  void CopyBytes(Register destination,
13617979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org                 Register source,
13627979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org                 Register length,
13637979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org                 int min_length = 0,
13647979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org                 Register scratch = kScratchRegister);
13657979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org
1366c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Initialize fields with filler values.  Fields starting at |start_offset|
1367c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // not including end_offset are overwritten with the value in |filler|.  At
1368c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // the end the loop, |start_offset| takes the value of |end_offset|.
1369c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void InitializeFieldsWithFiller(Register start_offset,
1370c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                  Register end_offset,
1371c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                  Register filler);
1372c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
13739085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
13749085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // ---------------------------------------------------------------------------
13759085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // StatsCounter support
13769085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
13779085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  void SetCounter(StatsCounter* counter, int value);
13789085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  void IncrementCounter(StatsCounter* counter, int value);
13799085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  void DecrementCounter(StatsCounter* counter, int value);
13809085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
13819085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
13829085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // ---------------------------------------------------------------------------
13839085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // Debugging
13849085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
13859085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // Calls Abort(msg) if the condition cc is not satisfied.
13869085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // Use --debug_code to enable.
1387594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void Assert(Condition cc, BailoutReason reason);
13889085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
13890b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org  void AssertFastElements(Register elements);
13900b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org
13919085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // Like Assert(), but always enabled.
1392594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void Check(Condition cc, BailoutReason reason);
13939085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
13949085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // Print a message to stdout and abort execution.
1395594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void Abort(BailoutReason msg);
13969085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
1397c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  // Check that the stack is aligned.
1398c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  void CheckStackAlignment();
1399c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org
14009085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // Verify restrictions about code generated in stubs.
14019085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  void set_generating_stub(bool value) { generating_stub_ = value; }
14029085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  bool generating_stub() { return generating_stub_; }
1403c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void set_has_frame(bool value) { has_frame_ = value; }
1404c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bool has_frame() { return has_frame_; }
1405c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  inline bool AllowThisStubCall(CodeStub* stub);
14069085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
140744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  static int SafepointRegisterStackIndex(Register reg) {
140844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    return SafepointRegisterStackIndex(reg.code());
140944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  }
141044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
1411c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Activation support.
1412c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void EnterFrame(StackFrame::Type type);
1413c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void LeaveFrame(StackFrame::Type type);
1414c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1415be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  // Expects object in rax and returns map with validated enum cache
1416be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  // in rax.  Assumes that any other register can be used as a scratch.
1417be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  void CheckEnumCache(Register null_value,
1418be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org                      Label* call_runtime);
1419be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
1420ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // AllocationMemento support. Arrays may have an associated
1421ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // AllocationMemento object that can be checked for in order to pretransition
142259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  // to another type.
142359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  // On entry, receiver_reg should point to the array object.
142459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  // scratch_reg gets clobbered.
1425b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  // If allocation info is present, condition flags are set to equal.
1426ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  void TestJSArrayForAllocationMemento(Register receiver_reg,
1427b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org                                       Register scratch_reg,
1428b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org                                       Label* no_memento_found);
1429b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org
1430b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  void JumpIfJSArrayHasAllocationMemento(Register receiver_reg,
1431b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org                                         Register scratch_reg,
1432b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org                                         Label* memento_found) {
1433b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    Label no_memento_found;
1434b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    TestJSArrayForAllocationMemento(receiver_reg, scratch_reg,
1435b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org                                    &no_memento_found);
1436b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    j(equal, memento_found);
1437b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    bind(&no_memento_found);
1438b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  }
143959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
1440e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  // Jumps to found label if a prototype map has dictionary elements.
1441e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  void JumpIfDictionaryInPrototypeChain(Register object, Register scratch0,
1442e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org                                        Register scratch1, Label* found);
1443e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org
14449085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org private:
14450ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  // Order general registers are pushed by Pushad.
1446b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org  // rax, rcx, rdx, rbx, rsi, rdi, r8, r9, r11, r14, r15.
14471456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org  static const int kSafepointPushRegisterIndices[Register::kNumRegisters];
144849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  static const int kNumSafepointSavedRegisters = 11;
144983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  static const int kSmiShift = kSmiTagSize + kSmiShiftSize;
145049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
14519085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  bool generating_stub_;
1452c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bool has_frame_;
1453ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  bool root_array_available_;
145469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org
145569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  // Returns a register holding the smi value. The register MUST NOT be
145669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  // modified. It may be the "smi 1 constant" register.
145769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  Register GetSmiConstant(Smi* value);
145869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org
1459000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org  intptr_t RootRegisterDelta(ExternalReference other);
1460000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org
146169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  // Moves the smi value to the destination register.
146269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  void LoadSmiConstant(Register dst, Smi* value);
146369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org
14645c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // This handle will be patched with the code object on installation.
14655c838251403b0be9a882540f1922577abba4c872ager@chromium.org  Handle<Object> code_object_;
14669085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
14679085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  // Helper functions for generating invokes.
14689085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  void InvokePrologue(const ParameterCount& expected,
14699085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org                      const ParameterCount& actual,
14709085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org                      Handle<Code> code_constant,
1471eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org                      Register code_register,
147283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                      Label* done,
14732efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org                      bool* definitely_mismatches,
14743a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                      InvokeFlag flag,
147540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org                      Label::Distance near_jump = Label::kFar,
147640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org                      const CallWrapper& call_wrapper = NullCallWrapper(),
147740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org                      CallKind call_kind = CALL_AS_METHOD);
14789085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
1479d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  void EnterExitFramePrologue(bool save_rax);
14804a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
14814a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // Allocates arg_stack_space * kPointerSize memory (not GCed) on the stack
14824a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  // accessible via StackSpaceOperand.
14830ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org  void EnterExitFrameEpilogue(int arg_stack_space, bool save_doubles);
14844a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
1485528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  void LeaveExitFrameEpilogue(bool restore_context);
1486e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org
148718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // Allocation support helpers.
1488ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org  // Loads the top of new-space into the result register.
1489ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org  // Otherwise the address of the new-space top is loaded into scratch (if
1490ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org  // scratch is valid), and the new-space top is loaded into result.
149118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  void LoadAllocationTopHelper(Register result,
149218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org                               Register scratch,
1493a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org                               AllocationFlags flags);
14942bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
1495ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org  // Update allocation top with value in result_end register.
1496ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org  // If scratch is valid, it contains the address of the allocation top.
14972bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  void UpdateAllocationTopHelper(Register result_end,
14982bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org                                 Register scratch,
14992bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org                                 AllocationFlags flags);
1500e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org
1501e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org  // Helper for PopHandleScope.  Allowed to perform a GC and returns
1502e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org  // NULL if gc_allowed.  Does not perform a GC if !gc_allowed, and
1503e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org  // possibly returns a failure object indicating an allocation failure.
1504e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org  Object* PopHandleScopeHelper(Register saved,
1505e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org                               Register scratch,
1506e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org                               bool gc_allowed);
15073a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
1508c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Helper for implementing JumpIfNotInNewSpace and JumpIfInNewSpace.
1509c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void InNewSpace(Register object,
1510c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                  Register scratch,
1511c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                  Condition cc,
1512c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                  Label* branch,
1513c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                  Label::Distance distance = Label::kFar);
1514c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1515c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Helper for finding the mark bits for an address.  Afterwards, the
1516c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // bitmap register points at the word with the mark bits and the mask
1517c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // the position of the first bit.  Uses rcx as scratch and leaves addr_reg
1518c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // unchanged.
1519c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  inline void GetMarkBits(Register addr_reg,
1520c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                          Register bitmap_reg,
1521c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                          Register mask_reg);
15223a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
152304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  // Helper for throwing exceptions.  Compute a handler address and jump to
152404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  // it.  See the implementation for register usage.
152504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  void JumpToHandlerEntry();
152604e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org
15273a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  // Compute memory operands for safepoint stack slots.
15283a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  Operand SafepointRegisterSlot(Register reg);
15293a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  static int SafepointRegisterStackIndex(int reg_code) {
15303a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org    return kNumSafepointRegisters - kSafepointPushRegisterIndices[reg_code] - 1;
15313a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  }
15323a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
1533a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // Needs access to SafepointRegisterStackIndex for compiled frame
15343a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  // traversal.
1535a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  friend class StandardFrame;
15369085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org};
15379085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
15389085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
15394af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org// The code patcher is used to patch (typically) small parts of code e.g. for
15404af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org// debugging and other types of instrumentation. When using the code patcher
15414af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org// the exact number of bytes specified must be emitted. Is not legal to emit
15424af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org// relocation information. If any of these constraints are violated it causes
15434af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org// an assertion.
15444af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgclass CodePatcher {
15454af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org public:
15464af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  CodePatcher(byte* address, int size);
15474af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  virtual ~CodePatcher();
15484af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
15494af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Macro assembler to emit code.
15504af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  MacroAssembler* masm() { return &masm_; }
15514af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
15524af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org private:
15534af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  byte* address_;  // The address of the code being patched.
15544af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  int size_;  // Number of bytes of the expected patch size.
15554af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  MacroAssembler masm_;  // Macro assembler used to generate the code.
15564af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org};
15574af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
15584af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
15599085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// -----------------------------------------------------------------------------
15609085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// Static helper functions.
15619085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
15629085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// Generate an Operand for loading a field from an object.
15631b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orginline Operand FieldOperand(Register object, int offset) {
15649085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  return Operand(object, offset - kHeapObjectTag);
15659085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org}
15669085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
15679085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
15689085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// Generate an Operand for loading an indexed field from an object.
15691b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orginline Operand FieldOperand(Register object,
15701b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                            Register index,
15711b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                            ScaleFactor scale,
15721b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org                            int offset) {
15739085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  return Operand(object, index, scale, offset - kHeapObjectTag);
15749085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org}
15759085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
15769085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
15771b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orginline Operand ContextOperand(Register context, int index) {
15784a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  return Operand(context, Context::SlotOffset(index));
15794a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com}
15804a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
15814a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
15821b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orginline Operand GlobalObjectOperand() {
158346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  return ContextOperand(rsi, Context::GLOBAL_OBJECT_INDEX);
15844a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com}
15854a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
15864a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
15874a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// Provides access to exit frame stack space (not GCed).
15881b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orginline Operand StackSpaceOperand(int index) {
15894a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com#ifdef _WIN64
15904a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  const int kShaddowSpace = 4;
15914a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  return Operand(rsp, (index + kShaddowSpace) * kPointerSize);
15924a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com#else
15934a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  return Operand(rsp, index * kPointerSize);
15944a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com#endif
15954a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com}
15964a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
15974a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
1598d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orginline Operand StackOperandForReturnAddress(int32_t disp) {
1599d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org  return Operand(rsp, disp);
1600d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org}
1601d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org
16024a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
16039085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#ifdef GENERATED_CODE_COVERAGE
16049085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.orgextern void LogGeneratedCodeCoverage(const char* file_line);
16059085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#define CODE_COVERAGE_STRINGIFY(x) #x
16069085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x)
16079085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__)
16084cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org#define ACCESS_MASM(masm) {                                                  \
16094cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    Address x64_coverage_function = FUNCTION_ADDR(LogGeneratedCodeCoverage); \
16104cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    masm->pushfq();                                                          \
16114cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    masm->Pushad();                                                          \
16124cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    masm->push(Immediate(reinterpret_cast<int>(&__FILE_LINE__)));            \
16134cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    masm->Call(x64_coverage_function, RelocInfo::EXTERNAL_REFERENCE);        \
16144cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    masm->pop(rax);                                                          \
16154cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    masm->Popad();                                                           \
16164cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    masm->popfq();                                                           \
16174cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  }                                                                          \
16189085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  masm->
16199085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#else
16209085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#define ACCESS_MASM(masm) masm->
16219085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#endif
16229085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
16239085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org} }  // namespace v8::internal
16249085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org
16259085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#endif  // V8_X64_MACRO_ASSEMBLER_X64_H_
1626