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 56c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool AreAliased(Register r1, Register r2, Register r3, Register r4); 57c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 589085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// Forward declaration. 599085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.orgclass JumpTarget; 609085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 614af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgstruct SmiIndex { 624af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org SmiIndex(Register index_register, ScaleFactor scale) 634af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org : reg(index_register), 644af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org scale(scale) {} 654af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register reg; 664af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org ScaleFactor scale; 674af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}; 689085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 69c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 709085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// MacroAssembler implements a collection of frequently used macros. 719085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.orgclass MacroAssembler: public Assembler { 729085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org public: 73c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // The isolate parameter can be NULL if the macro assembler should 74c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // not use isolate-dependent functionality. In this case, it's the 75c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // responsibility of the caller to never invoke such function on the 76c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // macro assembler. 77c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org MacroAssembler(Isolate* isolate, void* buffer, int size); 789085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 79ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Prevent the use of the RootArray during the lifetime of this 80ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // scope object. 81ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org class NoRootArrayScope BASE_EMBEDDED { 82ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org public: 83ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org explicit NoRootArrayScope(MacroAssembler* assembler) 84ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org : variable_(&assembler->root_array_available_), 85ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org old_value_(assembler->root_array_available_) { 86ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org assembler->root_array_available_ = false; 87ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 88ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ~NoRootArrayScope() { 89ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org *variable_ = old_value_; 90ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 91ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org private: 92ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org bool* variable_; 93ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org bool old_value_; 94ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org }; 95ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 96ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Operand pointing to an external reference. 97ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // May emit code to set up the scratch register. The operand is 98ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // only guaranteed to be correct as long as the scratch register 99ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // isn't changed. 100ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // If the operand is used more than once, use a scratch register 101ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // that is guaranteed not to be clobbered. 102ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Operand ExternalOperand(ExternalReference reference, 103ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Register scratch = kScratchRegister); 104ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Loads and stores the value of an external reference. 105ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Special case code for load and store to take advantage of 106ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // load_rax/store_rax if possible/necessary. 107ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // For other operations, just use: 108ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Operand operand = ExternalOperand(extref); 109ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // operation(operand, ..); 110ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org void Load(Register destination, ExternalReference source); 111ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org void Store(ExternalReference destination, Register source); 112ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Loads the address of the external reference into the destination 113ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // register. 114ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org void LoadAddress(Register destination, ExternalReference source); 115ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Returns the size of the code generated by LoadAddress. 116ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Used by CallSize(ExternalReference) to find the size of a call. 117ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org int LoadAddressSize(ExternalReference source); 118ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com // Pushes the address of the external reference onto the stack. 119ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com void PushAddress(ExternalReference source); 120ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 121ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Operations on roots in the root-array. 12218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org void LoadRoot(Register destination, Heap::RootListIndex index); 123ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org void StoreRoot(Register source, Heap::RootListIndex index); 1248f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org // Load a root value where the index (or part of it) is variable. 1258f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org // The variable_offset register is added to the fixed_offset value 1268f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org // to get the index into the root-array. 1278f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org void LoadRootIndexed(Register destination, 1288f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org Register variable_offset, 1298f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org int fixed_offset); 13018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org void CompareRoot(Register with, Heap::RootListIndex index); 13183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org void CompareRoot(const Operand& with, Heap::RootListIndex index); 13218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org void PushRoot(Heap::RootListIndex index); 13318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 134c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // These functions do not arrange the registers in any particular order so 135c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // they are not useful for calls that can cause a GC. The caller can 136c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // exclude up to 3 registers that do not need to be saved and restored. 137c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void PushCallerSaved(SaveFPRegsMode fp_mode, 138c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register exclusion1 = no_reg, 139c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register exclusion2 = no_reg, 140c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register exclusion3 = no_reg); 141c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void PopCallerSaved(SaveFPRegsMode fp_mode, 142c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register exclusion1 = no_reg, 143c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register exclusion2 = no_reg, 144c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register exclusion3 = no_reg); 145c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 146c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// --------------------------------------------------------------------------- 147c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// GC Support 148c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 149c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 150c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com enum RememberedSetFinalAction { 151c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com kReturnAtEnd, 152c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com kFallThroughAtEnd 153c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com }; 1544111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org 155c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Record in the remembered set the fact that we have a pointer to new space 156c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // at the address pointed to by the addr register. Only works if addr is not 157c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // in new space. 158c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void RememberedSetHelper(Register object, // Used for debug code. 159c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register addr, 160c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch, 161c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SaveFPRegsMode save_fp, 162c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RememberedSetFinalAction and_then); 163c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 164c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void CheckPageFlag(Register object, 165c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch, 166c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int mask, 167c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Condition cc, 168c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* condition_met, 169c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance condition_met_distance = Label::kFar); 170c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 171f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org void CheckMapDeprecated(Handle<Map> map, 172f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org Register scratch, 173f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org Label* if_deprecated); 174f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 175c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check if object is in new space. Jumps if the object is not in new space. 176c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // The register scratch can be object itself, but scratch will be clobbered. 177c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void JumpIfNotInNewSpace(Register object, 178c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch, 179c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* branch, 180c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance distance = Label::kFar) { 181c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com InNewSpace(object, scratch, not_equal, branch, distance); 182c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 183c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 184c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check if object is in new space. Jumps if the object is in new space. 185c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // The register scratch can be object itself, but it will be clobbered. 186c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void JumpIfInNewSpace(Register object, 187c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch, 188c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* branch, 189c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance distance = Label::kFar) { 190c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com InNewSpace(object, scratch, equal, branch, distance); 191c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 192c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 193c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check if an object has the black incremental marking color. Also uses rcx! 194c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void JumpIfBlack(Register object, 195c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch0, 196c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch1, 197c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* on_black, 198c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance on_black_distance = Label::kFar); 199c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2002efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // Detects conservatively whether an object is data-only, i.e. it does need to 201c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // be scanned by the garbage collector. 202c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void JumpIfDataObject(Register value, 203c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch, 204c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* not_data_object, 205c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance not_data_object_distance); 206c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 207c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Checks the color of an object. If the object is already grey or black 208c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // then we just fall through, since it is already live. If it is white and 209c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // we can determine that it doesn't need to be scanned, then we just mark it 210c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // black and fall through. For the rest we jump to the label so the 211c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // incremental marker can fix its assumptions. 212c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void EnsureNotWhite(Register object, 213c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch1, 214c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch2, 215c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* object_is_white_and_not_data, 216c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance distance); 217c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 218c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Notify the garbage collector that we wrote a pointer into an object. 219c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // |object| is the object being stored into, |value| is the object being 220c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // stored. value and scratch registers are clobbered by the operation. 221c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // The offset is the offset from the start of the object, not the offset from 222c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // the tagged HeapObject pointer. For use with FieldOperand(reg, off). 223c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void RecordWriteField( 224c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register object, 225c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int offset, 226c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register value, 227c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch, 228c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SaveFPRegsMode save_fp, 229c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, 230c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SmiCheck smi_check = INLINE_SMI_CHECK); 231c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 232c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // As above, but the offset has the tag presubtracted. For use with 233c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Operand(reg, off). 234c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void RecordWriteContextSlot( 235c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register context, 236c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int offset, 237c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register value, 238c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch, 239c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SaveFPRegsMode save_fp, 240c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, 241c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SmiCheck smi_check = INLINE_SMI_CHECK) { 242c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RecordWriteField(context, 243c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com offset + kHeapObjectTag, 244c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com value, 245c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com scratch, 246c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com save_fp, 247c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com remembered_set_action, 248c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com smi_check); 249c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 250c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 251c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Notify the garbage collector that we wrote a pointer into a fixed array. 252c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // |array| is the array being stored into, |value| is the 253394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // object being stored. |index| is the array index represented as a non-smi. 254394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // All registers are clobbered by the operation RecordWriteArray 255c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // filters out smis so it does not update the write barrier if the 256c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // value is a smi. 257c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void RecordWriteArray( 258c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register array, 259c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register value, 260c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register index, 261c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SaveFPRegsMode save_fp, 262c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, 263c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SmiCheck smi_check = INLINE_SMI_CHECK); 264c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 265c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // For page containing |object| mark region covering |address| 26669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org // dirty. |object| is the object being stored into, |value| is the 267c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // object being stored. The address and value registers are clobbered by the 26869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org // operation. RecordWrite filters out smis so it does not update 26969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org // the write barrier if the value is a smi. 270c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void RecordWrite( 271c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register object, 272c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register address, 273c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register value, 274c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SaveFPRegsMode save_fp, 275c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, 276c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SmiCheck smi_check = INLINE_SMI_CHECK); 2779d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com 2789085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#ifdef ENABLE_DEBUGGER_SUPPORT 2799085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // --------------------------------------------------------------------------- 2809085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Debugger Support 2819085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 2825c838251403b0be9a882540f1922577abba4c872ager@chromium.org void DebugBreak(); 2839085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#endif 2849085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 285c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org // Enter specific kind of exit frame; either in normal or 286c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org // debug mode. Expects the number of arguments in register rax and 287a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // sets up the number of arguments in register rdi and the pointer 288a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // to the first argument in register rsi. 2894a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // 2904a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // Allocates arg_stack_space * kPointerSize memory (not GCed) on the stack 2914a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // accessible via StackSpaceOperand. 2920ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org void EnterExitFrame(int arg_stack_space = 0, bool save_doubles = false); 2939085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 2944a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // Enter specific kind of exit frame. Allocates arg_stack_space * kPointerSize 2954a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // memory (not GCed) on the stack accessible via StackSpaceOperand. 2964a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com void EnterApiExitFrame(int arg_stack_space); 297e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 298a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // Leave the current exit frame. Expects/provides the return value in 299a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // register rax:rdx (untouched) and the pointer to the first 300a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // argument in register rsi. 3010ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org void LeaveExitFrame(bool save_doubles = false); 3029085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 3034a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // Leave the current exit frame. Expects/provides the return value in 3044a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // register rax (untouched). 3054a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com void LeaveApiExitFrame(); 3069085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 307a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Push and pop the registers that can hold pointers. 3080ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org void PushSafepointRegisters() { Pushad(); } 3090ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org void PopSafepointRegisters() { Popad(); } 3103a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Store the value in register src in the safepoint register stack 3113a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // slot for register dst. 31246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org void StoreToSafepointRegisterSlot(Register dst, const Immediate& imm); 3133a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org void StoreToSafepointRegisterSlot(Register dst, Register src); 3145d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org void LoadFromSafepointRegisterSlot(Register dst, Register src); 3150ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 3168f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org void InitializeRootRegister() { 317394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ExternalReference roots_array_start = 318394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ExternalReference::roots_array_start(isolate()); 319394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com movq(kRootRegister, roots_array_start); 3208f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org addq(kRootRegister, Immediate(kRootRegisterBias)); 3218f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org } 3228f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org 3239085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // --------------------------------------------------------------------------- 3249085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // JavaScript invokes 3259085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 326f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Set up call kind marking in rcx. The method takes rcx as an 32740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // explicit first parameter to make the code more readable at the 32840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // call sites. 32940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org void SetCallKind(Register dst, CallKind kind); 33040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 3319085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Invoke the JavaScript function code by either calling or jumping. 332eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org void InvokeCode(Register code, 3339085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org const ParameterCount& expected, 3349085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org const ParameterCount& actual, 3353a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org InvokeFlag flag, 336d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org const CallWrapper& call_wrapper, 337d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org CallKind call_kind); 3389085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 3399085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void InvokeCode(Handle<Code> code, 3409085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org const ParameterCount& expected, 3419085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org const ParameterCount& actual, 3429085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org RelocInfo::Mode rmode, 3433a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org InvokeFlag flag, 344d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org const CallWrapper& call_wrapper, 345d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org CallKind call_kind); 3469085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 3479085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Invoke the JavaScript function in the given register. Changes the 3489085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // current context to the context in the function before invoking. 3499085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void InvokeFunction(Register function, 3509085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org const ParameterCount& actual, 3513a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org InvokeFlag flag, 352d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org const CallWrapper& call_wrapper, 353d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org CallKind call_kind); 3549085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 355c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org void InvokeFunction(Handle<JSFunction> function, 35632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org const ParameterCount& expected, 3575c838251403b0be9a882540f1922577abba4c872ager@chromium.org const ParameterCount& actual, 3583a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org InvokeFlag flag, 359d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org const CallWrapper& call_wrapper, 360d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org CallKind call_kind); 3615c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3629085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Invoke specified builtin JavaScript function. Adds an entry to 3639085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // the unresolved list if the name does not resolve. 3643a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org void InvokeBuiltin(Builtins::JavaScript id, 3653a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org InvokeFlag flag, 366fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org const CallWrapper& call_wrapper = NullCallWrapper()); 3679085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 368145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com // Store the function for the given builtin in the target register. 369145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com void GetBuiltinFunction(Register target, Builtins::JavaScript id); 370145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com 3719085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Store the code object for the given builtin in the target register. 3729085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void GetBuiltinEntry(Register target, Builtins::JavaScript id); 3739085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 3744af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 3754af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // --------------------------------------------------------------------------- 3764af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Smi tagging, untagging and operations on tagged smis. 3774af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 37869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org void InitializeSmiConstantRegister() { 37969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org movq(kSmiConstantRegister, 38069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org reinterpret_cast<uint64_t>(Smi::FromInt(kSmiConstantRegisterValue)), 3814cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org RelocInfo::NONE64); 38269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org } 38369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 3844af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Conversions between tagged smi values and non-tagged integer values. 3854af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 3864af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Tag an integer value. The result must be known to be a valid smi value. 387b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Only uses the low 32 bits of the src register. Sets the N and Z flags 388c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org // based on the value of the resulting smi. 3894af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void Integer32ToSmi(Register dst, Register src); 3904af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 3915ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org // Stores an integer32 value into a memory field that already holds a smi. 3925ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org void Integer32ToSmiField(const Operand& dst, Register src); 3935ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org 3944af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Adds constant to src and tags the result as a smi. 3954af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Result must be a valid smi. 3969d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com void Integer64PlusConstantToSmi(Register dst, Register src, int constant); 3974af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 3984af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Convert smi to 32-bit integer. I.e., not sign extended into 3994af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // high 32 bits of destination. 4004af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiToInteger32(Register dst, Register src); 40130ce411529579186181838984710b0b0980857aaricow@chromium.org void SmiToInteger32(Register dst, const Operand& src); 4024af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 4034af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Convert smi to 64-bit integer (sign extended if necessary). 4044af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiToInteger64(Register dst, Register src); 4055ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org void SmiToInteger64(Register dst, const Operand& src); 4064af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 4074af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Multiply a positive smi's integer value by a power of two. 4084af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Provides result as 64-bit integer value. 4094af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void PositiveSmiTimesPowerOfTwoToInteger64(Register dst, 4104af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src, 4114af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org int power); 4124af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 41330ce411529579186181838984710b0b0980857aaricow@chromium.org // Divide a positive smi's integer value by a power of two. 41430ce411529579186181838984710b0b0980857aaricow@chromium.org // Provides result as 32-bit integer value. 41530ce411529579186181838984710b0b0980857aaricow@chromium.org void PositiveSmiDivPowerOfTwoToInteger32(Register dst, 41630ce411529579186181838984710b0b0980857aaricow@chromium.org Register src, 41730ce411529579186181838984710b0b0980857aaricow@chromium.org int power); 41830ce411529579186181838984710b0b0980857aaricow@chromium.org 41944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org // Perform the logical or of two smi values and return a smi value. 42044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org // If either argument is not a smi, jump to on_not_smis and retain 42144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org // the original values of source registers. The destination register 42244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org // may be changed if it's not one of the source registers. 42344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org void SmiOrIfSmis(Register dst, 42444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org Register src1, 42544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org Register src2, 42683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smis, 42783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 42844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 42930ce411529579186181838984710b0b0980857aaricow@chromium.org 430badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org // Simple comparison of smis. Both sides must be known smis to use these, 431badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org // otherwise use Cmp. 432badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org void SmiCompare(Register smi1, Register smi2); 4339d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com void SmiCompare(Register dst, Smi* src); 434ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org void SmiCompare(Register dst, const Operand& src); 4359d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com void SmiCompare(const Operand& dst, Register src); 4369d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com void SmiCompare(const Operand& dst, Smi* src); 4375ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org // Compare the int32 in src register to the value of the smi stored at dst. 4385ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org void SmiCompareInteger32(const Operand& dst, Register src); 4399d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com // Sets sign and zero flags depending on value of smi in register. 4409d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com void SmiTest(Register src); 4419d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com 4424af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Functions performing a check on a known or potential smi. Returns 4434af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // a condition that is satisfied if the check is successful. 4444af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 4454af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Is the value a tagged smi. 4464af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Condition CheckSmi(Register src); 4470a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org Condition CheckSmi(const Operand& src); 4484af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 449eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org // Is the value a non-negative tagged smi. 450eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org Condition CheckNonNegativeSmi(Register src); 4514af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 452b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Are both values tagged smis. 4534af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Condition CheckBothSmi(Register first, Register second); 4544af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 455eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org // Are both values non-negative tagged smis. 456eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org Condition CheckBothNonNegativeSmi(Register first, Register second); 457b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 458b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Are either value a tagged smi. 459c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org Condition CheckEitherSmi(Register first, 460c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org Register second, 461c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org Register scratch = kScratchRegister); 462b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4634af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Is the value the minimum smi value (since we are using 4644af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // two's complement numbers, negating the value is known to yield 4654af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // a non-smi value). 4664af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Condition CheckIsMinSmi(Register src); 4674af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 4684af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Checks whether an 32-bit integer value is a valid for conversion 4694af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // to a smi. 4704af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Condition CheckInteger32ValidSmiValue(Register src); 4714af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 4723811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Checks whether an 32-bit unsigned integer value is a valid for 4733811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // conversion to a smi. 4743811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org Condition CheckUInteger32ValidSmiValue(Register src); 4753811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 4760ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org // Check whether src is a Smi, and set dst to zero if it is a smi, 4770ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org // and to one if it isn't. 4780ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org void CheckSmiToIndicator(Register dst, Register src); 4790ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org void CheckSmiToIndicator(Register dst, const Operand& src); 4800ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 4814af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Test-and-jump functions. Typically combines a check function 4824af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // above with a conditional jump. 4834af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 4844af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Jump if the value cannot be represented by a smi. 48583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org void JumpIfNotValidSmiValue(Register src, Label* on_invalid, 48683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 4874af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 4883811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Jump if the unsigned integer value cannot be represented by a smi. 48983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org void JumpIfUIntNotValidSmiValue(Register src, Label* on_invalid, 49083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 4913811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 4924af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Jump to label if the value is a tagged smi. 49383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org void JumpIfSmi(Register src, 49483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_smi, 49583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 4964af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 4974af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Jump to label if the value is not a tagged smi. 49883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org void JumpIfNotSmi(Register src, 49983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi, 50083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 5014af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 502eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org // Jump to label if the value is not a non-negative tagged smi. 50383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org void JumpUnlessNonNegativeSmi(Register src, 50483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi, 50583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 5064af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 5079d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com // Jump to label if the value, which must be a tagged smi, has value equal 5084af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // to the constant. 509c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org void JumpIfSmiEqualsConstant(Register src, 510c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org Smi* constant, 51183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_equals, 51283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 513c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 5144af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Jump if either or both register are not smi values. 515c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org void JumpIfNotBothSmi(Register src1, 516c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org Register src2, 51783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_both_smi, 51883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 5194af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 520eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org // Jump if either or both register are not non-negative smi values. 521eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org void JumpUnlessBothNonNegativeSmi(Register src1, Register src2, 52283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_both_smi, 52383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 524b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 5254af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Operations on tagged smi values. 5264af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 5274af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Smis represent a subset of integers. The subset is always equivalent to 5284af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // a two's complement interpretation of a fixed number of bits. 5294af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 5304af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Optimistically adds an integer constant to a supposed smi. 5314af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // If the src is not a smi, or the result is not a smi, jump to 5324af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // the label. 5334af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiTryAddConstant(Register dst, 5344af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src, 5359d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com Smi* constant, 53683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi_result, 53783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 5384af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 5399d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com // Add an integer constant to a tagged smi, giving a tagged smi as result. 5409d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com // No overflow testing on the result is done. 5419d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com void SmiAddConstant(Register dst, Register src, Smi* constant); 5429d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com 5439dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Add an integer constant to a tagged smi, giving a tagged smi as result. 5449dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // No overflow testing on the result is done. 5459dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com void SmiAddConstant(const Operand& dst, Smi* constant); 5469dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 5474af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Add an integer constant to a tagged smi, giving a tagged smi as result, 5484af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // or jumping to a label if the result cannot be represented by a smi. 5494af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiAddConstant(Register dst, 5504af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src, 5519d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com Smi* constant, 55283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi_result, 55383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 5544af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 5554af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Subtract an integer constant from a tagged smi, giving a tagged smi as 556ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org // result. No testing on the result is done. Sets the N and Z flags 557ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org // based on the value of the resulting integer. 5589d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com void SmiSubConstant(Register dst, Register src, Smi* constant); 5599d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com 5609d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com // Subtract an integer constant from a tagged smi, giving a tagged smi as 5614af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // result, or jumping to a label if the result cannot be represented by a smi. 5624af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiSubConstant(Register dst, 5634af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src, 5649d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com Smi* constant, 56583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi_result, 56683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 5674af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 5684af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Negating a smi can give a negative zero or too large positive value. 5699d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com // NOTICE: This operation jumps on success, not failure! 5704af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiNeg(Register dst, 5714af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src, 57283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_smi_result, 57383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 5744af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 5754af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Adds smi values and return the result as a smi. 5764af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // If dst is src1, then src1 will be destroyed, even if 5774af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // the operation is unsuccessful. 5784af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiAdd(Register dst, 5794af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src1, 5804af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src2, 58183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi_result, 58283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 5837979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org void SmiAdd(Register dst, 5847979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Register src1, 5857979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org const Operand& src2, 58683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi_result, 58783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 588c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org 589c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org void SmiAdd(Register dst, 590c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org Register src1, 591c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org Register src2); 5924af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 5934af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Subtracts smi values and return the result as a smi. 5944af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // If dst is src1, then src1 will be destroyed, even if 5954af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // the operation is unsuccessful. 5964af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiSub(Register dst, 5974af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src1, 5984af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src2, 59983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi_result, 60083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 601c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org 602c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org void SmiSub(Register dst, 603c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org Register src1, 604c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org Register src2); 6054af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 606ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org void SmiSub(Register dst, 607ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org Register src1, 6089dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 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 SmiSub(Register dst, 613c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org Register src1, 614c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org const Operand& src2); 615ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 6164af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Multiplies smi values and return the result as a smi, 6174af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // if possible. 6184af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // If dst is src1, then src1 will be destroyed, even if 6194af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // the operation is unsuccessful. 6204af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiMul(Register dst, 6214af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src1, 6224af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src2, 62383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi_result, 62483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 6254af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 6264af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Divides one smi by another and returns the quotient. 6274af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Clobbers rax and rdx registers. 6284af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiDiv(Register dst, 6294af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src1, 6304af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src2, 63183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi_result, 63283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 6334af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 6344af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Divides one smi by another and returns the remainder. 6354af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Clobbers rax and rdx registers. 6364af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiMod(Register dst, 6374af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src1, 6384af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src2, 63983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi_result, 64083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 6414af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 6424af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Bitwise operations. 6434af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiNot(Register dst, Register src); 6444af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiAnd(Register dst, Register src1, Register src2); 6454af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiOr(Register dst, Register src1, Register src2); 6464af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiXor(Register dst, Register src1, Register src2); 6479d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com void SmiAndConstant(Register dst, Register src1, Smi* constant); 6489d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com void SmiOrConstant(Register dst, Register src1, Smi* constant); 6499d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com void SmiXorConstant(Register dst, Register src1, Smi* constant); 6504af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 6514af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiShiftLeftConstant(Register dst, 6524af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src, 653720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org int shift_value); 6544af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiShiftLogicalRightConstant(Register dst, 6554af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src, 6564af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org int shift_value, 65783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi_result, 65883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 6594af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiShiftArithmeticRightConstant(Register dst, 6604af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src, 6614af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org int shift_value); 6624af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 6634af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Shifts a smi value to the left, and returns the result if that is a smi. 6644af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Uses and clobbers rcx, so dst may not be rcx. 6654af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiShiftLeft(Register dst, 6664af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src1, 667720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org Register src2); 6684af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Shifts a smi value to the right, shifting in zero bits at the top, and 6694af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // returns the unsigned intepretation of the result if that is a smi. 6704af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Uses and clobbers rcx, so dst may not be rcx. 6714af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiShiftLogicalRight(Register dst, 672c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org Register src1, 673c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org Register src2, 67483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi_result, 67583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 6764af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Shifts a smi value to the right, sign extending the top, and 6774af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // returns the signed intepretation of the result. That will always 6784af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // be a valid smi value, since it's numerically smaller than the 6794af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // original. 6804af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Uses and clobbers rcx, so dst may not be rcx. 6814af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiShiftArithmeticRight(Register dst, 6824af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src1, 6834af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src2); 6844af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 6854af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Specialized operations 6864af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 6874af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Select the non-smi register of two registers where exactly one is a 6884af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // smi. If neither are smis, jump to the failure label. 6894af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SelectNonSmi(Register dst, 6904af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src1, 6914af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src2, 69283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smis, 69383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 6944af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 6954af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Converts, if necessary, a smi to a combination of number and 6964af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // multiplier to be used as a scaled index. 6974af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // The src register contains a *positive* smi value. The shift is the 6984af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // power of two to multiply the index value by (e.g. 6994af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // to index by smi-value * kPointerSize, pass the smi and kPointerSizeLog2). 7004af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // The returned index register may be either src or dst, depending 7014af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // on what is most efficient. If src and dst are different registers, 7024af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // src is always unchanged. 7034af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org SmiIndex SmiToIndex(Register dst, Register src, int shift); 7044af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 7054af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Converts a positive smi to a negative index. 7064af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org SmiIndex SmiToNegativeIndex(Register dst, Register src, int shift); 7074af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 7087979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Add the value of a smi in memory to an int32 register. 7097979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Sets flags as a normal add. 7107979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org void AddSmiField(Register dst, const Operand& src); 7117979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 7129d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com // Basic Smi operations. 7133811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org void Move(Register dst, Smi* source) { 71469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org LoadSmiConstant(dst, source); 7153811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 7163811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 7173811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org void Move(const Operand& dst, Smi* source) { 71869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org Register constant = GetSmiConstant(source); 71969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org movq(dst, constant); 7203811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 7213811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 7229d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com void Push(Smi* smi); 7239d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com void Test(const Operand& dst, Smi* source); 7249d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com 725394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 726eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // --------------------------------------------------------------------------- 727b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // String macros. 72883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 72983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org // If object is a string, its map is loaded into object_map. 73083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org void JumpIfNotString(Register object, 73183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org Register object_map, 73283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* not_string, 73383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 73483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 73583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 73683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org void JumpIfNotBothSequentialAsciiStrings( 73783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register first_object, 73883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register second_object, 73983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register scratch1, 74083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register scratch2, 74183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_both_flat_ascii, 74283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 743b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 7442efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // Check whether the instance type represents a flat ASCII string. Jump to the 745ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org // label if not. If the instance type can be scratched specify same register 746ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org // for both instance type and scratch. 747c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org void JumpIfInstanceTypeIsNotSequentialAscii( 748c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org Register instance_type, 749c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org Register scratch, 75083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label*on_not_flat_ascii_string, 75183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 752ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 753ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org void JumpIfBothInstanceTypesAreNotSequentialAscii( 754ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org Register first_object_instance_type, 755ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org Register second_object_instance_type, 756ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org Register scratch1, 757ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org Register scratch2, 75883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_fail, 75983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 760ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 7611510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org // Checks if the given register or operand is a unique name 7621510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org void JumpIfNotUniqueName(Register reg, Label* not_unique_name, 7631510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Label::Distance distance = Label::kFar); 7641510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org void JumpIfNotUniqueName(Operand operand, Label* not_unique_name, 7651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Label::Distance distance = Label::kFar); 7661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 767b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // --------------------------------------------------------------------------- 76813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // Macro instructions. 769eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 7709d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com // Load a register with a long value as efficiently as possible. 771e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void Set(Register dst, int64_t x); 772e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void Set(const Operand& dst, int64_t x); 7739085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 7744a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org // Move if the registers are not identical. 7754a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org void Move(Register target, Register source); 7764a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 7777a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org // Support for constant splitting. 7787a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org bool IsUnsafeInt(const int x); 7797a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org void SafeMove(Register dst, Smi* src); 7807a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org void SafePush(Smi* src); 7817a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org 782394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Bit-field support. 783394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com void TestBit(const Operand& dst, int bit_index); 784394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 7855aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org // Handle support 7865aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org void Move(Register dst, Handle<Object> source); 7875aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org void Move(const Operand& dst, Handle<Object> source); 7885aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org void Cmp(Register dst, Handle<Object> source); 7893e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org void Cmp(const Operand& dst, Handle<Object> source); 790badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org void Cmp(Register dst, Smi* src); 791badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org void Cmp(const Operand& dst, Smi* src); 7925aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org void Push(Handle<Object> source); 7930c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 79464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Load a heap object and handle the case of new-space objects by 79564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // indirecting via a global cell. 79664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org void LoadHeapObject(Register result, Handle<HeapObject> object); 797a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org void CmpHeapObject(Register reg, Handle<HeapObject> object); 79864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org void PushHeapObject(Handle<HeapObject> object); 79964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 800bf0c820d028452571c8c744ddd212c32c6d6a996danno@chromium.org void LoadObject(Register result, Handle<Object> object) { 80179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org AllowDeferredHandleDereference heap_object_check; 802bf0c820d028452571c8c744ddd212c32c6d6a996danno@chromium.org if (object->IsHeapObject()) { 803bf0c820d028452571c8c744ddd212c32c6d6a996danno@chromium.org LoadHeapObject(result, Handle<HeapObject>::cast(object)); 804bf0c820d028452571c8c744ddd212c32c6d6a996danno@chromium.org } else { 805bf0c820d028452571c8c744ddd212c32c6d6a996danno@chromium.org Move(result, object); 806bf0c820d028452571c8c744ddd212c32c6d6a996danno@chromium.org } 807bf0c820d028452571c8c744ddd212c32c6d6a996danno@chromium.org } 808bf0c820d028452571c8c744ddd212c32c6d6a996danno@chromium.org 809a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org void CmpObject(Register reg, Handle<Object> object) { 81079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org AllowDeferredHandleDereference heap_object_check; 811a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org if (object->IsHeapObject()) { 812a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org CmpHeapObject(reg, Handle<HeapObject>::cast(object)); 813a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org } else { 814a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Cmp(reg, object); 815a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org } 816a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org } 817a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 81864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Load a global cell into a register. 81941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org void LoadGlobalCell(Register dst, Handle<Cell> cell); 82064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 8210c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // Emit code to discard a non-negative number of pointer-sized elements 8220c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // from the stack, clobbering only the rsp register. 82313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org void Drop(int stack_elements); 8240c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 82513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org void Call(Label* target) { call(target); } 826594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org void Push(Register src) { push(src); } 827594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org void Pop(Register dst) { pop(dst); } 828594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org void PushReturnAddressFrom(Register src) { push(src); } 829594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org void PopReturnAddressTo(Register dst) { pop(dst); } 8305aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 831eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // Control Flow 832eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org void Jump(Address destination, RelocInfo::Mode rmode); 833eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org void Jump(ExternalReference ext); 8345aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org void Jump(Handle<Code> code_object, RelocInfo::Mode rmode); 8355aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 836eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org void Call(Address destination, RelocInfo::Mode rmode); 837eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org void Call(ExternalReference ext); 8388e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org void Call(Handle<Code> code_object, 8398e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org RelocInfo::Mode rmode, 840471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org TypeFeedbackId ast_id = TypeFeedbackId::None()); 841eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 842eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org // The size of the code generated for different call instructions. 843eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org int CallSize(Address destination, RelocInfo::Mode rmode) { 844594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return kCallSequenceLength; 845eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org } 846ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org int CallSize(ExternalReference ext); 847eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org int CallSize(Handle<Code> code_object) { 848eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org // Code calls use 32-bit relative addressing. 849eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org return kShortCallInstructionLength; 850eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org } 851eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org int CallSize(Register target) { 852eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org // Opcode: REX_opt FF /2 m64 853eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org return (target.high_bit() != 0) ? 3 : 2; 854eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org } 855eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org int CallSize(const Operand& target) { 856eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org // Opcode: REX_opt FF /2 m64 857eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org return (target.requires_rex() ? 2 : 1) + target.operand_size(); 858eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org } 859eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org 86083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org // Emit call to the code we are currently generating. 86183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org void CallSelf() { 86283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org Handle<Code> self(reinterpret_cast<Code**>(CodeObject().location())); 86383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org Call(self, RelocInfo::CODE_TARGET); 86483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 86583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 8660a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // Non-x64 instructions. 8670a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // Push/pop all general purpose registers. 8680a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // Does not push rsp/rbp nor any of the assembler's special purpose registers 8690a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // (kScratchRegister, kSmiConstantRegister, kRootRegister). 8700a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org void Pushad(); 8710a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org void Popad(); 8720ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org // Sets the stack as after performing Popad, without actually loading the 8730ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org // registers. 8740ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org void Dropad(); 8750a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 8769085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Compare object type for heap object. 877e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // Always use unsigned comparisons: above and below, not less and greater. 8789085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Incoming register is heap_object and outgoing register is map. 87986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // They may be the same register, and may be kScratchRegister. 8809085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void CmpObjectType(Register heap_object, InstanceType type, Register map); 8819085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 8829085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Compare instance type for map. 883e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // Always use unsigned comparisons: above and below, not less and greater. 8849085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void CmpInstanceType(Register map, InstanceType type); 8859085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 886d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com // Check if a map for a JSObject indicates that the object has fast elements. 887d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com // Jump to the specified label if it does not. 888d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com void CheckFastElements(Register map, 889d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com Label* fail, 890d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com Label::Distance distance = Label::kFar); 891d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com 892c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check if a map for a JSObject indicates that the object can have both smi 893c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // and HeapObject elements. Jump to the specified label if it does not. 894c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void CheckFastObjectElements(Register map, 895c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* fail, 896c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance distance = Label::kFar); 897c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 898c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check if a map for a JSObject indicates that the object has fast smi only 899c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // elements. Jump to the specified label if it does not. 900830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org void CheckFastSmiElements(Register map, 901830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Label* fail, 902830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Label::Distance distance = Label::kFar); 903c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 904c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check to see if maybe_number can be stored as a double in 905394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // FastDoubleElements. If it can, store it at the index specified by index in 906394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // the FastDoubleElements array elements, otherwise jump to fail. Note that 907394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // index must not be smi-tagged. 908c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void StoreNumberToDoubleElements(Register maybe_number, 909c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register elements, 910394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register index, 911c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com XMMRegister xmm_scratch, 912fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org Label* fail, 913fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org int elements_offset = 0); 914c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 915f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Compare an object's map with the specified map and its transitioned 916f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // elements maps if mode is ALLOW_ELEMENT_TRANSITION_MAPS. FLAGS are set with 917f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // result of map compare. If multiple map compares are required, the compare 918f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // sequences branches to early_success. 919f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com void CompareMap(Register obj, 920f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com Handle<Map> map, 921a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org Label* early_success); 922f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 923f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Check if the map of an object is equal to a specified map and branch to 924f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // label if not. Skip the smi check if not required (object is known to be a 925f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // heap object). If mode is ALLOW_ELEMENT_TRANSITION_MAPS, then also match 9262efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // against maps that are ElementsKind transition maps of the specified map. 9275c838251403b0be9a882540f1922577abba4c872ager@chromium.org void CheckMap(Register obj, 9285c838251403b0be9a882540f1922577abba4c872ager@chromium.org Handle<Map> map, 9295c838251403b0be9a882540f1922577abba4c872ager@chromium.org Label* fail, 930a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org SmiCheckType smi_check_type); 9315c838251403b0be9a882540f1922577abba4c872ager@chromium.org 932ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org // Check if the map of an object is equal to a specified map and branch to a 933ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org // specified target if equal. Skip the smi check if not required (object is 934ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org // known to be a heap object) 935ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org void DispatchMap(Register obj, 9362bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register unused, 937ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org Handle<Map> map, 938ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org Handle<Code> success, 939ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org SmiCheckType smi_check_type); 940ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 941b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Check if the object in register heap_object is a string. Afterwards the 942b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // register map contains the object map and the register instance_type 943b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // contains the instance_type. The registers map and instance_type can be the 944b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // same in which case it contains the instance type afterwards. Either of the 945b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // registers map and instance_type can be the same as heap_object. 946b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Condition IsObjectStringType(Register heap_object, 947b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Register map, 948b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Register instance_type); 949b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 950750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // Check if the object in register heap_object is a name. Afterwards the 951750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // register map contains the object map and the register instance_type 952750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // contains the instance_type. The registers map and instance_type can be the 953750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // same in which case it contains the instance type afterwards. Either of the 954750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // registers map and instance_type can be the same as heap_object. 955750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Condition IsObjectNameType(Register heap_object, 956750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Register map, 957750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Register instance_type); 958750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 95940b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org // FCmp compares and pops the two values on top of the FPU stack. 96040b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org // The flag results are similar to integer cmp, but requires unsigned 9619085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // jcc instructions (je, ja, jae, jb, jbe, je, and jz). 9629085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void FCmp(); 9639085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 964c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org void ClampUint8(Register reg); 965c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 966c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org void ClampDoubleToUint8(XMMRegister input_reg, 967c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org XMMRegister temp_xmm_reg, 96889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org Register result_reg); 969c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 97046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org void LoadUint32(XMMRegister dst, Register src, XMMRegister scratch); 97146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 97240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org void LoadInstanceDescriptors(Register map, Register descriptors); 973355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org void EnumLength(Register dst, Register map); 97406ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org void NumberOfOwnDescriptors(Register dst, Register map); 975355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 976355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org template<typename Field> 977355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org void DecodeField(Register reg) { 97806ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org static const int shift = Field::kShift + kSmiShift; 97906ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org static const int mask = Field::kMask >> Field::kShift; 98006ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org shr(reg, Immediate(shift)); 98106ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org and_(reg, Immediate(mask)); 98206ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org shl(reg, Immediate(kSmiShift)); 983355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org } 98440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 985c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org // Abort execution if argument is not a number, enabled via --debug-code. 986c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org void AssertNumber(Register object); 9875c838251403b0be9a882540f1922577abba4c872ager@chromium.org 988c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org // Abort execution if argument is a smi, enabled via --debug-code. 989c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org void AssertNotSmi(Register object); 990ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 991c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org // Abort execution if argument is not a smi, enabled via --debug-code. 992c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org void AssertSmi(Register object); 993c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org void AssertSmi(const Operand& object); 99425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org 995f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // Abort execution if a 64 bit register containing a 32 bit payload does not 996c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org // have zeros in the top 32 bits, enabled via --debug-code. 997c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org void AssertZeroExtended(Register reg); 998f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 999c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org // Abort execution if argument is not a string, enabled via --debug-code. 1000c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org void AssertString(Register object); 100149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 1002750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // Abort execution if argument is not a name, enabled via --debug-code. 1003750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org void AssertName(Register object); 1004750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 1005c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org // Abort execution if argument is not the root value with the given index, 1006c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org // enabled via --debug-code. 1007c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org void AssertRootValue(Register src, 1008c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Heap::RootListIndex root_value_index, 1009594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org BailoutReason reason); 10105ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org 10119085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // --------------------------------------------------------------------------- 10129085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Exception handling 10139085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 101404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Push a new try handler and link it into try handler chain. 101578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org void PushTryHandler(StackHandler::Kind kind, int handler_index); 10169085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 101713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // Unlink the stack handler on top of the stack from the try handler chain. 101813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org void PopTryHandler(); 10199085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 102049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // Activate the top handler in the try hander chain and pass the 102149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // thrown value. 102249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org void Throw(Register value); 102349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 102449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // Propagate an uncatchable exception out of the current JS stack. 102565a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org void ThrowUncatchable(Register value); 102649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 10279085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // --------------------------------------------------------------------------- 10289085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Inline caching support 10299085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 10309085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Generate code for checking access rights - used for security checks 10319085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // on access to global objects across environments. The holder register 1032e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // is left untouched, but the scratch register and kScratchRegister, 1033e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // which must be different, are clobbered. 10349085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void CheckAccessGlobalProxy(Register holder_reg, 10359085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org Register scratch, 10369085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org Label* miss); 10379085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 1038f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com void GetNumberHash(Register r0, Register scratch); 10399085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 10406db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org void LoadFromNumberDictionary(Label* miss, 10416db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register elements, 10426db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register key, 10436db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register r0, 10446db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register r1, 10456db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register r2, 10466db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register result); 10476db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 10486db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 10499085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // --------------------------------------------------------------------------- 105018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Allocation support 105118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 10522bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org // Allocate an object in new space or old pointer space. If the given space 10532bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org // is exhausted control continues at the gc_required label. The allocated 10542bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org // object is returned in result and end of the new object is returned in 10552bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org // result_end. The register scratch can be passed as no_reg in which case 10562bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org // an additional object reference will be added to the reloc info. The 10572bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org // returned pointers in result and result_end have not yet been tagged as 10582bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org // heap objects. If result_contains_top_on_entry is true the content of 10592bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org // result is known to be the allocation top on entry (could be result_end 10602bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org // from a previous call). If result_contains_top_on_entry is true scratch 106118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // should be no_reg as it is never used. 10622bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org void Allocate(int object_size, 10632bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register result, 10642bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register result_end, 10652bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register scratch, 10662bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Label* gc_required, 10672bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org AllocationFlags flags); 1068c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 1069f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org void Allocate(int header_size, 1070f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org ScaleFactor element_size, 1071f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register element_count, 1072f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register result, 1073f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register result_end, 1074f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register scratch, 1075f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Label* gc_required, 1076f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org AllocationFlags flags); 1077f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org 1078f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org void Allocate(Register object_size, 1079f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register result, 1080f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register result_end, 1081f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register scratch, 1082f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Label* gc_required, 1083f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org AllocationFlags flags); 108418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 108518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Undo allocation in new space. The object passed and objects allocated after 108618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // it will no longer be allocated. Make sure that no pointers are left to the 108718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // object(s) no longer allocated as they would be invalid when allocation is 108818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // un-done. 108918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org void UndoAllocationInNewSpace(Register object); 109018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 10913811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Allocate a heap number in new space with undefined value. Returns 10923811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // tagged pointer in result register, or jumps to gc_required if new 10933811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // space is full. 10943811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org void AllocateHeapNumber(Register result, 10953811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org Register scratch, 10963811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org Label* gc_required); 10973811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 109813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // Allocate a sequential string. All the header fields of the string object 109913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // are initialized. 110013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org void AllocateTwoByteString(Register result, 110113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register length, 110213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register scratch1, 110313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register scratch2, 110413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register scratch3, 110513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Label* gc_required); 110613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org void AllocateAsciiString(Register result, 110713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register length, 110813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register scratch1, 110913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register scratch2, 111013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register scratch3, 111113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Label* gc_required); 111213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 111313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // Allocate a raw cons string object. Only the map field of the result is 111413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // initialized. 11151805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org void AllocateTwoByteConsString(Register result, 111613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register scratch1, 111713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register scratch2, 111813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Label* gc_required); 111913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org void AllocateAsciiConsString(Register result, 112013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register scratch1, 112113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register scratch2, 112213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Label* gc_required); 112313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 11241805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // Allocate a raw sliced string object. Only the map field of the result is 11251805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // initialized. 11261805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org void AllocateTwoByteSlicedString(Register result, 11271805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org Register scratch1, 11281805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org Register scratch2, 11291805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org Label* gc_required); 11301805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org void AllocateAsciiSlicedString(Register result, 11311805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org Register scratch1, 11321805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org Register scratch2, 11331805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org Label* gc_required); 11341805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 113518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // --------------------------------------------------------------------------- 11369085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Support functions. 11379085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 11389085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Check if result is zero and op is negative. 11399085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void NegativeZeroTest(Register result, Register op, Label* then_label); 11409085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 11419085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Check if result is zero and op is negative in code using jump targets. 11429085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void NegativeZeroTest(CodeGenerator* cgen, 11439085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org Register result, 11449085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org Register op, 11459085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org JumpTarget* then_target); 11469085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 11479085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Check if result is zero and any of op1 and op2 are negative. 11489085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Register scratch is destroyed, and it must be different from op2. 11499085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void NegativeZeroTest(Register result, Register op1, Register op2, 11509085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org Register scratch, Label* then_label); 11519085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 11529085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Try to get function prototype of a function and puts the value in 11539085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // the result register. Checks that the function really is a 11549085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // function and jumps to the miss label if the fast checks fail. The 115586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // function register will be untouched; the other register may be 11569085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // clobbered. 11579085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void TryGetFunctionPrototype(Register function, 11589085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org Register result, 1159394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Label* miss, 1160394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com bool miss_on_bound_function = false); 11619085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 11629085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Generates code for reporting that an illegal operation has 11639085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // occurred. 11649085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void IllegalOperation(int num_arguments); 11659085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 1166d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // Picks out an array index from the hash field. 1167d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // Register use: 1168d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // hash - holds the index's hash. Clobbered. 1169d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // index - holds the overwritten index on exit. 1170d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org void IndexFromHash(Register hash, Register index); 1171d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 1172ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // Find the function context up the context chain. 1173ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org void LoadContext(Register dst, int context_chain_length); 1174ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 11751145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org // Conditionally load the cached Array transitioned map of type 117646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // transitioned_kind from the native context if the map in register 117746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // map_in_out is the cached Array map in the native context of 11781145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org // expected_kind. 11791145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org void LoadTransitionedArrayMapConditional( 11801145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org ElementsKind expected_kind, 11811145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org ElementsKind transitioned_kind, 11821145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org Register map_in_out, 11831145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org Register scratch, 11841145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org Label* no_map_match); 11851145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org 11861145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org // Load the initial map for new Arrays from a JSFunction. 11871145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org void LoadInitialArrayMap(Register function_in, 11881145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org Register scratch, 1189830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Register map_out, 1190830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org bool can_have_holes); 1191fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org 11925f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // Load the global function with the given index. 11935f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org void LoadGlobalFunction(int index, Register function); 11944a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org void LoadArrayFunction(Register function); 11955f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 11965f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // Load the initial map from the global function. The registers 11975f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // function and map can be the same. 11985f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org void LoadGlobalFunctionInitialMap(Register function, Register map); 11995f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 12009085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // --------------------------------------------------------------------------- 12019085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Runtime calls 12029085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 12039085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Call a code stub. 1204471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org void CallStub(CodeStub* stub, TypeFeedbackId ast_id = TypeFeedbackId::None()); 12059085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 120613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // Tail call a code stub (jump). 120713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org void TailCallStub(CodeStub* stub); 120813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 12099085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Return from a code stub after popping its arguments. 12109085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void StubReturn(int argc); 12119085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 12129085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Call a runtime routine. 1213ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org void CallRuntime(const Runtime::Function* f, int num_arguments); 12149085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 12150ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org // Call a runtime function and save the value of XMM registers. 12160ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org void CallRuntimeSaveDoubles(Runtime::FunctionId id); 12170ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 12189085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Convenience function: Same as above, but takes the fid instead. 12199085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void CallRuntime(Runtime::FunctionId id, int num_arguments); 12209085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 12215c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Convenience function: call an external reference. 12225c838251403b0be9a882540f1922577abba4c872ager@chromium.org void CallExternalReference(const ExternalReference& ext, 12235c838251403b0be9a882540f1922577abba4c872ager@chromium.org int num_arguments); 12245c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12259085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Tail call of a runtime routine (jump). 1226ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org // Like JumpToExternalReference, but also takes care of passing the number 1227ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org // of parameters. 1228ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org void TailCallExternalReference(const ExternalReference& ext, 1229ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int num_arguments, 1230ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int result_size); 1231ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 1232ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org // Convenience function: tail call a runtime routine (jump). 1233ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org void TailCallRuntime(Runtime::FunctionId fid, 1234a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org int num_arguments, 1235a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org int result_size); 12369085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 1237c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // Jump to a runtime routine. 1238ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org void JumpToExternalReference(const ExternalReference& ext, int result_size); 12399085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 1240c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Prepares stack to put arguments (aligns and so on). WIN64 calling 1241c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // convention requires to put the pointer to the return value slot into 1242c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // rcx (rcx must be preserverd until CallApiFunctionAndReturn). Saves 1243c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // context (rsi). Clobbers rax. Allocates arg_stack_space * kPointerSize 12444a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // inside the exit frame (not GCed) accessible via StackSpaceOperand. 1245bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org void PrepareCallApiFunction(int arg_stack_space, bool returns_handle); 12464a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 1247c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Calls an API function. Allocates HandleScope, extracts returned value 1248c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // from handle and propagates exceptions. Clobbers r14, r15, rbx and 1249c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // caller-save registers. Restores context. On return removes 1250c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // stack_space * kPointerSize (GCed). 1251bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org void CallApiFunctionAndReturn(Address function_address, 1252b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Address thunk_address, 1253b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Register thunk_last_arg, 1254bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org int stack_space, 1255bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org bool returns_handle, 1256bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org int return_value_offset_from_rbp); 1257303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org 1258b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Before calling a C-function from generated code, align arguments on stack. 1259c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org // After aligning the frame, arguments must be stored in rsp[0], rsp[8], 1260b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // etc., not pushed. The argument count assumes all arguments are word sized. 1261b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // The number of slots reserved for arguments depends on platform. On Windows 1262b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // stack slots are reserved for the arguments passed in registers. On other 1263b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // platforms stack slots are only reserved for the arguments actually passed 1264b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // on the stack. 1265b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org void PrepareCallCFunction(int num_arguments); 1266b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1267b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Calls a C function and cleans up the space for arguments allocated 1268b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // by PrepareCallCFunction. The called function is not allowed to trigger a 1269b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // garbage collection, since that might move the code and invalidate the 1270b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // return address (unless this is somehow accounted for by the called 1271b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // function). 1272b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org void CallCFunction(ExternalReference function, int num_arguments); 1273b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org void CallCFunction(Register function, int num_arguments); 1274b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1275b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Calculate the number of stack slots to reserve for arguments when calling a 1276b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // C function. 1277b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org int ArgumentStackSlotsForCFunctionCall(int num_arguments); 12789085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 12799085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // --------------------------------------------------------------------------- 12809085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Utilities 12819085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 12829085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void Ret(); 12839085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 1284d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com // Return and drop arguments from stack, where the number of arguments 1285d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com // may be bigger than 2^16 - 1. Requires a scratch register. 1286d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com void Ret(int bytes_dropped, Register scratch); 1287d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 1288c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org Handle<Object> CodeObject() { 1289c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org ASSERT(!code_object_.is_null()); 1290c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org return code_object_; 1291c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org } 12929085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 12937979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Copy length bytes from source to destination. 12947979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Uses scratch register internally (if you have a low-eight register 12957979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // free, do use it, otherwise kScratchRegister will be used). 12967979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // The min_length is a minimum limit on the value that length will have. 12977979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // The algorithm has some special cases that might be omitted if the string 12987979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // is known to always be long. 12997979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org void CopyBytes(Register destination, 13007979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Register source, 13017979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Register length, 13027979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org int min_length = 0, 13037979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Register scratch = kScratchRegister); 13047979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 1305c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Initialize fields with filler values. Fields starting at |start_offset| 1306c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // not including end_offset are overwritten with the value in |filler|. At 1307c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // the end the loop, |start_offset| takes the value of |end_offset|. 1308c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void InitializeFieldsWithFiller(Register start_offset, 1309c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register end_offset, 1310c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register filler); 1311c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 13129085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 13139085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // --------------------------------------------------------------------------- 13149085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // StatsCounter support 13159085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 13169085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void SetCounter(StatsCounter* counter, int value); 13179085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void IncrementCounter(StatsCounter* counter, int value); 13189085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void DecrementCounter(StatsCounter* counter, int value); 13199085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 13209085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 13219085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // --------------------------------------------------------------------------- 13229085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Debugging 13239085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 13249085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Calls Abort(msg) if the condition cc is not satisfied. 13259085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Use --debug_code to enable. 1326594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org void Assert(Condition cc, BailoutReason reason); 13279085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 13280b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org void AssertFastElements(Register elements); 13290b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org 13309085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Like Assert(), but always enabled. 1331594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org void Check(Condition cc, BailoutReason reason); 13329085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 13339085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Print a message to stdout and abort execution. 1334594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org void Abort(BailoutReason msg); 13359085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 1336c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org // Check that the stack is aligned. 1337c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org void CheckStackAlignment(); 1338c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org 13399085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Verify restrictions about code generated in stubs. 13409085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void set_generating_stub(bool value) { generating_stub_ = value; } 13419085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org bool generating_stub() { return generating_stub_; } 13429085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void set_allow_stub_calls(bool value) { allow_stub_calls_ = value; } 13439085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org bool allow_stub_calls() { return allow_stub_calls_; } 1344c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void set_has_frame(bool value) { has_frame_ = value; } 1345c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool has_frame() { return has_frame_; } 1346c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline bool AllowThisStubCall(CodeStub* stub); 13479085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 134844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org static int SafepointRegisterStackIndex(Register reg) { 134944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org return SafepointRegisterStackIndex(reg.code()); 135044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 135144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 1352c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Activation support. 1353c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void EnterFrame(StackFrame::Type type); 1354c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void LeaveFrame(StackFrame::Type type); 1355c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1356be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // Expects object in rax and returns map with validated enum cache 1357be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // in rax. Assumes that any other register can be used as a scratch. 1358be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org void CheckEnumCache(Register null_value, 1359be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Label* call_runtime); 1360be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 1361ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // AllocationMemento support. Arrays may have an associated 1362ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // AllocationMemento object that can be checked for in order to pretransition 136359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // to another type. 136459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // On entry, receiver_reg should point to the array object. 136559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // scratch_reg gets clobbered. 136694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org // If allocation info is present, condition flags are set to equal 1367ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org void TestJSArrayForAllocationMemento(Register receiver_reg, 1368ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Register scratch_reg); 136959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 13709085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org private: 13710ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org // Order general registers are pushed by Pushad. 1372b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org // rax, rcx, rdx, rbx, rsi, rdi, r8, r9, r11, r14, r15. 13731456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org static const int kSafepointPushRegisterIndices[Register::kNumRegisters]; 137449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org static const int kNumSafepointSavedRegisters = 11; 137583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org static const int kSmiShift = kSmiTagSize + kSmiShiftSize; 137649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 13779085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org bool generating_stub_; 13789085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org bool allow_stub_calls_; 1379c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool has_frame_; 1380ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org bool root_array_available_; 138169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 138269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org // Returns a register holding the smi value. The register MUST NOT be 138369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org // modified. It may be the "smi 1 constant" register. 138469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org Register GetSmiConstant(Smi* value); 138569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 1386000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org intptr_t RootRegisterDelta(ExternalReference other); 1387000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org 138869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org // Moves the smi value to the destination register. 138969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org void LoadSmiConstant(Register dst, Smi* value); 139069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 13915c838251403b0be9a882540f1922577abba4c872ager@chromium.org // This handle will be patched with the code object on installation. 13925c838251403b0be9a882540f1922577abba4c872ager@chromium.org Handle<Object> code_object_; 13939085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 13949085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Helper functions for generating invokes. 13959085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void InvokePrologue(const ParameterCount& expected, 13969085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org const ParameterCount& actual, 13979085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org Handle<Code> code_constant, 1398eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org Register code_register, 139983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* done, 14002efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org bool* definitely_mismatches, 14013a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org InvokeFlag flag, 140240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org Label::Distance near_jump = Label::kFar, 140340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org const CallWrapper& call_wrapper = NullCallWrapper(), 140440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org CallKind call_kind = CALL_AS_METHOD); 14059085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 1406d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org void EnterExitFramePrologue(bool save_rax); 14074a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 14084a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // Allocates arg_stack_space * kPointerSize memory (not GCed) on the stack 14094a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // accessible via StackSpaceOperand. 14100ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org void EnterExitFrameEpilogue(int arg_stack_space, bool save_doubles); 14114a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 14124a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com void LeaveExitFrameEpilogue(); 1413e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 141418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Allocation support helpers. 1415ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org // Loads the top of new-space into the result register. 1416ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org // Otherwise the address of the new-space top is loaded into scratch (if 1417ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org // scratch is valid), and the new-space top is loaded into result. 141818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org void LoadAllocationTopHelper(Register result, 141918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Register scratch, 1420a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org AllocationFlags flags); 14212bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org 1422ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org // Update allocation top with value in result_end register. 1423ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org // If scratch is valid, it contains the address of the allocation top. 14242bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org void UpdateAllocationTopHelper(Register result_end, 14252bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register scratch, 14262bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org AllocationFlags flags); 1427e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 1428e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org // Helper for PopHandleScope. Allowed to perform a GC and returns 1429e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org // NULL if gc_allowed. Does not perform a GC if !gc_allowed, and 1430e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org // possibly returns a failure object indicating an allocation failure. 1431e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org Object* PopHandleScopeHelper(Register saved, 1432e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org Register scratch, 1433e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org bool gc_allowed); 14343a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 1435c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Helper for implementing JumpIfNotInNewSpace and JumpIfInNewSpace. 1436c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void InNewSpace(Register object, 1437c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch, 1438c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Condition cc, 1439c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* branch, 1440c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance distance = Label::kFar); 1441c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1442c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Helper for finding the mark bits for an address. Afterwards, the 1443c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // bitmap register points at the word with the mark bits and the mask 1444c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // the position of the first bit. Uses rcx as scratch and leaves addr_reg 1445c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // unchanged. 1446c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline void GetMarkBits(Register addr_reg, 1447c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register bitmap_reg, 1448c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register mask_reg); 14493a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 145004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Helper for throwing exceptions. Compute a handler address and jump to 145104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // it. See the implementation for register usage. 145204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org void JumpToHandlerEntry(); 145304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 14543a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Compute memory operands for safepoint stack slots. 14553a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Operand SafepointRegisterSlot(Register reg); 14563a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org static int SafepointRegisterStackIndex(int reg_code) { 14573a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org return kNumSafepointRegisters - kSafepointPushRegisterIndices[reg_code] - 1; 14583a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 14593a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 1460a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Needs access to SafepointRegisterStackIndex for compiled frame 14613a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // traversal. 1462a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org friend class StandardFrame; 14639085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org}; 14649085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 14659085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 14664af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org// The code patcher is used to patch (typically) small parts of code e.g. for 14674af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org// debugging and other types of instrumentation. When using the code patcher 14684af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org// the exact number of bytes specified must be emitted. Is not legal to emit 14694af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org// relocation information. If any of these constraints are violated it causes 14704af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org// an assertion. 14714af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgclass CodePatcher { 14724af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org public: 14734af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org CodePatcher(byte* address, int size); 14744af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org virtual ~CodePatcher(); 14754af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 14764af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Macro assembler to emit code. 14774af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org MacroAssembler* masm() { return &masm_; } 14784af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 14794af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org private: 14804af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org byte* address_; // The address of the code being patched. 14814af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org int size_; // Number of bytes of the expected patch size. 14824af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org MacroAssembler masm_; // Macro assembler used to generate the code. 14834af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}; 14844af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 14854af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 14869085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// ----------------------------------------------------------------------------- 14879085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// Static helper functions. 14889085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 14899085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// Generate an Operand for loading a field from an object. 14901b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orginline Operand FieldOperand(Register object, int offset) { 14919085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org return Operand(object, offset - kHeapObjectTag); 14929085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org} 14939085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 14949085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 14959085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// Generate an Operand for loading an indexed field from an object. 14961b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orginline Operand FieldOperand(Register object, 14971b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org Register index, 14981b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ScaleFactor scale, 14991b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int offset) { 15009085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org return Operand(object, index, scale, offset - kHeapObjectTag); 15019085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org} 15029085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 15039085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 15041b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orginline Operand ContextOperand(Register context, int index) { 15054a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com return Operand(context, Context::SlotOffset(index)); 15064a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com} 15074a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 15084a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 15091b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orginline Operand GlobalObjectOperand() { 151046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org return ContextOperand(rsi, Context::GLOBAL_OBJECT_INDEX); 15114a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com} 15124a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 15134a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 15144a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// Provides access to exit frame stack space (not GCed). 15151b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orginline Operand StackSpaceOperand(int index) { 15164a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com#ifdef _WIN64 15174a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com const int kShaddowSpace = 4; 15184a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com return Operand(rsp, (index + kShaddowSpace) * kPointerSize); 15194a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com#else 15204a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com return Operand(rsp, index * kPointerSize); 15214a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com#endif 15224a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com} 15234a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 15244a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 1525d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orginline Operand StackOperandForReturnAddress(int32_t disp) { 1526d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org return Operand(rsp, disp); 1527d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org} 1528d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 15294a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 15309085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#ifdef GENERATED_CODE_COVERAGE 15319085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.orgextern void LogGeneratedCodeCoverage(const char* file_line); 15329085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#define CODE_COVERAGE_STRINGIFY(x) #x 15339085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x) 15349085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__) 15354cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org#define ACCESS_MASM(masm) { \ 15364cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org Address x64_coverage_function = FUNCTION_ADDR(LogGeneratedCodeCoverage); \ 15374cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org masm->pushfq(); \ 15384cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org masm->Pushad(); \ 15394cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org masm->push(Immediate(reinterpret_cast<int>(&__FILE_LINE__))); \ 15404cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org masm->Call(x64_coverage_function, RelocInfo::EXTERNAL_REFERENCE); \ 15414cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org masm->pop(rax); \ 15424cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org masm->Popad(); \ 15434cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org masm->popfq(); \ 15444cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org } \ 15459085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org masm-> 15469085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#else 15479085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#define ACCESS_MASM(masm) masm-> 15489085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#endif 15499085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 15509085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org} } // namespace v8::internal 15519085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 15529085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#endif // V8_X64_MACRO_ASSEMBLER_X64_H_ 1553