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