1f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com// Copyright 2012 the V8 project authors. All rights reserved. 25ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// Redistribution and use in source and binary forms, with or without 35ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// modification, are permitted provided that the following conditions are 45ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// met: 55ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// 65ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// * Redistributions of source code must retain the above copyright 75ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// notice, this list of conditions and the following disclaimer. 85ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// * Redistributions in binary form must reproduce the above 95ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// copyright notice, this list of conditions and the following 105ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// disclaimer in the documentation and/or other materials provided 115ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// with the distribution. 125ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// * Neither the name of Google Inc. nor the names of its 135ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// contributors may be used to endorse or promote products derived 145ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// from this software without specific prior written permission. 155ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// 165ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 175ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 185ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 195ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 205ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 215ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 225ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 235ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 245ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 255ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 265ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 275ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 2871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org#include "v8.h" 2971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 3093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_X64 319dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org#include "bootstrapper.h" 3344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org#include "codegen.h" 34c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org#include "cpu-profiler.h" 35eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org#include "assembler-x64.h" 36e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org#include "macro-assembler-x64.h" 37b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org#include "serialize.h" 38eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org#include "debug.h" 395ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org#include "heap.h" 40ed29eb2bdad388c1ce751d68bd4fe6f4f5a7cbc8machenbach@chromium.org#include "isolate-inl.h" 4171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 4271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 4371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal { 4471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 45c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgMacroAssembler::MacroAssembler(Isolate* arg_isolate, void* buffer, int size) 46c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org : Assembler(arg_isolate, buffer, size), 479d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com generating_stub_(false), 48c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com has_frame_(false), 49c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org root_array_available_(true) { 50c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org if (isolate() != NULL) { 51c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org code_object_ = Handle<Object>(isolate()->heap()->undefined_value(), 52c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org isolate()); 53c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org } 54ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org} 55ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 56ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 57000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.orgstatic const int kInvalidRootRegisterDelta = -1; 58000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org 59000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org 60000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.orgintptr_t MacroAssembler::RootRegisterDelta(ExternalReference other) { 61000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org if (predictable_code_size() && 62000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org (other.address() < reinterpret_cast<Address>(isolate()) || 63000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org other.address() >= reinterpret_cast<Address>(isolate() + 1))) { 64000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org return kInvalidRootRegisterDelta; 65000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org } 66ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Address roots_register_value = kRootRegisterBias + 67000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org reinterpret_cast<Address>(isolate()->heap()->roots_array_start()); 68ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org intptr_t delta = other.address() - roots_register_value; 69ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return delta; 70ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org} 71ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 72ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 73ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgOperand MacroAssembler::ExternalOperand(ExternalReference target, 74ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Register scratch) { 75ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (root_array_available_ && !Serializer::enabled()) { 76000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org intptr_t delta = RootRegisterDelta(target); 77000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org if (delta != kInvalidRootRegisterDelta && is_int32(delta)) { 78ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Serializer::TooLateToEnableNow(); 797979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org return Operand(kRootRegister, static_cast<int32_t>(delta)); 80ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 81ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 82e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Move(scratch, target); 83ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return Operand(scratch, 0); 84ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org} 85ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 86ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 87ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgvoid MacroAssembler::Load(Register destination, ExternalReference source) { 88ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (root_array_available_ && !Serializer::enabled()) { 89000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org intptr_t delta = RootRegisterDelta(source); 90000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org if (delta != kInvalidRootRegisterDelta && is_int32(delta)) { 91ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Serializer::TooLateToEnableNow(); 92ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org movq(destination, Operand(kRootRegister, static_cast<int32_t>(delta))); 93ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return; 94ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 95ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 96ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Safe code. 97ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (destination.is(rax)) { 98ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org load_rax(source); 99ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } else { 100e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Move(kScratchRegister, source); 101ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org movq(destination, Operand(kScratchRegister, 0)); 102ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 103ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org} 104ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 105ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 106ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgvoid MacroAssembler::Store(ExternalReference destination, Register source) { 107ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (root_array_available_ && !Serializer::enabled()) { 108000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org intptr_t delta = RootRegisterDelta(destination); 109000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org if (delta != kInvalidRootRegisterDelta && is_int32(delta)) { 110ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Serializer::TooLateToEnableNow(); 111ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org movq(Operand(kRootRegister, static_cast<int32_t>(delta)), source); 112ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return; 113ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 114ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 115ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Safe code. 116ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (source.is(rax)) { 117ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org store_rax(destination); 118ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } else { 119e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Move(kScratchRegister, destination); 120ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org movq(Operand(kScratchRegister, 0), source); 121ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 122ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org} 123ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 124ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 125ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgvoid MacroAssembler::LoadAddress(Register destination, 126ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ExternalReference source) { 127ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (root_array_available_ && !Serializer::enabled()) { 128000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org intptr_t delta = RootRegisterDelta(source); 129000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org if (delta != kInvalidRootRegisterDelta && is_int32(delta)) { 130ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Serializer::TooLateToEnableNow(); 131ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org lea(destination, Operand(kRootRegister, static_cast<int32_t>(delta))); 132ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return; 133ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 134ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 135ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Safe code. 136e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Move(destination, source); 137ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org} 138ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 139ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 140ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgint MacroAssembler::LoadAddressSize(ExternalReference source) { 141ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (root_array_available_ && !Serializer::enabled()) { 142ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // This calculation depends on the internals of LoadAddress. 143ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // It's correctness is ensured by the asserts in the Call 144ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // instruction below. 145000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org intptr_t delta = RootRegisterDelta(source); 146000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org if (delta != kInvalidRootRegisterDelta && is_int32(delta)) { 147ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Serializer::TooLateToEnableNow(); 148ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Operand is lea(scratch, Operand(kRootRegister, delta)); 149ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Opcodes : REX.W 8D ModRM Disp8/Disp32 - 4 or 7. 150ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org int size = 4; 151ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (!is_int8(static_cast<int32_t>(delta))) { 152ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org size += 3; // Need full four-byte displacement in lea. 153ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 154ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return size; 155ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 156ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 157ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Size of movq(destination, src); 158594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Assembler::kMoveAddressIntoScratchRegisterInstructionLength; 15971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 16071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 161e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 162ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.comvoid MacroAssembler::PushAddress(ExternalReference source) { 163ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com int64_t address = reinterpret_cast<int64_t>(source.address()); 164ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com if (is_int32(address) && !Serializer::enabled()) { 165ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com if (emit_debug_code()) { 166e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org movq(kScratchRegister, kZapValue, RelocInfo::NONE64); 167ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com } 168ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com push(Immediate(static_cast<int32_t>(address))); 169ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com return; 170ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com } 171ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com LoadAddress(kScratchRegister, source); 172ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com push(kScratchRegister); 173ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com} 174ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com 175ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com 1769d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::LoadRoot(Register destination, Heap::RootListIndex index) { 177ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ASSERT(root_array_available_); 1788f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org movq(destination, Operand(kRootRegister, 1798f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org (index << kPointerSizeLog2) - kRootRegisterBias)); 1808f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org} 1818f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org 1828f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org 1838f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.orgvoid MacroAssembler::LoadRootIndexed(Register destination, 1848f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org Register variable_offset, 1858f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org int fixed_offset) { 186ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ASSERT(root_array_available_); 1878f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org movq(destination, 1888f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org Operand(kRootRegister, 1898f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org variable_offset, times_pointer_size, 1908f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org (fixed_offset << kPointerSizeLog2) - kRootRegisterBias)); 19118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 19218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 19318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 194720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.orgvoid MacroAssembler::StoreRoot(Register source, Heap::RootListIndex index) { 195ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ASSERT(root_array_available_); 1968f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org movq(Operand(kRootRegister, (index << kPointerSizeLog2) - kRootRegisterBias), 1978f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org source); 198720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org} 199720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org 200720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org 20118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid MacroAssembler::PushRoot(Heap::RootListIndex index) { 202ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ASSERT(root_array_available_); 2038f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org push(Operand(kRootRegister, (index << kPointerSizeLog2) - kRootRegisterBias)); 20418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 20518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 20618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 2079d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::CompareRoot(Register with, Heap::RootListIndex index) { 208ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ASSERT(root_array_available_); 2098f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org cmpq(with, Operand(kRootRegister, 2108f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org (index << kPointerSizeLog2) - kRootRegisterBias)); 21118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 21218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 213b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org 21483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.orgvoid MacroAssembler::CompareRoot(const Operand& with, 21583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org Heap::RootListIndex index) { 216ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ASSERT(root_array_available_); 21783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org ASSERT(!with.AddressUsesRegister(kScratchRegister)); 218c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org LoadRoot(kScratchRegister, index); 219c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org cmpq(with, kScratchRegister); 220c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org} 221c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 222c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 223c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::RememberedSetHelper(Register object, // For debug tests. 224c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register addr, 225c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch, 226c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SaveFPRegsMode save_fp, 227c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RememberedSetFinalAction and_then) { 228000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org if (emit_debug_code()) { 229c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label ok; 230c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com JumpIfNotInNewSpace(object, scratch, &ok, Label::kNear); 231c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int3(); 232c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&ok); 233c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 234c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Load store buffer top. 235c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com LoadRoot(scratch, Heap::kStoreBufferTopRootIndex); 236c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Store pointer to buffer. 237c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com movq(Operand(scratch, 0), addr); 238c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Increment buffer top. 239c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com addq(scratch, Immediate(kPointerSize)); 240c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Write back new top of buffer. 241c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com StoreRoot(scratch, Heap::kStoreBufferTopRootIndex); 242c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Call stub on end of buffer. 243c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label done; 244c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check for end of buffer. 245c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com testq(scratch, Immediate(StoreBuffer::kStoreBufferOverflowBit)); 246c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (and_then == kReturnAtEnd) { 247c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label buffer_overflowed; 248c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(not_equal, &buffer_overflowed, Label::kNear); 249c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ret(0); 250c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&buffer_overflowed); 251c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 252c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(and_then == kFallThroughAtEnd); 253c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(equal, &done, Label::kNear); 254c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 255c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com StoreBufferOverflowStub store_buffer_overflow = 256c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com StoreBufferOverflowStub(save_fp); 257c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CallStub(&store_buffer_overflow); 258c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (and_then == kReturnAtEnd) { 259c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ret(0); 260c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 261c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(and_then == kFallThroughAtEnd); 262c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&done); 263ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org } 26430ce411529579186181838984710b0b0980857aaricow@chromium.org} 26530ce411529579186181838984710b0b0980857aaricow@chromium.org 26630ce411529579186181838984710b0b0980857aaricow@chromium.org 26783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::InNewSpace(Register object, 26883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register scratch, 26983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Condition cc, 27083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* branch, 271c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance distance) { 27283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (Serializer::enabled()) { 27383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Can't do arithmetic on external references if it might get serialized. 27483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // The mask isn't really an address. We load it as an external reference in 27583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // case the size of the new space is different between the snapshot maker 27683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // and the running system. 27783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (scratch.is(object)) { 278e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Move(kScratchRegister, ExternalReference::new_space_mask(isolate())); 27983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org and_(scratch, kScratchRegister); 28083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 281e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Move(scratch, ExternalReference::new_space_mask(isolate())); 28283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org and_(scratch, object); 28383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 284e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Move(kScratchRegister, ExternalReference::new_space_start(isolate())); 28583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org cmpq(scratch, kScratchRegister); 286c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(cc, branch, distance); 28783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 288c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org ASSERT(is_int32(static_cast<int64_t>(isolate()->heap()->NewSpaceMask()))); 28983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org intptr_t new_space_start = 290c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org reinterpret_cast<intptr_t>(isolate()->heap()->NewSpaceStart()); 291e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org movq(kScratchRegister, reinterpret_cast<Address>(-new_space_start), 292e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org RelocInfo::NONE64); 29383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (scratch.is(object)) { 29483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org addq(scratch, kScratchRegister); 29583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 29683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org lea(scratch, Operand(object, kScratchRegister, times_1, 0)); 29783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 298c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org and_(scratch, 299c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org Immediate(static_cast<int32_t>(isolate()->heap()->NewSpaceMask()))); 300c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(cc, branch, distance); 30183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 30283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 30383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 30483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 305c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::RecordWriteField( 306c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register object, 307c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int offset, 308c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register value, 309c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register dst, 310c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SaveFPRegsMode save_fp, 311c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RememberedSetAction remembered_set_action, 312c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SmiCheck smi_check) { 31330ce411529579186181838984710b0b0980857aaricow@chromium.org // First, check if a write barrier is even needed. The tests below 314c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // catch stores of Smis. 315b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org Label done; 316b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org 317c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Skip barrier if writing a smi. 318c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (smi_check == INLINE_SMI_CHECK) { 319c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com JumpIfSmi(value, &done); 320c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 321c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 322c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Although the object register is tagged, the offset is relative to the start 323c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // of the object, so so offset must be a multiple of kPointerSize. 324c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(IsAligned(offset, kPointerSize)); 325c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 326c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com lea(dst, FieldOperand(object, offset)); 327c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (emit_debug_code()) { 328c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label ok; 329c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com testb(dst, Immediate((1 << kPointerSizeLog2) - 1)); 330c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(zero, &ok, Label::kNear); 331c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int3(); 332c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&ok); 333c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 334c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 335c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RecordWrite( 336c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com object, dst, value, save_fp, remembered_set_action, OMIT_SMI_CHECK); 337c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3389d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com bind(&done); 339b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 340c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Clobber clobbered input registers when running with the debug-code flag 341c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // turned on to provoke errors. 342badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 343e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org movq(value, kZapValue, RelocInfo::NONE64); 344e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org movq(dst, kZapValue, RelocInfo::NONE64); 345b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 3469d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com} 3479d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com 3489d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com 349394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comvoid MacroAssembler::RecordWriteArray(Register object, 350394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register value, 351394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register index, 352394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com SaveFPRegsMode save_fp, 353394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com RememberedSetAction remembered_set_action, 354394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com SmiCheck smi_check) { 355394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // First, check if a write barrier is even needed. The tests below 356394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // catch stores of Smis. 357394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Label done; 358394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 359394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Skip barrier if writing a smi. 360394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (smi_check == INLINE_SMI_CHECK) { 361394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com JumpIfSmi(value, &done); 362394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 363394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 364394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Array access: calculate the destination address. Index is not a smi. 365394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register dst = index; 366394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com lea(dst, Operand(object, index, times_pointer_size, 367394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com FixedArray::kHeaderSize - kHeapObjectTag)); 368394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 369394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com RecordWrite( 370394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com object, dst, value, save_fp, remembered_set_action, OMIT_SMI_CHECK); 371394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 372394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com bind(&done); 373394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 374394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Clobber clobbered input registers when running with the debug-code flag 375394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // turned on to provoke errors. 376394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (emit_debug_code()) { 377e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org movq(value, kZapValue, RelocInfo::NONE64); 378e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org movq(index, kZapValue, RelocInfo::NONE64); 379394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 380394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com} 381394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 382394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 38369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.orgvoid MacroAssembler::RecordWrite(Register object, 38469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org Register address, 385c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register value, 386c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SaveFPRegsMode fp_mode, 387c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RememberedSetAction remembered_set_action, 388c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SmiCheck smi_check) { 389c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!object.is(value)); 390c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!object.is(address)); 391c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!value.is(address)); 392c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org AssertNotSmi(object); 393c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 394c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (remembered_set_action == OMIT_REMEMBERED_SET && 395c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com !FLAG_incremental_marking) { 396c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return; 39769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org } 39869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 399000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org if (emit_debug_code()) { 400c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label ok; 401c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmpq(value, Operand(address, 0)); 402c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(equal, &ok, Label::kNear); 403c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int3(); 404c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&ok); 405c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 40669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 407f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org // Count number of write barriers in generated code. 408f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org isolate()->counters()->write_barriers_static()->Increment(); 409f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1); 410f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org 411c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // First, check if a write barrier is even needed. The tests below 412c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // catch stores of smis and stores into the young generation. 4139d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com Label done; 414b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 415c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (smi_check == INLINE_SMI_CHECK) { 416c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Skip barrier if writing a smi. 417c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com JumpIfSmi(value, &done); 418b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 419b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 420c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CheckPageFlag(value, 421c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com value, // Used as scratch. 422c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MemoryChunk::kPointersToHereAreInterestingMask, 423c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com zero, 424c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com &done, 425c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::kNear); 426b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org 427c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CheckPageFlag(object, 428c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com value, // Used as scratch. 429c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MemoryChunk::kPointersFromHereAreInterestingMask, 430c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com zero, 431c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com &done, 432c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::kNear); 433e88a9edffbbdbc4ccc9872560ac4d9ea6b188fbdwhesse@chromium.org 434c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RecordWriteStub stub(object, value, address, remembered_set_action, fp_mode); 435c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CallStub(&stub); 436b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org 437b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org bind(&done); 438b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 439c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Clobber clobbered registers when running with the debug-code flag 440b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // turned on to provoke errors. 441badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 442e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org movq(address, kZapValue, RelocInfo::NONE64); 443e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org movq(value, kZapValue, RelocInfo::NONE64); 444b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 4455aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org} 4465aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 447c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 448594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid MacroAssembler::Assert(Condition cc, BailoutReason reason) { 449594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (emit_debug_code()) Check(cc, reason); 450eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 451eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 452eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 4530b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.orgvoid MacroAssembler::AssertFastElements(Register elements) { 454badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 45583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label ok; 4560b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org CompareRoot(FieldOperand(elements, HeapObject::kMapOffset), 4570b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org Heap::kFixedArrayMapRootIndex); 45883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(equal, &ok, Label::kNear); 4590b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org CompareRoot(FieldOperand(elements, HeapObject::kMapOffset), 46084bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org Heap::kFixedDoubleArrayMapRootIndex); 46184bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org j(equal, &ok, Label::kNear); 46284bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org CompareRoot(FieldOperand(elements, HeapObject::kMapOffset), 4630b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org Heap::kFixedCOWArrayMapRootIndex); 46483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(equal, &ok, Label::kNear); 465594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(kJSObjectWithFastElementsMapHasSlowElements); 4660b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org bind(&ok); 4670b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org } 4680b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org} 4690b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org 4700b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org 471594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid MacroAssembler::Check(Condition cc, BailoutReason reason) { 47283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label L; 47383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(cc, &L, Label::kNear); 474594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(reason); 475c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Control will not return here. 476eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org bind(&L); 477eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 478eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 479eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 480c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.orgvoid MacroAssembler::CheckStackAlignment() { 481c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org int frame_alignment = OS::ActivationFrameAlignment(); 482c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org int frame_alignment_mask = frame_alignment - 1; 483c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org if (frame_alignment > kPointerSize) { 484c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org ASSERT(IsPowerOf2(frame_alignment)); 48583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label alignment_as_expected; 486c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org testq(rsp, Immediate(frame_alignment_mask)); 48783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(zero, &alignment_as_expected, Label::kNear); 488c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org // Abort if stack is not aligned. 489c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org int3(); 490c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org bind(&alignment_as_expected); 491c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org } 492c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org} 493c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org 494c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org 4955aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.orgvoid MacroAssembler::NegativeZeroTest(Register result, 4965aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org Register op, 4975aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org Label* then_label) { 49883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label ok; 4990b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org testl(result, result); 50083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(not_zero, &ok, Label::kNear); 5010b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org testl(op, op); 5025aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org j(sign, then_label); 5035aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org bind(&ok); 5045aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org} 5055aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 5065aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 507594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid MacroAssembler::Abort(BailoutReason reason) { 508eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // We want to pass the msg string like a smi to avoid GC 509eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // problems, however msg is not guaranteed to be aligned 510eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // properly. Instead, we pass an aligned pointer that is 511eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // a proper v8 smi, but also pass the alignment difference 512eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // from the real pointer as a smi. 513594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org const char* msg = GetBailoutReason(reason); 514eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org intptr_t p1 = reinterpret_cast<intptr_t>(msg); 515eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org intptr_t p0 = (p1 & ~kSmiTagMask) + kSmiTag; 516f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Note: p0 might not be a valid Smi _value_, but it has a valid Smi tag. 517eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org ASSERT(reinterpret_cast<Object*>(p0)->IsSmi()); 518eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org#ifdef DEBUG 519eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org if (msg != NULL) { 520eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org RecordComment("Abort message: "); 521eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org RecordComment(msg); 522eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org } 5231e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 5241e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org if (FLAG_trap_on_abort) { 5251e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org int3(); 5261e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org return; 5271e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org } 528eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org#endif 5291e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 530eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org push(rax); 531e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org movq(kScratchRegister, reinterpret_cast<Smi*>(p0), RelocInfo::NONE64); 532eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org push(kScratchRegister); 533e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org movq(kScratchRegister, Smi::FromInt(static_cast<int>(p1 - p0)), 5344cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org RelocInfo::NONE64); 535eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org push(kScratchRegister); 536c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 537c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!has_frame_) { 538c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // We don't actually want to generate a pile of code for this, so just 539c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // claim there is a stack frame, without generating one. 540c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope scope(this, StackFrame::NONE); 541c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CallRuntime(Runtime::kAbort, 2); 542c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 543c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CallRuntime(Runtime::kAbort, 2); 544c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 545c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Control will not return here. 546ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org int3(); 547eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 548eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 549eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 550471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.orgvoid MacroAssembler::CallStub(CodeStub* stub, TypeFeedbackId ast_id) { 551c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(AllowThisStubCall(stub)); // Calls are not allowed in some stubs 5528432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org Call(stub->GetCode(isolate()), RelocInfo::CODE_TARGET, ast_id); 553eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 554eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 555eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 55613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid MacroAssembler::TailCallStub(CodeStub* stub) { 5578432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org Jump(stub->GetCode(isolate()), RelocInfo::CODE_TARGET); 55813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org} 55913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 56013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 561eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::StubReturn(int argc) { 562eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org ASSERT(argc >= 1 && generating_stub()); 563eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org ret((argc - 1) * kPointerSize); 564eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 565eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 566eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 567c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool MacroAssembler::AllowThisStubCall(CodeStub* stub) { 5688a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org return has_frame_ || !stub->SometimesSetsUpAFrame(); 569c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 570c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 571c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 572eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::IllegalOperation(int num_arguments) { 573eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org if (num_arguments > 0) { 574eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org addq(rsp, Immediate(num_arguments * kPointerSize)); 575eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org } 57618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org LoadRoot(rax, Heap::kUndefinedValueRootIndex); 577eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 578eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 579eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 580d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.orgvoid MacroAssembler::IndexFromHash(Register hash, Register index) { 581d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // The assert checks that the constants for the maximum number of digits 582d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // for an array index cached in the hash field and the number of bits 583d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // reserved for it does not conflict. 584d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) < 585d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org (1 << String::kArrayIndexValueBits)); 586d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // We want the smi-tagged index in key. Even if we subsequently go to 587d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // the slow case, converting the key to a smi is always valid. 588d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // key: string key 589d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // hash: key's hash field, including its array index value. 590d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org and_(hash, Immediate(String::kArrayIndexValueMask)); 591d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org shr(hash, Immediate(String::kHashShift)); 592d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // Here we actually clobber the key which will be used if calling into 593d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // runtime later. However as the new key is the numeric value of a string key 594d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // there is no difference in using either key. 595d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org Integer32ToSmi(index, hash); 596d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org} 597d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 598d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 599ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgvoid MacroAssembler::CallRuntime(const Runtime::Function* f, 600fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org int num_arguments, 601fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org SaveFPRegsMode save_doubles) { 602eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // If the expected number of arguments of the runtime function is 603eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // constant, we check that the actual number of arguments match the 604eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // expectation. 605eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org if (f->nargs >= 0 && f->nargs != num_arguments) { 606eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org IllegalOperation(num_arguments); 607eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org return; 608eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org } 609eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 610b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // TODO(1236192): Most runtime routines don't need the number of 611b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // arguments passed in because it is constant. At some point we 612b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // should remove this need and make the runtime routine entry code 613b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // smarter. 61432d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org Set(rax, num_arguments); 615ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org LoadAddress(rbx, ExternalReference(f, isolate())); 616fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org CEntryStub ces(f->result_size, save_doubles); 617b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org CallStub(&ces); 618eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 619eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 620eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 6215c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid MacroAssembler::CallExternalReference(const ExternalReference& ext, 6225c838251403b0be9a882540f1922577abba4c872ager@chromium.org int num_arguments) { 62332d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org Set(rax, num_arguments); 624ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org LoadAddress(rbx, ext); 6255c838251403b0be9a882540f1922577abba4c872ager@chromium.org 6265c838251403b0be9a882540f1922577abba4c872ager@chromium.org CEntryStub stub(1); 6275c838251403b0be9a882540f1922577abba4c872ager@chromium.org CallStub(&stub); 6285c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 6295c838251403b0be9a882540f1922577abba4c872ager@chromium.org 6305c838251403b0be9a882540f1922577abba4c872ager@chromium.org 631ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgvoid MacroAssembler::TailCallExternalReference(const ExternalReference& ext, 632ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int num_arguments, 633ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int result_size) { 6340b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // ----------- S t a t e ------------- 635c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org // -- rsp[0] : return address 636c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org // -- rsp[8] : argument num_arguments - 1 6370b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // ... 6380b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // -- rsp[8 * num_arguments] : argument 0 (receiver) 6390b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // ----------------------------------- 6400b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 641eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // TODO(1236192): Most runtime routines don't need the number of 642eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // arguments passed in because it is constant. At some point we 643eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // should remove this need and make the runtime routine entry code 644eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // smarter. 64532d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org Set(rax, num_arguments); 646ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org JumpToExternalReference(ext, result_size); 647eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 648eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 649eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 650ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgvoid MacroAssembler::TailCallRuntime(Runtime::FunctionId fid, 651ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int num_arguments, 652ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int result_size) { 653ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org TailCallExternalReference(ExternalReference(fid, isolate()), 654ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org num_arguments, 655ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org result_size); 656ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org} 657ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 658ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 659e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.orgstatic int Offset(ExternalReference ref0, ExternalReference ref1) { 660e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org int64_t offset = (ref0.address() - ref1.address()); 661e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org // Check that fits into int. 662e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org ASSERT(static_cast<int>(offset) == offset); 663e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org return static_cast<int>(offset); 664e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org} 665e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 666e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 667662436e7b124b3535773535c671c53db322070b5verwaest@chromium.orgvoid MacroAssembler::PrepareCallApiFunction(int arg_stack_space) { 6684a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com EnterApiExitFrame(arg_stack_space); 669e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org} 670e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 671e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 672528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid MacroAssembler::CallApiFunctionAndReturn( 673528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Address function_address, 674528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Address thunk_address, 675528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register thunk_last_arg, 676528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org int stack_space, 677528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Operand return_value_operand, 678528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Operand* context_restore_operand) { 679303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org Label prologue; 680303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org Label promote_scheduled_exception; 681528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Label exception_handled; 682303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org Label delete_allocated_handles; 683303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org Label leave_exit_frame; 684e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org Label write_back; 685e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 686160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org Factory* factory = isolate()->factory(); 687303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org ExternalReference next_address = 68809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org ExternalReference::handle_scope_next_address(isolate()); 689303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org const int kNextOffset = 0; 690303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org const int kLimitOffset = Offset( 69109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org ExternalReference::handle_scope_limit_address(isolate()), 692303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org next_address); 693303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org const int kLevelOffset = Offset( 69409d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org ExternalReference::handle_scope_level_address(isolate()), 695303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org next_address); 696303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org ExternalReference scheduled_exception_address = 697ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ExternalReference::scheduled_exception_address(isolate()); 698303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org 699303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // Allocate HandleScope in callee-save registers. 700303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org Register prev_next_address_reg = r14; 701303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org Register prev_limit_reg = rbx; 702b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org Register base_reg = r15; 703e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Move(base_reg, next_address); 704303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org movq(prev_next_address_reg, Operand(base_reg, kNextOffset)); 705303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org movq(prev_limit_reg, Operand(base_reg, kLimitOffset)); 706303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org addl(Operand(base_reg, kLevelOffset), Immediate(1)); 70783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 70883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org if (FLAG_log_timer_events) { 70983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org FrameScope frame(this, StackFrame::MANUAL); 71083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org PushSafepointRegisters(); 711ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org PrepareCallCFunction(1); 712ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org LoadAddress(arg_reg_1, ExternalReference::isolate_address(isolate())); 713ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org CallCFunction(ExternalReference::log_enter_external_function(isolate()), 1); 71483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org PopSafepointRegisters(); 71583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org } 71683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 717b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 718b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Label profiler_disabled; 719b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Label end_profiler_check; 720b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org bool* is_profiling_flag = 721b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org isolate()->cpu_profiler()->is_profiling_address(); 722b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org STATIC_ASSERT(sizeof(*is_profiling_flag) == 1); 723b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org movq(rax, is_profiling_flag, RelocInfo::EXTERNAL_REFERENCE); 724b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org cmpb(Operand(rax, 0), Immediate(0)); 725b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org j(zero, &profiler_disabled); 726b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 727b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // Third parameter is the address of the actual getter function. 728b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org movq(thunk_last_arg, function_address, RelocInfo::EXTERNAL_REFERENCE); 729b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org movq(rax, thunk_address, RelocInfo::EXTERNAL_REFERENCE); 730b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org jmp(&end_profiler_check); 731b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 732b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org bind(&profiler_disabled); 733303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // Call the api function! 734c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org movq(rax, reinterpret_cast<Address>(function_address), 7354cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org RelocInfo::EXTERNAL_REFERENCE); 736b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 737b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org bind(&end_profiler_check); 738b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 739b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // Call the api function! 740303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org call(rax); 741e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 74283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org if (FLAG_log_timer_events) { 74383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org FrameScope frame(this, StackFrame::MANUAL); 74483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org PushSafepointRegisters(); 745ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org PrepareCallCFunction(1); 746ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org LoadAddress(arg_reg_1, ExternalReference::isolate_address(isolate())); 747ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org CallCFunction(ExternalReference::log_leave_external_function(isolate()), 1); 74883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org PopSafepointRegisters(); 74983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org } 75083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 751bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org // Load the value from ReturnValue 752528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org movq(rax, return_value_operand); 753303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org bind(&prologue); 754303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org 755303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // No more valid handles (the result handle was the last one). Restore 756303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // previous handle scope. 757303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org subl(Operand(base_reg, kLevelOffset), Immediate(1)); 758303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org movq(Operand(base_reg, kNextOffset), prev_next_address_reg); 759303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org cmpq(prev_limit_reg, Operand(base_reg, kLimitOffset)); 760303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org j(not_equal, &delete_allocated_handles); 761303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org bind(&leave_exit_frame); 762303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org 763303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // Check if the function scheduled an exception. 764e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Move(rsi, scheduled_exception_address); 765160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org Cmp(Operand(rsi, 0), factory->the_hole_value()); 766303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org j(not_equal, &promote_scheduled_exception); 767528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org bind(&exception_handled); 768303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org 76967255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org#if ENABLE_EXTRA_CHECKS 77067255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org // Check if the function returned a valid JavaScript value. 77167255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org Label ok; 77267255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org Register return_value = rax; 77367255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org Register map = rcx; 77467255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 77567255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org JumpIfSmi(return_value, &ok, Label::kNear); 77667255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org movq(map, FieldOperand(return_value, HeapObject::kMapOffset)); 77767255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 77867255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org CmpInstanceType(map, FIRST_NONSTRING_TYPE); 77967255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org j(below, &ok, Label::kNear); 78067255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 78167255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE); 78267255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org j(above_equal, &ok, Label::kNear); 78367255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 78467255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org CompareRoot(map, Heap::kHeapNumberMapRootIndex); 78567255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org j(equal, &ok, Label::kNear); 78667255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 78767255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org CompareRoot(return_value, Heap::kUndefinedValueRootIndex); 78867255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org j(equal, &ok, Label::kNear); 78967255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 79067255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org CompareRoot(return_value, Heap::kTrueValueRootIndex); 79167255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org j(equal, &ok, Label::kNear); 79267255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 79367255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org CompareRoot(return_value, Heap::kFalseValueRootIndex); 79467255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org j(equal, &ok, Label::kNear); 79567255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 79667255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org CompareRoot(return_value, Heap::kNullValueRootIndex); 79767255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org j(equal, &ok, Label::kNear); 79867255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 799594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(kAPICallReturnedInvalidObject); 80067255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 80167255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org bind(&ok); 80267255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org#endif 80367255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 804528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org bool restore_context = context_restore_operand != NULL; 805528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (restore_context) { 806528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org movq(rsi, *context_restore_operand); 807528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 808528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org LeaveApiExitFrame(!restore_context); 8094a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com ret(stack_space * kPointerSize); 810e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 811b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org bind(&promote_scheduled_exception); 812528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org { 813528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org FrameScope frame(this, StackFrame::INTERNAL); 814528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org CallRuntime(Runtime::kPromoteScheduledException, 0); 815528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 816528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org jmp(&exception_handled); 817b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org 818303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // HandleScope limit has changed. Delete allocated extensions. 819303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org bind(&delete_allocated_handles); 820303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org movq(Operand(base_reg, kLimitOffset), prev_limit_reg); 821303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org movq(prev_limit_reg, rax); 822ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org LoadAddress(arg_reg_1, ExternalReference::isolate_address(isolate())); 823ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org LoadAddress(rax, 824ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ExternalReference::delete_handle_scope_extensions(isolate())); 825303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org call(rax); 826303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org movq(rax, prev_limit_reg); 827303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org jmp(&leave_exit_frame); 828e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org} 829e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 830e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 831ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgvoid MacroAssembler::JumpToExternalReference(const ExternalReference& ext, 832ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int result_size) { 833eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // Set the entry point and jump to the C entry runtime stub. 834ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org LoadAddress(rbx, ext); 835a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org CEntryStub ces(result_size); 8368432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org jmp(ces.GetCode(isolate()), RelocInfo::CODE_TARGET); 83771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 83871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 839e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 8403a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, 8413a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org InvokeFlag flag, 842fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org const CallWrapper& call_wrapper) { 843c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // You can't call a builtin without a valid frame. 844c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(flag == JUMP_FUNCTION || has_frame()); 8455aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 8465c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Rely on the assertion to check that the number of provided 8475c838251403b0be9a882540f1922577abba4c872ager@chromium.org // arguments match the expected number of arguments. Fake a 8485c838251403b0be9a882540f1922577abba4c872ager@chromium.org // parameter count to avoid emitting code to do the check. 8495c838251403b0be9a882540f1922577abba4c872ager@chromium.org ParameterCount expected(0); 8505c838251403b0be9a882540f1922577abba4c872ager@chromium.org GetBuiltinEntry(rdx, id); 851d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org InvokeCode(rdx, expected, expected, flag, call_wrapper, CALL_AS_METHOD); 8525aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org} 8535aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 8545c838251403b0be9a882540f1922577abba4c872ager@chromium.org 855145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.comvoid MacroAssembler::GetBuiltinFunction(Register target, 856145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com Builtins::JavaScript id) { 857c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org // Load the builtins object into target register. 85846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org movq(target, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 859c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org movq(target, FieldOperand(target, GlobalObject::kBuiltinsOffset)); 860145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com movq(target, FieldOperand(target, 861145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com JSBuiltinsObject::OffsetOfFunctionWithId(id))); 862145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com} 863c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org 864c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org 865145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.comvoid MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) { 866145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com ASSERT(!target.is(rdi)); 867145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com // Load the JavaScript builtin function from the builtins object. 868145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com GetBuiltinFunction(rdi, id); 869145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com movq(target, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); 8705aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org} 8715aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 8725aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 8731456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org#define REG(Name) { kRegister_ ## Name ## _Code } 8741456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 8751456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgstatic const Register saved_regs[] = { 8761456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org REG(rax), REG(rcx), REG(rdx), REG(rbx), REG(rbp), REG(rsi), REG(rdi), REG(r8), 8771456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org REG(r9), REG(r10), REG(r11) 8781456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org}; 8791456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 8801456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org#undef REG 8811456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 882c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic const int kNumberOfSavedRegs = sizeof(saved_regs) / sizeof(Register); 883c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 884c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 885c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::PushCallerSaved(SaveFPRegsMode fp_mode, 886c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register exclusion1, 887c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register exclusion2, 888c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register exclusion3) { 889c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // We don't allow a GC during a store buffer overflow so there is no need to 890c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // store the registers in any particular way, but we do have to store and 891c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // restore them. 892c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (int i = 0; i < kNumberOfSavedRegs; i++) { 893c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register reg = saved_regs[i]; 894c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!reg.is(exclusion1) && !reg.is(exclusion2) && !reg.is(exclusion3)) { 895c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com push(reg); 896c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 897c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 898c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // R12 to r15 are callee save on all platforms. 899c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (fp_mode == kSaveFPRegs) { 90094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org subq(rsp, Immediate(kDoubleSize * XMMRegister::kMaxNumRegisters)); 90194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { 902c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com XMMRegister reg = XMMRegister::from_code(i); 903c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com movsd(Operand(rsp, i * kDoubleSize), reg); 904c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 905c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 906c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 907c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 908c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 909c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::PopCallerSaved(SaveFPRegsMode fp_mode, 910c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register exclusion1, 911c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register exclusion2, 912c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register exclusion3) { 913c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (fp_mode == kSaveFPRegs) { 91494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { 915c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com XMMRegister reg = XMMRegister::from_code(i); 916c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com movsd(reg, Operand(rsp, i * kDoubleSize)); 917c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 91894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org addq(rsp, Immediate(kDoubleSize * XMMRegister::kMaxNumRegisters)); 919c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 920c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (int i = kNumberOfSavedRegs - 1; i >= 0; i--) { 921c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register reg = saved_regs[i]; 922c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!reg.is(exclusion1) && !reg.is(exclusion2) && !reg.is(exclusion3)) { 923c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com pop(reg); 924c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 925c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 926c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 927c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 928c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 929528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid MacroAssembler::Cvtlsi2sd(XMMRegister dst, Register src) { 930528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org xorps(dst, dst); 931528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org cvtlsi2sd(dst, src); 932528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org} 933528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 934528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 935528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid MacroAssembler::Cvtlsi2sd(XMMRegister dst, const Operand& src) { 936528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org xorps(dst, dst); 937528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org cvtlsi2sd(dst, src); 938528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org} 939528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 940528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 941d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.orgvoid MacroAssembler::Load(Register dst, const Operand& src, Representation r) { 942dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org ASSERT(!r.IsDouble()); 943935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org if (r.IsInteger8()) { 944935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org movsxbq(dst, src); 945935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } else if (r.IsUInteger8()) { 946d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org movzxbl(dst, src); 947935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } else if (r.IsInteger16()) { 948935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org movsxwq(dst, src); 949935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } else if (r.IsUInteger16()) { 950935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org movzxwl(dst, src); 951d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } else if (r.IsInteger32()) { 952d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org movl(dst, src); 953d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } else { 954d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org movq(dst, src); 955d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } 956d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org} 957d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 958d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 959d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.orgvoid MacroAssembler::Store(const Operand& dst, Register src, Representation r) { 960dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org ASSERT(!r.IsDouble()); 961935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org if (r.IsInteger8() || r.IsUInteger8()) { 962d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org movb(dst, src); 963935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } else if (r.IsInteger16() || r.IsUInteger16()) { 964935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org movw(dst, src); 965d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } else if (r.IsInteger32()) { 966d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org movl(dst, src); 967d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } else { 968d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org movq(dst, src); 969d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } 970d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org} 971d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 972d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 973e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.orgvoid MacroAssembler::Set(Register dst, int64_t x) { 97468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org if (x == 0) { 97569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org xorl(dst, dst); 976e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org } else if (is_uint32(x)) { 977c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org movl(dst, Immediate(static_cast<uint32_t>(x))); 978a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org } else if (is_int32(x)) { 979a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org movq(dst, Immediate(static_cast<int32_t>(x))); 980e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org } else { 981e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org movq(dst, x); 982e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org } 983e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org} 984e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 985e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 986e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.orgvoid MacroAssembler::Set(const Operand& dst, int64_t x) { 9875ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org if (is_int32(x)) { 988c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org movq(dst, Immediate(static_cast<int32_t>(x))); 989e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org } else { 990a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org Set(kScratchRegister, x); 99168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org movq(dst, kScratchRegister); 992e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org } 993e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org} 994e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 9957a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org 996dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org// ---------------------------------------------------------------------------- 997dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org// Smi tagging, untagging and tag detection. 998dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org 999dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgbool MacroAssembler::IsUnsafeInt(const int32_t x) { 10007a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org static const int kMaxBits = 17; 10017a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org return !is_intn(x, kMaxBits); 10027a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org} 10037a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org 10047a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org 10057a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.orgvoid MacroAssembler::SafeMove(Register dst, Smi* src) { 10067a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org ASSERT(!dst.is(kScratchRegister)); 1007662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org ASSERT(SmiValuesAre32Bits()); // JIT cookie can be converted to Smi. 10087a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org if (IsUnsafeInt(src->value()) && jit_cookie() != 0) { 10097a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org Move(dst, Smi::FromInt(src->value() ^ jit_cookie())); 10107a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org Move(kScratchRegister, Smi::FromInt(jit_cookie())); 10117a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org xor_(dst, kScratchRegister); 10127a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org } else { 10137a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org Move(dst, src); 10147a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org } 10157a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org} 10167a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org 10177a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org 10187a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.orgvoid MacroAssembler::SafePush(Smi* src) { 1019662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org ASSERT(SmiValuesAre32Bits()); // JIT cookie can be converted to Smi. 10207a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org if (IsUnsafeInt(src->value()) && jit_cookie() != 0) { 10217a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org Push(Smi::FromInt(src->value() ^ jit_cookie())); 10227a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org Move(kScratchRegister, Smi::FromInt(jit_cookie())); 10237a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org xor_(Operand(rsp, 0), kScratchRegister); 10247a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org } else { 10257a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org Push(src); 10267a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org } 10277a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org} 10287a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org 10297a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org 103069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.orgRegister MacroAssembler::GetSmiConstant(Smi* source) { 103169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org int value = source->value(); 103269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org if (value == 0) { 103369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org xorl(kScratchRegister, kScratchRegister); 103469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return kScratchRegister; 103569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org } 103669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org if (value == 1) { 103769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return kSmiConstantRegister; 103869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org } 103969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org LoadSmiConstant(kScratchRegister, source); 104069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return kScratchRegister; 104169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org} 104269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 1043e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 104469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.orgvoid MacroAssembler::LoadSmiConstant(Register dst, Smi* source) { 1045badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 1046e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org movq(dst, Smi::FromInt(kSmiConstantRegisterValue), RelocInfo::NONE64); 104769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org cmpq(dst, kSmiConstantRegister); 10488a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org Assert(equal, kUninitializedKSmiConstantRegister); 104969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org } 1050b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org int value = source->value(); 1051b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org if (value == 0) { 105269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org xorl(dst, dst); 105369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return; 105469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org } 105569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org bool negative = value < 0; 105669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org unsigned int uvalue = negative ? -value : value; 105769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 105869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org switch (uvalue) { 105969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org case 9: 106069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org lea(dst, Operand(kSmiConstantRegister, kSmiConstantRegister, times_8, 0)); 106169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org break; 106269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org case 8: 106369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org xorl(dst, dst); 106469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org lea(dst, Operand(dst, kSmiConstantRegister, times_8, 0)); 106569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org break; 106669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org case 4: 106769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org xorl(dst, dst); 106869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org lea(dst, Operand(dst, kSmiConstantRegister, times_4, 0)); 106969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org break; 107069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org case 5: 107169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org lea(dst, Operand(kSmiConstantRegister, kSmiConstantRegister, times_4, 0)); 107269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org break; 107369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org case 3: 107469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org lea(dst, Operand(kSmiConstantRegister, kSmiConstantRegister, times_2, 0)); 107569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org break; 107669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org case 2: 107769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org lea(dst, Operand(kSmiConstantRegister, kSmiConstantRegister, times_1, 0)); 107869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org break; 107969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org case 1: 108069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org movq(dst, kSmiConstantRegister); 108169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org break; 108269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org case 0: 108369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org UNREACHABLE(); 108469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return; 108569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org default: 1086e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org movq(dst, source, RelocInfo::NONE64); 108769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return; 108869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org } 108969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org if (negative) { 109069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org neg(dst); 109169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org } 109269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org} 109369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 10944af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 1095c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.orgvoid MacroAssembler::Integer32ToSmi(Register dst, Register src) { 109680c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org STATIC_ASSERT(kSmiTag == 0); 10974af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org if (!dst.is(src)) { 10984af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org movl(dst, src); 10994af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 11009d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com shl(dst, Immediate(kSmiShift)); 11014af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 11024af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 11034af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 11045ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.orgvoid MacroAssembler::Integer32ToSmiField(const Operand& dst, Register src) { 1105badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 11065ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org testb(dst, Immediate(0x01)); 110783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label ok; 110883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(zero, &ok, Label::kNear); 11098a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org Abort(kInteger32ToSmiFieldWritingToNonSmiLocation); 11105ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org bind(&ok); 11115ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org } 11125ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org ASSERT(kSmiShift % kBitsPerByte == 0); 11135ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org movl(Operand(dst, kSmiShift / kBitsPerByte), src); 11145ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org} 11155ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org 11165ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org 11179d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::Integer64PlusConstantToSmi(Register dst, 11189d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com Register src, 11199d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com int constant) { 11209d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (dst.is(src)) { 11217979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org addl(dst, Immediate(constant)); 11229d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } else { 11237979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org leal(dst, Operand(src, constant)); 11249d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } 11259d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com shl(dst, Immediate(kSmiShift)); 11264af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 11274af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 11284af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 11294af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgvoid MacroAssembler::SmiToInteger32(Register dst, Register src) { 113080c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org STATIC_ASSERT(kSmiTag == 0); 11314af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org if (!dst.is(src)) { 11329d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com movq(dst, src); 11334af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 11349d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com shr(dst, Immediate(kSmiShift)); 11354af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 11364af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 11374af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 113830ce411529579186181838984710b0b0980857aaricow@chromium.orgvoid MacroAssembler::SmiToInteger32(Register dst, const Operand& src) { 113930ce411529579186181838984710b0b0980857aaricow@chromium.org movl(dst, Operand(src, kSmiShift / kBitsPerByte)); 114030ce411529579186181838984710b0b0980857aaricow@chromium.org} 114130ce411529579186181838984710b0b0980857aaricow@chromium.org 114230ce411529579186181838984710b0b0980857aaricow@chromium.org 11434af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgvoid MacroAssembler::SmiToInteger64(Register dst, Register src) { 114480c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org STATIC_ASSERT(kSmiTag == 0); 11459d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (!dst.is(src)) { 11469d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com movq(dst, src); 11474af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 11489d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com sar(dst, Immediate(kSmiShift)); 11494af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 11504af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 11514af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 11525ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.orgvoid MacroAssembler::SmiToInteger64(Register dst, const Operand& src) { 11535ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org movsxlq(dst, Operand(src, kSmiShift / kBitsPerByte)); 11545ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org} 11555ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org 11565ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org 11579d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::SmiTest(Register src) { 1158ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org AssertSmi(src); 11599d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com testq(src, src); 11604af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 11614af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 11624af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 1163badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.orgvoid MacroAssembler::SmiCompare(Register smi1, Register smi2) { 1164c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org AssertSmi(smi1); 1165c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org AssertSmi(smi2); 1166badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org cmpq(smi1, smi2); 11674af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 11684af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 11694af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 11709d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::SmiCompare(Register dst, Smi* src) { 1171c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org AssertSmi(dst); 1172badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org Cmp(dst, src); 1173badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org} 1174badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org 1175badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org 1176badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.orgvoid MacroAssembler::Cmp(Register dst, Smi* src) { 11779d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com ASSERT(!dst.is(kScratchRegister)); 11789d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (src->value() == 0) { 11799d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com testq(dst, dst); 11809d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } else { 1181ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org Register constant_reg = GetSmiConstant(src); 1182ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org cmpq(dst, constant_reg); 11834af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 11844af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 11854af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 11864af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 11879155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.orgvoid MacroAssembler::SmiCompare(Register dst, const Operand& src) { 1188c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org AssertSmi(dst); 1189c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org AssertSmi(src); 1190ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org cmpq(dst, src); 1191ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org} 1192ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 1193ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 11949d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::SmiCompare(const Operand& dst, Register src) { 1195c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org AssertSmi(dst); 1196c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org AssertSmi(src); 11979d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com cmpq(dst, src); 1198c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org} 1199c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 1200c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 12019d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::SmiCompare(const Operand& dst, Smi* src) { 1202c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org AssertSmi(dst); 120330ce411529579186181838984710b0b0980857aaricow@chromium.org cmpl(Operand(dst, kSmiShift / kBitsPerByte), Immediate(src->value())); 12044af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 12054af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 12064af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 1207badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.orgvoid MacroAssembler::Cmp(const Operand& dst, Smi* src) { 1208badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org // The Operand cannot use the smi register. 1209badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org Register smi_reg = GetSmiConstant(src); 1210badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org ASSERT(!dst.AddressUsesRegister(smi_reg)); 1211badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org cmpq(dst, smi_reg); 1212badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org} 1213badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org 1214badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org 12155ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.orgvoid MacroAssembler::SmiCompareInteger32(const Operand& dst, Register src) { 12165ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org cmpl(Operand(dst, kSmiShift / kBitsPerByte), src); 12175ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org} 12185ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org 12195ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org 12209d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::PositiveSmiTimesPowerOfTwoToInteger64(Register dst, 12219d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com Register src, 12229d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com int power) { 12239d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com ASSERT(power >= 0); 12249d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com ASSERT(power < 64); 12259d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (power == 0) { 12269d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com SmiToInteger64(dst, src); 12279d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com return; 12289d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } 12299d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (!dst.is(src)) { 12309d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com movq(dst, src); 12319d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } 12329d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (power < kSmiShift) { 12339d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com sar(dst, Immediate(kSmiShift - power)); 12349d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } else if (power > kSmiShift) { 12359d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com shl(dst, Immediate(power - kSmiShift)); 12369d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } 12374af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 12384af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 12394af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 124030ce411529579186181838984710b0b0980857aaricow@chromium.orgvoid MacroAssembler::PositiveSmiDivPowerOfTwoToInteger32(Register dst, 124130ce411529579186181838984710b0b0980857aaricow@chromium.org Register src, 124230ce411529579186181838984710b0b0980857aaricow@chromium.org int power) { 124330ce411529579186181838984710b0b0980857aaricow@chromium.org ASSERT((0 <= power) && (power < 32)); 124430ce411529579186181838984710b0b0980857aaricow@chromium.org if (dst.is(src)) { 124530ce411529579186181838984710b0b0980857aaricow@chromium.org shr(dst, Immediate(power + kSmiShift)); 124630ce411529579186181838984710b0b0980857aaricow@chromium.org } else { 124730ce411529579186181838984710b0b0980857aaricow@chromium.org UNIMPLEMENTED(); // Not used. 124830ce411529579186181838984710b0b0980857aaricow@chromium.org } 124930ce411529579186181838984710b0b0980857aaricow@chromium.org} 125030ce411529579186181838984710b0b0980857aaricow@chromium.org 125130ce411529579186181838984710b0b0980857aaricow@chromium.org 125283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::SmiOrIfSmis(Register dst, Register src1, Register src2, 125383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smis, 125483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 125583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (dst.is(src1) || dst.is(src2)) { 125683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src1.is(kScratchRegister)); 125783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src2.is(kScratchRegister)); 125883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movq(kScratchRegister, src1); 125983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org or_(kScratchRegister, src2); 126083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org JumpIfNotSmi(kScratchRegister, on_not_smis, near_jump); 126183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movq(dst, kScratchRegister); 126283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 126383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movq(dst, src1); 126483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org or_(dst, src2); 126583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org JumpIfNotSmi(dst, on_not_smis, near_jump); 126683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 126783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 126883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 126983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 12709d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comCondition MacroAssembler::CheckSmi(Register src) { 127180c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org STATIC_ASSERT(kSmiTag == 0); 12724af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org testb(src, Immediate(kSmiTagMask)); 12739d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com return zero; 12744af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 12754af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 12764af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 12770a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.orgCondition MacroAssembler::CheckSmi(const Operand& src) { 127880c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org STATIC_ASSERT(kSmiTag == 0); 12790a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org testb(src, Immediate(kSmiTagMask)); 12800a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org return zero; 12810a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org} 12820a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 12830a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 1284eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.orgCondition MacroAssembler::CheckNonNegativeSmi(Register src) { 128580c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org STATIC_ASSERT(kSmiTag == 0); 12868f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org // Test that both bits of the mask 0x8000000000000001 are zero. 12879d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com movq(kScratchRegister, src); 12889d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com rol(kScratchRegister, Immediate(1)); 128969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org testb(kScratchRegister, Immediate(3)); 12904af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org return zero; 12914af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 12924af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 12934af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 12944af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgCondition MacroAssembler::CheckBothSmi(Register first, Register second) { 12954af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org if (first.is(second)) { 12964af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org return CheckSmi(first); 12974af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 129880c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org STATIC_ASSERT(kSmiTag == 0 && kHeapObjectTag == 1 && kHeapObjectTagMask == 3); 129932d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org leal(kScratchRegister, Operand(first, second, times_1, 0)); 130032d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org testb(kScratchRegister, Immediate(0x03)); 13019d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com return zero; 13024af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 13034af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 13044af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 1305eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.orgCondition MacroAssembler::CheckBothNonNegativeSmi(Register first, 1306eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org Register second) { 1307b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (first.is(second)) { 1308eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org return CheckNonNegativeSmi(first); 1309b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 131040b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org movq(kScratchRegister, first); 131140b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org or_(kScratchRegister, second); 1312b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org rol(kScratchRegister, Immediate(1)); 1313eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org testl(kScratchRegister, Immediate(3)); 1314b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org return zero; 1315b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 1316b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1317b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1318c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.orgCondition MacroAssembler::CheckEitherSmi(Register first, 1319c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org Register second, 1320c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org Register scratch) { 1321b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (first.is(second)) { 1322b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org return CheckSmi(first); 1323b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 1324c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org if (scratch.is(second)) { 1325c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org andl(scratch, first); 1326c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org } else { 1327c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org if (!scratch.is(first)) { 1328c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org movl(scratch, first); 1329c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org } 1330c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org andl(scratch, second); 1331c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org } 1332c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org testb(scratch, Immediate(kSmiTagMask)); 1333b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org return zero; 1334b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 1335b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1336b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 13374af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgCondition MacroAssembler::CheckIsMinSmi(Register src) { 133869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org ASSERT(!src.is(kScratchRegister)); 133969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org // If we overflow by subtracting one, it's the minimal smi value. 134069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org cmpq(src, kSmiConstantRegister); 134169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return overflow; 13424af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 13434af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 1344c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 13454af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgCondition MacroAssembler::CheckInteger32ValidSmiValue(Register src) { 13469d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com // A 32-bit integer value can always be converted to a smi. 13479d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com return always; 13484af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 13494af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 13504af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 13513811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.orgCondition MacroAssembler::CheckUInteger32ValidSmiValue(Register src) { 13523811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // An unsigned 32-bit integer value is valid as long as the high bit 13533811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // is not set. 135469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org testl(src, src); 135569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return positive; 13563811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org} 13573811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 13583811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 13590ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.orgvoid MacroAssembler::CheckSmiToIndicator(Register dst, Register src) { 13600ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org if (dst.is(src)) { 13610ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org andl(dst, Immediate(kSmiTagMask)); 13620ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } else { 13630ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org movl(dst, Immediate(kSmiTagMask)); 13640ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org andl(dst, src); 13650ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } 13660ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org} 13670ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 13680ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 13690ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.orgvoid MacroAssembler::CheckSmiToIndicator(Register dst, const Operand& src) { 13700ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org if (!(src.AddressUsesRegister(dst))) { 13710ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org movl(dst, Immediate(kSmiTagMask)); 13720ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org andl(dst, src); 13730ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } else { 13740ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org movl(dst, src); 13750ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org andl(dst, Immediate(kSmiTagMask)); 13760ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } 13770ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org} 13780ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 13790ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 138083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::JumpIfNotValidSmiValue(Register src, 138183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_invalid, 138283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 138383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Condition is_valid = CheckInteger32ValidSmiValue(src); 138483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(NegateCondition(is_valid), on_invalid, near_jump); 138583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 138683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 138783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 138883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::JumpIfUIntNotValidSmiValue(Register src, 138983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_invalid, 139083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 139183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Condition is_valid = CheckUInteger32ValidSmiValue(src); 139283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(NegateCondition(is_valid), on_invalid, near_jump); 139383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 139483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 139583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 139683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::JumpIfSmi(Register src, 139783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_smi, 139883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 139983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Condition smi = CheckSmi(src); 140083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(smi, on_smi, near_jump); 140183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 140283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 140383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 140483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::JumpIfNotSmi(Register src, 140583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi, 140683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 140783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Condition smi = CheckSmi(src); 140883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(NegateCondition(smi), on_not_smi, near_jump); 140983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 141083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 141183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 141283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::JumpUnlessNonNegativeSmi( 141383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src, Label* on_not_smi_or_negative, 141483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 141583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Condition non_negative_smi = CheckNonNegativeSmi(src); 141683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(NegateCondition(non_negative_smi), on_not_smi_or_negative, near_jump); 141783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 141883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 141983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 142083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::JumpIfSmiEqualsConstant(Register src, 142183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Smi* constant, 142283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_equals, 142383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 142483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org SmiCompare(src, constant); 142583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(equal, on_equals, near_jump); 142683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 142783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 142883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 142983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::JumpIfNotBothSmi(Register src1, 143083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src2, 143183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_both_smi, 143283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 143383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Condition both_smi = CheckBothSmi(src1, src2); 143483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(NegateCondition(both_smi), on_not_both_smi, near_jump); 143583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 143683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 143783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 143883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::JumpUnlessBothNonNegativeSmi(Register src1, 143983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src2, 144083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_both_smi, 144183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 144283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Condition both_smi = CheckBothNonNegativeSmi(src1, src2); 144383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(NegateCondition(both_smi), on_not_both_smi, near_jump); 144483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 144583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 144683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 14479d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::SmiAddConstant(Register dst, Register src, Smi* constant) { 14489d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (constant->value() == 0) { 14499d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (!dst.is(src)) { 14509d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com movq(dst, src); 14519d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } 145269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return; 14539d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } else if (dst.is(src)) { 14549d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com ASSERT(!dst.is(kScratchRegister)); 145569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org switch (constant->value()) { 145669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org case 1: 145769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org addq(dst, kSmiConstantRegister); 145869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return; 145969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org case 2: 146069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org lea(dst, Operand(src, kSmiConstantRegister, times_2, 0)); 146169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return; 146269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org case 4: 146369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org lea(dst, Operand(src, kSmiConstantRegister, times_4, 0)); 146469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return; 146569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org case 8: 146669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org lea(dst, Operand(src, kSmiConstantRegister, times_8, 0)); 146769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return; 146869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org default: 146969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org Register constant_reg = GetSmiConstant(constant); 147069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org addq(dst, constant_reg); 147169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return; 147269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org } 14734af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } else { 147469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org switch (constant->value()) { 147569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org case 1: 147669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org lea(dst, Operand(src, kSmiConstantRegister, times_1, 0)); 147769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return; 147869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org case 2: 147969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org lea(dst, Operand(src, kSmiConstantRegister, times_2, 0)); 148069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return; 148169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org case 4: 148269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org lea(dst, Operand(src, kSmiConstantRegister, times_4, 0)); 148369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return; 148469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org case 8: 148569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org lea(dst, Operand(src, kSmiConstantRegister, times_8, 0)); 148669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return; 148769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org default: 148869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org LoadSmiConstant(dst, constant); 148969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org addq(dst, src); 149069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return; 149169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org } 14924af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 14934af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 14944af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 14954af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 14969dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.comvoid MacroAssembler::SmiAddConstant(const Operand& dst, Smi* constant) { 14979dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com if (constant->value() != 0) { 149830ce411529579186181838984710b0b0980857aaricow@chromium.org addl(Operand(dst, kSmiShift / kBitsPerByte), Immediate(constant->value())); 14999dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com } 15009dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 15019dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 15029dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 150383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::SmiAddConstant(Register dst, 150483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src, 150583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Smi* constant, 1506e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org SmiOperationExecutionMode mode, 1507e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Label* bailout_label, 150883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 150983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (constant->value() == 0) { 151083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (!dst.is(src)) { 151183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movq(dst, src); 151283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 151383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else if (dst.is(src)) { 151483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!dst.is(kScratchRegister)); 151583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org LoadSmiConstant(kScratchRegister, constant); 1516d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org addq(dst, kScratchRegister); 1517e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (mode.Contains(BAILOUT_ON_NO_OVERFLOW)) { 1518e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org j(no_overflow, bailout_label, near_jump); 1519e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org ASSERT(mode.Contains(PRESERVE_SOURCE_REGISTER)); 1520e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org subq(dst, kScratchRegister); 1521e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } else if (mode.Contains(BAILOUT_ON_OVERFLOW)) { 1522e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (mode.Contains(PRESERVE_SOURCE_REGISTER)) { 1523e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Label done; 1524e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org j(no_overflow, &done, Label::kNear); 1525e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org subq(dst, kScratchRegister); 1526e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org jmp(bailout_label, near_jump); 1527e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org bind(&done); 1528e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } else { 1529e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // Bailout if overflow without reserving src. 1530e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org j(overflow, bailout_label, near_jump); 1531e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 1532e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } else { 1533e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org CHECK(mode.IsEmpty()); 1534e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 153583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 1536e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org ASSERT(mode.Contains(PRESERVE_SOURCE_REGISTER)); 1537e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org ASSERT(mode.Contains(BAILOUT_ON_OVERFLOW)); 153883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org LoadSmiConstant(dst, constant); 153983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org addq(dst, src); 1540e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org j(overflow, bailout_label, near_jump); 154183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 154283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 154383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 154483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 15459d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::SmiSubConstant(Register dst, Register src, Smi* constant) { 15469d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (constant->value() == 0) { 15474af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org if (!dst.is(src)) { 15489d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com movq(dst, src); 15494af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 15509d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } else if (dst.is(src)) { 15519d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com ASSERT(!dst.is(kScratchRegister)); 155269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org Register constant_reg = GetSmiConstant(constant); 155369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org subq(dst, constant_reg); 15549d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } else { 15559d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (constant->value() == Smi::kMinValue) { 155669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org LoadSmiConstant(dst, constant); 15575ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org // Adding and subtracting the min-value gives the same result, it only 15585ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org // differs on the overflow bit, which we don't check here. 15595ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org addq(dst, src); 15604af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } else { 15615ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org // Subtract by adding the negation. 156269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org LoadSmiConstant(dst, Smi::FromInt(-constant->value())); 15639d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com addq(dst, src); 15644af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 15654af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 15664af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 15674af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 15684af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 156983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::SmiSubConstant(Register dst, 157083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src, 157183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Smi* constant, 1572e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org SmiOperationExecutionMode mode, 1573e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Label* bailout_label, 157483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 157583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (constant->value() == 0) { 157683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (!dst.is(src)) { 157783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movq(dst, src); 157883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 157983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else if (dst.is(src)) { 158083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!dst.is(kScratchRegister)); 1581e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org LoadSmiConstant(kScratchRegister, constant); 1582e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org subq(dst, kScratchRegister); 1583e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (mode.Contains(BAILOUT_ON_NO_OVERFLOW)) { 1584e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org j(no_overflow, bailout_label, near_jump); 1585e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org ASSERT(mode.Contains(PRESERVE_SOURCE_REGISTER)); 1586e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org addq(dst, kScratchRegister); 1587e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } else if (mode.Contains(BAILOUT_ON_OVERFLOW)) { 1588e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (mode.Contains(PRESERVE_SOURCE_REGISTER)) { 1589e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Label done; 1590e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org j(no_overflow, &done, Label::kNear); 1591e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org addq(dst, kScratchRegister); 1592e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org jmp(bailout_label, near_jump); 1593e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org bind(&done); 1594e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } else { 1595e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // Bailout if overflow without reserving src. 1596e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org j(overflow, bailout_label, near_jump); 1597e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 159883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 1599e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org CHECK(mode.IsEmpty()); 160083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 160183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 1602e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org ASSERT(mode.Contains(PRESERVE_SOURCE_REGISTER)); 1603e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org ASSERT(mode.Contains(BAILOUT_ON_OVERFLOW)); 160483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (constant->value() == Smi::kMinValue) { 1605e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org ASSERT(!dst.is(kScratchRegister)); 1606e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org movq(dst, src); 1607e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org LoadSmiConstant(kScratchRegister, constant); 1608e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org subq(dst, kScratchRegister); 1609e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org j(overflow, bailout_label, near_jump); 161083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 161183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Subtract by adding the negation. 161283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org LoadSmiConstant(dst, Smi::FromInt(-(constant->value()))); 161383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org addq(dst, src); 1614e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org j(overflow, bailout_label, near_jump); 161583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 161683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 161783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 161883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 161983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 162083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::SmiNeg(Register dst, 162183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src, 162283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_smi_result, 162383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 162483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (dst.is(src)) { 162583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!dst.is(kScratchRegister)); 162683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movq(kScratchRegister, src); 162783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org neg(dst); // Low 32 bits are retained as zero by negation. 162883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Test if result is zero or Smi::kMinValue. 162983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org cmpq(dst, kScratchRegister); 163083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(not_equal, on_smi_result, near_jump); 163183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movq(src, kScratchRegister); 163283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 163383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movq(dst, src); 163483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org neg(dst); 163583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org cmpq(dst, src); 163683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // If the result is zero or Smi::kMinValue, negation failed to create a smi. 163783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(not_equal, on_smi_result, near_jump); 163883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 163983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 164083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 164183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 1642d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.orgtemplate<class T> 1643d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.orgstatic void SmiAddHelper(MacroAssembler* masm, 1644d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Register dst, 1645d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Register src1, 1646d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org T src2, 1647d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Label* on_not_smi_result, 1648d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Label::Distance near_jump) { 1649d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org if (dst.is(src1)) { 1650d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Label done; 1651d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org masm->addq(dst, src2); 1652d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org masm->j(no_overflow, &done, Label::kNear); 1653d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org // Restore src1. 1654d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org masm->subq(dst, src2); 1655d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org masm->jmp(on_not_smi_result, near_jump); 1656d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org masm->bind(&done); 1657d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } else { 1658d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org masm->movq(dst, src1); 1659d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org masm->addq(dst, src2); 1660d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org masm->j(overflow, on_not_smi_result, near_jump); 1661d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } 1662d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org} 1663d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 1664d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 166583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::SmiAdd(Register dst, 166683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src1, 166783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src2, 166883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi_result, 166983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 167083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT_NOT_NULL(on_not_smi_result); 167183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!dst.is(src2)); 1672d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org SmiAddHelper<Register>(this, dst, src1, src2, on_not_smi_result, near_jump); 167383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 167483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 167583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 167683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::SmiAdd(Register dst, 167783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src1, 167883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org const Operand& src2, 167983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi_result, 168083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 168183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT_NOT_NULL(on_not_smi_result); 1682d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ASSERT(!src2.AddressUsesRegister(dst)); 1683d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org SmiAddHelper<Operand>(this, dst, src1, src2, on_not_smi_result, near_jump); 168483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 168583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 168683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 1687c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.orgvoid MacroAssembler::SmiAdd(Register dst, 1688c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org Register src1, 1689c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org Register src2) { 1690c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org // No overflow checking. Use only when it's known that 1691c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org // overflowing is impossible. 16927979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org if (!dst.is(src1)) { 1693160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org if (emit_debug_code()) { 1694160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org movq(kScratchRegister, src1); 1695160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org addq(kScratchRegister, src2); 1696594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(no_overflow, kSmiAdditionOverflow); 1697160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } 1698160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org lea(dst, Operand(src1, src2, times_1, 0)); 1699160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } else { 1700160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org addq(dst, src2); 1701594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Assert(no_overflow, kSmiAdditionOverflow); 17024af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 17034af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 17044af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 17054af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 1706c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgtemplate<class T> 1707c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgstatic void SmiSubHelper(MacroAssembler* masm, 1708c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org Register dst, 1709c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org Register src1, 1710c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org T src2, 1711c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org Label* on_not_smi_result, 1712c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org Label::Distance near_jump) { 171383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (dst.is(src1)) { 1714c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org Label done; 1715c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org masm->subq(dst, src2); 1716c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org masm->j(no_overflow, &done, Label::kNear); 1717c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org // Restore src1. 1718c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org masm->addq(dst, src2); 1719c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org masm->jmp(on_not_smi_result, near_jump); 1720c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org masm->bind(&done); 172183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 1722c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org masm->movq(dst, src1); 1723c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org masm->subq(dst, src2); 1724c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org masm->j(overflow, on_not_smi_result, near_jump); 172583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 172683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 172783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 172883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 1729c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgvoid MacroAssembler::SmiSub(Register dst, 1730c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org Register src1, 1731c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org Register src2, 1732c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org Label* on_not_smi_result, 1733c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org Label::Distance near_jump) { 1734c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org ASSERT_NOT_NULL(on_not_smi_result); 1735c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org ASSERT(!dst.is(src2)); 1736c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org SmiSubHelper<Register>(this, dst, src1, src2, on_not_smi_result, near_jump); 17374af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 17384af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 17394af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 1740c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.orgvoid MacroAssembler::SmiSub(Register dst, 17414af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src1, 174283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org const Operand& src2, 174383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi_result, 174483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 174583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT_NOT_NULL(on_not_smi_result); 1746c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org ASSERT(!src2.AddressUsesRegister(dst)); 1747c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org SmiSubHelper<Operand>(this, dst, src1, src2, on_not_smi_result, near_jump); 174883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 174983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 175083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 1751c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgtemplate<class T> 1752c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgstatic void SmiSubNoOverflowHelper(MacroAssembler* masm, 1753c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org Register dst, 1754c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org Register src1, 1755c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org T src2) { 1756c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org // No overflow checking. Use only when it's known that 1757c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org // overflowing is impossible (e.g., subtracting two positive smis). 17587979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org if (!dst.is(src1)) { 1759c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org masm->movq(dst, src1); 17604af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 1761c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org masm->subq(dst, src2); 1762c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org masm->Assert(no_overflow, kSmiSubtractionOverflow); 1763c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org} 1764c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org 1765c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org 1766c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgvoid MacroAssembler::SmiSub(Register dst, Register src1, Register src2) { 1767c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org ASSERT(!dst.is(src2)); 1768c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org SmiSubNoOverflowHelper<Register>(this, dst, src1, src2); 1769c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org} 1770c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org 1771c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org 1772c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgvoid MacroAssembler::SmiSub(Register dst, 1773c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org Register src1, 1774c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org const Operand& src2) { 1775c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org SmiSubNoOverflowHelper<Operand>(this, dst, src1, src2); 17764af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 17774af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 17784af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 177983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::SmiMul(Register dst, 178083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src1, 178183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src2, 178283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi_result, 178383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 178483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!dst.is(src2)); 178583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!dst.is(kScratchRegister)); 178683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src1.is(kScratchRegister)); 178783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src2.is(kScratchRegister)); 178883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 178983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (dst.is(src1)) { 179083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label failure, zero_correct_result; 179183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movq(kScratchRegister, src1); // Create backup for later testing. 179283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org SmiToInteger64(dst, src1); 179383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org imul(dst, src2); 179483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(overflow, &failure, Label::kNear); 179583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 179683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Check for negative zero result. If product is zero, and one 179783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // argument is negative, go to slow case. 179883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label correct_result; 179983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org testq(dst, dst); 180083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(not_zero, &correct_result, Label::kNear); 180183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 180283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movq(dst, kScratchRegister); 180383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org xor_(dst, src2); 180483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Result was positive zero. 180583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(positive, &zero_correct_result, Label::kNear); 180683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 180783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org bind(&failure); // Reused failure exit, restores src1. 180883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movq(src1, kScratchRegister); 180983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org jmp(on_not_smi_result, near_jump); 181083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 181183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org bind(&zero_correct_result); 181283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Set(dst, 0); 181383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 181483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org bind(&correct_result); 181583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 181683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org SmiToInteger64(dst, src1); 181783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org imul(dst, src2); 181883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(overflow, on_not_smi_result, near_jump); 181983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Check for negative zero result. If product is zero, and one 182083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // argument is negative, go to slow case. 182183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label correct_result; 182283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org testq(dst, dst); 182383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(not_zero, &correct_result, Label::kNear); 182483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // One of src1 and src2 is zero, the check whether the other is 182583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // negative. 182683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movq(kScratchRegister, src1); 182783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org xor_(kScratchRegister, src2); 182883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(negative, on_not_smi_result, near_jump); 182983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org bind(&correct_result); 183083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 183183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 183283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 183383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 183483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::SmiDiv(Register dst, 183583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src1, 183683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src2, 183783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi_result, 183883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 183983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src1.is(kScratchRegister)); 184083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src2.is(kScratchRegister)); 184183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!dst.is(kScratchRegister)); 184283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src2.is(rax)); 184383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src2.is(rdx)); 184483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src1.is(rdx)); 184583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 184683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Check for 0 divisor (result is +/-Infinity). 184783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org testq(src2, src2); 184883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(zero, on_not_smi_result, near_jump); 184983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 185083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (src1.is(rax)) { 185183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movq(kScratchRegister, src1); 185283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 185383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org SmiToInteger32(rax, src1); 185483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // We need to rule out dividing Smi::kMinValue by -1, since that would 185583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // overflow in idiv and raise an exception. 185683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // We combine this with negative zero test (negative zero only happens 185783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // when dividing zero by a negative number). 185883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 185983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // We overshoot a little and go to slow case if we divide min-value 186083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // by any negative value, not just -1. 186183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label safe_div; 186283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org testl(rax, Immediate(0x7fffffff)); 186383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(not_zero, &safe_div, Label::kNear); 186483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org testq(src2, src2); 186583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (src1.is(rax)) { 186683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(positive, &safe_div, Label::kNear); 186783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movq(src1, kScratchRegister); 186883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org jmp(on_not_smi_result, near_jump); 186983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 187083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(negative, on_not_smi_result, near_jump); 187183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 187283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org bind(&safe_div); 187383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 187483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org SmiToInteger32(src2, src2); 187583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Sign extend src1 into edx:eax. 187683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org cdq(); 187783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org idivl(src2); 187883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Integer32ToSmi(src2, src2); 187983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Check that the remainder is zero. 188083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org testl(rdx, rdx); 188183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (src1.is(rax)) { 188283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label smi_result; 188383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(zero, &smi_result, Label::kNear); 188483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movq(src1, kScratchRegister); 188583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org jmp(on_not_smi_result, near_jump); 188683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org bind(&smi_result); 188783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 188883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(not_zero, on_not_smi_result, near_jump); 188983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 189083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (!dst.is(src1) && src1.is(rax)) { 189183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movq(src1, kScratchRegister); 189283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 189383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Integer32ToSmi(dst, rax); 189483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 189583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 189683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 189783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::SmiMod(Register dst, 189883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src1, 189983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src2, 190083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi_result, 190183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 190283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!dst.is(kScratchRegister)); 190383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src1.is(kScratchRegister)); 190483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src2.is(kScratchRegister)); 190583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src2.is(rax)); 190683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src2.is(rdx)); 190783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src1.is(rdx)); 190883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src1.is(src2)); 190983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 191083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org testq(src2, src2); 191183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(zero, on_not_smi_result, near_jump); 191283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 191383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (src1.is(rax)) { 191483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movq(kScratchRegister, src1); 191583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 191683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org SmiToInteger32(rax, src1); 191783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org SmiToInteger32(src2, src2); 191883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 191983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Test for the edge case of dividing Smi::kMinValue by -1 (will overflow). 192083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label safe_div; 192183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org cmpl(rax, Immediate(Smi::kMinValue)); 192283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(not_equal, &safe_div, Label::kNear); 192383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org cmpl(src2, Immediate(-1)); 192483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(not_equal, &safe_div, Label::kNear); 192583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Retag inputs and go slow case. 192683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Integer32ToSmi(src2, src2); 192783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (src1.is(rax)) { 192883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movq(src1, kScratchRegister); 192983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 193083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org jmp(on_not_smi_result, near_jump); 193183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org bind(&safe_div); 193283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 193383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Sign extend eax into edx:eax. 193483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org cdq(); 193583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org idivl(src2); 193683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Restore smi tags on inputs. 193783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Integer32ToSmi(src2, src2); 193883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (src1.is(rax)) { 193983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movq(src1, kScratchRegister); 194083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 194183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Check for a negative zero result. If the result is zero, and the 194283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // dividend is negative, go slow to return a floating point negative zero. 194383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label smi_result; 194483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org testl(rdx, rdx); 194583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(not_zero, &smi_result, Label::kNear); 194683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org testq(src1, src1); 194783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(negative, on_not_smi_result, near_jump); 194883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org bind(&smi_result); 194983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Integer32ToSmi(dst, rdx); 195083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 195183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 195283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 19534af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgvoid MacroAssembler::SmiNot(Register dst, Register src) { 19549d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com ASSERT(!dst.is(kScratchRegister)); 19559d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com ASSERT(!src.is(kScratchRegister)); 19569d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com // Set tag and padding bits before negating, so that they are zero afterwards. 19579d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com movl(kScratchRegister, Immediate(~0)); 19584af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org if (dst.is(src)) { 19599d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com xor_(dst, kScratchRegister); 19604af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } else { 19619d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com lea(dst, Operand(src, kScratchRegister, times_1, 0)); 19624af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 19639d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com not_(dst); 19644af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 19654af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 19664af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 19674af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgvoid MacroAssembler::SmiAnd(Register dst, Register src1, Register src2) { 19689d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com ASSERT(!dst.is(src2)); 19694af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org if (!dst.is(src1)) { 19709d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com movq(dst, src1); 19714af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 19724af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org and_(dst, src2); 19734af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 19744af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 19754af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 19769d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::SmiAndConstant(Register dst, Register src, Smi* constant) { 19779d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (constant->value() == 0) { 19785d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Set(dst, 0); 19799d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } else if (dst.is(src)) { 19809d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com ASSERT(!dst.is(kScratchRegister)); 198169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org Register constant_reg = GetSmiConstant(constant); 198269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org and_(dst, constant_reg); 19839d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } else { 198469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org LoadSmiConstant(dst, constant); 19859d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com and_(dst, src); 19864af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 19874af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 19884af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 19894af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 19904af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgvoid MacroAssembler::SmiOr(Register dst, Register src1, Register src2) { 19914af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org if (!dst.is(src1)) { 199244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org ASSERT(!src1.is(src2)); 19939d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com movq(dst, src1); 19944af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 19954af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org or_(dst, src2); 19964af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 19974af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 19984af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 19999d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::SmiOrConstant(Register dst, Register src, Smi* constant) { 20009d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (dst.is(src)) { 20019d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com ASSERT(!dst.is(kScratchRegister)); 200269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org Register constant_reg = GetSmiConstant(constant); 200369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org or_(dst, constant_reg); 20049d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } else { 200569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org LoadSmiConstant(dst, constant); 20069d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com or_(dst, src); 20074af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 20084af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 20094af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 20109d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com 20114af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgvoid MacroAssembler::SmiXor(Register dst, Register src1, Register src2) { 20124af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org if (!dst.is(src1)) { 201344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org ASSERT(!src1.is(src2)); 20149d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com movq(dst, src1); 20154af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 20164af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org xor_(dst, src2); 20174af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 20184af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 20194af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 20209d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::SmiXorConstant(Register dst, Register src, Smi* constant) { 20219d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (dst.is(src)) { 20229d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com ASSERT(!dst.is(kScratchRegister)); 202369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org Register constant_reg = GetSmiConstant(constant); 202469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org xor_(dst, constant_reg); 20259d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } else { 202669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org LoadSmiConstant(dst, constant); 20279d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com xor_(dst, src); 20284af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 20294af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 20304af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 20314af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 20324af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgvoid MacroAssembler::SmiShiftArithmeticRightConstant(Register dst, 20334af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src, 20344af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org int shift_value) { 20359d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com ASSERT(is_uint5(shift_value)); 20364af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org if (shift_value > 0) { 20374af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org if (dst.is(src)) { 20389d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com sar(dst, Immediate(shift_value + kSmiShift)); 20399d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com shl(dst, Immediate(kSmiShift)); 20404af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } else { 20414af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org UNIMPLEMENTED(); // Not used. 20424af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 20434af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 20444af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 20454af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 20464af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 20474af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgvoid MacroAssembler::SmiShiftLeftConstant(Register dst, 20484af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src, 2049720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org int shift_value) { 20509d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (!dst.is(src)) { 20519d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com movq(dst, src); 20529d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } 20539d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (shift_value > 0) { 20549d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com shl(dst, Immediate(shift_value)); 20554af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 20564af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 20574af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 20584af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 205983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::SmiShiftLogicalRightConstant( 206083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register dst, Register src, int shift_value, 206183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi_result, Label::Distance near_jump) { 206283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Logic right shift interprets its result as an *unsigned* number. 206383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (dst.is(src)) { 206483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org UNIMPLEMENTED(); // Not used. 206583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 206683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movq(dst, src); 206783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (shift_value == 0) { 206883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org testq(dst, dst); 206983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(negative, on_not_smi_result, near_jump); 207083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 207183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org shr(dst, Immediate(shift_value + kSmiShift)); 207283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org shl(dst, Immediate(kSmiShift)); 207383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 207483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 207583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 207683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 20774af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgvoid MacroAssembler::SmiShiftLeft(Register dst, 20784af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src1, 2079720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org Register src2) { 20804af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org ASSERT(!dst.is(rcx)); 20819d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com // Untag shift amount. 20829d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (!dst.is(src1)) { 20839d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com movq(dst, src1); 20844af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 20859d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com SmiToInteger32(rcx, src2); 20869d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com // Shift amount specified by lower 5 bits, not six as the shl opcode. 20879d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com and_(rcx, Immediate(0x1f)); 2088c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org shl_cl(dst); 20894af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 20904af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 20914af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 209283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::SmiShiftLogicalRight(Register dst, 209383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src1, 209483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src2, 209583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi_result, 209683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 209783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!dst.is(kScratchRegister)); 209883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src1.is(kScratchRegister)); 209983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src2.is(kScratchRegister)); 210083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!dst.is(rcx)); 210183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // dst and src1 can be the same, because the one case that bails out 210283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // is a shift by 0, which leaves dst, and therefore src1, unchanged. 210383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (src1.is(rcx) || src2.is(rcx)) { 210483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movq(kScratchRegister, rcx); 210583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 210683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (!dst.is(src1)) { 210783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movq(dst, src1); 210883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 210983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org SmiToInteger32(rcx, src2); 211083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org orl(rcx, Immediate(kSmiShift)); 211183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org shr_cl(dst); // Shift is rcx modulo 0x1f + 32. 211283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org shl(dst, Immediate(kSmiShift)); 211383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org testq(dst, dst); 211483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (src1.is(rcx) || src2.is(rcx)) { 211583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label positive_result; 211683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(positive, &positive_result, Label::kNear); 211783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (src1.is(rcx)) { 211883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movq(src1, kScratchRegister); 211983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 212083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movq(src2, kScratchRegister); 212183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 212283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org jmp(on_not_smi_result, near_jump); 212383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org bind(&positive_result); 212483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 212583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // src2 was zero and src1 negative. 212683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(negative, on_not_smi_result, near_jump); 212783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 212883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 212983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 213083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 21314af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgvoid MacroAssembler::SmiShiftArithmeticRight(Register dst, 21324af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src1, 21334af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src2) { 21349d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com ASSERT(!dst.is(kScratchRegister)); 21359d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com ASSERT(!src1.is(kScratchRegister)); 21369d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com ASSERT(!src2.is(kScratchRegister)); 21374af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org ASSERT(!dst.is(rcx)); 21389d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (src1.is(rcx)) { 21399d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com movq(kScratchRegister, src1); 21409d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } else if (src2.is(rcx)) { 21419d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com movq(kScratchRegister, src2); 21429d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } 21439d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (!dst.is(src1)) { 21449d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com movq(dst, src1); 21459d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } 21464af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org SmiToInteger32(rcx, src2); 21479d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com orl(rcx, Immediate(kSmiShift)); 2148c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org sar_cl(dst); // Shift 32 + original rcx & 0x1f. 21499d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com shl(dst, Immediate(kSmiShift)); 21509d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (src1.is(rcx)) { 21519d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com movq(src1, kScratchRegister); 21529d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } else if (src2.is(rcx)) { 21539d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com movq(src2, kScratchRegister); 21549d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } 21554af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 21564af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 21574af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 215883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::SelectNonSmi(Register dst, 215983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src1, 216083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src2, 216183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smis, 216283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 216383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!dst.is(kScratchRegister)); 216483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src1.is(kScratchRegister)); 216583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src2.is(kScratchRegister)); 216683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!dst.is(src1)); 216783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!dst.is(src2)); 216883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Both operands must not be smis. 216983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org#ifdef DEBUG 21708a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org Condition not_both_smis = NegateCondition(CheckBothSmi(src1, src2)); 21718a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org Check(not_both_smis, kBothRegistersWereSmisInSelectNonSmi); 217283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org#endif 217380c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org STATIC_ASSERT(kSmiTag == 0); 217483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT_EQ(0, Smi::FromInt(0)); 217583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movl(kScratchRegister, Immediate(kSmiTagMask)); 217683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org and_(kScratchRegister, src1); 217783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org testl(kScratchRegister, src2); 217883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // If non-zero then both are smis. 217983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(not_zero, on_not_smis, near_jump); 218083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 218183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Exactly one operand is a smi. 218283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT_EQ(1, static_cast<int>(kSmiTagMask)); 218383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // kScratchRegister still holds src1 & kSmiTag, which is either zero or one. 218483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org subq(kScratchRegister, Immediate(1)); 218583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // If src1 is a smi, then scratch register all 1s, else it is all 0s. 218683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movq(dst, src1); 218783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org xor_(dst, src2); 218883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org and_(dst, kScratchRegister); 218983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // If src1 is a smi, dst holds src1 ^ src2, else it is zero. 219083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org xor_(dst, src1); 219183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // If src1 is a smi, dst is src2, else it is src1, i.e., the non-smi. 219283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 219383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 219483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 21959d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comSmiIndex MacroAssembler::SmiToIndex(Register dst, 21969d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com Register src, 21979d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com int shift) { 21984af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org ASSERT(is_uint6(shift)); 21999d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com // There is a possible optimization if shift is in the range 60-63, but that 22009d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com // will (and must) never happen. 22019d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (!dst.is(src)) { 22029d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com movq(dst, src); 22039d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } 22049d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (shift < kSmiShift) { 22059d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com sar(dst, Immediate(kSmiShift - shift)); 22069d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } else { 22079d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com shl(dst, Immediate(shift - kSmiShift)); 22089d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } 22094af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org return SmiIndex(dst, times_1); 22104af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 22114af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 22124af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgSmiIndex MacroAssembler::SmiToNegativeIndex(Register dst, 22134af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src, 22144af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org int shift) { 22154af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Register src holds a positive smi. 22164af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org ASSERT(is_uint6(shift)); 22179d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (!dst.is(src)) { 22189d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com movq(dst, src); 22194af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 22204af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org neg(dst); 22219d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (shift < kSmiShift) { 22229d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com sar(dst, Immediate(kSmiShift - shift)); 22239d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } else { 22249d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com shl(dst, Immediate(shift - kSmiShift)); 22259d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } 22264af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org return SmiIndex(dst, times_1); 22274af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 22284af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 22294af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 22307979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.orgvoid MacroAssembler::AddSmiField(Register dst, const Operand& src) { 22317979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org ASSERT_EQ(0, kSmiShift % kBitsPerByte); 22327979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org addl(dst, Operand(src, kSmiShift / kBitsPerByte)); 22337979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org} 22347979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 22357979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 2236dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgvoid MacroAssembler::Push(Smi* source) { 2237dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org intptr_t smi = reinterpret_cast<intptr_t>(source); 2238dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org if (is_int32(smi)) { 2239dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org push(Immediate(static_cast<int32_t>(smi))); 2240dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org } else { 2241dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org Register constant = GetSmiConstant(source); 2242dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org push(constant); 2243dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org } 2244dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org} 2245dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org 2246dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org 2247662436e7b124b3535773535c671c53db322070b5verwaest@chromium.orgvoid MacroAssembler::PushInt64AsTwoSmis(Register src, Register scratch) { 2248662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org movq(scratch, src); 2249662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org // High bits. 2250662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org shr(src, Immediate(64 - kSmiShift)); 2251662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org shl(src, Immediate(kSmiShift)); 2252662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org push(src); 2253662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org // Low bits. 2254662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org shl(scratch, Immediate(kSmiShift)); 2255662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org push(scratch); 2256662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org} 2257662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org 2258662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org 2259662436e7b124b3535773535c671c53db322070b5verwaest@chromium.orgvoid MacroAssembler::PopInt64AsTwoSmis(Register dst, Register scratch) { 2260662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org pop(scratch); 2261662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org // Low bits. 2262662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org shr(scratch, Immediate(kSmiShift)); 2263662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org pop(dst); 2264662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org shr(dst, Immediate(kSmiShift)); 2265662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org // High bits. 2266662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org shl(dst, Immediate(64 - kSmiShift)); 2267662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org or_(dst, scratch); 2268662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org} 2269662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org 2270662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org 2271dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgvoid MacroAssembler::Test(const Operand& src, Smi* source) { 2272dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org testl(Operand(src, kIntSize), Immediate(source->value())); 2273dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org} 2274dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org 2275dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org 2276dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org// ---------------------------------------------------------------------------- 2277dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org 2278dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org 2279528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid MacroAssembler::LookupNumberStringCache(Register object, 2280528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register result, 2281528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register scratch1, 2282528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register scratch2, 2283528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Label* not_found) { 2284528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Use of registers. Register result is used as a temporary. 2285528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register number_string_cache = result; 2286528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register mask = scratch1; 2287528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register scratch = scratch2; 2288528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 2289528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Load the number string cache. 2290528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex); 2291528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 2292528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Make the hash mask from the length of the number string cache. It 2293528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // contains two elements (number and string) for each cache entry. 2294528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org SmiToInteger32( 2295528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset)); 2296528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org shrl(mask, Immediate(1)); 2297528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org subq(mask, Immediate(1)); // Make mask. 2298528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 2299528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Calculate the entry in the number string cache. The hash value in the 2300528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // number string cache for smis is just the smi value, and the hash for 2301528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // doubles is the xor of the upper and lower words. See 2302528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Heap::GetNumberStringCache. 2303528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Label is_smi; 2304528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Label load_result_from_cache; 2305528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org JumpIfSmi(object, &is_smi); 2306528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org CheckMap(object, 2307528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org isolate()->factory()->heap_number_map(), 2308528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org not_found, 2309528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org DONT_DO_SMI_CHECK); 2310528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 2311528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org STATIC_ASSERT(8 == kDoubleSize); 2312528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org movl(scratch, FieldOperand(object, HeapNumber::kValueOffset + 4)); 2313528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org xor_(scratch, FieldOperand(object, HeapNumber::kValueOffset)); 2314528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org and_(scratch, mask); 2315528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Each entry in string cache consists of two pointer sized fields, 2316528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // but times_twice_pointer_size (multiplication by 16) scale factor 2317528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // is not supported by addrmode on x64 platform. 2318528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // So we have to premultiply entry index before lookup. 2319528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org shl(scratch, Immediate(kPointerSizeLog2 + 1)); 2320528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 2321528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register index = scratch; 2322528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register probe = mask; 2323528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org movq(probe, 2324528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org FieldOperand(number_string_cache, 2325528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org index, 2326528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org times_1, 2327528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org FixedArray::kHeaderSize)); 2328528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org JumpIfSmi(probe, not_found); 2329528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org movsd(xmm0, FieldOperand(object, HeapNumber::kValueOffset)); 2330528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org ucomisd(xmm0, FieldOperand(probe, HeapNumber::kValueOffset)); 2331528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org j(parity_even, not_found); // Bail out if NaN is involved. 2332528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org j(not_equal, not_found); // The cache did not contain this value. 2333528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org jmp(&load_result_from_cache); 2334528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 2335528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org bind(&is_smi); 2336528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org SmiToInteger32(scratch, object); 2337528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org and_(scratch, mask); 2338528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Each entry in string cache consists of two pointer sized fields, 2339528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // but times_twice_pointer_size (multiplication by 16) scale factor 2340528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // is not supported by addrmode on x64 platform. 2341528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // So we have to premultiply entry index before lookup. 2342528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org shl(scratch, Immediate(kPointerSizeLog2 + 1)); 2343528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 2344528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Check if the entry is the smi we are looking for. 2345528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org cmpq(object, 2346528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org FieldOperand(number_string_cache, 2347528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org index, 2348528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org times_1, 2349528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org FixedArray::kHeaderSize)); 2350528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org j(not_equal, not_found); 2351528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 2352528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Get the result from the cache. 2353528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org bind(&load_result_from_cache); 2354528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org movq(result, 2355528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org FieldOperand(number_string_cache, 2356528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org index, 2357528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org times_1, 2358528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org FixedArray::kHeaderSize + kPointerSize)); 2359528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org IncrementCounter(isolate()->counters()->number_to_string_native(), 1); 2360528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org} 2361528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 2362528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 236383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::JumpIfNotString(Register object, 236483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register object_map, 236583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* not_string, 236683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 236783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Condition is_smi = CheckSmi(object); 236883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(is_smi, not_string, near_jump); 236983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org CmpObjectType(object, FIRST_NONSTRING_TYPE, object_map); 237083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(above_equal, not_string, near_jump); 237183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 237283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 237383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 237483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::JumpIfNotBothSequentialAsciiStrings( 237583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register first_object, 237683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register second_object, 237783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register scratch1, 237883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register scratch2, 237983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_fail, 238083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 238183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Check that both objects are not smis. 238283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Condition either_smi = CheckEitherSmi(first_object, second_object); 238383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(either_smi, on_fail, near_jump); 238483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 238583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Load instance type for both strings. 238683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movq(scratch1, FieldOperand(first_object, HeapObject::kMapOffset)); 238783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movq(scratch2, FieldOperand(second_object, HeapObject::kMapOffset)); 238883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movzxbl(scratch1, FieldOperand(scratch1, Map::kInstanceTypeOffset)); 238983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movzxbl(scratch2, FieldOperand(scratch2, Map::kInstanceTypeOffset)); 239083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 23912efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // Check that both are flat ASCII strings. 239283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(kNotStringTag != 0); 239383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org const int kFlatAsciiStringMask = 239446a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask; 2395c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org const int kFlatAsciiStringTag = 2396c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org kStringTag | kOneByteStringTag | kSeqStringTag; 239783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 239883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org andl(scratch1, Immediate(kFlatAsciiStringMask)); 239983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org andl(scratch2, Immediate(kFlatAsciiStringMask)); 240083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Interleave the bits to check both scratch1 and scratch2 in one test. 240146a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org ASSERT_EQ(0, kFlatAsciiStringMask & (kFlatAsciiStringMask << 3)); 240246a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org lea(scratch1, Operand(scratch1, scratch2, times_8, 0)); 240383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org cmpl(scratch1, 240446a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org Immediate(kFlatAsciiStringTag + (kFlatAsciiStringTag << 3))); 240583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(not_equal, on_fail, near_jump); 240683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 240783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 240883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 240983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::JumpIfInstanceTypeIsNotSequentialAscii( 241083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register instance_type, 241183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register scratch, 241283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* failure, 241383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 241483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (!scratch.is(instance_type)) { 241583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movl(scratch, instance_type); 241683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 241783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 241883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org const int kFlatAsciiStringMask = 241983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask; 242083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 242183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org andl(scratch, Immediate(kFlatAsciiStringMask)); 2422e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org cmpl(scratch, Immediate(kStringTag | kSeqStringTag | kOneByteStringTag)); 242383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(not_equal, failure, near_jump); 242483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 242583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 242683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 242783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialAscii( 242883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register first_object_instance_type, 242983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register second_object_instance_type, 243083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register scratch1, 243183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register scratch2, 243283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_fail, 243383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 243483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Load instance type for both strings. 243583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movq(scratch1, first_object_instance_type); 243683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movq(scratch2, second_object_instance_type); 243783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 24382efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // Check that both are flat ASCII strings. 243983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(kNotStringTag != 0); 244046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org const int kFlatAsciiStringMask = 244146a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask; 2442c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org const int kFlatAsciiStringTag = 2443c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org kStringTag | kOneByteStringTag | kSeqStringTag; 244483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 244583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org andl(scratch1, Immediate(kFlatAsciiStringMask)); 244683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org andl(scratch2, Immediate(kFlatAsciiStringMask)); 244783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Interleave the bits to check both scratch1 and scratch2 in one test. 244846a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org ASSERT_EQ(0, kFlatAsciiStringMask & (kFlatAsciiStringMask << 3)); 244946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org lea(scratch1, Operand(scratch1, scratch2, times_8, 0)); 245083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org cmpl(scratch1, 245146a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org Immediate(kFlatAsciiStringTag + (kFlatAsciiStringTag << 3))); 245283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(not_equal, on_fail, near_jump); 245383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 245483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 245583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 24561510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgtemplate<class T> 24571510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgstatic void JumpIfNotUniqueNameHelper(MacroAssembler* masm, 24581510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org T operand_or_register, 24591510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Label* not_unique_name, 24601510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Label::Distance distance) { 2461ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0); 2462ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Label succeed; 2463ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org masm->testb(operand_or_register, 2464ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Immediate(kIsNotStringMask | kIsNotInternalizedMask)); 2465ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org masm->j(zero, &succeed, Label::kNear); 2466ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org masm->cmpb(operand_or_register, Immediate(static_cast<uint8_t>(SYMBOL_TYPE))); 2467ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org masm->j(not_equal, not_unique_name, distance); 2468ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 2469ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org masm->bind(&succeed); 24701510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org} 24711510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 24721510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 24731510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid MacroAssembler::JumpIfNotUniqueName(Operand operand, 24741510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Label* not_unique_name, 24751510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Label::Distance distance) { 24761510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org JumpIfNotUniqueNameHelper<Operand>(this, operand, not_unique_name, distance); 24771510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org} 24781510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 24791510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 24801510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid MacroAssembler::JumpIfNotUniqueName(Register reg, 24811510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Label* not_unique_name, 24821510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Label::Distance distance) { 24831510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org JumpIfNotUniqueNameHelper<Register>(this, reg, not_unique_name, distance); 24841510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org} 24851510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 24867979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 24874a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.orgvoid MacroAssembler::Move(Register dst, Register src) { 24884a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org if (!dst.is(src)) { 24894a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org movq(dst, src); 24904a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org } 24914a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org} 24924a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 24934a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 24945aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.orgvoid MacroAssembler::Move(Register dst, Handle<Object> source) { 249579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org AllowDeferredHandleDereference smi_check; 24965aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org if (source->IsSmi()) { 24979d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com Move(dst, Smi::cast(*source)); 24985aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org } else { 2499c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org MoveHeapObject(dst, source); 25005aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org } 25015aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org} 25025aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 25035aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 25045aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.orgvoid MacroAssembler::Move(const Operand& dst, Handle<Object> source) { 250579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org AllowDeferredHandleDereference smi_check; 250668ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org if (source->IsSmi()) { 25079d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com Move(dst, Smi::cast(*source)); 250868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } else { 2509c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org MoveHeapObject(kScratchRegister, source); 251068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org movq(dst, kScratchRegister); 251168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 25125aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org} 25135aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 25145aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 25155aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.orgvoid MacroAssembler::Cmp(Register dst, Handle<Object> source) { 251679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org AllowDeferredHandleDereference smi_check; 25179d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (source->IsSmi()) { 2518badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org Cmp(dst, Smi::cast(*source)); 25199d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } else { 2520c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org MoveHeapObject(kScratchRegister, source); 25219d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com cmpq(dst, kScratchRegister); 25229d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } 25235aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org} 25245aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 25255aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 25263e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgvoid MacroAssembler::Cmp(const Operand& dst, Handle<Object> source) { 252779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org AllowDeferredHandleDereference smi_check; 252868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org if (source->IsSmi()) { 2529badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org Cmp(dst, Smi::cast(*source)); 253068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } else { 2531c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org MoveHeapObject(kScratchRegister, source); 253268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org cmpq(dst, kScratchRegister); 253368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 25343e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org} 25353e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 25363e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 25375aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.orgvoid MacroAssembler::Push(Handle<Object> source) { 253879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org AllowDeferredHandleDereference smi_check; 253968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org if (source->IsSmi()) { 25409d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com Push(Smi::cast(*source)); 254168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } else { 2542c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org MoveHeapObject(kScratchRegister, source); 254368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org push(kScratchRegister); 254468ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 25455aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org} 25465aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 25475aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 2548c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.orgvoid MacroAssembler::MoveHeapObject(Register result, 2549c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org Handle<Object> object) { 255079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org AllowDeferredHandleDereference using_raw_address; 2551c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org ASSERT(object->IsHeapObject()); 255264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (isolate()->heap()->InNewSpace(*object)) { 255341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Handle<Cell> cell = isolate()->factory()->NewCell(object); 255441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org movq(result, cell, RelocInfo::CELL); 255564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org movq(result, Operand(result, 0)); 255664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else { 2557c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org movq(result, object, RelocInfo::EMBEDDED_OBJECT); 255864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 255964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org} 256064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 256164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 256241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgvoid MacroAssembler::LoadGlobalCell(Register dst, Handle<Cell> cell) { 256364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (dst.is(rax)) { 256479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org AllowDeferredHandleDereference embedding_raw_address; 256541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org load_rax(cell.location(), RelocInfo::CELL); 256664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else { 256741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org movq(dst, cell, RelocInfo::CELL); 256864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org movq(dst, Operand(dst, 0)); 256964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 257064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org} 257164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 257264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 257313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid MacroAssembler::Drop(int stack_elements) { 257413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org if (stack_elements > 0) { 257513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org addq(rsp, Immediate(stack_elements * kPointerSize)); 257613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org } 257713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org} 257813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 257913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 2580394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comvoid MacroAssembler::TestBit(const Operand& src, int bits) { 2581394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com int byte_offset = bits / kBitsPerByte; 2582394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com int bit_in_byte = bits & (kBitsPerByte - 1); 2583394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com testb(Operand(src, byte_offset), Immediate(1 << bit_in_byte)); 2584394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com} 2585394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 2586394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 2587eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::Jump(ExternalReference ext) { 2588ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org LoadAddress(kScratchRegister, ext); 2589eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org jmp(kScratchRegister); 2590eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 2591eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 2592eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 2593eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::Jump(Address destination, RelocInfo::Mode rmode) { 2594eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org movq(kScratchRegister, destination, rmode); 2595eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org jmp(kScratchRegister); 2596eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 2597eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 2598eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 25995aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.orgvoid MacroAssembler::Jump(Handle<Code> code_object, RelocInfo::Mode rmode) { 2600c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // TODO(X64): Inline this 2601c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org jmp(code_object, rmode); 26025aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org} 26035aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 26045aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 2605ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgint MacroAssembler::CallSize(ExternalReference ext) { 2606ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Opcode for call kScratchRegister is: Rex.B FF D4 (three bytes). 2607594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return LoadAddressSize(ext) + 2608594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Assembler::kCallScratchRegisterInstructionLength; 2609ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org} 2610ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 2611ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 2612eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::Call(ExternalReference ext) { 2613eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org#ifdef DEBUG 2614ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org int end_position = pc_offset() + CallSize(ext); 2615eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org#endif 2616ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org LoadAddress(kScratchRegister, ext); 2617eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org call(kScratchRegister); 2618eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org#ifdef DEBUG 2619ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org CHECK_EQ(end_position, pc_offset()); 2620eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org#endif 2621eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 2622eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 2623eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 2624eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::Call(Address destination, RelocInfo::Mode rmode) { 2625eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org#ifdef DEBUG 2626ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org int end_position = pc_offset() + CallSize(destination, rmode); 2627eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org#endif 2628eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org movq(kScratchRegister, destination, rmode); 2629eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org call(kScratchRegister); 2630eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org#ifdef DEBUG 2631ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org CHECK_EQ(pc_offset(), end_position); 2632eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org#endif 2633eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 2634eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 2635eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 26368e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.orgvoid MacroAssembler::Call(Handle<Code> code_object, 26378e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org RelocInfo::Mode rmode, 2638471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org TypeFeedbackId ast_id) { 2639eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org#ifdef DEBUG 2640ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org int end_position = pc_offset() + CallSize(code_object); 2641eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org#endif 2642c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org ASSERT(RelocInfo::IsCodeTarget(rmode) || 2643c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org rmode == RelocInfo::CODE_AGE_SEQUENCE); 26448e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org call(code_object, rmode, ast_id); 2645eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org#ifdef DEBUG 2646ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org CHECK_EQ(end_position, pc_offset()); 2647eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org#endif 26485aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org} 26495aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 26505aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 26510a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.orgvoid MacroAssembler::Pushad() { 26520a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org push(rax); 26530a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org push(rcx); 26540a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org push(rdx); 26550a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org push(rbx); 26560a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // Not pushing rsp or rbp. 26570a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org push(rsi); 26580a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org push(rdi); 26590a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org push(r8); 26600a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org push(r9); 26610a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // r10 is kScratchRegister. 26620a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org push(r11); 2663b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org // r12 is kSmiConstantRegister. 26640a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // r13 is kRootRegister. 26650a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org push(r14); 2666b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org push(r15); 266749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org STATIC_ASSERT(11 == kNumSafepointSavedRegisters); 266849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // Use lea for symmetry with Popad. 26693a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org int sp_delta = 26703a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org (kNumSafepointRegisters - kNumSafepointSavedRegisters) * kPointerSize; 26713a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org lea(rsp, Operand(rsp, -sp_delta)); 26720a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org} 26730a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 26740a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 26750a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.orgvoid MacroAssembler::Popad() { 267649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // Popad must not change the flags, so use lea instead of addq. 26773a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org int sp_delta = 26783a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org (kNumSafepointRegisters - kNumSafepointSavedRegisters) * kPointerSize; 26793a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org lea(rsp, Operand(rsp, sp_delta)); 2680b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org pop(r15); 26810a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org pop(r14); 26820a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org pop(r11); 26830a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org pop(r9); 26840a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org pop(r8); 26850a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org pop(rdi); 26860a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org pop(rsi); 26870a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org pop(rbx); 26880a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org pop(rdx); 26890a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org pop(rcx); 26900a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org pop(rax); 26910a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org} 26920a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 26930a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 26940ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.orgvoid MacroAssembler::Dropad() { 269549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org addq(rsp, Immediate(kNumSafepointRegisters * kPointerSize)); 26960ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org} 26970ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 26980ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 26990ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org// Order general registers are pushed by Pushad: 2700b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org// rax, rcx, rdx, rbx, rsi, rdi, r8, r9, r11, r14, r15. 27011456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst int 27021456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgMacroAssembler::kSafepointPushRegisterIndices[Register::kNumRegisters] = { 27030ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 0, 27040ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 1, 27050ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 2, 27060ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 3, 27070ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org -1, 27080ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org -1, 27090ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 4, 27100ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 5, 27110ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 6, 27120ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 7, 27130ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org -1, 27140ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 8, 27150ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org -1, 2716b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org -1, 2717b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 9, 2718b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 10 27190ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org}; 27200ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 27210ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 272246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgvoid MacroAssembler::StoreToSafepointRegisterSlot(Register dst, 272346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org const Immediate& imm) { 272446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org movq(SafepointRegisterSlot(dst), imm); 272546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org} 272646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 272746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 27283a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid MacroAssembler::StoreToSafepointRegisterSlot(Register dst, Register src) { 27293a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org movq(SafepointRegisterSlot(dst), src); 27303a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 27313a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 27323a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 27335d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.orgvoid MacroAssembler::LoadFromSafepointRegisterSlot(Register dst, Register src) { 27345d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org movq(dst, SafepointRegisterSlot(src)); 27355d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org} 27365d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org 27375d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org 27383a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgOperand MacroAssembler::SafepointRegisterSlot(Register reg) { 27393a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org return Operand(rsp, SafepointRegisterStackIndex(reg.code()) * kPointerSize); 27403a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 27413a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 27423a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 274378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.orgvoid MacroAssembler::PushTryHandler(StackHandler::Kind kind, 274404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org int handler_index) { 2745eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // Adjust this code if not the case. 2746d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize + 2747d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org kFPOnStackSize); 274804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); 274904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kCodeOffset == 1 * kPointerSize); 275004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kStateOffset == 2 * kPointerSize); 275104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kContextOffset == 3 * kPointerSize); 275204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize); 275304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 275404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // We will build up the handler from the bottom by pushing on the stack. 275578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // First push the frame pointer and context. 275678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org if (kind == StackHandler::JS_ENTRY) { 275704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // The frame pointer does not point to a JS frame so we save NULL for 275804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // rbp. We expect the code throwing an exception to check rbp before 275904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // dereferencing it to restore the context. 2760eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org push(Immediate(0)); // NULL frame pointer. 27614acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org Push(Smi::FromInt(0)); // No context. 276278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org } else { 276378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org push(rbp); 276478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org push(rsi); 2765e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org } 276604e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 276704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Push the state and the code object. 276878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org unsigned state = 276978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org StackHandler::IndexField::encode(handler_index) | 277078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org StackHandler::KindField::encode(kind); 277104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org push(Immediate(state)); 277204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org Push(CodeObject()); 277304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 277404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Link the current handler as the next handler. 277504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); 277604e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org push(ExternalOperand(handler_address)); 277704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Set this new handler as the current one. 277804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org movq(ExternalOperand(handler_address), rsp); 2779e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org} 2780e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 2781e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 278213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid MacroAssembler::PopTryHandler() { 278304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); 278404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); 278504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org pop(ExternalOperand(handler_address)); 278613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org addq(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize)); 278713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org} 278813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 278913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 279004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.orgvoid MacroAssembler::JumpToHandlerEntry() { 279104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Compute the handler entry address and jump to it. The handler table is 279204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // a fixed array of (smi-tagged) code offsets. 279304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // rax = exception, rdi = code object, rdx = state. 279404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org movq(rbx, FieldOperand(rdi, Code::kHandlerTableOffset)); 279504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org shr(rdx, Immediate(StackHandler::kKindWidth)); 27961510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org movq(rdx, 27971510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org FieldOperand(rbx, rdx, times_pointer_size, FixedArray::kHeaderSize)); 279804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org SmiToInteger64(rdx, rdx); 279904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org lea(rdi, FieldOperand(rdi, rdx, times_1, Code::kHeaderSize)); 280004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org jmp(rdi); 280104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org} 280204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 280304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 280449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.orgvoid MacroAssembler::Throw(Register value) { 28054acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org // Adjust this code if not the case. 2806d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize + 2807d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org kFPOnStackSize); 280804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); 280904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kCodeOffset == 1 * kPointerSize); 281004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kStateOffset == 2 * kPointerSize); 281104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kContextOffset == 3 * kPointerSize); 281204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize); 281304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 281404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // The exception is expected in rax. 281549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org if (!value.is(rax)) { 281649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org movq(rax, value); 281749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org } 281804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Drop the stack pointer to the top of the top handler. 281983e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); 282004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org movq(rsp, ExternalOperand(handler_address)); 282104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Restore the next handler. 282204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org pop(ExternalOperand(handler_address)); 282304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 282404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Remove the code object and state, compute the handler address in rdi. 282504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org pop(rdi); // Code object. 282604e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org pop(rdx); // Offset and state. 282704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 282804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Restore the context and frame pointer. 28294acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org pop(rsi); // Context. 28304acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org pop(rbp); // Frame pointer. 283149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 28324acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org // If the handler is a JS frame, restore the context to the frame. 283304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // (kind == ENTRY) == (rbp == 0) == (rsi == 0), so we could test either 283404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // rbp or rsi. 283583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label skip; 283604e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org testq(rsi, rsi); 283704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org j(zero, &skip, Label::kNear); 28384acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org movq(Operand(rbp, StandardFrameConstants::kContextOffset), rsi); 283949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org bind(&skip); 28404acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org 284104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org JumpToHandlerEntry(); 284249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org} 284349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 284449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 284565a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.orgvoid MacroAssembler::ThrowUncatchable(Register value) { 28464acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org // Adjust this code if not the case. 2847d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize + 2848d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org kFPOnStackSize); 284904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); 285004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kCodeOffset == 1 * kPointerSize); 285104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kStateOffset == 2 * kPointerSize); 285204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kContextOffset == 3 * kPointerSize); 285304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize); 285449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 2855c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // The exception is expected in rax. 285665a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org if (!value.is(rax)) { 2857c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org movq(rax, value); 285849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org } 2859c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // Drop the stack pointer to the top of the top stack handler. 2860c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); 2861c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org Load(rsp, handler_address); 286249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 2863c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // Unwind the handlers until the top ENTRY handler is found. 2864c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org Label fetch_next, check_kind; 2865c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org jmp(&check_kind, Label::kNear); 2866c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org bind(&fetch_next); 2867c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org movq(rsp, Operand(rsp, StackHandlerConstants::kNextOffset)); 2868c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org 2869c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org bind(&check_kind); 287078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org STATIC_ASSERT(StackHandler::JS_ENTRY == 0); 287104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org testl(Operand(rsp, StackHandlerConstants::kStateOffset), 287204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org Immediate(StackHandler::KindField::kMask)); 287304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org j(not_zero, &fetch_next); 2874c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org 2875c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // Set the top handler address to next handler past the top ENTRY handler. 2876c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org pop(ExternalOperand(handler_address)); 2877c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org 287804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Remove the code object and state, compute the handler address in rdi. 287904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org pop(rdi); // Code object. 288004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org pop(rdx); // Offset and state. 288104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 288204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Clear the context pointer and frame pointer (0 was saved in the handler). 2883c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org pop(rsi); 2884c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org pop(rbp); 288549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 288604e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org JumpToHandlerEntry(); 288749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org} 288849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 288949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 2890eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::Ret() { 2891eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org ret(0); 2892eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 2893eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 2894eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 2895d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.comvoid MacroAssembler::Ret(int bytes_dropped, Register scratch) { 2896d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com if (is_uint16(bytes_dropped)) { 2897d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com ret(bytes_dropped); 2898d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } else { 2899594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org PopReturnAddressTo(scratch); 2900d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com addq(rsp, Immediate(bytes_dropped)); 2901594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org PushReturnAddressFrom(scratch); 2902d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com ret(0); 2903d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 2904d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com} 2905d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 2906d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 29073e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgvoid MacroAssembler::FCmp() { 29083811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org fucomip(); 290940b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org fstp(0); 29103e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org} 29113e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 29123e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 2913eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::CmpObjectType(Register heap_object, 2914eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org InstanceType type, 2915eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org Register map) { 2916eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org movq(map, FieldOperand(heap_object, HeapObject::kMapOffset)); 2917eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org CmpInstanceType(map, type); 2918eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 2919eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 2920eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 2921eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::CmpInstanceType(Register map, InstanceType type) { 2922eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org cmpb(FieldOperand(map, Map::kInstanceTypeOffset), 2923eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org Immediate(static_cast<int8_t>(type))); 2924eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 2925eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 2926eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 2927d6076d96a1411932548838e5960b594564264010erik.corry@gmail.comvoid MacroAssembler::CheckFastElements(Register map, 2928d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com Label* fail, 2929d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com Label::Distance distance) { 2930830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); 2931830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); 2932830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_ELEMENTS == 2); 2933830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); 2934c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmpb(FieldOperand(map, Map::kBitField2Offset), 2935830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Immediate(Map::kMaximumBitField2FastHoleyElementValue)); 2936c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(above, fail, distance); 2937c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 2938c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2939c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2940c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::CheckFastObjectElements(Register map, 2941c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* fail, 2942c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance distance) { 2943830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); 2944830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); 2945830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_ELEMENTS == 2); 2946830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); 2947c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmpb(FieldOperand(map, Map::kBitField2Offset), 2948830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Immediate(Map::kMaximumBitField2FastHoleySmiElementValue)); 2949c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(below_equal, fail, distance); 2950d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com cmpb(FieldOperand(map, Map::kBitField2Offset), 2951830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Immediate(Map::kMaximumBitField2FastHoleyElementValue)); 2952d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com j(above, fail, distance); 2953d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com} 2954d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com 2955d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com 2956830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.orgvoid MacroAssembler::CheckFastSmiElements(Register map, 2957830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Label* fail, 2958830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Label::Distance distance) { 2959830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); 2960830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); 2961c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmpb(FieldOperand(map, Map::kBitField2Offset), 2962830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Immediate(Map::kMaximumBitField2FastHoleySmiElementValue)); 2963c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(above, fail, distance); 2964c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 2965c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2966c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2967c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::StoreNumberToDoubleElements( 2968c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register maybe_number, 2969c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register elements, 2970394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register index, 2971c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com XMMRegister xmm_scratch, 2972fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org Label* fail, 2973fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org int elements_offset) { 2974c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label smi_value, is_nan, maybe_nan, not_nan, have_double_value, done; 2975c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2976c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com JumpIfSmi(maybe_number, &smi_value, Label::kNear); 2977c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2978c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CheckMap(maybe_number, 2979c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com isolate()->factory()->heap_number_map(), 2980c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com fail, 2981c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com DONT_DO_SMI_CHECK); 2982c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2983c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Double value, canonicalize NaN. 2984c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com uint32_t offset = HeapNumber::kValueOffset + sizeof(kHoleNanLower32); 2985c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmpl(FieldOperand(maybe_number, offset), 2986c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Immediate(kNaNOrInfinityLowerBoundUpper32)); 2987c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(greater_equal, &maybe_nan, Label::kNear); 2988c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2989c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(¬_nan); 2990c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com movsd(xmm_scratch, FieldOperand(maybe_number, HeapNumber::kValueOffset)); 2991c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&have_double_value); 2992fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org movsd(FieldOperand(elements, index, times_8, 2993fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org FixedDoubleArray::kHeaderSize - elements_offset), 2994c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com xmm_scratch); 2995c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com jmp(&done); 2996c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 2997c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&maybe_nan); 2998c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Could be NaN or Infinity. If fraction is not zero, it's NaN, otherwise 2999c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // it's an Infinity, and the non-NaN code path applies. 3000c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(greater, &is_nan, Label::kNear); 3001c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmpl(FieldOperand(maybe_number, HeapNumber::kValueOffset), Immediate(0)); 3002c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(zero, ¬_nan); 3003c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&is_nan); 3004c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Convert all NaNs to the same canonical NaN value when they are stored in 3005c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // the double array. 3006c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Set(kScratchRegister, BitCast<uint64_t>( 3007c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FixedDoubleArray::canonical_not_the_hole_nan_as_double())); 3008c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com movq(xmm_scratch, kScratchRegister); 3009c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com jmp(&have_double_value, Label::kNear); 3010c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3011c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&smi_value); 3012c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Value is a smi. convert to a double and store. 3013c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Preserve original value. 3014c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SmiToInteger32(kScratchRegister, maybe_number); 3015528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Cvtlsi2sd(xmm_scratch, kScratchRegister); 3016fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org movsd(FieldOperand(elements, index, times_8, 3017fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org FixedDoubleArray::kHeaderSize - elements_offset), 3018c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com xmm_scratch); 3019c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&done); 3020c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 3021c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3022c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3023935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.orgvoid MacroAssembler::CompareMap(Register obj, Handle<Map> map) { 3024f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com Cmp(FieldOperand(obj, HeapObject::kMapOffset), map); 3025f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com} 3026f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 3027f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 30285c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid MacroAssembler::CheckMap(Register obj, 30295c838251403b0be9a882540f1922577abba4c872ager@chromium.org Handle<Map> map, 30305c838251403b0be9a882540f1922577abba4c872ager@chromium.org Label* fail, 3031a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org SmiCheckType smi_check_type) { 3032c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (smi_check_type == DO_SMI_CHECK) { 30335c838251403b0be9a882540f1922577abba4c872ager@chromium.org JumpIfSmi(obj, fail); 30345c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 3035f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 3036935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org CompareMap(obj, map); 30375c838251403b0be9a882540f1922577abba4c872ager@chromium.org j(not_equal, fail); 30385c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 30395c838251403b0be9a882540f1922577abba4c872ager@chromium.org 30405c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3041c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.orgvoid MacroAssembler::ClampUint8(Register reg) { 3042c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label done; 3043c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org testl(reg, Immediate(0xFFFFFF00)); 3044c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org j(zero, &done, Label::kNear); 3045c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org setcc(negative, reg); // 1 if negative, 0 if positive. 3046c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org decb(reg); // 0 if negative, 255 if positive. 3047c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org bind(&done); 3048c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org} 3049c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 3050c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 3051c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.orgvoid MacroAssembler::ClampDoubleToUint8(XMMRegister input_reg, 3052c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org XMMRegister temp_xmm_reg, 305389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org Register result_reg) { 3054c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label done; 305589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org Label conv_failure; 3056c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org xorps(temp_xmm_reg, temp_xmm_reg); 305746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org cvtsd2si(result_reg, input_reg); 3058c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org testl(result_reg, Immediate(0xFFFFFF00)); 3059c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org j(zero, &done, Label::kNear); 306089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org cmpl(result_reg, Immediate(0x80000000)); 306189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org j(equal, &conv_failure, Label::kNear); 306289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org movl(result_reg, Immediate(0)); 306389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org setcc(above, result_reg); 306489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org subl(result_reg, Immediate(1)); 306589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org andl(result_reg, Immediate(255)); 306689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org jmp(&done, Label::kNear); 306789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org bind(&conv_failure); 306889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org Set(result_reg, 0); 306989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org ucomisd(input_reg, temp_xmm_reg); 307089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org j(below, &done, Label::kNear); 3071c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Set(result_reg, 255); 3072c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org bind(&done); 3073c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org} 3074c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 3075c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 307646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgvoid MacroAssembler::LoadUint32(XMMRegister dst, 307746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Register src, 307846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org XMMRegister scratch) { 30792f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org if (FLAG_debug_code) { 30802f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org cmpq(src, Immediate(0xffffffff)); 3081594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Assert(below_equal, kInputGPRIsExpectedToHaveUpper32Cleared); 30822f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org } 30832f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org cvtqsi2sd(dst, src); 308446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org} 308546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 308646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 3087c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.orgvoid MacroAssembler::SlowTruncateToI(Register result_reg, 3088c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org Register input_reg, 3089c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org int offset) { 3090c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org DoubleToIStub stub(input_reg, result_reg, offset, true); 3091c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org call(stub.GetCode(isolate()), RelocInfo::CODE_TARGET); 3092c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org} 3093c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 3094c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 3095c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.orgvoid MacroAssembler::TruncateHeapNumberToI(Register result_reg, 3096c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org Register input_reg) { 3097c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org Label done; 3098c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 3099c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org cvttsd2siq(result_reg, xmm0); 3100c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org Set(kScratchRegister, V8_UINT64_C(0x8000000000000000)); 3101c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org cmpq(result_reg, kScratchRegister); 3102c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org j(not_equal, &done, Label::kNear); 3103c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 3104c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // Slow case. 3105c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org if (input_reg.is(result_reg)) { 3106c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org subq(rsp, Immediate(kDoubleSize)); 3107c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org movsd(MemOperand(rsp, 0), xmm0); 3108c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org SlowTruncateToI(result_reg, rsp, 0); 3109c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org addq(rsp, Immediate(kDoubleSize)); 3110c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org } else { 3111c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org SlowTruncateToI(result_reg, input_reg); 3112c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org } 3113c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 3114c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org bind(&done); 3115c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org} 3116c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 3117c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 3118c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.orgvoid MacroAssembler::TruncateDoubleToI(Register result_reg, 3119c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org XMMRegister input_reg) { 3120c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org Label done; 3121c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org cvttsd2siq(result_reg, input_reg); 3122e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org movq(kScratchRegister, V8_INT64_C(0x8000000000000000)); 3123c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org cmpq(result_reg, kScratchRegister); 3124c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org j(not_equal, &done, Label::kNear); 3125c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 3126c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org subq(rsp, Immediate(kDoubleSize)); 3127c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org movsd(MemOperand(rsp, 0), input_reg); 3128c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org SlowTruncateToI(result_reg, rsp, 0); 3129c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org addq(rsp, Immediate(kDoubleSize)); 3130c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 3131c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org bind(&done); 3132c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org} 3133c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 3134c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 3135c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.orgvoid MacroAssembler::DoubleToI(Register result_reg, 3136c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org XMMRegister input_reg, 3137c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org XMMRegister scratch, 3138c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org MinusZeroMode minus_zero_mode, 3139c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org Label* conversion_failed, 3140c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org Label::Distance dst) { 3141c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org cvttsd2si(result_reg, input_reg); 3142528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Cvtlsi2sd(xmm0, result_reg); 3143c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org ucomisd(xmm0, input_reg); 3144c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org j(not_equal, conversion_failed, dst); 3145c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org j(parity_even, conversion_failed, dst); // NaN. 3146c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org if (minus_zero_mode == FAIL_ON_MINUS_ZERO) { 3147c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org Label done; 3148c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // The integer converted back is equal to the original. We 3149c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // only have to test if we got -0 as an input. 3150c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org testl(result_reg, result_reg); 3151c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org j(not_zero, &done, Label::kNear); 3152c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org movmskpd(result_reg, input_reg); 3153c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // Bit 0 contains the sign of the double in input_reg. 3154c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // If input was positive, we are ok and return 0, otherwise 3155c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // jump to conversion_failed. 3156c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org andl(result_reg, Immediate(1)); 3157c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org j(not_zero, conversion_failed, dst); 3158c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org bind(&done); 3159c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org } 3160c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org} 3161c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 3162c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 3163c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.orgvoid MacroAssembler::TaggedToI(Register result_reg, 3164c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org Register input_reg, 3165c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org XMMRegister temp, 3166c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org MinusZeroMode minus_zero_mode, 3167c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org Label* lost_precision, 3168c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org Label::Distance dst) { 3169c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org Label done; 3170c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org ASSERT(!temp.is(xmm0)); 3171c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 3172c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // Heap number map check. 3173c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), 3174c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org Heap::kHeapNumberMapRootIndex); 3175c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org j(not_equal, lost_precision, dst); 3176c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 3177c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 3178c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org cvttsd2si(result_reg, xmm0); 3179528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Cvtlsi2sd(temp, result_reg); 3180c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org ucomisd(xmm0, temp); 3181c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org RecordComment("Deferred TaggedToI: lost precision"); 3182c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org j(not_equal, lost_precision, dst); 3183c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org RecordComment("Deferred TaggedToI: NaN"); 3184c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org j(parity_even, lost_precision, dst); // NaN. 3185c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org if (minus_zero_mode == FAIL_ON_MINUS_ZERO) { 3186c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org testl(result_reg, result_reg); 3187c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org j(not_zero, &done, Label::kNear); 3188c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org movmskpd(result_reg, xmm0); 3189c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org andl(result_reg, Immediate(1)); 3190c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org j(not_zero, lost_precision, dst); 3191c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org } 3192c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org bind(&done); 3193c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org} 3194c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 3195c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 31969af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.orgvoid MacroAssembler::Throw(BailoutReason reason) { 31979af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org#ifdef DEBUG 31989af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org const char* msg = GetBailoutReason(reason); 31999af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org if (msg != NULL) { 32009af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org RecordComment("Throw message: "); 32019af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org RecordComment(msg); 32029af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org } 32039af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org#endif 32049af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 32059af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org push(rax); 32069af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org Push(Smi::FromInt(reason)); 32079af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org if (!has_frame_) { 32089af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org // We don't actually want to generate a pile of code for this, so just 32099af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org // claim there is a stack frame, without generating one. 32109af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org FrameScope scope(this, StackFrame::NONE); 32119af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org CallRuntime(Runtime::kThrowMessage, 1); 32129af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org } else { 32139af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org CallRuntime(Runtime::kThrowMessage, 1); 32149af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org } 32159af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org // Control will not return here. 32169af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org int3(); 32179af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org} 32189af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 32199af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 32209af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.orgvoid MacroAssembler::ThrowIf(Condition cc, BailoutReason reason) { 32219af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org Label L; 32229af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org j(NegateCondition(cc), &L); 32239af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org Throw(reason); 32249af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org // will not return here 32259af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org bind(&L); 32269af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org} 32279af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 32289af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 322940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.orgvoid MacroAssembler::LoadInstanceDescriptors(Register map, 323040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org Register descriptors) { 323189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org movq(descriptors, FieldOperand(map, Map::kDescriptorsOffset)); 323240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org} 323340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 323440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 323506ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.orgvoid MacroAssembler::NumberOfOwnDescriptors(Register dst, Register map) { 323606ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org movq(dst, FieldOperand(map, Map::kBitField3Offset)); 323706ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org DecodeField<Map::NumberOfOwnDescriptorsBits>(dst); 323806ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org} 323906ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org 324006ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org 3241355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.orgvoid MacroAssembler::EnumLength(Register dst, Register map) { 3242355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org STATIC_ASSERT(Map::EnumLengthBits::kShift == 0); 3243355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org movq(dst, FieldOperand(map, Map::kBitField3Offset)); 3244355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org Move(kScratchRegister, Smi::FromInt(Map::EnumLengthBits::kMask)); 3245355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org and_(dst, kScratchRegister); 3246355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org} 3247355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 3248355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 3249ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.orgvoid MacroAssembler::DispatchMap(Register obj, 32502bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register unused, 3251ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org Handle<Map> map, 3252ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org Handle<Code> success, 3253ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org SmiCheckType smi_check_type) { 3254ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org Label fail; 3255ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org if (smi_check_type == DO_SMI_CHECK) { 3256ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org JumpIfSmi(obj, &fail); 3257ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org } 3258ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org Cmp(FieldOperand(obj, HeapObject::kMapOffset), map); 3259ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org j(equal, success, RelocInfo::CODE_TARGET); 3260ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 3261ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org bind(&fail); 3262ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org} 3263ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 3264ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 3265c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid MacroAssembler::AssertNumber(Register object) { 3266c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org if (emit_debug_code()) { 3267c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Label ok; 3268c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Condition is_smi = CheckSmi(object); 3269c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org j(is_smi, &ok, Label::kNear); 3270c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Cmp(FieldOperand(object, HeapObject::kMapOffset), 3271c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org isolate()->factory()->heap_number_map()); 3272594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(equal, kOperandIsNotANumber); 3273c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org bind(&ok); 3274c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org } 32755c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 32765c838251403b0be9a882540f1922577abba4c872ager@chromium.org 32775c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3278c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid MacroAssembler::AssertNotSmi(Register object) { 3279c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org if (emit_debug_code()) { 3280c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Condition is_smi = CheckSmi(object); 3281594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(NegateCondition(is_smi), kOperandIsASmi); 3282c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org } 3283ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org} 3284ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 3285ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 3286c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid MacroAssembler::AssertSmi(Register object) { 3287c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org if (emit_debug_code()) { 3288c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Condition is_smi = CheckSmi(object); 3289594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(is_smi, kOperandIsNotASmi); 3290c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org } 3291badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org} 3292badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org 3293badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org 3294c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid MacroAssembler::AssertSmi(const Operand& object) { 3295c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org if (emit_debug_code()) { 3296c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Condition is_smi = CheckSmi(object); 3297594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(is_smi, kOperandIsNotASmi); 3298c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org } 329925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org} 330025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org 330125156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org 3302c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid MacroAssembler::AssertZeroExtended(Register int32_register) { 3303c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org if (emit_debug_code()) { 3304c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org ASSERT(!int32_register.is(kScratchRegister)); 3305e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org movq(kScratchRegister, V8_INT64_C(0x0000000100000000)); 3306c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org cmpq(kScratchRegister, int32_register); 3307594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(above_equal, k32BitValueInRegisterIsNotZeroExtended); 3308c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org } 3309f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org} 3310f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 3311f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 3312c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid MacroAssembler::AssertString(Register object) { 3313c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org if (emit_debug_code()) { 3314c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org testb(object, Immediate(kSmiTagMask)); 3315594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(not_equal, kOperandIsASmiAndNotAString); 3316c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org push(object); 3317c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org movq(object, FieldOperand(object, HeapObject::kMapOffset)); 3318c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org CmpInstanceType(object, FIRST_NONSTRING_TYPE); 3319c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org pop(object); 3320594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(below, kOperandIsNotAString); 3321c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org } 332249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org} 332349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 332449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 3325750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgvoid MacroAssembler::AssertName(Register object) { 3326750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (emit_debug_code()) { 3327750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org testb(object, Immediate(kSmiTagMask)); 3328594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(not_equal, kOperandIsASmiAndNotAName); 3329750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org push(object); 3330750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org movq(object, FieldOperand(object, HeapObject::kMapOffset)); 3331750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CmpInstanceType(object, LAST_NAME_TYPE); 3332750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org pop(object); 3333594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(below_equal, kOperandIsNotAName); 3334750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org } 3335750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org} 3336750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 3337750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 3338c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid MacroAssembler::AssertRootValue(Register src, 3339c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Heap::RootListIndex root_value_index, 3340594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org BailoutReason reason) { 3341c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org if (emit_debug_code()) { 3342c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org ASSERT(!src.is(kScratchRegister)); 3343c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org LoadRoot(kScratchRegister, root_value_index); 3344c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org cmpq(src, kScratchRegister); 3345594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(equal, reason); 3346c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org } 33475ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org} 33485ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org 33495ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org 33505ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org 3351b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgCondition MacroAssembler::IsObjectStringType(Register heap_object, 3352b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Register map, 3353b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Register instance_type) { 3354b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org movq(map, FieldOperand(heap_object, HeapObject::kMapOffset)); 3355b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org movzxbl(instance_type, FieldOperand(map, Map::kInstanceTypeOffset)); 335680c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org STATIC_ASSERT(kNotStringTag != 0); 3357b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org testb(instance_type, Immediate(kIsNotStringMask)); 3358b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org return zero; 3359b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 3360b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 3361b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 3362750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgCondition MacroAssembler::IsObjectNameType(Register heap_object, 3363750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Register map, 3364750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Register instance_type) { 3365750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org movq(map, FieldOperand(heap_object, HeapObject::kMapOffset)); 3366750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org movzxbl(instance_type, FieldOperand(map, Map::kInstanceTypeOffset)); 3367750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org cmpb(instance_type, Immediate(static_cast<uint8_t>(LAST_NAME_TYPE))); 3368750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org return below_equal; 3369750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org} 3370750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 3371750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 337286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.orgvoid MacroAssembler::TryGetFunctionPrototype(Register function, 337386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org Register result, 3374394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Label* miss, 3375394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com bool miss_on_bound_function) { 337686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // Check that the receiver isn't a smi. 337786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org testl(function, Immediate(kSmiTagMask)); 337886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org j(zero, miss); 337986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org 338086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // Check that the function really is a function. 338186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org CmpObjectType(function, JS_FUNCTION_TYPE, result); 338286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org j(not_equal, miss); 338386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org 3384394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (miss_on_bound_function) { 3385394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com movq(kScratchRegister, 3386394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); 3387394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // It's not smi-tagged (stored in the top half of a smi-tagged 8-byte 3388394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // field). 3389394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com TestBit(FieldOperand(kScratchRegister, 3390394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com SharedFunctionInfo::kCompilerHintsOffset), 3391394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com SharedFunctionInfo::kBoundFunction); 3392394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com j(not_zero, miss); 3393394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 3394394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 339586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // Make sure that the function has an instance prototype. 339683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label non_instance; 339786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org testb(FieldOperand(result, Map::kBitFieldOffset), 339886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org Immediate(1 << Map::kHasNonInstancePrototype)); 339983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(not_zero, &non_instance, Label::kNear); 340086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org 340186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // Get the prototype or initial map from the function. 340286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org movq(result, 340386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); 340486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org 340586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // If the prototype or initial map is the hole, don't return it and 340686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // simply miss the cache instead. This will allow us to allocate a 340786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // prototype object on-demand in the runtime system. 340818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org CompareRoot(result, Heap::kTheHoleValueRootIndex); 340986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org j(equal, miss); 341086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org 341186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // If the function does not have an initial map, we're done. 341283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label done; 341386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org CmpObjectType(result, MAP_TYPE, kScratchRegister); 341483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(not_equal, &done, Label::kNear); 341586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org 341686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // Get the prototype from the initial map. 341786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org movq(result, FieldOperand(result, Map::kPrototypeOffset)); 341883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org jmp(&done, Label::kNear); 341986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org 342086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // Non-instance prototype: Fetch prototype from constructor field 342186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // in initial map. 342286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org bind(&non_instance); 342386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org movq(result, FieldOperand(result, Map::kConstructorOffset)); 342486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org 342586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // All done. 342686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org bind(&done); 342786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org} 342886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org 3429eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3430eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::SetCounter(StatsCounter* counter, int value) { 3431eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org if (FLAG_native_code_counters && counter->Enabled()) { 3432ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Operand counter_operand = ExternalOperand(ExternalReference(counter)); 3433a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org movl(counter_operand, Immediate(value)); 3434eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org } 3435eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 3436eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3437eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3438eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::IncrementCounter(StatsCounter* counter, int value) { 3439eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org ASSERT(value > 0); 3440eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org if (FLAG_native_code_counters && counter->Enabled()) { 3441ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Operand counter_operand = ExternalOperand(ExternalReference(counter)); 3442eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org if (value == 1) { 3443ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org incl(counter_operand); 3444eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org } else { 3445ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org addl(counter_operand, Immediate(value)); 3446eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org } 3447eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org } 3448eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 3449eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3450eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3451eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::DecrementCounter(StatsCounter* counter, int value) { 3452eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org ASSERT(value > 0); 3453eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org if (FLAG_native_code_counters && counter->Enabled()) { 3454ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Operand counter_operand = ExternalOperand(ExternalReference(counter)); 3455eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org if (value == 1) { 3456ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org decl(counter_operand); 3457eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org } else { 3458ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org subl(counter_operand, Immediate(value)); 3459eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org } 3460eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org } 3461eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 3462eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3463eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3464d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org#ifdef ENABLE_DEBUGGER_SUPPORT 34655c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid MacroAssembler::DebugBreak() { 34665d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Set(rax, 0); // No arguments. 3467ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org LoadAddress(rbx, ExternalReference(Runtime::kDebugBreak, isolate())); 34685c838251403b0be9a882540f1922577abba4c872ager@chromium.org CEntryStub ces(1); 3469c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(AllowThisStubCall(&ces)); 34708432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org Call(ces.GetCode(isolate()), RelocInfo::DEBUG_BREAK); 34713e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org} 34725c838251403b0be9a882540f1922577abba4c872ager@chromium.org#endif // ENABLE_DEBUGGER_SUPPORT 34733e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 34743e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 347540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.orgvoid MacroAssembler::SetCallKind(Register dst, CallKind call_kind) { 347640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // This macro takes the dst register to make the code more readable 347740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // at the call sites. However, the dst register has to be rcx to 347840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // follow the calling convention which requires the call type to be 347940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // in rcx. 348040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org ASSERT(dst.is(rcx)); 348140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org if (call_kind == CALL_AS_FUNCTION) { 348240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org LoadSmiConstant(dst, Smi::FromInt(1)); 348340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org } else { 348440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org LoadSmiConstant(dst, Smi::FromInt(0)); 348540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org } 348640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org} 348740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 348840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 3489eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::InvokeCode(Register code, 3490eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org const ParameterCount& expected, 3491eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org const ParameterCount& actual, 34923a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org InvokeFlag flag, 349340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org const CallWrapper& call_wrapper, 349440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org CallKind call_kind) { 3495c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // You can't call a function without a valid frame. 3496c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(flag == JUMP_FUNCTION || has_frame()); 3497c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 349883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label done; 34992efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org bool definitely_mismatches = false; 35003a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org InvokePrologue(expected, 35013a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org actual, 35023a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Handle<Code>::null(), 35033a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org code, 35043a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org &done, 35052efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org &definitely_mismatches, 35063a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org flag, 350740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org Label::kNear, 350883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org call_wrapper, 350940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org call_kind); 35102efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org if (!definitely_mismatches) { 35112efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org if (flag == CALL_FUNCTION) { 35122efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org call_wrapper.BeforeCall(CallSize(code)); 35132efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org SetCallKind(rcx, call_kind); 35142efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org call(code); 35152efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org call_wrapper.AfterCall(); 35162efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } else { 35172efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org ASSERT(flag == JUMP_FUNCTION); 35182efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org SetCallKind(rcx, call_kind); 35192efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org jmp(code); 35202efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } 35212efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org bind(&done); 3522eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org } 3523eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 3524eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3525eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3526eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::InvokeCode(Handle<Code> code, 3527eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org const ParameterCount& expected, 3528eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org const ParameterCount& actual, 3529eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org RelocInfo::Mode rmode, 35303a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org InvokeFlag flag, 353140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org const CallWrapper& call_wrapper, 353240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org CallKind call_kind) { 3533c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // You can't call a function without a valid frame. 3534c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(flag == JUMP_FUNCTION || has_frame()); 3535c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 353683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label done; 35372efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org bool definitely_mismatches = false; 3538eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org Register dummy = rax; 35393a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org InvokePrologue(expected, 35403a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org actual, 35413a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org code, 35423a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org dummy, 35433a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org &done, 35442efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org &definitely_mismatches, 35453a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org flag, 354640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org Label::kNear, 354783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org call_wrapper, 354840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org call_kind); 35492efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org if (!definitely_mismatches) { 35502efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org if (flag == CALL_FUNCTION) { 35512efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org call_wrapper.BeforeCall(CallSize(code)); 35522efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org SetCallKind(rcx, call_kind); 35532efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org Call(code, rmode); 35542efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org call_wrapper.AfterCall(); 35552efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } else { 35562efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org ASSERT(flag == JUMP_FUNCTION); 35572efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org SetCallKind(rcx, call_kind); 35582efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org Jump(code, rmode); 35592efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } 35602efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org bind(&done); 3561eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org } 3562eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 3563eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3564eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3565eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::InvokeFunction(Register function, 3566eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org const ParameterCount& actual, 35673a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org InvokeFlag flag, 356840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org const CallWrapper& call_wrapper, 356940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org CallKind call_kind) { 3570c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // You can't call a function without a valid frame. 3571c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(flag == JUMP_FUNCTION || has_frame()); 3572c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3573eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org ASSERT(function.is(rdi)); 3574eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org movq(rdx, FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); 3575eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org movq(rsi, FieldOperand(function, JSFunction::kContextOffset)); 35763e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org movsxlq(rbx, 35773e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org FieldOperand(rdx, SharedFunctionInfo::kFormalParameterCountOffset)); 35785aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org // Advances rdx to the end of the Code object header, to the start of 3579eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // the executable code. 3580145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); 3581eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3582eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org ParameterCount expected(rbx); 358340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org InvokeCode(rdx, expected, actual, flag, call_wrapper, call_kind); 3584eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 3585eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3586eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 35878a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.orgvoid MacroAssembler::InvokeFunction(Register function, 358832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org const ParameterCount& expected, 35895c838251403b0be9a882540f1922577abba4c872ager@chromium.org const ParameterCount& actual, 35903a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org InvokeFlag flag, 3591d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org const CallWrapper& call_wrapper, 3592d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org CallKind call_kind) { 3593c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // You can't call a function without a valid frame. 3594c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(flag == JUMP_FUNCTION || has_frame()); 3595c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 35968a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org ASSERT(function.is(rdi)); 35978a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org movq(rsi, FieldOperand(function, JSFunction::kContextOffset)); 35988a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org // Advances rdx to the end of the Code object header, to the start of 35998a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org // the executable code. 3600394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); 36018a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org 3602394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com InvokeCode(rdx, expected, actual, flag, call_wrapper, call_kind); 36035c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 36045c838251403b0be9a882540f1922577abba4c872ager@chromium.org 36055c838251403b0be9a882540f1922577abba4c872ager@chromium.org 36068a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.orgvoid MacroAssembler::InvokeFunction(Handle<JSFunction> function, 36078a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org const ParameterCount& expected, 36088a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org const ParameterCount& actual, 36098a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org InvokeFlag flag, 36108a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org const CallWrapper& call_wrapper, 36118a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org CallKind call_kind) { 36128a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org Move(rdi, function); 36138a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org InvokeFunction(rdi, expected, actual, flag, call_wrapper, call_kind); 36148a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org} 36158a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org 36168a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org 361783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::InvokePrologue(const ParameterCount& expected, 361883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org const ParameterCount& actual, 361983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Handle<Code> code_constant, 362083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register code_register, 362183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* done, 36222efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org bool* definitely_mismatches, 362383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org InvokeFlag flag, 362440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org Label::Distance near_jump, 362583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org const CallWrapper& call_wrapper, 362640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org CallKind call_kind) { 362783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org bool definitely_matches = false; 36282efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org *definitely_mismatches = false; 362983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label invoke; 363083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (expected.is_immediate()) { 363183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(actual.is_immediate()); 363283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (expected.immediate() == actual.immediate()) { 363383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org definitely_matches = true; 363483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 363583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Set(rax, actual.immediate()); 363683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (expected.immediate() == 363783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org SharedFunctionInfo::kDontAdaptArgumentsSentinel) { 363883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Don't worry about adapting arguments for built-ins that 363983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // don't want that done. Skip adaption code by making it look 364083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // like we have a match between expected and actual number of 364183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // arguments. 364283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org definitely_matches = true; 364383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 36442efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org *definitely_mismatches = true; 364583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Set(rbx, expected.immediate()); 364683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 364783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 364883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 364983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (actual.is_immediate()) { 365083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Expected is in register, actual is immediate. This is the 365183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // case when we invoke function values without going through the 365283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // IC mechanism. 365383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org cmpq(expected.reg(), Immediate(actual.immediate())); 365483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(equal, &invoke, Label::kNear); 365583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(expected.reg().is(rbx)); 365683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Set(rax, actual.immediate()); 365783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else if (!expected.reg().is(actual.reg())) { 365883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Both expected and actual are in (different) registers. This 365983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // is the case when we invoke functions using call and apply. 366083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org cmpq(expected.reg(), actual.reg()); 366183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(equal, &invoke, Label::kNear); 366283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(actual.reg().is(rax)); 366383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(expected.reg().is(rbx)); 366483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 366583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 366683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 366783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (!definitely_matches) { 366883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Handle<Code> adaptor = isolate()->builtins()->ArgumentsAdaptorTrampoline(); 366983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (!code_constant.is_null()) { 367083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movq(rdx, code_constant, RelocInfo::EMBEDDED_OBJECT); 367183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org addq(rdx, Immediate(Code::kHeaderSize - kHeapObjectTag)); 367283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else if (!code_register.is(rdx)) { 367383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movq(rdx, code_register); 367483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 367583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 367683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (flag == CALL_FUNCTION) { 367783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org call_wrapper.BeforeCall(CallSize(adaptor)); 367840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org SetCallKind(rcx, call_kind); 367983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Call(adaptor, RelocInfo::CODE_TARGET); 368083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org call_wrapper.AfterCall(); 36812efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org if (!*definitely_mismatches) { 36822efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org jmp(done, near_jump); 36832efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } 368483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 368540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org SetCallKind(rcx, call_kind); 368683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Jump(adaptor, RelocInfo::CODE_TARGET); 368783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 368883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org bind(&invoke); 368983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 369083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 369183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 369283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 3693c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.orgvoid MacroAssembler::Prologue(PrologueFrameMode frame_mode) { 3694c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org if (frame_mode == BUILD_STUB_FRAME) { 3695c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org push(rbp); // Caller's frame pointer. 3696c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org movq(rbp, rsp); 3697c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org push(rsi); // Callee's context. 3698c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org Push(Smi::FromInt(StackFrame::STUB)); 3699c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org } else { 3700c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org PredictableCodeSizeScope predictible_code_size_scope(this, 3701c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org kNoCodeAgeSequenceLength); 3702ed29eb2bdad388c1ce751d68bd4fe6f4f5a7cbc8machenbach@chromium.org if (isolate()->IsCodePreAgingActive()) { 3703c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // Pre-age the code. 3704c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org Call(isolate()->builtins()->MarkCodeAsExecutedOnce(), 3705c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org RelocInfo::CODE_AGE_SEQUENCE); 3706c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org Nop(kNoCodeAgeSequenceLength - Assembler::kShortCallInstructionLength); 3707c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org } else { 3708c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org push(rbp); // Caller's frame pointer. 3709c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org movq(rbp, rsp); 3710c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org push(rsi); // Callee's context. 3711c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org push(rdi); // Callee's JS function. 3712c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org } 3713c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org } 3714c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org} 3715c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 3716c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 3717eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::EnterFrame(StackFrame::Type type) { 3718eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org push(rbp); 3719eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org movq(rbp, rsp); 3720eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org push(rsi); // Context. 37219d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com Push(Smi::FromInt(type)); 3722eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org movq(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); 3723eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org push(kScratchRegister); 3724badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 3725eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org movq(kScratchRegister, 3726160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org isolate()->factory()->undefined_value(), 3727eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org RelocInfo::EMBEDDED_OBJECT); 3728eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org cmpq(Operand(rsp, 0), kScratchRegister); 3729594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(not_equal, kCodeObjectNotProperlyPatched); 3730eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org } 3731eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 3732eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3733eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3734eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::LeaveFrame(StackFrame::Type type) { 3735badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 37369d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com Move(kScratchRegister, Smi::FromInt(type)); 3737eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org cmpq(Operand(rbp, StandardFrameConstants::kMarkerOffset), kScratchRegister); 3738594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(equal, kStackFrameTypesMustMatch); 3739eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org } 3740eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org movq(rsp, rbp); 3741eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org pop(rbp); 3742eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 3743eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3744eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3745d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.orgvoid MacroAssembler::EnterExitFramePrologue(bool save_rax) { 3746f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Set up the frame structure on the stack. 374786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // All constants are relative to the frame pointer of the exit frame. 3748d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ASSERT(ExitFrameConstants::kCallerSPDisplacement == 3749d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org kFPOnStackSize + kPCOnStackSize); 3750d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ASSERT(ExitFrameConstants::kCallerPCOffset == kFPOnStackSize); 3751d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ASSERT(ExitFrameConstants::kCallerFPOffset == 0 * kPointerSize); 3752eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org push(rbp); 3753eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org movq(rbp, rsp); 3754eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3755d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // Reserve room for entry stack pointer and push the code object. 37569d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com ASSERT(ExitFrameConstants::kSPOffset == -1 * kPointerSize); 37575c838251403b0be9a882540f1922577abba4c872ager@chromium.org push(Immediate(0)); // Saved entry sp, patched before call. 37585c838251403b0be9a882540f1922577abba4c872ager@chromium.org movq(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); 37595c838251403b0be9a882540f1922577abba4c872ager@chromium.org push(kScratchRegister); // Accessed from EditFrame::code_slot. 3760eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3761eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // Save the frame pointer and the context in top. 3762e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org if (save_rax) { 37634d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org movq(r14, rax); // Backup rax in callee-save register. 3764e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org } 3765eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 376683e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org Store(ExternalReference(Isolate::kCEntryFPAddress, isolate()), rbp); 376783e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org Store(ExternalReference(Isolate::kContextAddress, isolate()), rsi); 3768e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org} 3769eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 37704a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 37710ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.orgvoid MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space, 37720ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org bool save_doubles) { 3773a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org#ifdef _WIN64 37740ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org const int kShadowSpace = 4; 37750ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org arg_stack_space += kShadowSpace; 3776a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org#endif 37770ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org // Optionally save all XMM registers. 37780ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org if (save_doubles) { 3779c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org int space = XMMRegister::kMaxNumAllocatableRegisters * kDoubleSize + 37800ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org arg_stack_space * kPointerSize; 37810ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org subq(rsp, Immediate(space)); 37820ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org int offset = -2 * kPointerSize; 3783a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org for (int i = 0; i < XMMRegister::NumAllocatableRegisters(); i++) { 37840ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org XMMRegister reg = XMMRegister::FromAllocationIndex(i); 37850ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org movsd(Operand(rbp, offset - ((i + 1) * kDoubleSize)), reg); 37860ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } 37870ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } else if (arg_stack_space > 0) { 37884a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com subq(rsp, Immediate(arg_stack_space * kPointerSize)); 37894a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com } 3790a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org 3791eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // Get the required frame alignment for the OS. 3792ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org const int kFrameAlignment = OS::ActivationFrameAlignment(); 3793eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org if (kFrameAlignment > 0) { 3794eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org ASSERT(IsPowerOf2(kFrameAlignment)); 3795a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org ASSERT(is_int8(kFrameAlignment)); 3796a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org and_(rsp, Immediate(-kFrameAlignment)); 3797eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org } 3798eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3799eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // Patch the saved entry sp. 3800eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org movq(Operand(rbp, ExitFrameConstants::kSPOffset), rsp); 3801eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 3802eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3803eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 38040ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.orgvoid MacroAssembler::EnterExitFrame(int arg_stack_space, bool save_doubles) { 3805d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org EnterExitFramePrologue(true); 3806e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 3807f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Set up argv in callee-saved register r15. It is reused in LeaveExitFrame, 3808e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org // so it must be retained across the C-call. 3809e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; 3810b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org lea(r15, Operand(rbp, r14, times_pointer_size, offset)); 3811e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 38120ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org EnterExitFrameEpilogue(arg_stack_space, save_doubles); 3813e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org} 3814e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 3815e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 38164a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.comvoid MacroAssembler::EnterApiExitFrame(int arg_stack_space) { 3817d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org EnterExitFramePrologue(false); 38180ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org EnterExitFrameEpilogue(arg_stack_space, false); 3819e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org} 3820e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 3821e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 38220ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.orgvoid MacroAssembler::LeaveExitFrame(bool save_doubles) { 3823eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // Registers: 3824b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org // r15 : argv 38250ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org if (save_doubles) { 38260ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org int offset = -2 * kPointerSize; 3827a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org for (int i = 0; i < XMMRegister::NumAllocatableRegisters(); i++) { 38280ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org XMMRegister reg = XMMRegister::FromAllocationIndex(i); 38290ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org movsd(reg, Operand(rbp, offset - ((i + 1) * kDoubleSize))); 38300ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } 38310ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } 3832eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // Get the return address from the stack and restore the frame pointer. 3833eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org movq(rcx, Operand(rbp, 1 * kPointerSize)); 3834eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org movq(rbp, Operand(rbp, 0 * kPointerSize)); 3835eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 38360ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org // Drop everything up to and including the arguments and the receiver 3837a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // from the caller stack. 3838b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org lea(rsp, Operand(r15, 1 * kPointerSize)); 3839eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3840594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org PushReturnAddressFrom(rcx); 38414a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 3842528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org LeaveExitFrameEpilogue(true); 38434a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com} 38444a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 38454a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 3846528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid MacroAssembler::LeaveApiExitFrame(bool restore_context) { 38474a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com movq(rsp, rbp); 38484a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com pop(rbp); 38494a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 3850528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org LeaveExitFrameEpilogue(restore_context); 38514a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com} 38524a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 38534a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 3854528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid MacroAssembler::LeaveExitFrameEpilogue(bool restore_context) { 3855eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // Restore current context from top and clear it in debug mode. 385683e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org ExternalReference context_address(Isolate::kContextAddress, isolate()); 3857ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Operand context_operand = ExternalOperand(context_address); 3858528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (restore_context) { 3859528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org movq(rsi, context_operand); 3860528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 3861eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org#ifdef DEBUG 3862ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org movq(context_operand, Immediate(0)); 3863eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org#endif 3864eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3865eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // Clear the top frame. 386683e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress, 3867ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate()); 3868ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Operand c_entry_fp_operand = ExternalOperand(c_entry_fp_address); 3869ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org movq(c_entry_fp_operand, Immediate(0)); 3870eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 3871eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3872eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3873e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.orgvoid MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, 3874e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org Register scratch, 3875e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org Label* miss) { 3876e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org Label same_contexts; 3877e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 3878e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org ASSERT(!holder_reg.is(scratch)); 3879e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org ASSERT(!scratch.is(kScratchRegister)); 3880e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // Load current lexical context from the stack frame. 3881e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org movq(scratch, Operand(rbp, StandardFrameConstants::kContextOffset)); 3882e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 3883e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // When generating debug code, make sure the lexical context is set. 3884badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 3885e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org cmpq(scratch, Immediate(0)); 3886594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(not_equal, kWeShouldNotHaveAnEmptyLexicalContext); 3887e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org } 388846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Load the native context of the current context. 388946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org int offset = 389046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize; 3891e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org movq(scratch, FieldOperand(scratch, offset)); 389246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org movq(scratch, FieldOperand(scratch, GlobalObject::kNativeContextOffset)); 3893e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 389446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Check the context is a native context. 3895badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 3896e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org Cmp(FieldOperand(scratch, HeapObject::kMapOffset), 389746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org isolate()->factory()->native_context_map()); 3898594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(equal, kJSGlobalObjectNativeContextShouldBeANativeContext); 3899e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org } 3900e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 3901e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // Check if both contexts are the same. 390246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org cmpq(scratch, FieldOperand(holder_reg, JSGlobalProxy::kNativeContextOffset)); 3903e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org j(equal, &same_contexts); 3904e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 3905e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // Compare security tokens. 3906e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // Check that the security token in the calling global object is 3907e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // compatible with the security token in the receiving global 3908e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // object. 3909e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 391046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Check the context is a native context. 3911badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 3912e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // Preserve original value of holder_reg. 3913e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org push(holder_reg); 391446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org movq(holder_reg, 391546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org FieldOperand(holder_reg, JSGlobalProxy::kNativeContextOffset)); 391618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org CompareRoot(holder_reg, Heap::kNullValueRootIndex); 3917594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(not_equal, kJSGlobalProxyContextShouldNotBeNull); 3918e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 391946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Read the first word and compare to native_context_map(), 3920e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org movq(holder_reg, FieldOperand(holder_reg, HeapObject::kMapOffset)); 392146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org CompareRoot(holder_reg, Heap::kNativeContextMapRootIndex); 3922594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(equal, kJSGlobalObjectNativeContextShouldBeANativeContext); 3923e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org pop(holder_reg); 3924e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org } 3925e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 3926e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org movq(kScratchRegister, 392746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org FieldOperand(holder_reg, JSGlobalProxy::kNativeContextOffset)); 39289d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com int token_offset = 39299d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com Context::kHeaderSize + Context::SECURITY_TOKEN_INDEX * kPointerSize; 3930e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org movq(scratch, FieldOperand(scratch, token_offset)); 3931e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org cmpq(scratch, FieldOperand(kScratchRegister, token_offset)); 3932e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org j(not_equal, miss); 3933e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 3934e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org bind(&same_contexts); 3935e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org} 3936e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 3937e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 3938ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org// Compute the hash code from the untagged key. This must be kept in sync with 3939ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org// ComputeIntegerHash in utils.h and KeyedLoadGenericElementStub in 3940ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org// code-stub-hydrogen.cc 3941f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.comvoid MacroAssembler::GetNumberHash(Register r0, Register scratch) { 3942f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // First of all we assign the hash seed to scratch. 3943f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com LoadRoot(scratch, Heap::kHashSeedRootIndex); 3944f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com SmiToInteger32(scratch, scratch); 3945f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 3946f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Xor original key with a seed. 3947f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com xorl(r0, scratch); 3948f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 3949f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Compute the hash code from the untagged key. This must be kept in sync 3950f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // with ComputeIntegerHash in utils.h. 3951f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // 3952f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // hash = ~hash + (hash << 15); 3953f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com movl(scratch, r0); 3954f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com notl(r0); 3955f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com shll(scratch, Immediate(15)); 3956f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com addl(r0, scratch); 3957f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // hash = hash ^ (hash >> 12); 3958f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com movl(scratch, r0); 3959f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com shrl(scratch, Immediate(12)); 3960f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com xorl(r0, scratch); 3961f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // hash = hash + (hash << 2); 3962f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com leal(r0, Operand(r0, r0, times_4, 0)); 3963f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // hash = hash ^ (hash >> 4); 3964f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com movl(scratch, r0); 3965f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com shrl(scratch, Immediate(4)); 3966f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com xorl(r0, scratch); 3967f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // hash = hash * 2057; 3968f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com imull(r0, r0, Immediate(2057)); 3969f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // hash = hash ^ (hash >> 16); 3970f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com movl(scratch, r0); 3971f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com shrl(scratch, Immediate(16)); 3972f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com xorl(r0, scratch); 3973f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com} 3974f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 3975f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 3976f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 39776db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.orgvoid MacroAssembler::LoadFromNumberDictionary(Label* miss, 39786db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register elements, 39796db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register key, 39806db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register r0, 39816db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register r1, 39826db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register r2, 39836db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register result) { 39846db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Register use: 39856db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // 39866db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // elements - holds the slow-case elements of the receiver on entry. 39876db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Unchanged unless 'result' is the same register. 39886db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // 39896db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // key - holds the smi key on entry. 39906db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Unchanged unless 'result' is the same register. 39916db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // 39926db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Scratch registers: 39936db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // 39946db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // r0 - holds the untagged key on entry and holds the hash once computed. 39956db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // 39966db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // r1 - used to hold the capacity mask of the dictionary 39976db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // 39986db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // r2 - used for the index into the dictionary. 39996db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // 40006db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // result - holds the result on exit if the load succeeded. 40016db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Allowed to be the same as 'key' or 'result'. 40026db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Unchanged on bailout so 'key' or 'result' can be used 40036db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // in further computation. 40046db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 40056db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Label done; 40066db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 4007f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com GetNumberHash(r0, r1); 40086db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 40096db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Compute capacity mask. 4010f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com SmiToInteger32(r1, FieldOperand(elements, 4011f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com SeededNumberDictionary::kCapacityOffset)); 40126db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org decl(r1); 40136db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 40146db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Generate an unrolled loop that performs a few probes before giving up. 4015ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org for (int i = 0; i < kNumberDictionaryProbes; i++) { 40166db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Use r2 for index calculations and keep the hash intact in r0. 40176db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org movq(r2, r0); 40186db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Compute the masked index: (hash + i + i * i) & mask. 40196db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org if (i > 0) { 4020f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com addl(r2, Immediate(SeededNumberDictionary::GetProbeOffset(i))); 40216db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org } 40226db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org and_(r2, r1); 40236db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 40246db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Scale the index by multiplying by the entry size. 4025f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com ASSERT(SeededNumberDictionary::kEntrySize == 3); 40266db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org lea(r2, Operand(r2, r2, times_2, 0)); // r2 = r2 * 3 40276db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 40286db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Check if the key matches. 40296db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org cmpq(key, FieldOperand(elements, 40306db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org r2, 40316db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org times_pointer_size, 4032f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com SeededNumberDictionary::kElementsStartOffset)); 4033ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org if (i != (kNumberDictionaryProbes - 1)) { 40346db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org j(equal, &done); 40356db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org } else { 40366db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org j(not_equal, miss); 40376db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org } 40386db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org } 40396db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 40406db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org bind(&done); 40416db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Check that the value is a normal propety. 40426db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org const int kDetailsOffset = 4043f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com SeededNumberDictionary::kElementsStartOffset + 2 * kPointerSize; 40446db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org ASSERT_EQ(NORMAL, 0); 40456db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset), 404683e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org Smi::FromInt(PropertyDetails::TypeField::kMask)); 40476db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org j(not_zero, miss); 40486db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 40496db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Get the value at the masked, scaled index. 40506db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org const int kValueOffset = 4051f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com SeededNumberDictionary::kElementsStartOffset + kPointerSize; 40526db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org movq(result, FieldOperand(elements, r2, times_pointer_size, kValueOffset)); 40536db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org} 40546db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 40556db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 4056a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.orgvoid MacroAssembler::LoadAllocationTopHelper(Register result, 4057a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org Register scratch, 4058a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org AllocationFlags flags) { 40592bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org ExternalReference allocation_top = 40602bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org AllocationUtils::GetAllocationTopReference(isolate(), flags); 406118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 406218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Just return if allocation top is already known. 4063a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org if ((flags & RESULT_CONTAINS_TOP) != 0) { 406418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // No use of scratch if allocation top is provided. 4065ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org ASSERT(!scratch.is_valid()); 4066a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org#ifdef DEBUG 4067a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // Assert that result actually contains top on entry. 40682bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Operand top_operand = ExternalOperand(allocation_top); 4069ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org cmpq(result, top_operand); 4070594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(equal, kUnexpectedAllocationTop); 4071a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org#endif 407218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org return; 407318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 407418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 4075ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org // Move address of new object to result. Use scratch register if available, 4076ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org // and keep address in scratch until call to UpdateAllocationTopHelper. 4077ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org if (scratch.is_valid()) { 40782bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org LoadAddress(scratch, allocation_top); 407918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org movq(result, Operand(scratch, 0)); 4080ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org } else { 40812bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Load(result, allocation_top); 408218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 408318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 408418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 408518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 408618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid MacroAssembler::UpdateAllocationTopHelper(Register result_end, 40872bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register scratch, 40882bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org AllocationFlags flags) { 4089badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 4090ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org testq(result_end, Immediate(kObjectAlignmentMask)); 4091594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(zero, kUnalignedAllocationInNewSpace); 4092ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org } 4093ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 40942bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org ExternalReference allocation_top = 40952bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org AllocationUtils::GetAllocationTopReference(isolate(), flags); 409618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 409718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Update new top. 4098ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (scratch.is_valid()) { 4099ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Scratch already contains address of allocation top. 4100ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org movq(Operand(scratch, 0), result_end); 410118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } else { 41022bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Store(allocation_top, result_end); 410318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 410418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 410518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 410618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 41072bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.orgvoid MacroAssembler::Allocate(int object_size, 41082bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register result, 41092bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register result_end, 41102bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register scratch, 41112bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Label* gc_required, 41122bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org AllocationFlags flags) { 41134cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org ASSERT((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0); 4114c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org ASSERT(object_size <= Page::kMaxNonCodeHeapObjectSize); 4115b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (!FLAG_inline_new) { 4116badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 4117303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // Trash the registers to simulate an allocation failure. 4118303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org movl(result, Immediate(0x7091)); 4119303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org if (result_end.is_valid()) { 4120303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org movl(result_end, Immediate(0x7191)); 4121303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 4122303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org if (scratch.is_valid()) { 4123303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org movl(scratch, Immediate(0x7291)); 4124303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 4125303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 4126303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org jmp(gc_required); 4127303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org return; 4128303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 412918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org ASSERT(!result.is(result_end)); 413018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 413118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Load address of new object into result. 4132beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org LoadAllocationTopHelper(result, scratch, flags); 413318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 41344cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org // Align the next allocation. Storing the filler map without checking top is 4135f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org // safe in new-space because the limit of the heap is aligned there. 41364cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org if (((flags & DOUBLE_ALIGNMENT) != 0) && FLAG_debug_code) { 41374cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org testq(result, Immediate(kDoubleAlignmentMask)); 4138594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(zero, kAllocationIsNotDoubleAligned); 41394cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org } 41404cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org 414118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Calculate new top and bail out if new space is exhausted. 41422bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org ExternalReference allocation_limit = 41432bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org AllocationUtils::GetAllocationLimitReference(isolate(), flags); 4144ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 4145ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org Register top_reg = result_end.is_valid() ? result_end : result; 4146ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 4147d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com if (!top_reg.is(result)) { 4148d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com movq(top_reg, result); 4149ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org } 4150d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com addq(top_reg, Immediate(object_size)); 4151d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com j(carry, gc_required); 41522bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Operand limit_operand = ExternalOperand(allocation_limit); 4153ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org cmpq(top_reg, limit_operand); 415418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org j(above, gc_required); 415518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 415618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Update allocation top. 41572bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org UpdateAllocationTopHelper(top_reg, scratch, flags); 4158a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org 41594cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org bool tag_result = (flags & TAG_OBJECT) != 0; 4160ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org if (top_reg.is(result)) { 41614cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org if (tag_result) { 4162ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org subq(result, Immediate(object_size - kHeapObjectTag)); 4163ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org } else { 4164ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org subq(result, Immediate(object_size)); 4165ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org } 41664cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org } else if (tag_result) { 4167ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org // Tag the result if requested. 41684cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org ASSERT(kHeapObjectTag == 1); 41694cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org incq(result); 4170a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org } 417118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 417218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 417318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 4174f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.orgvoid MacroAssembler::Allocate(int header_size, 4175f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org ScaleFactor element_size, 4176f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register element_count, 4177f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register result, 4178f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register result_end, 4179f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register scratch, 4180f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Label* gc_required, 4181f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org AllocationFlags flags) { 41824cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org ASSERT((flags & SIZE_IN_WORDS) == 0); 4183d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com lea(result_end, Operand(element_count, element_size, header_size)); 4184e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org Allocate(result_end, result, result_end, scratch, gc_required, flags); 4185a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org} 418618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 418718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 4188f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.orgvoid MacroAssembler::Allocate(Register object_size, 4189f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register result, 4190f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register result_end, 4191f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register scratch, 4192f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Label* gc_required, 4193f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org AllocationFlags flags) { 4194e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org ASSERT((flags & SIZE_IN_WORDS) == 0); 4195b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (!FLAG_inline_new) { 4196badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 4197303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // Trash the registers to simulate an allocation failure. 4198303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org movl(result, Immediate(0x7091)); 4199303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org movl(result_end, Immediate(0x7191)); 4200303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org if (scratch.is_valid()) { 4201303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org movl(scratch, Immediate(0x7291)); 4202303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 4203303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // object_size is left unchanged by this function. 4204303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 4205303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org jmp(gc_required); 4206303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org return; 4207303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 4208303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org ASSERT(!result.is(result_end)); 4209303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org 421018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Load address of new object into result. 4211beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org LoadAllocationTopHelper(result, scratch, flags); 421218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 4213e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org // Align the next allocation. Storing the filler map without checking top is 4214f6fe1183c2663bdae2b8e265d4ec3d9e925568e7mstarzinger@chromium.org // safe in new-space because the limit of the heap is aligned there. 4215e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org if (((flags & DOUBLE_ALIGNMENT) != 0) && FLAG_debug_code) { 4216e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org testq(result, Immediate(kDoubleAlignmentMask)); 4217594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(zero, kAllocationIsNotDoubleAligned); 4218e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org } 4219e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 422018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Calculate new top and bail out if new space is exhausted. 4221f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org ExternalReference allocation_limit = 4222f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org AllocationUtils::GetAllocationLimitReference(isolate(), flags); 422318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (!object_size.is(result_end)) { 422418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org movq(result_end, object_size); 422518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 422618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org addq(result_end, result); 4227d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com j(carry, gc_required); 4228f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Operand limit_operand = ExternalOperand(allocation_limit); 4229ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org cmpq(result_end, limit_operand); 423018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org j(above, gc_required); 423118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 423218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Update allocation top. 42332bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org UpdateAllocationTopHelper(result_end, scratch, flags); 4234a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org 4235a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // Tag the result if requested. 4236a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org if ((flags & TAG_OBJECT) != 0) { 4237a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org addq(result, Immediate(kHeapObjectTag)); 4238a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org } 423918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 424018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 424118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 424218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid MacroAssembler::UndoAllocationInNewSpace(Register object) { 424318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org ExternalReference new_space_allocation_top = 4244ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ExternalReference::new_space_allocation_top_address(isolate()); 424518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 424618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Make sure the object has no tag before resetting top. 424718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org and_(object, Immediate(~kHeapObjectTagMask)); 4248ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Operand top_operand = ExternalOperand(new_space_allocation_top); 424918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org#ifdef DEBUG 4250ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org cmpq(object, top_operand); 4251594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(below, kUndoAllocationOfNonAllocatedMemory); 425218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org#endif 4253ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org movq(top_operand, object); 425418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 425518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 425618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 42573811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.orgvoid MacroAssembler::AllocateHeapNumber(Register result, 42583811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org Register scratch, 42593811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org Label* gc_required) { 42603811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Allocate heap number in new space. 42612bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Allocate(HeapNumber::kSize, result, scratch, no_reg, gc_required, TAG_OBJECT); 42623811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 42633811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Set the map. 42643811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org LoadRoot(kScratchRegister, Heap::kHeapNumberMapRootIndex); 42653811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org movq(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); 42663811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org} 42673811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 42683811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 426913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid MacroAssembler::AllocateTwoByteString(Register result, 427013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register length, 427113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register scratch1, 427213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register scratch2, 427313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register scratch3, 427413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Label* gc_required) { 427513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // Calculate the number of bytes needed for the characters in the string while 427613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // observing object alignment. 4277ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org const int kHeaderAlignment = SeqTwoByteString::kHeaderSize & 4278ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org kObjectAlignmentMask; 427913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org ASSERT(kShortSize == 2); 428013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // scratch1 = length * 2 + kObjectAlignmentMask. 4281ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org lea(scratch1, Operand(length, length, times_1, kObjectAlignmentMask + 4282ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org kHeaderAlignment)); 428313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org and_(scratch1, Immediate(~kObjectAlignmentMask)); 4284ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org if (kHeaderAlignment > 0) { 4285ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org subq(scratch1, Immediate(kHeaderAlignment)); 4286ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org } 428713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 428813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // Allocate two byte string in new space. 4289f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Allocate(SeqTwoByteString::kHeaderSize, 4290f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org times_1, 4291f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org scratch1, 4292f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org result, 4293f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org scratch2, 4294f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org scratch3, 4295f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org gc_required, 4296f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org TAG_OBJECT); 429713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 429813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // Set the map, length and hash field. 429913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org LoadRoot(kScratchRegister, Heap::kStringMapRootIndex); 430013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org movq(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); 4301ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org Integer32ToSmi(scratch1, length); 4302ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org movq(FieldOperand(result, String::kLengthOffset), scratch1); 430330ce411529579186181838984710b0b0980857aaricow@chromium.org movq(FieldOperand(result, String::kHashFieldOffset), 430413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Immediate(String::kEmptyHashField)); 430513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org} 430613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 430713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 430813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid MacroAssembler::AllocateAsciiString(Register result, 430913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register length, 431013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register scratch1, 431113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register scratch2, 431213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register scratch3, 431313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Label* gc_required) { 431413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // Calculate the number of bytes needed for the characters in the string while 431513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // observing object alignment. 4316fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org const int kHeaderAlignment = SeqOneByteString::kHeaderSize & 4317ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org kObjectAlignmentMask; 431813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org movl(scratch1, length); 431913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org ASSERT(kCharSize == 1); 4320ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org addq(scratch1, Immediate(kObjectAlignmentMask + kHeaderAlignment)); 432113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org and_(scratch1, Immediate(~kObjectAlignmentMask)); 4322ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org if (kHeaderAlignment > 0) { 4323ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org subq(scratch1, Immediate(kHeaderAlignment)); 4324ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org } 432513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 43262efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // Allocate ASCII string in new space. 4327f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Allocate(SeqOneByteString::kHeaderSize, 4328f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org times_1, 4329f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org scratch1, 4330f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org result, 4331f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org scratch2, 4332f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org scratch3, 4333f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org gc_required, 4334f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org TAG_OBJECT); 433513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 433613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // Set the map, length and hash field. 433713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org LoadRoot(kScratchRegister, Heap::kAsciiStringMapRootIndex); 433813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org movq(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); 4339ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org Integer32ToSmi(scratch1, length); 4340ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org movq(FieldOperand(result, String::kLengthOffset), scratch1); 434130ce411529579186181838984710b0b0980857aaricow@chromium.org movq(FieldOperand(result, String::kHashFieldOffset), 434213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Immediate(String::kEmptyHashField)); 434313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org} 434413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 434513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 43461805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.orgvoid MacroAssembler::AllocateTwoByteConsString(Register result, 434713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register scratch1, 434813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register scratch2, 434913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Label* gc_required) { 435013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // Allocate heap number in new space. 43512bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, 43522bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org TAG_OBJECT); 435313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 435413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // Set the map. The other fields are left uninitialized. 435513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org LoadRoot(kScratchRegister, Heap::kConsStringMapRootIndex); 435613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org movq(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); 435713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org} 435813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 435913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 436013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid MacroAssembler::AllocateAsciiConsString(Register result, 436113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register scratch1, 436213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register scratch2, 436313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Label* gc_required) { 436457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Label allocate_new_space, install_map; 436557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org AllocationFlags flags = TAG_OBJECT; 436657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 436757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org ExternalReference high_promotion_mode = ExternalReference:: 436857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org new_space_high_promotion_mode_active_address(isolate()); 436957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 437057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Load(scratch1, high_promotion_mode); 437157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org testb(scratch1, Immediate(1)); 437257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org j(zero, &allocate_new_space); 437357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Allocate(ConsString::kSize, 437457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org result, 437557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org scratch1, 437657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org scratch2, 437757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org gc_required, 437857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org static_cast<AllocationFlags>(flags | PRETENURE_OLD_POINTER_SPACE)); 437957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 438057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org jmp(&install_map); 438157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 438257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org bind(&allocate_new_space); 438357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Allocate(ConsString::kSize, 438457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org result, 438557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org scratch1, 438657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org scratch2, 438757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org gc_required, 438857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org flags); 438957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 439057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org bind(&install_map); 439113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 439213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // Set the map. The other fields are left uninitialized. 439313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org LoadRoot(kScratchRegister, Heap::kConsAsciiStringMapRootIndex); 439413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org movq(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); 439513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org} 439613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 439713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 43981805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.orgvoid MacroAssembler::AllocateTwoByteSlicedString(Register result, 43991805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org Register scratch1, 44001805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org Register scratch2, 44011805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org Label* gc_required) { 44021805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // Allocate heap number in new space. 44032bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, 44042bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org TAG_OBJECT); 44051805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 44061805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // Set the map. The other fields are left uninitialized. 44071805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org LoadRoot(kScratchRegister, Heap::kSlicedStringMapRootIndex); 44081805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org movq(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); 44091805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org} 44101805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 44111805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 44121805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.orgvoid MacroAssembler::AllocateAsciiSlicedString(Register result, 44131805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org Register scratch1, 44141805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org Register scratch2, 44151805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org Label* gc_required) { 44161805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // Allocate heap number in new space. 44172bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, 44182bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org TAG_OBJECT); 44191805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 44201805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // Set the map. The other fields are left uninitialized. 44211805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org LoadRoot(kScratchRegister, Heap::kSlicedAsciiStringMapRootIndex); 44221805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org movq(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); 44231805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org} 44241805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 44251805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 44267979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org// Copy memory, byte-by-byte, from source to destination. Not optimized for 44277979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org// long or aligned copies. The contents of scratch and length are destroyed. 44287979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org// Destination is incremented by length, source, length and scratch are 44297979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org// clobbered. 44307979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org// A simpler loop is faster on small copies, but slower on large ones. 44317979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org// The cld() instruction must have been emitted, to set the direction flag(), 44327979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org// before calling this function. 44337979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.orgvoid MacroAssembler::CopyBytes(Register destination, 44347979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Register source, 44357979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Register length, 44367979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org int min_length, 44377979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Register scratch) { 44387979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org ASSERT(min_length >= 0); 4439000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org if (emit_debug_code()) { 44407979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org cmpl(length, Immediate(min_length)); 4441594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Assert(greater_equal, kInvalidMinLength); 44427979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org } 44430cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org Label short_loop, len8, len16, len24, done, short_string; 44447979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 44450cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org const int kLongStringLimit = 4 * kPointerSize; 44467979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org if (min_length <= kLongStringLimit) { 44470cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org cmpl(length, Immediate(kPointerSize)); 44480cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org j(below, &short_string, Label::kNear); 44497979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org } 44507979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 44517979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org ASSERT(source.is(rsi)); 44527979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org ASSERT(destination.is(rdi)); 44537979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org ASSERT(length.is(rcx)); 44547979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 44550cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org if (min_length <= kLongStringLimit) { 44560cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org cmpl(length, Immediate(2 * kPointerSize)); 44570cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org j(below_equal, &len8, Label::kNear); 44580cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org cmpl(length, Immediate(3 * kPointerSize)); 44590cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org j(below_equal, &len16, Label::kNear); 44600cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org cmpl(length, Immediate(4 * kPointerSize)); 44610cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org j(below_equal, &len24, Label::kNear); 44620cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org } 44630cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 44647979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Because source is 8-byte aligned in our uses of this function, 44657979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // we keep source aligned for the rep movs operation by copying the odd bytes 44667979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // at the end of the ranges. 44677979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org movq(scratch, length); 446893a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org shrl(length, Immediate(kPointerSizeLog2)); 44697979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org repmovsq(); 44707979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Move remaining bytes of length. 447193a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org andl(scratch, Immediate(kPointerSize - 1)); 447293a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org movq(length, Operand(source, scratch, times_1, -kPointerSize)); 447393a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org movq(Operand(destination, scratch, times_1, -kPointerSize), length); 44747979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org addq(destination, scratch); 44757979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 44767979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org if (min_length <= kLongStringLimit) { 44770cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org jmp(&done, Label::kNear); 44780cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org bind(&len24); 44790cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org movq(scratch, Operand(source, 2 * kPointerSize)); 44800cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org movq(Operand(destination, 2 * kPointerSize), scratch); 44810cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org bind(&len16); 44820cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org movq(scratch, Operand(source, kPointerSize)); 44830cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org movq(Operand(destination, kPointerSize), scratch); 44840cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org bind(&len8); 44850cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org movq(scratch, Operand(source, 0)); 44860cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org movq(Operand(destination, 0), scratch); 44870cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org // Move remaining bytes of length. 44880cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org movq(scratch, Operand(source, length, times_1, -kPointerSize)); 44890cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org movq(Operand(destination, length, times_1, -kPointerSize), scratch); 44900cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org addq(destination, length); 44910cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org jmp(&done, Label::kNear); 44927979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 44937979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org bind(&short_string); 44947979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org if (min_length == 0) { 44957979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org testl(length, length); 44960cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org j(zero, &done, Label::kNear); 44977979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org } 44987979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 44997979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org bind(&short_loop); 45000cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org movb(scratch, Operand(source, 0)); 45010cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org movb(Operand(destination, 0), scratch); 45027979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org incq(source); 45037979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org incq(destination); 45040cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org decl(length); 45050cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org j(not_zero, &short_loop); 45067979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org } 45070cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 45080cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org bind(&done); 45097979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org} 45107979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 45117979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 4512c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::InitializeFieldsWithFiller(Register start_offset, 4513c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register end_offset, 4514c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register filler) { 4515c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label loop, entry; 4516c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com jmp(&entry); 4517c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&loop); 4518c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com movq(Operand(start_offset, 0), filler); 4519c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com addq(start_offset, Immediate(kPointerSize)); 4520c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&entry); 4521c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmpq(start_offset, end_offset); 4522c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(less, &loop); 4523c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 4524c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 4525c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 4526ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.orgvoid MacroAssembler::LoadContext(Register dst, int context_chain_length) { 4527ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org if (context_chain_length > 0) { 4528ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // Move up the chain of contexts to the context containing the slot. 45296d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org movq(dst, Operand(rsi, Context::SlotOffset(Context::PREVIOUS_INDEX))); 4530ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org for (int i = 1; i < context_chain_length; i++) { 45316d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org movq(dst, Operand(dst, Context::SlotOffset(Context::PREVIOUS_INDEX))); 4532ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org } 45335d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org } else { 45345d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // Slot is in the current function context. Move it into the 45355d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // destination register in case we store into it (the write barrier 45365d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // cannot be allowed to destroy the context in rsi). 45375d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org movq(dst, rsi); 45385d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org } 45395d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org 45404f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // We should not have found a with context by walking the context 45414f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // chain (i.e., the static scope chain and runtime context chain do 45424f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // not agree). A variable occurring in such a scope should have 45434f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // slot type LOOKUP and not CONTEXT. 4544badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 45453cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org CompareRoot(FieldOperand(dst, HeapObject::kMapOffset), 45463cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org Heap::kWithContextMapRootIndex); 4547594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(not_equal, kVariableResolvedToWithContext); 4548ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org } 4549ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org} 4550ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 4551fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org 45521145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.orgvoid MacroAssembler::LoadTransitionedArrayMapConditional( 45531145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org ElementsKind expected_kind, 45541145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org ElementsKind transitioned_kind, 45551145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org Register map_in_out, 45561145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org Register scratch, 45571145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org Label* no_map_match) { 45581145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org // Load the global or builtins object from the current context. 455946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org movq(scratch, 456046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 456146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org movq(scratch, FieldOperand(scratch, GlobalObject::kNativeContextOffset)); 45621145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org 45631145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org // Check that the function's map is the same as the expected cached map. 4564830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org movq(scratch, Operand(scratch, 4565830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Context::SlotOffset(Context::JS_ARRAY_MAPS_INDEX))); 4566830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org 4567830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org int offset = expected_kind * kPointerSize + 4568830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org FixedArrayBase::kHeaderSize; 4569830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org cmpq(map_in_out, FieldOperand(scratch, offset)); 45701145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org j(not_equal, no_map_match); 45711145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org 45721145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org // Use the transitioned cached map. 4573830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org offset = transitioned_kind * kPointerSize + 4574830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org FixedArrayBase::kHeaderSize; 4575830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org movq(map_in_out, FieldOperand(scratch, offset)); 45761145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org} 45771145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org 45781145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org 45791145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.orgvoid MacroAssembler::LoadInitialArrayMap( 4580830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Register function_in, Register scratch, 4581830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Register map_out, bool can_have_holes) { 4582fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org ASSERT(!function_in.is(map_out)); 4583fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org Label done; 4584fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org movq(map_out, FieldOperand(function_in, 4585fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org JSFunction::kPrototypeOrInitialMapOffset)); 4586fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org if (!FLAG_smi_only_arrays) { 4587830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org ElementsKind kind = can_have_holes ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS; 4588830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS, 4589830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org kind, 4590830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org map_out, 4591830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org scratch, 4592830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org &done); 4593830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org } else if (can_have_holes) { 4594830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS, 4595830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org FAST_HOLEY_SMI_ELEMENTS, 45961145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org map_out, 45971145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org scratch, 45981145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org &done); 4599fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org } 4600fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org bind(&done); 4601fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org} 4602fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org 4603ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org#ifdef _WIN64 4604ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic const int kRegisterPassedArguments = 4; 4605ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org#else 4606ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic const int kRegisterPassedArguments = 6; 4607ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org#endif 460830ce411529579186181838984710b0b0980857aaricow@chromium.org 46095f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvoid MacroAssembler::LoadGlobalFunction(int index, Register function) { 46105f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // Load the global or builtins object from the current context. 461146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org movq(function, 461246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 461346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Load the native context from the global or builtins object. 461446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org movq(function, FieldOperand(function, GlobalObject::kNativeContextOffset)); 461546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Load the function from the native context. 46165f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org movq(function, Operand(function, Context::SlotOffset(index))); 46175f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org} 46185f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 46195f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 46204a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgvoid MacroAssembler::LoadArrayFunction(Register function) { 46214a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org movq(function, 46224a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 46234a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org movq(function, FieldOperand(function, GlobalObject::kGlobalContextOffset)); 46244a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org movq(function, 46254a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Operand(function, Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX))); 46264a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org} 46274a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 46284a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 46295f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvoid MacroAssembler::LoadGlobalFunctionInitialMap(Register function, 46305f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org Register map) { 46315f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // Load the initial map. The global functions all have initial maps. 46325f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org movq(map, FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); 4633badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 46345f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org Label ok, fail; 4635c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org CheckMap(map, isolate()->factory()->meta_map(), &fail, DO_SMI_CHECK); 46365f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org jmp(&ok); 46375f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org bind(&fail); 4638594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(kGlobalFunctionsMustHaveInitialMap); 46395f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org bind(&ok); 46405f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } 46415f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org} 46425f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 46435f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 4644b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgint MacroAssembler::ArgumentStackSlotsForCFunctionCall(int num_arguments) { 464530ce411529579186181838984710b0b0980857aaricow@chromium.org // On Windows 64 stack slots are reserved by the caller for all arguments 464630ce411529579186181838984710b0b0980857aaricow@chromium.org // including the ones passed in registers, and space is always allocated for 464730ce411529579186181838984710b0b0980857aaricow@chromium.org // the four register arguments even if the function takes fewer than four 464830ce411529579186181838984710b0b0980857aaricow@chromium.org // arguments. 464930ce411529579186181838984710b0b0980857aaricow@chromium.org // On AMD64 ABI (Linux/Mac) the first six arguments are passed in registers 465030ce411529579186181838984710b0b0980857aaricow@chromium.org // and the caller does not reserve stack slots for them. 4651b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ASSERT(num_arguments >= 0); 4652b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#ifdef _WIN64 4653ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org const int kMinimumStackSlots = kRegisterPassedArguments; 465430ce411529579186181838984710b0b0980857aaricow@chromium.org if (num_arguments < kMinimumStackSlots) return kMinimumStackSlots; 465530ce411529579186181838984710b0b0980857aaricow@chromium.org return num_arguments; 4656b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#else 465730ce411529579186181838984710b0b0980857aaricow@chromium.org if (num_arguments < kRegisterPassedArguments) return 0; 465830ce411529579186181838984710b0b0980857aaricow@chromium.org return num_arguments - kRegisterPassedArguments; 4659b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#endif 4660b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 4661b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 466230ce411529579186181838984710b0b0980857aaricow@chromium.org 46639af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.orgvoid MacroAssembler::EmitSeqStringSetCharCheck(Register string, 46649af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org Register index, 46659af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org Register value, 46669af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org uint32_t encoding_mask) { 46679af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org Label is_object; 46689af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org JumpIfNotSmi(string, &is_object); 46699af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org Throw(kNonObject); 46709af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org bind(&is_object); 46719af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 46729af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org push(value); 46739af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org movq(value, FieldOperand(string, HeapObject::kMapOffset)); 46749af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org movzxbq(value, FieldOperand(value, Map::kInstanceTypeOffset)); 46759af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 46769af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org andb(value, Immediate(kStringRepresentationMask | kStringEncodingMask)); 46779af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org cmpq(value, Immediate(encoding_mask)); 46789af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org pop(value); 46799af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org ThrowIf(not_equal, kUnexpectedStringType); 46809af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 46819af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org // The index is assumed to be untagged coming in, tag it to compare with the 46829af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org // string length without using a temp register, it is restored at the end of 46839af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org // this function. 46849af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org Integer32ToSmi(index, index); 46859af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org SmiCompare(index, FieldOperand(string, String::kLengthOffset)); 46869af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org ThrowIf(greater_equal, kIndexIsTooLarge); 46879af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 46889af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org SmiCompare(index, Smi::FromInt(0)); 46899af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org ThrowIf(less, kIndexIsNegative); 46909af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 46919af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org // Restore the index 46929af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org SmiToInteger32(index, index); 46939af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org} 46949af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 46959af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 4696b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid MacroAssembler::PrepareCallCFunction(int num_arguments) { 4697b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org int frame_alignment = OS::ActivationFrameAlignment(); 4698b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ASSERT(frame_alignment != 0); 4699b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ASSERT(num_arguments >= 0); 4700ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 4701b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Make stack end at alignment and allocate space for arguments and old rsp. 4702b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org movq(kScratchRegister, rsp); 4703b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ASSERT(IsPowerOf2(frame_alignment)); 4704b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org int argument_slots_on_stack = 4705b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ArgumentStackSlotsForCFunctionCall(num_arguments); 4706b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org subq(rsp, Immediate((argument_slots_on_stack + 1) * kPointerSize)); 4707b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org and_(rsp, Immediate(-frame_alignment)); 4708b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org movq(Operand(rsp, argument_slots_on_stack * kPointerSize), kScratchRegister); 4709b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 4710b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4711b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4712b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid MacroAssembler::CallCFunction(ExternalReference function, 4713b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org int num_arguments) { 4714ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org LoadAddress(rax, function); 4715b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org CallCFunction(rax, num_arguments); 4716b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 4717b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4718b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4719b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid MacroAssembler::CallCFunction(Register function, int num_arguments) { 4720c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(has_frame()); 4721c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org // Check stack alignment. 4722badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 4723c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org CheckStackAlignment(); 4724c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org } 4725c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org 4726b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org call(function); 4727b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ASSERT(OS::ActivationFrameAlignment() != 0); 4728b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ASSERT(num_arguments >= 0); 4729b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org int argument_slots_on_stack = 4730b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ArgumentStackSlotsForCFunctionCall(num_arguments); 4731b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org movq(rsp, Operand(rsp, argument_slots_on_stack * kPointerSize)); 4732b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 4733b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4734ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 4735c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool AreAliased(Register r1, Register r2, Register r3, Register r4) { 4736c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (r1.is(r2)) return true; 4737c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (r1.is(r3)) return true; 4738c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (r1.is(r4)) return true; 4739c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (r2.is(r3)) return true; 4740c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (r2.is(r4)) return true; 4741c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (r3.is(r4)) return true; 4742c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return false; 4743c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 4744c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 4745c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 47464af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgCodePatcher::CodePatcher(byte* address, int size) 4747c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org : address_(address), 4748c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org size_(size), 4749212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org masm_(NULL, address, size + Assembler::kGap) { 47504af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Create a new macro assembler pointing to the address of the code to patch. 47514af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // The size is adjusted with kGap on order for the assembler to generate size 47524af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // bytes of instructions without failing with buffer size constraints. 47534af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 47544af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 47554af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 47564af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 47574af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgCodePatcher::~CodePatcher() { 47584af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Indicate that code has changed. 47594af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org CPU::FlushICache(address_, size_); 47604af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 47614af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Check that the code was patched as expected. 47624af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org ASSERT(masm_.pc_ == address_ + size_); 47634af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 47644af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 47654af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 4766c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 4767c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::CheckPageFlag( 4768c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register object, 4769c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch, 4770c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int mask, 4771c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Condition cc, 4772c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* condition_met, 4773c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance condition_met_distance) { 4774c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(cc == zero || cc == not_zero); 4775c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (scratch.is(object)) { 4776c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(scratch, Immediate(~Page::kPageAlignmentMask)); 4777c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 4778c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com movq(scratch, Immediate(~Page::kPageAlignmentMask)); 4779c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(scratch, object); 4780c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 4781c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (mask < (1 << kBitsPerByte)) { 4782c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com testb(Operand(scratch, MemoryChunk::kFlagsOffset), 4783c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Immediate(static_cast<uint8_t>(mask))); 4784c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 4785c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com testl(Operand(scratch, MemoryChunk::kFlagsOffset), Immediate(mask)); 4786c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 4787c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(cc, condition_met, condition_met_distance); 4788c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 4789c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 4790c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 4791f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.orgvoid MacroAssembler::CheckMapDeprecated(Handle<Map> map, 4792f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org Register scratch, 4793f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org Label* if_deprecated) { 4794f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org if (map->CanBeDeprecated()) { 4795f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org Move(scratch, map); 4796f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org movq(scratch, FieldOperand(scratch, Map::kBitField3Offset)); 4797f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org SmiToInteger32(scratch, scratch); 4798f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org and_(scratch, Immediate(Map::Deprecated::kMask)); 4799f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org j(not_zero, if_deprecated); 4800f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 4801f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org} 4802f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 4803f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 4804c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::JumpIfBlack(Register object, 4805c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register bitmap_scratch, 4806c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register mask_scratch, 4807c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* on_black, 4808c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance on_black_distance) { 4809c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!AreAliased(object, bitmap_scratch, mask_scratch, rcx)); 4810c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com GetMarkBits(object, bitmap_scratch, mask_scratch); 4811c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 4812c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(strcmp(Marking::kBlackBitPattern, "10") == 0); 4813c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // The mask_scratch register contains a 1 at the position of the first bit 4814c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // and a 0 at all other positions, including the position of the second bit. 4815c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com movq(rcx, mask_scratch); 4816c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Make rcx into a mask that covers both marking bits using the operation 4817c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // rcx = mask | (mask << 1). 4818c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com lea(rcx, Operand(mask_scratch, mask_scratch, times_2, 0)); 4819c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Note that we are using a 4-byte aligned 8-byte load. 4820c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(rcx, Operand(bitmap_scratch, MemoryChunk::kHeaderSize)); 4821c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmpq(mask_scratch, rcx); 4822c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(equal, on_black, on_black_distance); 4823c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 4824c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 4825c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 4826c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Detect some, but not all, common pointer-free objects. This is used by the 4827c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// incremental write barrier which doesn't care about oddballs (they are always 4828c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// marked black immediately so this code is not hit). 4829c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::JumpIfDataObject( 4830c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register value, 4831c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch, 4832c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* not_data_object, 4833c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance not_data_object_distance) { 4834c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label is_data_object; 4835c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com movq(scratch, FieldOperand(value, HeapObject::kMapOffset)); 4836c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CompareRoot(scratch, Heap::kHeapNumberMapRootIndex); 4837c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(equal, &is_data_object, Label::kNear); 4838c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(kIsIndirectStringTag == 1 && kIsIndirectStringMask == 1); 4839c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(kNotStringTag == 0x80 && kIsNotStringMask == 0x80); 4840c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // If it's a string and it's not a cons string then it's an object containing 4841c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // no GC pointers. 4842c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com testb(FieldOperand(scratch, Map::kInstanceTypeOffset), 4843c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Immediate(kIsIndirectStringMask | kIsNotStringMask)); 4844c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(not_zero, not_data_object, not_data_object_distance); 4845c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&is_data_object); 4846c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 4847c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 4848c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 4849c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::GetMarkBits(Register addr_reg, 4850c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register bitmap_reg, 4851c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register mask_reg) { 4852c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!AreAliased(addr_reg, bitmap_reg, mask_reg, rcx)); 4853c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com movq(bitmap_reg, addr_reg); 4854c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Sign extended 32 bit immediate. 4855c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(bitmap_reg, Immediate(~Page::kPageAlignmentMask)); 4856c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com movq(rcx, addr_reg); 4857c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int shift = 4858c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Bitmap::kBitsPerCellLog2 + kPointerSizeLog2 - Bitmap::kBytesPerCellLog2; 4859c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com shrl(rcx, Immediate(shift)); 4860c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(rcx, 4861c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Immediate((Page::kPageAlignmentMask >> shift) & 4862c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ~(Bitmap::kBytesPerCell - 1))); 4863c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 4864c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com addq(bitmap_reg, rcx); 4865c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com movq(rcx, addr_reg); 4866c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com shrl(rcx, Immediate(kPointerSizeLog2)); 4867c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(rcx, Immediate((1 << Bitmap::kBitsPerCellLog2) - 1)); 4868c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com movl(mask_reg, Immediate(1)); 4869c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com shl_cl(mask_reg); 4870c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 4871c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 4872c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 4873c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::EnsureNotWhite( 4874c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register value, 4875c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register bitmap_scratch, 4876c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register mask_scratch, 4877c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* value_is_white_and_not_data, 4878c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance distance) { 4879c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!AreAliased(value, bitmap_scratch, mask_scratch, rcx)); 4880c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com GetMarkBits(value, bitmap_scratch, mask_scratch); 4881c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 4882c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // If the value is black or grey we don't need to do anything. 4883c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(strcmp(Marking::kWhiteBitPattern, "00") == 0); 4884c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(strcmp(Marking::kBlackBitPattern, "10") == 0); 4885c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(strcmp(Marking::kGreyBitPattern, "11") == 0); 4886c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(strcmp(Marking::kImpossibleBitPattern, "01") == 0); 4887c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 4888c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label done; 4889c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 4890c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Since both black and grey have a 1 in the first position and white does 4891c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // not have a 1 there we only need to check one bit. 4892c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com testq(Operand(bitmap_scratch, MemoryChunk::kHeaderSize), mask_scratch); 4893c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(not_zero, &done, Label::kNear); 4894c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 4895000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org if (emit_debug_code()) { 4896c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check for impossible bit pattern. 4897c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label ok; 4898c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com push(mask_scratch); 4899c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // shl. May overflow making the check conservative. 4900c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com addq(mask_scratch, mask_scratch); 4901c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com testq(Operand(bitmap_scratch, MemoryChunk::kHeaderSize), mask_scratch); 4902c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(zero, &ok, Label::kNear); 4903c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int3(); 4904c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&ok); 4905c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com pop(mask_scratch); 4906c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 4907c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 4908c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Value is white. We check whether it is data that doesn't need scanning. 4909c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Currently only checks for HeapNumber and non-cons strings. 4910c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register map = rcx; // Holds map while checking type. 4911c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register length = rcx; // Holds length of object after checking type. 4912c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label not_heap_number; 4913c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label is_data_object; 4914c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 4915c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check for heap-number 4916c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com movq(map, FieldOperand(value, HeapObject::kMapOffset)); 4917c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CompareRoot(map, Heap::kHeapNumberMapRootIndex); 4918c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(not_equal, ¬_heap_number, Label::kNear); 4919c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com movq(length, Immediate(HeapNumber::kSize)); 4920c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com jmp(&is_data_object, Label::kNear); 4921c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 4922c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(¬_heap_number); 4923c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check for strings. 4924c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(kIsIndirectStringTag == 1 && kIsIndirectStringMask == 1); 4925c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(kNotStringTag == 0x80 && kIsNotStringMask == 0x80); 4926c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // If it's a string and it's not a cons string then it's an object containing 4927c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // no GC pointers. 4928c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register instance_type = rcx; 4929c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com movzxbl(instance_type, FieldOperand(map, Map::kInstanceTypeOffset)); 4930c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com testb(instance_type, Immediate(kIsIndirectStringMask | kIsNotStringMask)); 4931c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(not_zero, value_is_white_and_not_data); 4932c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // It's a non-indirect (non-cons and non-slice) string. 4933c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // If it's external, the length is just ExternalString::kSize. 4934c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Otherwise it's String::kHeaderSize + string->length() * (1 or 2). 4935c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label not_external; 4936c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // External strings are the only ones with the kExternalStringTag bit 4937c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // set. 4938c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT_EQ(0, kSeqStringTag & kExternalStringTag); 4939c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT_EQ(0, kConsStringTag & kExternalStringTag); 4940c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com testb(instance_type, Immediate(kExternalStringTag)); 4941c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(zero, ¬_external, Label::kNear); 4942c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com movq(length, Immediate(ExternalString::kSize)); 4943c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com jmp(&is_data_object, Label::kNear); 4944c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 4945c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(¬_external); 4946c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Sequential string, either ASCII or UC16. 4947e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org ASSERT(kOneByteStringTag == 0x04); 4948c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(length, Immediate(kStringEncodingMask)); 4949c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com xor_(length, Immediate(kStringEncodingMask)); 4950c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com addq(length, Immediate(0x04)); 4951c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Value now either 4 (if ASCII) or 8 (if UC16), i.e. char-size shifted by 2. 4952c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com imul(length, FieldOperand(value, String::kLengthOffset)); 4953c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com shr(length, Immediate(2 + kSmiTagSize + kSmiShiftSize)); 4954c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com addq(length, Immediate(SeqString::kHeaderSize + kObjectAlignmentMask)); 4955c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(length, Immediate(~kObjectAlignmentMask)); 4956c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 4957c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&is_data_object); 4958c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Value is a data object, and it is white. Mark it black. Since we know 4959c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // that the object is white we can make it black by flipping one bit. 4960c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com or_(Operand(bitmap_scratch, MemoryChunk::kHeaderSize), mask_scratch); 4961c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 4962c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com and_(bitmap_scratch, Immediate(~Page::kPageAlignmentMask)); 4963c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com addl(Operand(bitmap_scratch, MemoryChunk::kLiveBytesOffset), length); 4964c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 4965c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&done); 4966c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 4967c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 4968be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 4969be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.orgvoid MacroAssembler::CheckEnumCache(Register null_value, Label* call_runtime) { 4970355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org Label next, start; 4971be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Register empty_fixed_array_value = r8; 4972be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org LoadRoot(empty_fixed_array_value, Heap::kEmptyFixedArrayRootIndex); 4973be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org movq(rcx, rax); 4974be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 4975355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // Check if the enum length field is properly initialized, indicating that 4976355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // there is an enum cache. 4977be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org movq(rbx, FieldOperand(rcx, HeapObject::kMapOffset)); 4978657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org 4979355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org EnumLength(rdx, rbx); 4980af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org Cmp(rdx, Smi::FromInt(kInvalidEnumCacheSentinel)); 4981de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org j(equal, call_runtime); 4982de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org 4983355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org jmp(&start); 4984355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 4985355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org bind(&next); 4986355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 4987355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org movq(rbx, FieldOperand(rcx, HeapObject::kMapOffset)); 4988be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 4989be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // For all objects but the receiver, check that the cache is empty. 4990355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org EnumLength(rdx, rbx); 4991355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org Cmp(rdx, Smi::FromInt(0)); 4992355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org j(not_equal, call_runtime); 4993355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 4994355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org bind(&start); 4995355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 4996355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // Check that there are no elements. Register rcx contains the current JS 4997355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // object we've reached through the prototype chain. 4998355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org cmpq(empty_fixed_array_value, 4999355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org FieldOperand(rcx, JSObject::kElementsOffset)); 5000be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org j(not_equal, call_runtime); 5001be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5002be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org movq(rcx, FieldOperand(rbx, Map::kPrototypeOffset)); 5003be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org cmpq(rcx, null_value); 5004be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org j(not_equal, &next); 5005be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org} 5006be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5007ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgvoid MacroAssembler::TestJSArrayForAllocationMemento( 500859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org Register receiver_reg, 5009b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org Register scratch_reg, 5010b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org Label* no_memento_found) { 501159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org ExternalReference new_space_start = 501259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org ExternalReference::new_space_start(isolate()); 501359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org ExternalReference new_space_allocation_top = 501459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org ExternalReference::new_space_allocation_top_address(isolate()); 501559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 501659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org lea(scratch_reg, Operand(receiver_reg, 5017ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org JSArray::kSize + AllocationMemento::kSize - kHeapObjectTag)); 5018e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Move(kScratchRegister, new_space_start); 501959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org cmpq(scratch_reg, kScratchRegister); 5020b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org j(less, no_memento_found); 502159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org cmpq(scratch_reg, ExternalOperand(new_space_allocation_top)); 5022b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org j(greater, no_memento_found); 5023ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org CompareRoot(MemOperand(scratch_reg, -AllocationMemento::kSize), 5024ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Heap::kAllocationMementoMapRootIndex); 502559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org} 502659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 5027be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5028e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.orgvoid MacroAssembler::JumpIfDictionaryInPrototypeChain( 5029e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Register object, 5030e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Register scratch0, 5031e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Register scratch1, 5032e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Label* found) { 5033e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org ASSERT(!(scratch0.is(kScratchRegister) && scratch1.is(kScratchRegister))); 5034e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org ASSERT(!scratch1.is(scratch0)); 5035e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Register current = scratch0; 5036e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Label loop_again; 5037e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 5038e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org movq(current, object); 5039e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 5040e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // Loop based on the map going up the prototype chain. 5041e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org bind(&loop_again); 5042e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org movq(current, FieldOperand(current, HeapObject::kMapOffset)); 5043e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org movq(scratch1, FieldOperand(current, Map::kBitField2Offset)); 5044e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org and_(scratch1, Immediate(Map::kElementsKindMask)); 5045e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org shr(scratch1, Immediate(Map::kElementsKindShift)); 5046e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org cmpq(scratch1, Immediate(DICTIONARY_ELEMENTS)); 5047e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org j(equal, found); 5048e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org movq(current, FieldOperand(current, Map::kPrototypeOffset)); 5049e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org CompareRoot(current, Heap::kNullValueRootIndex); 5050e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org j(not_equal, &loop_again); 5051e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org} 5052e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 5053e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 505471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} } // namespace v8::internal 50559dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 50569dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#endif // V8_TARGET_ARCH_X64 5057