1f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com// Copyright 2012 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 45ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 59085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#ifndef V8_X64_MACRO_ASSEMBLER_X64_H_ 69085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#define V8_X64_MACRO_ASSEMBLER_X64_H_ 79085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/assembler.h" 9b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org#include "src/bailout-reason.h" 10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/frames.h" 11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/globals.h" 129085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 1371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 1471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal { 159085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 16e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org// Default scratch register used by MacroAssembler (and other code that needs 17e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org// a spare register). The register isn't callee save, and not used by the 18e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org// function calling convention. 191b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgconst Register kScratchRegister = { 10 }; // r10. 201b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgconst Register kSmiConstantRegister = { 12 }; // r12 (callee save). 211b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgconst Register kRootRegister = { 13 }; // r13 (callee save). 2269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org// Value of smi in kSmiConstantRegister. 231b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgconst int kSmiConstantRegisterValue = 1; 248f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org// Actual value of root register is offset from the root array's start 258f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org// to take advantage of negitive 8-bit displacement values. 261b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgconst int kRootRegisterBias = 128; 27e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 280c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org// Convenience for platform-independent signatures. 290c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.orgtypedef Operand MemOperand; 300c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 31c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comenum RememberedSetAction { EMIT_REMEMBERED_SET, OMIT_REMEMBERED_SET }; 32c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comenum SmiCheck { INLINE_SMI_CHECK, OMIT_SMI_CHECK }; 33196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgenum PointersToHereCheck { 34196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org kPointersToHereMaybeInteresting, 35196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org kPointersToHereAreAlwaysInteresting 36196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org}; 37c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 38e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.orgenum SmiOperationConstraint { 39e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org PRESERVE_SOURCE_REGISTER, 40e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org BAILOUT_ON_NO_OVERFLOW, 41e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org BAILOUT_ON_OVERFLOW, 42e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org NUMBER_OF_CONSTRAINTS 43e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org}; 44e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 45e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.orgSTATIC_ASSERT(NUMBER_OF_CONSTRAINTS <= 8); 46e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 47e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.orgclass SmiOperationExecutionMode : public EnumSet<SmiOperationConstraint, byte> { 48e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org public: 49e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org SmiOperationExecutionMode() : EnumSet<SmiOperationConstraint, byte>(0) { } 50e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org explicit SmiOperationExecutionMode(byte bits) 51e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org : EnumSet<SmiOperationConstraint, byte>(bits) { } 52e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org}; 53e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 549bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org#ifdef DEBUG 559bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.orgbool AreAliased(Register reg1, 569bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register reg2, 579bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register reg3 = no_reg, 589bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register reg4 = no_reg, 599bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register reg5 = no_reg, 609bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register reg6 = no_reg, 619bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register reg7 = no_reg, 629bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register reg8 = no_reg); 639bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org#endif 64c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 659085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// Forward declaration. 669085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.orgclass JumpTarget; 679085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 684af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgstruct SmiIndex { 694af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org SmiIndex(Register index_register, ScaleFactor scale) 704af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org : reg(index_register), 714af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org scale(scale) {} 724af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register reg; 734af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org ScaleFactor scale; 744af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}; 759085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 76c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 779085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// MacroAssembler implements a collection of frequently used macros. 789085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.orgclass MacroAssembler: public Assembler { 799085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org public: 80c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // The isolate parameter can be NULL if the macro assembler should 81c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // not use isolate-dependent functionality. In this case, it's the 82c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // responsibility of the caller to never invoke such function on the 83c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // macro assembler. 84c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org MacroAssembler(Isolate* isolate, void* buffer, int size); 859085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 86ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Prevent the use of the RootArray during the lifetime of this 87ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // scope object. 88ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org class NoRootArrayScope BASE_EMBEDDED { 89ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org public: 90ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org explicit NoRootArrayScope(MacroAssembler* assembler) 91ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org : variable_(&assembler->root_array_available_), 92ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org old_value_(assembler->root_array_available_) { 93ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org assembler->root_array_available_ = false; 94ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 95ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ~NoRootArrayScope() { 96ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org *variable_ = old_value_; 97ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 98ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org private: 99ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org bool* variable_; 100ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org bool old_value_; 101ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org }; 102ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 103ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Operand pointing to an external reference. 104ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // May emit code to set up the scratch register. The operand is 105ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // only guaranteed to be correct as long as the scratch register 106ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // isn't changed. 107ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // If the operand is used more than once, use a scratch register 108ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // that is guaranteed not to be clobbered. 109ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Operand ExternalOperand(ExternalReference reference, 110ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Register scratch = kScratchRegister); 111ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Loads and stores the value of an external reference. 112ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Special case code for load and store to take advantage of 113ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // load_rax/store_rax if possible/necessary. 114ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // For other operations, just use: 115ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Operand operand = ExternalOperand(extref); 116ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // operation(operand, ..); 117ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org void Load(Register destination, ExternalReference source); 118ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org void Store(ExternalReference destination, Register source); 119ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Loads the address of the external reference into the destination 120ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // register. 121ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org void LoadAddress(Register destination, ExternalReference source); 122ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Returns the size of the code generated by LoadAddress. 123ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Used by CallSize(ExternalReference) to find the size of a call. 124ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org int LoadAddressSize(ExternalReference source); 125ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com // Pushes the address of the external reference onto the stack. 126ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com void PushAddress(ExternalReference source); 127ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 128ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Operations on roots in the root-array. 12918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org void LoadRoot(Register destination, Heap::RootListIndex index); 130ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org void StoreRoot(Register source, Heap::RootListIndex index); 1318f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org // Load a root value where the index (or part of it) is variable. 1328f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org // The variable_offset register is added to the fixed_offset value 1338f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org // to get the index into the root-array. 1348f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org void LoadRootIndexed(Register destination, 1358f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org Register variable_offset, 1368f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org int fixed_offset); 13718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org void CompareRoot(Register with, Heap::RootListIndex index); 13883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org void CompareRoot(const Operand& with, Heap::RootListIndex index); 13918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org void PushRoot(Heap::RootListIndex index); 14018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 141c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // These functions do not arrange the registers in any particular order so 142c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // they are not useful for calls that can cause a GC. The caller can 143c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // exclude up to 3 registers that do not need to be saved and restored. 144c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void PushCallerSaved(SaveFPRegsMode fp_mode, 145c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register exclusion1 = no_reg, 146c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register exclusion2 = no_reg, 147c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register exclusion3 = no_reg); 148c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void PopCallerSaved(SaveFPRegsMode fp_mode, 149c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register exclusion1 = no_reg, 150c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register exclusion2 = no_reg, 151c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register exclusion3 = no_reg); 152c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 153c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// --------------------------------------------------------------------------- 154c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// GC Support 155c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 156c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 157c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com enum RememberedSetFinalAction { 158c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com kReturnAtEnd, 159c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com kFallThroughAtEnd 160c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com }; 1614111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org 162c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Record in the remembered set the fact that we have a pointer to new space 163c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // at the address pointed to by the addr register. Only works if addr is not 164c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // in new space. 165c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void RememberedSetHelper(Register object, // Used for debug code. 166c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register addr, 167c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch, 168c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SaveFPRegsMode save_fp, 169c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RememberedSetFinalAction and_then); 170c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 171c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void CheckPageFlag(Register object, 172c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch, 173c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int mask, 174c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Condition cc, 175c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* condition_met, 176c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance condition_met_distance = Label::kFar); 177c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 178f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org void CheckMapDeprecated(Handle<Map> map, 179f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org Register scratch, 180f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org Label* if_deprecated); 181f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 182c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check if object is in new space. Jumps if the object is not in new space. 183c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // The register scratch can be object itself, but scratch will be clobbered. 184c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void JumpIfNotInNewSpace(Register object, 185c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch, 186c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* branch, 187c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance distance = Label::kFar) { 188c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com InNewSpace(object, scratch, not_equal, branch, distance); 189c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 190c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 191c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check if object is in new space. Jumps if the object is in new space. 192c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // The register scratch can be object itself, but it will be clobbered. 193c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void JumpIfInNewSpace(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, equal, branch, distance); 198c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 199c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 200c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check if an object has the black incremental marking color. Also uses rcx! 201c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void JumpIfBlack(Register object, 202c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch0, 203c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch1, 204c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* on_black, 205c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance on_black_distance = Label::kFar); 206c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2072efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // Detects conservatively whether an object is data-only, i.e. it does need to 208c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // be scanned by the garbage collector. 209c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void JumpIfDataObject(Register value, 210c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch, 211c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* not_data_object, 212c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance not_data_object_distance); 213c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 214c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Checks the color of an object. If the object is already grey or black 215c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // then we just fall through, since it is already live. If it is white and 216c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // we can determine that it doesn't need to be scanned, then we just mark it 217c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // black and fall through. For the rest we jump to the label so the 218c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // incremental marker can fix its assumptions. 219c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void EnsureNotWhite(Register object, 220c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch1, 221c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch2, 222c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* object_is_white_and_not_data, 223c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance distance); 224c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 225c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Notify the garbage collector that we wrote a pointer into an object. 226c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // |object| is the object being stored into, |value| is the object being 227c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // stored. value and scratch registers are clobbered by the operation. 228c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // The offset is the offset from the start of the object, not the offset from 229c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // the tagged HeapObject pointer. For use with FieldOperand(reg, off). 230c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void RecordWriteField( 231c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register object, 232c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int offset, 233c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register value, 234c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch, 235c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SaveFPRegsMode save_fp, 236c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, 237196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org SmiCheck smi_check = INLINE_SMI_CHECK, 238196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org PointersToHereCheck pointers_to_here_check_for_value = 239196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org kPointersToHereMaybeInteresting); 240c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 241c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // As above, but the offset has the tag presubtracted. For use with 242c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Operand(reg, off). 243c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void RecordWriteContextSlot( 244c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register context, 245c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int offset, 246c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register value, 247c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch, 248c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SaveFPRegsMode save_fp, 249c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, 250196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org SmiCheck smi_check = INLINE_SMI_CHECK, 251196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org PointersToHereCheck pointers_to_here_check_for_value = 252196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org kPointersToHereMaybeInteresting) { 253c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RecordWriteField(context, 254c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com offset + kHeapObjectTag, 255c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com value, 256c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com scratch, 257c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com save_fp, 258c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com remembered_set_action, 259196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org smi_check, 260196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org pointers_to_here_check_for_value); 261c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 262c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 263c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Notify the garbage collector that we wrote a pointer into a fixed array. 264c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // |array| is the array being stored into, |value| is the 265394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // object being stored. |index| is the array index represented as a non-smi. 266394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // All registers are clobbered by the operation RecordWriteArray 267c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // filters out smis so it does not update the write barrier if the 268c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // value is a smi. 269c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void RecordWriteArray( 270c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register array, 271c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register value, 272c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register index, 273c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SaveFPRegsMode save_fp, 274c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, 275196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org SmiCheck smi_check = INLINE_SMI_CHECK, 276196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org PointersToHereCheck pointers_to_here_check_for_value = 277196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org kPointersToHereMaybeInteresting); 278196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org 279196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org void RecordWriteForMap( 280196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Register object, 281196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Register map, 282196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Register dst, 283196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org SaveFPRegsMode save_fp); 284c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 285c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // For page containing |object| mark region covering |address| 28669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org // dirty. |object| is the object being stored into, |value| is the 287c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // object being stored. The address and value registers are clobbered by the 28869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org // operation. RecordWrite filters out smis so it does not update 28969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org // the write barrier if the value is a smi. 290c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void RecordWrite( 291c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register object, 292c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register address, 293c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register value, 294c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SaveFPRegsMode save_fp, 295c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET, 296196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org SmiCheck smi_check = INLINE_SMI_CHECK, 297196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org PointersToHereCheck pointers_to_here_check_for_value = 298196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org kPointersToHereMaybeInteresting); 2999d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com 3009085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // --------------------------------------------------------------------------- 3019085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Debugger Support 3029085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 3035c838251403b0be9a882540f1922577abba4c872ager@chromium.org void DebugBreak(); 3049085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 305c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // Generates function and stub prologue code. 306285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org void StubPrologue(); 307285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org void Prologue(bool code_pre_aging); 308c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 309c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org // Enter specific kind of exit frame; either in normal or 310c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org // debug mode. Expects the number of arguments in register rax and 311a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // sets up the number of arguments in register rdi and the pointer 312a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // to the first argument in register rsi. 3134a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // 3144a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // Allocates arg_stack_space * kPointerSize memory (not GCed) on the stack 3154a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // accessible via StackSpaceOperand. 3160ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org void EnterExitFrame(int arg_stack_space = 0, bool save_doubles = false); 3179085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 3184a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // Enter specific kind of exit frame. Allocates arg_stack_space * kPointerSize 3194a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // memory (not GCed) on the stack accessible via StackSpaceOperand. 3204a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com void EnterApiExitFrame(int arg_stack_space); 321e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 322a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // Leave the current exit frame. Expects/provides the return value in 323a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // register rax:rdx (untouched) and the pointer to the first 324a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // argument in register rsi. 3250ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org void LeaveExitFrame(bool save_doubles = false); 3269085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 3274a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // Leave the current exit frame. Expects/provides the return value in 3284a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // register rax (untouched). 329528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org void LeaveApiExitFrame(bool restore_context); 3309085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 331a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Push and pop the registers that can hold pointers. 3320ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org void PushSafepointRegisters() { Pushad(); } 3330ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org void PopSafepointRegisters() { Popad(); } 3343a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Store the value in register src in the safepoint register stack 3353a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // slot for register dst. 33646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org void StoreToSafepointRegisterSlot(Register dst, const Immediate& imm); 3373a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org void StoreToSafepointRegisterSlot(Register dst, Register src); 3385d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org void LoadFromSafepointRegisterSlot(Register dst, Register src); 3390ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 3408f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org void InitializeRootRegister() { 341394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ExternalReference roots_array_start = 342394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ExternalReference::roots_array_start(isolate()); 343e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Move(kRootRegister, roots_array_start); 344fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org addp(kRootRegister, Immediate(kRootRegisterBias)); 3458f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org } 3468f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org 3479085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // --------------------------------------------------------------------------- 3489085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // JavaScript invokes 3499085a016223a6b72bf580d5781c93ec7b9e54422ager@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, 355e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org const CallWrapper& call_wrapper); 3569085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 3579085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Invoke the JavaScript function in the given register. Changes the 3589085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // current context to the context in the function before invoking. 3599085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void InvokeFunction(Register function, 3609085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org const ParameterCount& actual, 3613a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org InvokeFlag flag, 362e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org const CallWrapper& call_wrapper); 3639085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 3648a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org void InvokeFunction(Register function, 3658a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org const ParameterCount& expected, 3668a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org const ParameterCount& actual, 3678a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org InvokeFlag flag, 368e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org const CallWrapper& call_wrapper); 3698a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org 370c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org void InvokeFunction(Handle<JSFunction> function, 37132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org const ParameterCount& expected, 3725c838251403b0be9a882540f1922577abba4c872ager@chromium.org const ParameterCount& actual, 3733a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org InvokeFlag flag, 374e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org const CallWrapper& call_wrapper); 3755c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3769085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Invoke specified builtin JavaScript function. Adds an entry to 3779085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // the unresolved list if the name does not resolve. 3783a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org void InvokeBuiltin(Builtins::JavaScript id, 3793a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org InvokeFlag flag, 380fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org const CallWrapper& call_wrapper = NullCallWrapper()); 3819085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 382145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com // Store the function for the given builtin in the target register. 383145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com void GetBuiltinFunction(Register target, Builtins::JavaScript id); 384145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com 3859085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Store the code object for the given builtin in the target register. 3869085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void GetBuiltinEntry(Register target, Builtins::JavaScript id); 3879085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 3884af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 3894af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // --------------------------------------------------------------------------- 3904af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Smi tagging, untagging and operations on tagged smis. 3914af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 392dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org // Support for constant splitting. 393dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org bool IsUnsafeInt(const int32_t x); 394dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org void SafeMove(Register dst, Smi* src); 395dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org void SafePush(Smi* src); 396dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org 39769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org void InitializeSmiConstantRegister() { 3989cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org Move(kSmiConstantRegister, Smi::FromInt(kSmiConstantRegisterValue), 399af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org Assembler::RelocInfoNone()); 40069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org } 40169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 4024af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Conversions between tagged smi values and non-tagged integer values. 4034af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 4044af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Tag an integer value. The result must be known to be a valid smi value. 405b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Only uses the low 32 bits of the src register. Sets the N and Z flags 406c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org // based on the value of the resulting smi. 4074af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void Integer32ToSmi(Register dst, Register src); 4084af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 4095ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org // Stores an integer32 value into a memory field that already holds a smi. 4105ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org void Integer32ToSmiField(const Operand& dst, Register src); 4115ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org 4124af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Adds constant to src and tags the result as a smi. 4134af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Result must be a valid smi. 4149d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com void Integer64PlusConstantToSmi(Register dst, Register src, int constant); 4154af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 4164af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Convert smi to 32-bit integer. I.e., not sign extended into 4174af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // high 32 bits of destination. 4184af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiToInteger32(Register dst, Register src); 41930ce411529579186181838984710b0b0980857aaricow@chromium.org void SmiToInteger32(Register dst, const Operand& src); 4204af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 4214af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Convert smi to 64-bit integer (sign extended if necessary). 4224af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiToInteger64(Register dst, Register src); 4235ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org void SmiToInteger64(Register dst, const Operand& src); 4244af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 4254af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Multiply a positive smi's integer value by a power of two. 4264af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Provides result as 64-bit integer value. 4274af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void PositiveSmiTimesPowerOfTwoToInteger64(Register dst, 4284af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src, 4294af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org int power); 4304af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 43130ce411529579186181838984710b0b0980857aaricow@chromium.org // Divide a positive smi's integer value by a power of two. 43230ce411529579186181838984710b0b0980857aaricow@chromium.org // Provides result as 32-bit integer value. 43330ce411529579186181838984710b0b0980857aaricow@chromium.org void PositiveSmiDivPowerOfTwoToInteger32(Register dst, 43430ce411529579186181838984710b0b0980857aaricow@chromium.org Register src, 43530ce411529579186181838984710b0b0980857aaricow@chromium.org int power); 43630ce411529579186181838984710b0b0980857aaricow@chromium.org 43744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org // Perform the logical or of two smi values and return a smi value. 43844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org // If either argument is not a smi, jump to on_not_smis and retain 43944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org // the original values of source registers. The destination register 44044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org // may be changed if it's not one of the source registers. 44144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org void SmiOrIfSmis(Register dst, 44244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org Register src1, 44344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org Register src2, 44483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smis, 44583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 44644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 44730ce411529579186181838984710b0b0980857aaricow@chromium.org 448badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org // Simple comparison of smis. Both sides must be known smis to use these, 449badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org // otherwise use Cmp. 450badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org void SmiCompare(Register smi1, Register smi2); 4519d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com void SmiCompare(Register dst, Smi* src); 452ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org void SmiCompare(Register dst, const Operand& src); 4539d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com void SmiCompare(const Operand& dst, Register src); 4549d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com void SmiCompare(const Operand& dst, Smi* src); 4555ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org // Compare the int32 in src register to the value of the smi stored at dst. 4565ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org void SmiCompareInteger32(const Operand& dst, Register src); 4579d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com // Sets sign and zero flags depending on value of smi in register. 4589d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com void SmiTest(Register src); 4599d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com 4604af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Functions performing a check on a known or potential smi. Returns 4614af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // a condition that is satisfied if the check is successful. 4624af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 4634af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Is the value a tagged smi. 4644af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Condition CheckSmi(Register src); 4650a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org Condition CheckSmi(const Operand& src); 4664af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 467eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org // Is the value a non-negative tagged smi. 468eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org Condition CheckNonNegativeSmi(Register src); 4694af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 470b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Are both values tagged smis. 4714af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Condition CheckBothSmi(Register first, Register second); 4724af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 473eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org // Are both values non-negative tagged smis. 474eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org Condition CheckBothNonNegativeSmi(Register first, Register second); 475b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 476b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Are either value a tagged smi. 477c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org Condition CheckEitherSmi(Register first, 478c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org Register second, 479c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org Register scratch = kScratchRegister); 480b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4814af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Is the value the minimum smi value (since we are using 4824af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // two's complement numbers, negating the value is known to yield 4834af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // a non-smi value). 4844af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Condition CheckIsMinSmi(Register src); 4854af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 4864af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Checks whether an 32-bit integer value is a valid for conversion 4874af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // to a smi. 4884af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Condition CheckInteger32ValidSmiValue(Register src); 4894af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 4903811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Checks whether an 32-bit unsigned integer value is a valid for 4913811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // conversion to a smi. 4923811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org Condition CheckUInteger32ValidSmiValue(Register src); 4933811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 4940ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org // Check whether src is a Smi, and set dst to zero if it is a smi, 4950ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org // and to one if it isn't. 4960ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org void CheckSmiToIndicator(Register dst, Register src); 4970ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org void CheckSmiToIndicator(Register dst, const Operand& src); 4980ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 4994af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Test-and-jump functions. Typically combines a check function 5004af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // above with a conditional jump. 5014af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 502e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org // Jump if the value can be represented by a smi. 503e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org void JumpIfValidSmiValue(Register src, Label* on_valid, 504e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org Label::Distance near_jump = Label::kFar); 505e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org 5064af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Jump if the value cannot be represented by a smi. 50783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org void JumpIfNotValidSmiValue(Register src, Label* on_invalid, 50883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 5094af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 510e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org // Jump if the unsigned integer value can be represented by a smi. 511e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org void JumpIfUIntValidSmiValue(Register src, Label* on_valid, 512e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org Label::Distance near_jump = Label::kFar); 513e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org 5143811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Jump if the unsigned integer value cannot be represented by a smi. 51583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org void JumpIfUIntNotValidSmiValue(Register src, Label* on_invalid, 51683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 5173811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 5184af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Jump to label if the value is a tagged smi. 51983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org void JumpIfSmi(Register src, 52083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_smi, 52183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 5224af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 5234af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Jump to label if the value is not a tagged smi. 52483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org void JumpIfNotSmi(Register src, 52583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi, 52683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 5274af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 528eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org // Jump to label if the value is not a non-negative tagged smi. 52983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org void JumpUnlessNonNegativeSmi(Register src, 53083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi, 53183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 5324af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 5339d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com // Jump to label if the value, which must be a tagged smi, has value equal 5344af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // to the constant. 535c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org void JumpIfSmiEqualsConstant(Register src, 536c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org Smi* constant, 53783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_equals, 53883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 539c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 5404af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Jump if either or both register are not smi values. 541c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org void JumpIfNotBothSmi(Register src1, 542c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org Register src2, 54383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_both_smi, 54483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 5454af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 546eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org // Jump if either or both register are not non-negative smi values. 547eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org void JumpUnlessBothNonNegativeSmi(Register src1, Register src2, 54883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_both_smi, 54983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 550b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 5514af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Operations on tagged smi values. 5524af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 5534af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Smis represent a subset of integers. The subset is always equivalent to 5544af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // a two's complement interpretation of a fixed number of bits. 5554af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 5569d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com // Add an integer constant to a tagged smi, giving a tagged smi as result. 5579d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com // No overflow testing on the result is done. 5589d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com void SmiAddConstant(Register dst, Register src, Smi* constant); 5599d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com 5609dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // Add an integer constant to a tagged smi, giving a tagged smi as result. 5619dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // No overflow testing on the result is done. 5629dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com void SmiAddConstant(const Operand& dst, Smi* constant); 5639dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 5644af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Add an integer constant to a tagged smi, giving a tagged smi as result, 5654af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // or jumping to a label if the result cannot be represented by a smi. 5664af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiAddConstant(Register dst, 5674af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src, 5689d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com Smi* constant, 569e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org SmiOperationExecutionMode mode, 570e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Label* bailout_label, 57183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 5724af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 5734af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Subtract an integer constant from a tagged smi, giving a tagged smi as 574ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org // result. No testing on the result is done. Sets the N and Z flags 575ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org // based on the value of the resulting integer. 5769d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com void SmiSubConstant(Register dst, Register src, Smi* constant); 5779d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com 5789d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com // Subtract an integer constant from a tagged smi, giving a tagged smi as 5794af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // result, or jumping to a label if the result cannot be represented by a smi. 5804af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiSubConstant(Register dst, 5814af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src, 5829d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com Smi* constant, 583e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org SmiOperationExecutionMode mode, 584e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Label* bailout_label, 58583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 5864af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 5874af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Negating a smi can give a negative zero or too large positive value. 5889d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com // NOTICE: This operation jumps on success, not failure! 5894af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiNeg(Register dst, 5904af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src, 59183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_smi_result, 59283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 5934af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 5944af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Adds smi values and return the result as a smi. 595d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org // If dst is src1, then src1 will be destroyed if the operation is 596d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org // successful, otherwise kept intact. 5974af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiAdd(Register dst, 5984af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src1, 5994af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src2, 60083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi_result, 60183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 6027979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org void SmiAdd(Register dst, 6037979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Register src1, 6047979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org const Operand& src2, 60583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi_result, 60683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 607c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org 608c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org void SmiAdd(Register dst, 609c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org Register src1, 610c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org Register src2); 6114af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 6124af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Subtracts smi values and return the result as a smi. 613c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org // If dst is src1, then src1 will be destroyed if the operation is 614c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org // successful, otherwise kept intact. 6154af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiSub(Register dst, 6164af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src1, 6174af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src2, 61883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi_result, 61983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 620ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org void SmiSub(Register dst, 621ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org Register src1, 6229dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com const Operand& src2, 62383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi_result, 62483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 625c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org 626c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org void SmiSub(Register dst, 627c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org Register src1, 628c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org Register src2); 629c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org 630c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org void SmiSub(Register dst, 631c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org Register src1, 632c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org const Operand& src2); 633ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 6344af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Multiplies smi values and return the result as a smi, 6354af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // if possible. 6364af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // If dst is src1, then src1 will be destroyed, even if 6374af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // the operation is unsuccessful. 6384af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiMul(Register dst, 6394af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src1, 6404af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src2, 64183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi_result, 64283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 6434af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 6444af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Divides one smi by another and returns the quotient. 6454af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Clobbers rax and rdx registers. 6464af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiDiv(Register dst, 6474af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src1, 6484af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src2, 64983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi_result, 65083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 6514af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 6524af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Divides one smi by another and returns the remainder. 6534af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Clobbers rax and rdx registers. 6544af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiMod(Register dst, 6554af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src1, 6564af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src2, 65783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi_result, 65883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 6594af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 6604af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Bitwise operations. 6614af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiNot(Register dst, Register src); 6624af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiAnd(Register dst, Register src1, Register src2); 6634af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiOr(Register dst, Register src1, Register src2); 6644af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiXor(Register dst, Register src1, Register src2); 6659d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com void SmiAndConstant(Register dst, Register src1, Smi* constant); 6669d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com void SmiOrConstant(Register dst, Register src1, Smi* constant); 6679d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com void SmiXorConstant(Register dst, Register src1, Smi* constant); 6684af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 6694af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiShiftLeftConstant(Register dst, 6704af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src, 671e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org int shift_value, 672e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org Label* on_not_smi_result = NULL, 673e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org Label::Distance near_jump = Label::kFar); 6744af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiShiftLogicalRightConstant(Register dst, 67504a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org Register src, 67604a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org int shift_value, 67704a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org Label* on_not_smi_result, 67804a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org Label::Distance near_jump = Label::kFar); 6794af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiShiftArithmeticRightConstant(Register dst, 6804af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src, 6814af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org int shift_value); 6824af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 6834af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Shifts a smi value to the left, and returns the result if that is a smi. 6844af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Uses and clobbers rcx, so dst may not be rcx. 6854af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org void SmiShiftLeft(Register dst, 6864af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src1, 687e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org Register src2, 688e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org Label* on_not_smi_result = NULL, 689e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org Label::Distance near_jump = Label::kFar); 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); 74143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(dst, constant); 7423811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 7433811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 7449d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com void Push(Smi* smi); 745662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org 7462ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org // Save away a raw integer with pointer size on the stack as two integers 747662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org // masquerading as smis so that the garbage collector skips visiting them. 7482ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org void PushRegisterAsTwoSmis(Register src, Register scratch = kScratchRegister); 7492ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org // Reconstruct a raw integer with pointer size from two integers masquerading 7502ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org // as smis on the top of stack. 7512ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org void PopRegisterAsTwoSmis(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 7772c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org void JumpIfNotBothSequentialOneByteStrings( 7782c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Register first_object, Register second_object, Register scratch1, 7792c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Register scratch2, Label* on_not_both_flat_one_byte, 78083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 781b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 7822c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // Check whether the instance type represents a flat one-byte string. Jump 7832c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // to the label if not. If the instance type can be scratched specify same 7842c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // register for both instance type and scratch. 7852c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org void JumpIfInstanceTypeIsNotSequentialOneByte( 7862c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Register instance_type, Register scratch, 7872c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Label* on_not_flat_one_byte_string, 78883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 789ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 7902c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org void JumpIfBothInstanceTypesAreNotSequentialOneByte( 7912c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Register first_object_instance_type, Register second_object_instance_type, 7922c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Register scratch1, Register scratch2, Label* on_fail, 79383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump = Label::kFar); 794ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 7959af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org void EmitSeqStringSetCharCheck(Register string, 7969af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org Register index, 7979af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org Register value, 7989af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org uint32_t encoding_mask); 7999af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 8001510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org // Checks if the given register or operand is a unique name 80106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org void JumpIfNotUniqueNameInstanceType(Register reg, Label* not_unique_name, 80206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Label::Distance distance = Label::kFar); 80306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org void JumpIfNotUniqueNameInstanceType(Operand operand, Label* not_unique_name, 80406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Label::Distance distance = Label::kFar); 8051510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 806b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // --------------------------------------------------------------------------- 80713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // Macro instructions. 808eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 809d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org // Load/store with specific representation. 810d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org void Load(Register dst, const Operand& src, Representation r); 811d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org void Store(const Operand& dst, Register src, Representation r); 812d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 8139d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com // Load a register with a long value as efficiently as possible. 814e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org void Set(Register dst, int64_t x); 815f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void Set(const Operand& dst, intptr_t x); 8169085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 817528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // cvtsi2sd instruction only writes to the low 64-bit of dst register, which 818528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // hinders register renaming and makes dependence chains longer. So we use 819528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // xorps to clear the dst register before cvtsi2sd to solve this issue. 820528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org void Cvtlsi2sd(XMMRegister dst, Register src); 821528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org void Cvtlsi2sd(XMMRegister dst, const Operand& src); 822528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 8234a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org // Move if the registers are not identical. 8244a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org void Move(Register target, Register source); 8254a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 82604a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org // TestBit and Load SharedFunctionInfo special field. 82704a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org void TestBitSharedFunctionInfoSpecialField(Register base, 82804a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org int offset, 82904a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org int bit_index); 83004a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org void LoadSharedFunctionInfoSpecialField(Register dst, 83104a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org Register base, 83204a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org int offset); 833394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 8345aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org // Handle support 8355aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org void Move(Register dst, Handle<Object> source); 8365aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org void Move(const Operand& dst, Handle<Object> source); 8375aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org void Cmp(Register dst, Handle<Object> source); 8383e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org void Cmp(const Operand& dst, Handle<Object> source); 839badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org void Cmp(Register dst, Smi* src); 840badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org void Cmp(const Operand& dst, Smi* src); 8415aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org void Push(Handle<Object> source); 8420c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 84364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Load a heap object and handle the case of new-space objects by 84464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // indirecting via a global cell. 845c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org void MoveHeapObject(Register result, Handle<Object> object); 846a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org 84764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Load a global cell into a register. 84841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org void LoadGlobalCell(Register dst, Handle<Cell> cell); 84964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 8500c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // Emit code to discard a non-negative number of pointer-sized elements 8510c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // from the stack, clobbering only the rsp register. 85213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org void Drop(int stack_elements); 853a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // Emit code to discard a positive number of pointer-sized elements 854a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // from the stack under the return address which remains on the top, 855a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // clobbering the rsp register. 856a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org void DropUnderReturnAddress(int stack_elements, 857a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org Register scratch = kScratchRegister); 8580c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org 85913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org void Call(Label* target) { call(target); } 860763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org void Push(Register src); 861763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org void Push(const Operand& src); 862a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org void PushQuad(const Operand& src); 863763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org void Push(Immediate value); 864763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org void PushImm32(int32_t imm32); 865763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org void Pop(Register dst); 866763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org void Pop(const Operand& dst); 867a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org void PopQuad(const Operand& dst); 868763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org void PushReturnAddressFrom(Register src) { pushq(src); } 869763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org void PopReturnAddressTo(Register dst) { popq(dst); } 870e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org void Move(Register dst, ExternalReference ext) { 871fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org movp(dst, reinterpret_cast<void*>(ext.address()), 872e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org RelocInfo::EXTERNAL_REFERENCE); 873e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 8745aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 8759cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org // Loads a pointer into a register with a relocation mode. 8769cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org void Move(Register dst, void* ptr, RelocInfo::Mode rmode) { 8779cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org // This method must not be used with heap object references. The stored 8789cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org // address is not GC safe. Use the handle version instead. 879e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(rmode > RelocInfo::LAST_GCED_ENUM); 8809cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org movp(dst, ptr, rmode); 8819cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org } 8829cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 8839cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org void Move(Register dst, Handle<Object> value, RelocInfo::Mode rmode) { 8849cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org AllowDeferredHandleDereference using_raw_address; 885e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!RelocInfo::IsNone(rmode)); 886e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(value->IsHeapObject()); 887e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!isolate()->heap()->InNewSpace(*value)); 888fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org movp(dst, reinterpret_cast<void*>(value.location()), rmode); 8899cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org } 8909cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 891eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // Control Flow 892eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org void Jump(Address destination, RelocInfo::Mode rmode); 893eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org void Jump(ExternalReference ext); 894f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void Jump(const Operand& op); 8955aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org void Jump(Handle<Code> code_object, RelocInfo::Mode rmode); 8965aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 897eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org void Call(Address destination, RelocInfo::Mode rmode); 898eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org void Call(ExternalReference ext); 899f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void Call(const Operand& op); 9008e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org void Call(Handle<Code> code_object, 9018e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org RelocInfo::Mode rmode, 902471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org TypeFeedbackId ast_id = TypeFeedbackId::None()); 903eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 904eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org // The size of the code generated for different call instructions. 905af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org int CallSize(Address destination) { 906594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return kCallSequenceLength; 907eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org } 908ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org int CallSize(ExternalReference ext); 909eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org int CallSize(Handle<Code> code_object) { 910eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org // Code calls use 32-bit relative addressing. 911eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org return kShortCallInstructionLength; 912eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org } 913eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org int CallSize(Register target) { 914eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org // Opcode: REX_opt FF /2 m64 915eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org return (target.high_bit() != 0) ? 3 : 2; 916eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org } 917eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org int CallSize(const Operand& target) { 918eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org // Opcode: REX_opt FF /2 m64 919eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org return (target.requires_rex() ? 2 : 1) + target.operand_size(); 920eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org } 921eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org 92283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org // Emit call to the code we are currently generating. 92383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org void CallSelf() { 92483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org Handle<Code> self(reinterpret_cast<Code**>(CodeObject().location())); 92583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org Call(self, RelocInfo::CODE_TARGET); 92683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org } 92783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org 9280a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // Non-x64 instructions. 9290a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // Push/pop all general purpose registers. 9300a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // Does not push rsp/rbp nor any of the assembler's special purpose registers 9310a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // (kScratchRegister, kSmiConstantRegister, kRootRegister). 9320a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org void Pushad(); 9330a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org void Popad(); 9340ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org // Sets the stack as after performing Popad, without actually loading the 9350ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org // registers. 9360ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org void Dropad(); 9370a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 9389085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Compare object type for heap object. 939e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // Always use unsigned comparisons: above and below, not less and greater. 9409085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Incoming register is heap_object and outgoing register is map. 94186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // They may be the same register, and may be kScratchRegister. 9429085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void CmpObjectType(Register heap_object, InstanceType type, Register map); 9439085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 9449085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Compare instance type for map. 945e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // Always use unsigned comparisons: above and below, not less and greater. 9469085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void CmpInstanceType(Register map, InstanceType type); 9479085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 948d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com // Check if a map for a JSObject indicates that the object has fast elements. 949d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com // Jump to the specified label if it does not. 950d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com void CheckFastElements(Register map, 951d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com Label* fail, 952d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com Label::Distance distance = Label::kFar); 953d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com 954c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check if a map for a JSObject indicates that the object can have both smi 955c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // and HeapObject elements. Jump to the specified label if it does not. 956c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void CheckFastObjectElements(Register map, 957c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* fail, 958c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance distance = Label::kFar); 959c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 960c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check if a map for a JSObject indicates that the object has fast smi only 961c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // elements. Jump to the specified label if it does not. 962830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org void CheckFastSmiElements(Register map, 963830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Label* fail, 964830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Label::Distance distance = Label::kFar); 965c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 966c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check to see if maybe_number can be stored as a double in 967394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // FastDoubleElements. If it can, store it at the index specified by index in 968394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // the FastDoubleElements array elements, otherwise jump to fail. Note that 969394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // index must not be smi-tagged. 970c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void StoreNumberToDoubleElements(Register maybe_number, 971c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register elements, 972394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register index, 973c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com XMMRegister xmm_scratch, 974fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org Label* fail, 975fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org int elements_offset = 0); 976c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 977935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org // Compare an object's map with the specified map. 978935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org void CompareMap(Register obj, Handle<Map> map); 979f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 980f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Check if the map of an object is equal to a specified map and branch to 981f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // label if not. Skip the smi check if not required (object is known to be a 982f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // heap object). If mode is ALLOW_ELEMENT_TRANSITION_MAPS, then also match 9832efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // against maps that are ElementsKind transition maps of the specified map. 9845c838251403b0be9a882540f1922577abba4c872ager@chromium.org void CheckMap(Register obj, 9855c838251403b0be9a882540f1922577abba4c872ager@chromium.org Handle<Map> map, 9865c838251403b0be9a882540f1922577abba4c872ager@chromium.org Label* fail, 987a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org SmiCheckType smi_check_type); 9885c838251403b0be9a882540f1922577abba4c872ager@chromium.org 989ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org // Check if the map of an object is equal to a specified map and branch to a 990ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org // specified target if equal. Skip the smi check if not required (object is 991ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org // known to be a heap object) 992ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org void DispatchMap(Register obj, 9932bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register unused, 994ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org Handle<Map> map, 995ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org Handle<Code> success, 996ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org SmiCheckType smi_check_type); 997ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 998b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Check if the object in register heap_object is a string. Afterwards the 999b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // register map contains the object map and the register instance_type 1000b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // contains the instance_type. The registers map and instance_type can be the 1001b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // same in which case it contains the instance type afterwards. Either of the 1002b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // registers map and instance_type can be the same as heap_object. 1003b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Condition IsObjectStringType(Register heap_object, 1004b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Register map, 1005b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Register instance_type); 1006b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1007750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // Check if the object in register heap_object is a name. Afterwards the 1008750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // register map contains the object map and the register instance_type 1009750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // contains the instance_type. The registers map and instance_type can be the 1010750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // same in which case it contains the instance type afterwards. Either of the 1011750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // registers map and instance_type can be the same as heap_object. 1012750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Condition IsObjectNameType(Register heap_object, 1013750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Register map, 1014750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Register instance_type); 1015750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 101640b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org // FCmp compares and pops the two values on top of the FPU stack. 101740b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org // The flag results are similar to integer cmp, but requires unsigned 10189085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // jcc instructions (je, ja, jae, jb, jbe, je, and jz). 10199085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void FCmp(); 10209085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 1021c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org void ClampUint8(Register reg); 1022c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1023c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org void ClampDoubleToUint8(XMMRegister input_reg, 1024c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org XMMRegister temp_xmm_reg, 102589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org Register result_reg); 1026c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1027c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org void SlowTruncateToI(Register result_reg, Register input_reg, 1028c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org int offset = HeapNumber::kValueOffset - kHeapObjectTag); 1029c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 1030c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org void TruncateHeapNumberToI(Register result_reg, Register input_reg); 1031c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org void TruncateDoubleToI(Register result_reg, XMMRegister input_reg); 1032c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 1033c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org void DoubleToI(Register result_reg, XMMRegister input_reg, 103406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org XMMRegister scratch, MinusZeroMode minus_zero_mode, 103506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Label* lost_precision, Label* is_nan, Label* minus_zero, 103606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Label::Distance dst = Label::kFar); 1037c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 10387e6132b924829c353864933f29124419916db550machenbach@chromium.org void LoadUint32(XMMRegister dst, Register src); 103946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 104040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org void LoadInstanceDescriptors(Register map, Register descriptors); 1041355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org void EnumLength(Register dst, Register map); 104206ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org void NumberOfOwnDescriptors(Register dst, Register map); 1043355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 1044355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org template<typename Field> 1045355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org void DecodeField(Register reg) { 10463c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org static const int shift = Field::kShift; 104706ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org static const int mask = Field::kMask >> Field::kShift; 1048d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org if (shift != 0) { 1049d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org shrp(reg, Immediate(shift)); 1050d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org } 1051895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org andp(reg, Immediate(mask)); 1052355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org } 105340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 1054d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org template<typename Field> 1055d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org void DecodeFieldToSmi(Register reg) { 1056e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org if (SmiValuesAre32Bits()) { 1057e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org andp(reg, Immediate(Field::kMask)); 1058e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org shlp(reg, Immediate(kSmiShift - Field::kShift)); 1059e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org } else { 1060e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org static const int shift = Field::kShift; 1061e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org static const int mask = (Field::kMask >> Field::kShift) << kSmiTagSize; 1062e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(SmiValuesAre31Bits()); 1063e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(kSmiShift == kSmiTagSize); 1064e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK((mask & 0x80000000u) == 0); 1065e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org if (shift < kSmiShift) { 1066e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org shlp(reg, Immediate(kSmiShift - shift)); 1067e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org } else if (shift > kSmiShift) { 1068e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org sarp(reg, Immediate(shift - kSmiShift)); 1069e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org } 1070e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org andp(reg, Immediate(mask)); 1071e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org } 1072d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org } 1073d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org 1074c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org // Abort execution if argument is not a number, enabled via --debug-code. 1075c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org void AssertNumber(Register object); 10765c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1077c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org // Abort execution if argument is a smi, enabled via --debug-code. 1078c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org void AssertNotSmi(Register object); 1079ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 1080c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org // Abort execution if argument is not a smi, enabled via --debug-code. 1081c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org void AssertSmi(Register object); 1082c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org void AssertSmi(const Operand& object); 108325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org 1084f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // Abort execution if a 64 bit register containing a 32 bit payload does not 1085c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org // have zeros in the top 32 bits, enabled via --debug-code. 1086c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org void AssertZeroExtended(Register reg); 1087f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 1088c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org // Abort execution if argument is not a string, enabled via --debug-code. 1089c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org void AssertString(Register object); 109049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 1091750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // Abort execution if argument is not a name, enabled via --debug-code. 1092750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org void AssertName(Register object); 1093750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 10942904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org // Abort execution if argument is not undefined or an AllocationSite, enabled 10952904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org // via --debug-code. 10962904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org void AssertUndefinedOrAllocationSite(Register object); 10972904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org 1098c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org // Abort execution if argument is not the root value with the given index, 1099c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org // enabled via --debug-code. 1100c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org void AssertRootValue(Register src, 1101c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Heap::RootListIndex root_value_index, 1102594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org BailoutReason reason); 11035ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org 11049085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // --------------------------------------------------------------------------- 11059085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Exception handling 11069085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 110704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Push a new try handler and link it into try handler chain. 110878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org void PushTryHandler(StackHandler::Kind kind, int handler_index); 11099085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 111013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // Unlink the stack handler on top of the stack from the try handler chain. 111113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org void PopTryHandler(); 11129085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 111349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // Activate the top handler in the try hander chain and pass the 111449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // thrown value. 111549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org void Throw(Register value); 111649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 111749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // Propagate an uncatchable exception out of the current JS stack. 111865a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org void ThrowUncatchable(Register value); 111949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 11209085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // --------------------------------------------------------------------------- 11219085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Inline caching support 11229085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 11239085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Generate code for checking access rights - used for security checks 11249085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // on access to global objects across environments. The holder register 1125e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // is left untouched, but the scratch register and kScratchRegister, 1126e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // which must be different, are clobbered. 11279085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void CheckAccessGlobalProxy(Register holder_reg, 11289085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org Register scratch, 11299085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org Label* miss); 11309085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 1131f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com void GetNumberHash(Register r0, Register scratch); 11329085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 11336db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org void LoadFromNumberDictionary(Label* miss, 11346db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register elements, 11356db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register key, 11366db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register r0, 11376db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register r1, 11386db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register r2, 11396db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register result); 11406db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 11416db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 11429085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // --------------------------------------------------------------------------- 114318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Allocation support 114418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 11452bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org // Allocate an object in new space or old pointer space. If the given space 11462bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org // is exhausted control continues at the gc_required label. The allocated 11472bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org // object is returned in result and end of the new object is returned in 11482bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org // result_end. The register scratch can be passed as no_reg in which case 11492bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org // an additional object reference will be added to the reloc info. The 11502bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org // returned pointers in result and result_end have not yet been tagged as 11512bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org // heap objects. If result_contains_top_on_entry is true the content of 11522bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org // result is known to be the allocation top on entry (could be result_end 11532bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org // from a previous call). If result_contains_top_on_entry is true scratch 115418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // should be no_reg as it is never used. 11552bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org void Allocate(int object_size, 11562bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register result, 11572bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register result_end, 11582bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register scratch, 11592bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Label* gc_required, 11602bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org AllocationFlags flags); 1161c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 1162f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org void Allocate(int header_size, 1163f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org ScaleFactor element_size, 1164f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register element_count, 1165f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register result, 1166f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register result_end, 1167f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register scratch, 1168f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Label* gc_required, 1169f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org AllocationFlags flags); 1170f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org 1171f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org void Allocate(Register object_size, 1172f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register result, 1173f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register result_end, 1174f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register scratch, 1175f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Label* gc_required, 1176f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org AllocationFlags flags); 117718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 117818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Undo allocation in new space. The object passed and objects allocated after 117918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // it will no longer be allocated. Make sure that no pointers are left to the 118018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // object(s) no longer allocated as they would be invalid when allocation is 118118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // un-done. 118218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org void UndoAllocationInNewSpace(Register object); 118318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 11843811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Allocate a heap number in new space with undefined value. Returns 11853811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // tagged pointer in result register, or jumps to gc_required if new 11863811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // space is full. 11873811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org void AllocateHeapNumber(Register result, 11883811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org Register scratch, 118958a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org Label* gc_required, 119058a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org MutableMode mode = IMMUTABLE); 11913811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 119213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // Allocate a sequential string. All the header fields of the string object 119313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // are initialized. 119413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org void AllocateTwoByteString(Register result, 119513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register length, 119613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register scratch1, 119713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register scratch2, 119813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register scratch3, 119913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Label* gc_required); 12002c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org void AllocateOneByteString(Register result, Register length, 12012c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Register scratch1, Register scratch2, 12022c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Register scratch3, Label* gc_required); 120313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 120413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // Allocate a raw cons string object. Only the map field of the result is 120513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // initialized. 12061805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org void AllocateTwoByteConsString(Register result, 120713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register scratch1, 120813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register scratch2, 120913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Label* gc_required); 12102c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org void AllocateOneByteConsString(Register result, Register scratch1, 12112c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Register scratch2, Label* gc_required); 121213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 12131805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // Allocate a raw sliced string object. Only the map field of the result is 12141805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // initialized. 12151805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org void AllocateTwoByteSlicedString(Register result, 12161805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org Register scratch1, 12171805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org Register scratch2, 12181805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org Label* gc_required); 12192c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org void AllocateOneByteSlicedString(Register result, Register scratch1, 12202c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Register scratch2, Label* gc_required); 12211805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 122218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // --------------------------------------------------------------------------- 12239085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Support functions. 12249085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 12259085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Check if result is zero and op is negative. 12269085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void NegativeZeroTest(Register result, Register op, Label* then_label); 12279085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 12289085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Check if result is zero and op is negative in code using jump targets. 12299085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void NegativeZeroTest(CodeGenerator* cgen, 12309085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org Register result, 12319085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org Register op, 12329085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org JumpTarget* then_target); 12339085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 12349085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Check if result is zero and any of op1 and op2 are negative. 12359085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Register scratch is destroyed, and it must be different from op2. 12369085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void NegativeZeroTest(Register result, Register op1, Register op2, 12379085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org Register scratch, Label* then_label); 12389085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 12399085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Try to get function prototype of a function and puts the value in 12409085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // the result register. Checks that the function really is a 12419085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // function and jumps to the miss label if the fast checks fail. The 124286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // function register will be untouched; the other register may be 12439085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // clobbered. 12449085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void TryGetFunctionPrototype(Register function, 12459085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org Register result, 1246394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Label* miss, 1247394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com bool miss_on_bound_function = false); 12489085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 1249d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // Picks out an array index from the hash field. 1250d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // Register use: 1251d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // hash - holds the index's hash. Clobbered. 1252d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // index - holds the overwritten index on exit. 1253d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org void IndexFromHash(Register hash, Register index); 1254d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 1255ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // Find the function context up the context chain. 1256ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org void LoadContext(Register dst, int context_chain_length); 1257ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 12581145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org // Conditionally load the cached Array transitioned map of type 125946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // transitioned_kind from the native context if the map in register 126046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // map_in_out is the cached Array map in the native context of 12611145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org // expected_kind. 12621145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org void LoadTransitionedArrayMapConditional( 12631145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org ElementsKind expected_kind, 12641145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org ElementsKind transitioned_kind, 12651145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org Register map_in_out, 12661145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org Register scratch, 12671145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org Label* no_map_match); 12681145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org 12695f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // Load the global function with the given index. 12705f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org void LoadGlobalFunction(int index, Register function); 12715f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 12725f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // Load the initial map from the global function. The registers 12735f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // function and map can be the same. 12745f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org void LoadGlobalFunctionInitialMap(Register function, Register map); 12755f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 12769085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // --------------------------------------------------------------------------- 12779085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Runtime calls 12789085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 12799085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Call a code stub. 1280471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org void CallStub(CodeStub* stub, TypeFeedbackId ast_id = TypeFeedbackId::None()); 12819085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 128213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // Tail call a code stub (jump). 128313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org void TailCallStub(CodeStub* stub); 128413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 12859085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Return from a code stub after popping its arguments. 12869085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void StubReturn(int argc); 12879085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 12889085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Call a runtime routine. 1289fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org void CallRuntime(const Runtime::Function* f, 1290fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org int num_arguments, 1291fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org SaveFPRegsMode save_doubles = kDontSaveFPRegs); 12929085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 12930ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org // Call a runtime function and save the value of XMM registers. 1294fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org void CallRuntimeSaveDoubles(Runtime::FunctionId id) { 1295fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org const Runtime::Function* function = Runtime::FunctionForId(id); 1296fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org CallRuntime(function, function->nargs, kSaveFPRegs); 1297fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org } 12980ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 12999085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Convenience function: Same as above, but takes the fid instead. 1300f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org void CallRuntime(Runtime::FunctionId id, 1301f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org int num_arguments, 1302f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org SaveFPRegsMode save_doubles = kDontSaveFPRegs) { 1303f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org CallRuntime(Runtime::FunctionForId(id), num_arguments, save_doubles); 1304fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org } 13059085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 13065c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Convenience function: call an external reference. 13075c838251403b0be9a882540f1922577abba4c872ager@chromium.org void CallExternalReference(const ExternalReference& ext, 13085c838251403b0be9a882540f1922577abba4c872ager@chromium.org int num_arguments); 13095c838251403b0be9a882540f1922577abba4c872ager@chromium.org 13109085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Tail call of a runtime routine (jump). 1311ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org // Like JumpToExternalReference, but also takes care of passing the number 1312ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org // of parameters. 1313ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org void TailCallExternalReference(const ExternalReference& ext, 1314ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int num_arguments, 1315ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int result_size); 1316ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 1317ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org // Convenience function: tail call a runtime routine (jump). 1318ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org void TailCallRuntime(Runtime::FunctionId fid, 1319a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org int num_arguments, 1320a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org int result_size); 13219085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 1322c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // Jump to a runtime routine. 1323ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org void JumpToExternalReference(const ExternalReference& ext, int result_size); 13249085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 1325c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Prepares stack to put arguments (aligns and so on). WIN64 calling 1326c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // convention requires to put the pointer to the return value slot into 1327c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // rcx (rcx must be preserverd until CallApiFunctionAndReturn). Saves 1328c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // context (rsi). Clobbers rax. Allocates arg_stack_space * kPointerSize 13294a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // inside the exit frame (not GCed) accessible via StackSpaceOperand. 1330662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org void PrepareCallApiFunction(int arg_stack_space); 13314a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 1332c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Calls an API function. Allocates HandleScope, extracts returned value 1333c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // from handle and propagates exceptions. Clobbers r14, r15, rbx and 1334c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // caller-save registers. Restores context. On return removes 1335c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // stack_space * kPointerSize (GCed). 1336e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org void CallApiFunctionAndReturn(Register function_address, 1337a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org ExternalReference thunk_ref, 1338b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Register thunk_last_arg, 1339bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org int stack_space, 1340528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Operand return_value_operand, 1341528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Operand* context_restore_operand); 1342303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org 1343b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Before calling a C-function from generated code, align arguments on stack. 1344c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org // After aligning the frame, arguments must be stored in rsp[0], rsp[8], 1345b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // etc., not pushed. The argument count assumes all arguments are word sized. 1346b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // The number of slots reserved for arguments depends on platform. On Windows 1347b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // stack slots are reserved for the arguments passed in registers. On other 1348b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // platforms stack slots are only reserved for the arguments actually passed 1349b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // on the stack. 1350b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org void PrepareCallCFunction(int num_arguments); 1351b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1352b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Calls a C function and cleans up the space for arguments allocated 1353b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // by PrepareCallCFunction. The called function is not allowed to trigger a 1354b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // garbage collection, since that might move the code and invalidate the 1355b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // return address (unless this is somehow accounted for by the called 1356b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // function). 1357b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org void CallCFunction(ExternalReference function, int num_arguments); 1358b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org void CallCFunction(Register function, int num_arguments); 1359b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1360b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Calculate the number of stack slots to reserve for arguments when calling a 1361b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // C function. 1362b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org int ArgumentStackSlotsForCFunctionCall(int num_arguments); 13639085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 13649085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // --------------------------------------------------------------------------- 13659085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Utilities 13669085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 13679085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void Ret(); 13689085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 1369d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com // Return and drop arguments from stack, where the number of arguments 1370d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com // may be bigger than 2^16 - 1. Requires a scratch register. 1371d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com void Ret(int bytes_dropped, Register scratch); 1372d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 1373c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org Handle<Object> CodeObject() { 1374e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!code_object_.is_null()); 1375c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org return code_object_; 1376c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org } 13779085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 13787979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Copy length bytes from source to destination. 13797979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Uses scratch register internally (if you have a low-eight register 13807979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // free, do use it, otherwise kScratchRegister will be used). 13817979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // The min_length is a minimum limit on the value that length will have. 13827979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // The algorithm has some special cases that might be omitted if the string 13837979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // is known to always be long. 13847979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org void CopyBytes(Register destination, 13857979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Register source, 13867979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Register length, 13877979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org int min_length = 0, 13887979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Register scratch = kScratchRegister); 13897979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 1390c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Initialize fields with filler values. Fields starting at |start_offset| 1391c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // not including end_offset are overwritten with the value in |filler|. At 1392c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // the end the loop, |start_offset| takes the value of |end_offset|. 1393c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void InitializeFieldsWithFiller(Register start_offset, 1394c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register end_offset, 1395c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register filler); 1396c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 13979085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 1398763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org // Emit code for a truncating division by a constant. The dividend register is 1399bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org // unchanged, the result is in rdx, and rax gets clobbered. 1400763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org void TruncatingDiv(Register dividend, int32_t divisor); 1401bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 14029085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // --------------------------------------------------------------------------- 14039085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // StatsCounter support 14049085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 14059085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void SetCounter(StatsCounter* counter, int value); 14069085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void IncrementCounter(StatsCounter* counter, int value); 14079085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void DecrementCounter(StatsCounter* counter, int value); 14089085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 14099085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 14109085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // --------------------------------------------------------------------------- 14119085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Debugging 14129085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 14139085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Calls Abort(msg) if the condition cc is not satisfied. 14149085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Use --debug_code to enable. 1415594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org void Assert(Condition cc, BailoutReason reason); 14169085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 14170b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org void AssertFastElements(Register elements); 14180b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org 14199085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Like Assert(), but always enabled. 1420594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org void Check(Condition cc, BailoutReason reason); 14219085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 14229085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Print a message to stdout and abort execution. 1423594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org void Abort(BailoutReason msg); 14249085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 1425c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org // Check that the stack is aligned. 1426c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org void CheckStackAlignment(); 1427c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org 14289085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Verify restrictions about code generated in stubs. 14299085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void set_generating_stub(bool value) { generating_stub_ = value; } 14309085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org bool generating_stub() { return generating_stub_; } 1431c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void set_has_frame(bool value) { has_frame_ = value; } 1432c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool has_frame() { return has_frame_; } 1433c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline bool AllowThisStubCall(CodeStub* stub); 14349085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 143544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org static int SafepointRegisterStackIndex(Register reg) { 143644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org return SafepointRegisterStackIndex(reg.code()); 143744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 143844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 1439c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Activation support. 1440c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void EnterFrame(StackFrame::Type type); 1441c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void LeaveFrame(StackFrame::Type type); 1442c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1443be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // Expects object in rax and returns map with validated enum cache 1444be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // in rax. Assumes that any other register can be used as a scratch. 1445be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org void CheckEnumCache(Register null_value, 1446be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Label* call_runtime); 1447be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 1448ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // AllocationMemento support. Arrays may have an associated 1449ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // AllocationMemento object that can be checked for in order to pretransition 145059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // to another type. 145159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // On entry, receiver_reg should point to the array object. 145259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // scratch_reg gets clobbered. 1453b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org // If allocation info is present, condition flags are set to equal. 1454ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org void TestJSArrayForAllocationMemento(Register receiver_reg, 1455b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org Register scratch_reg, 1456b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org Label* no_memento_found); 1457b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org 1458b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org void JumpIfJSArrayHasAllocationMemento(Register receiver_reg, 1459b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org Register scratch_reg, 1460b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org Label* memento_found) { 1461b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org Label no_memento_found; 1462b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org TestJSArrayForAllocationMemento(receiver_reg, scratch_reg, 1463b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org &no_memento_found); 1464b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org j(equal, memento_found); 1465b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org bind(&no_memento_found); 1466b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org } 146759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 1468e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // Jumps to found label if a prototype map has dictionary elements. 1469e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org void JumpIfDictionaryInPrototypeChain(Register object, Register scratch0, 1470e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Register scratch1, Label* found); 1471e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 14729085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org private: 14730ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org // Order general registers are pushed by Pushad. 1474b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org // rax, rcx, rdx, rbx, rsi, rdi, r8, r9, r11, r14, r15. 14751456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org static const int kSafepointPushRegisterIndices[Register::kNumRegisters]; 147649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org static const int kNumSafepointSavedRegisters = 11; 147783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org static const int kSmiShift = kSmiTagSize + kSmiShiftSize; 147849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 14799085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org bool generating_stub_; 1480c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bool has_frame_; 1481ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org bool root_array_available_; 148269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 148369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org // Returns a register holding the smi value. The register MUST NOT be 148469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org // modified. It may be the "smi 1 constant" register. 148569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org Register GetSmiConstant(Smi* value); 148669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 14874ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org int64_t RootRegisterDelta(ExternalReference other); 1488000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org 148969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org // Moves the smi value to the destination register. 149069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org void LoadSmiConstant(Register dst, Smi* value); 149169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 14925c838251403b0be9a882540f1922577abba4c872ager@chromium.org // This handle will be patched with the code object on installation. 14935c838251403b0be9a882540f1922577abba4c872ager@chromium.org Handle<Object> code_object_; 14949085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 14959085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org // Helper functions for generating invokes. 14969085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org void InvokePrologue(const ParameterCount& expected, 14979085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org const ParameterCount& actual, 14989085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org Handle<Code> code_constant, 1499eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org Register code_register, 150083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* done, 15012efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org bool* definitely_mismatches, 15023a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org InvokeFlag flag, 150340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org Label::Distance near_jump = Label::kFar, 1504e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org const CallWrapper& call_wrapper = NullCallWrapper()); 15059085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 1506d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org void EnterExitFramePrologue(bool save_rax); 15074a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 15084a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // Allocates arg_stack_space * kPointerSize memory (not GCed) on the stack 15094a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // accessible via StackSpaceOperand. 15100ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org void EnterExitFrameEpilogue(int arg_stack_space, bool save_doubles); 15114a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 1512528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org void LeaveExitFrameEpilogue(bool restore_context); 1513e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 151418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Allocation support helpers. 1515ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org // Loads the top of new-space into the result register. 1516ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org // Otherwise the address of the new-space top is loaded into scratch (if 1517ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org // scratch is valid), and the new-space top is loaded into result. 151818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org void LoadAllocationTopHelper(Register result, 151918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org Register scratch, 1520a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org AllocationFlags flags); 15212bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org 152238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org void MakeSureDoubleAlignedHelper(Register result, 152338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org Register scratch, 152438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org Label* gc_required, 152538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org AllocationFlags flags); 152638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org 1527ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org // Update allocation top with value in result_end register. 1528ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org // If scratch is valid, it contains the address of the allocation top. 15292bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org void UpdateAllocationTopHelper(Register result_end, 15302bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register scratch, 15312bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org AllocationFlags flags); 1532e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 1533c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Helper for implementing JumpIfNotInNewSpace and JumpIfInNewSpace. 1534c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com void InNewSpace(Register object, 1535c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch, 1536c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Condition cc, 1537c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* branch, 1538c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance distance = Label::kFar); 1539c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1540c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Helper for finding the mark bits for an address. Afterwards, the 1541c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // bitmap register points at the word with the mark bits and the mask 1542c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // the position of the first bit. Uses rcx as scratch and leaves addr_reg 1543c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // unchanged. 1544c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com inline void GetMarkBits(Register addr_reg, 1545c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register bitmap_reg, 1546c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register mask_reg); 15473a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 154804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Helper for throwing exceptions. Compute a handler address and jump to 154904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // it. See the implementation for register usage. 155004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org void JumpToHandlerEntry(); 155104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 15523a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Compute memory operands for safepoint stack slots. 15533a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Operand SafepointRegisterSlot(Register reg); 15543a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org static int SafepointRegisterStackIndex(int reg_code) { 15553a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org return kNumSafepointRegisters - kSafepointPushRegisterIndices[reg_code] - 1; 15563a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 15573a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 1558a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Needs access to SafepointRegisterStackIndex for compiled frame 15593a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // traversal. 1560a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org friend class StandardFrame; 15619085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org}; 15629085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 15639085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 15644af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org// The code patcher is used to patch (typically) small parts of code e.g. for 15654af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org// debugging and other types of instrumentation. When using the code patcher 15664af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org// the exact number of bytes specified must be emitted. Is not legal to emit 15674af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org// relocation information. If any of these constraints are violated it causes 15684af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org// an assertion. 15694af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgclass CodePatcher { 15704af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org public: 15714af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org CodePatcher(byte* address, int size); 15724af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org virtual ~CodePatcher(); 15734af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 15744af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Macro assembler to emit code. 15754af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org MacroAssembler* masm() { return &masm_; } 15764af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 15774af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org private: 15784af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org byte* address_; // The address of the code being patched. 15794af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org int size_; // Number of bytes of the expected patch size. 15804af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org MacroAssembler masm_; // Macro assembler used to generate the code. 15814af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org}; 15824af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 15834af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 15849085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// ----------------------------------------------------------------------------- 15859085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// Static helper functions. 15869085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 15879085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// Generate an Operand for loading a field from an object. 15881b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orginline Operand FieldOperand(Register object, int offset) { 15899085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org return Operand(object, offset - kHeapObjectTag); 15909085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org} 15919085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 15929085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 15939085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org// Generate an Operand for loading an indexed field from an object. 15941b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orginline Operand FieldOperand(Register object, 15951b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org Register index, 15961b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org ScaleFactor scale, 15971b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org int offset) { 15989085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org return Operand(object, index, scale, offset - kHeapObjectTag); 15999085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org} 16009085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 16019085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 16021b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orginline Operand ContextOperand(Register context, int index) { 16034a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com return Operand(context, Context::SlotOffset(index)); 16044a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com} 16054a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 16064a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 16071b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orginline Operand GlobalObjectOperand() { 160846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org return ContextOperand(rsi, Context::GLOBAL_OBJECT_INDEX); 16094a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com} 16104a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 16114a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 16124a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// Provides access to exit frame stack space (not GCed). 16131b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orginline Operand StackSpaceOperand(int index) { 16144a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com#ifdef _WIN64 16154a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com const int kShaddowSpace = 4; 16164a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com return Operand(rsp, (index + kShaddowSpace) * kPointerSize); 16174a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com#else 16184a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com return Operand(rsp, index * kPointerSize); 16194a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com#endif 16204a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com} 16214a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 16224a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 1623d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.orginline Operand StackOperandForReturnAddress(int32_t disp) { 1624d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org return Operand(rsp, disp); 1625d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org} 1626d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org 16274a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 16289085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#ifdef GENERATED_CODE_COVERAGE 16299085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.orgextern void LogGeneratedCodeCoverage(const char* file_line); 16309085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#define CODE_COVERAGE_STRINGIFY(x) #x 16319085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x) 16329085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__) 16334cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org#define ACCESS_MASM(masm) { \ 16344cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org Address x64_coverage_function = FUNCTION_ADDR(LogGeneratedCodeCoverage); \ 16354cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org masm->pushfq(); \ 16364cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org masm->Pushad(); \ 1637763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org masm->Push(Immediate(reinterpret_cast<int>(&__FILE_LINE__))); \ 16384cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org masm->Call(x64_coverage_function, RelocInfo::EXTERNAL_REFERENCE); \ 1639763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org masm->Pop(rax); \ 16404cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org masm->Popad(); \ 16414cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org masm->popfq(); \ 16424cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org } \ 16439085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org masm-> 16449085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#else 16459085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#define ACCESS_MASM(masm) masm-> 16469085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#endif 16479085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 16489085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org} } // namespace v8::internal 16499085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org 16509085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org#endif // V8_X64_MACRO_ASSEMBLER_X64_H_ 1651