1f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com// Copyright 2012 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 45ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_X64 89dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/bootstrapper.h" 10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/codegen.h" 11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/cpu-profiler.h" 12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/x64/assembler-x64.h" 13196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/x64/macro-assembler-x64.h" 14196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/serialize.h" 15196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/debug.h" 16196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/heap.h" 17196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/isolate-inl.h" 1871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 1971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 2071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal { 2171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 22c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgMacroAssembler::MacroAssembler(Isolate* arg_isolate, void* buffer, int size) 23c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org : Assembler(arg_isolate, buffer, size), 249d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com generating_stub_(false), 25c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com has_frame_(false), 26c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org root_array_available_(true) { 27c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org if (isolate() != NULL) { 28c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org code_object_ = Handle<Object>(isolate()->heap()->undefined_value(), 29c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org isolate()); 30c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org } 31ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org} 32ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 33ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 344ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgstatic const int64_t kInvalidRootRegisterDelta = -1; 35000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org 36000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org 374ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.orgint64_t MacroAssembler::RootRegisterDelta(ExternalReference other) { 38000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org if (predictable_code_size() && 39000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org (other.address() < reinterpret_cast<Address>(isolate()) || 40000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org other.address() >= reinterpret_cast<Address>(isolate() + 1))) { 41000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org return kInvalidRootRegisterDelta; 42000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org } 43ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Address roots_register_value = kRootRegisterBias + 44000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org reinterpret_cast<Address>(isolate()->heap()->roots_array_start()); 454ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org 464ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org int64_t delta = kInvalidRootRegisterDelta; // Bogus initialization. 474ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org if (kPointerSize == kInt64Size) { 484ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org delta = other.address() - roots_register_value; 494ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org } else { 504ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org // For x32, zero extend the address to 64-bit and calculate the delta. 514ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org uint64_t o = static_cast<uint32_t>( 524ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org reinterpret_cast<intptr_t>(other.address())); 534ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org uint64_t r = static_cast<uint32_t>( 544ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org reinterpret_cast<intptr_t>(roots_register_value)); 554ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org delta = o - r; 564ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org } 57ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return delta; 58ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org} 59ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 60ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 61ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgOperand MacroAssembler::ExternalOperand(ExternalReference target, 62ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Register scratch) { 63874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org if (root_array_available_ && !serializer_enabled()) { 644ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org int64_t delta = RootRegisterDelta(target); 65000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org if (delta != kInvalidRootRegisterDelta && is_int32(delta)) { 667979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org return Operand(kRootRegister, static_cast<int32_t>(delta)); 67ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 68ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 69e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Move(scratch, target); 70ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return Operand(scratch, 0); 71ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org} 72ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 73ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 74ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgvoid MacroAssembler::Load(Register destination, ExternalReference source) { 75874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org if (root_array_available_ && !serializer_enabled()) { 764ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org int64_t delta = RootRegisterDelta(source); 77000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org if (delta != kInvalidRootRegisterDelta && is_int32(delta)) { 7843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(destination, Operand(kRootRegister, static_cast<int32_t>(delta))); 79ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return; 80ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 81ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 82ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Safe code. 83ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (destination.is(rax)) { 84ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org load_rax(source); 85ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } else { 86e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Move(kScratchRegister, source); 8743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(destination, Operand(kScratchRegister, 0)); 88ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 89ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org} 90ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 91ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 92ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgvoid MacroAssembler::Store(ExternalReference destination, Register source) { 93874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org if (root_array_available_ && !serializer_enabled()) { 944ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org int64_t delta = RootRegisterDelta(destination); 95000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org if (delta != kInvalidRootRegisterDelta && is_int32(delta)) { 9643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(Operand(kRootRegister, static_cast<int32_t>(delta)), source); 97ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return; 98ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 99ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 100ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Safe code. 101ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (source.is(rax)) { 102ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org store_rax(destination); 103ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } else { 104e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Move(kScratchRegister, destination); 10543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(Operand(kScratchRegister, 0), source); 106ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 107ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org} 108ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 109ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 110ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgvoid MacroAssembler::LoadAddress(Register destination, 111ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ExternalReference source) { 112874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org if (root_array_available_ && !serializer_enabled()) { 1134ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org int64_t delta = RootRegisterDelta(source); 114000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org if (delta != kInvalidRootRegisterDelta && is_int32(delta)) { 115895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org leap(destination, Operand(kRootRegister, static_cast<int32_t>(delta))); 116ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return; 117ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 118ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 119ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Safe code. 120e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Move(destination, source); 121ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org} 122ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 123ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 124ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgint MacroAssembler::LoadAddressSize(ExternalReference source) { 125874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org if (root_array_available_ && !serializer_enabled()) { 126ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // This calculation depends on the internals of LoadAddress. 127ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // It's correctness is ensured by the asserts in the Call 128ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // instruction below. 1294ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org int64_t delta = RootRegisterDelta(source); 130000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org if (delta != kInvalidRootRegisterDelta && is_int32(delta)) { 131895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org // Operand is leap(scratch, Operand(kRootRegister, delta)); 132ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Opcodes : REX.W 8D ModRM Disp8/Disp32 - 4 or 7. 133ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org int size = 4; 134ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (!is_int8(static_cast<int32_t>(delta))) { 135ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org size += 3; // Need full four-byte displacement in lea. 136ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 137ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return size; 138ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 139ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org } 14043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org // Size of movp(destination, src); 141594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return Assembler::kMoveAddressIntoScratchRegisterInstructionLength; 14271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 14371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 144e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 145ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.comvoid MacroAssembler::PushAddress(ExternalReference source) { 146ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com int64_t address = reinterpret_cast<int64_t>(source.address()); 147874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org if (is_int32(address) && !serializer_enabled()) { 148ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com if (emit_debug_code()) { 149af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org Move(kScratchRegister, kZapValue, Assembler::RelocInfoNone()); 150ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com } 151763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Push(Immediate(static_cast<int32_t>(address))); 152ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com return; 153ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com } 154ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com LoadAddress(kScratchRegister, source); 155763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Push(kScratchRegister); 156ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com} 157ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com 158ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com 1599d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::LoadRoot(Register destination, Heap::RootListIndex index) { 160ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ASSERT(root_array_available_); 16143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(destination, Operand(kRootRegister, 1628f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org (index << kPointerSizeLog2) - kRootRegisterBias)); 1638f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org} 1648f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org 1658f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org 1668f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.orgvoid MacroAssembler::LoadRootIndexed(Register destination, 1678f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org Register variable_offset, 1688f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org int fixed_offset) { 169ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ASSERT(root_array_available_); 17043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(destination, 1718f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org Operand(kRootRegister, 1728f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org variable_offset, times_pointer_size, 1738f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org (fixed_offset << kPointerSizeLog2) - kRootRegisterBias)); 17418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 17518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 17618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 177720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.orgvoid MacroAssembler::StoreRoot(Register source, Heap::RootListIndex index) { 178ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ASSERT(root_array_available_); 17943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(Operand(kRootRegister, (index << kPointerSizeLog2) - kRootRegisterBias), 1808f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org source); 181720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org} 182720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org 183720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org 18418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid MacroAssembler::PushRoot(Heap::RootListIndex index) { 185ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ASSERT(root_array_available_); 186763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Push(Operand(kRootRegister, (index << kPointerSizeLog2) - kRootRegisterBias)); 18718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 18818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 18918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 1909d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::CompareRoot(Register with, Heap::RootListIndex index) { 191ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ASSERT(root_array_available_); 1927a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(with, Operand(kRootRegister, 1938f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org (index << kPointerSizeLog2) - kRootRegisterBias)); 19418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 19518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 196b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org 19783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.orgvoid MacroAssembler::CompareRoot(const Operand& with, 19883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org Heap::RootListIndex index) { 199ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ASSERT(root_array_available_); 20083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org ASSERT(!with.AddressUsesRegister(kScratchRegister)); 201c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org LoadRoot(kScratchRegister, index); 2027a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(with, kScratchRegister); 203c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org} 204c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 205c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 206c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::RememberedSetHelper(Register object, // For debug tests. 207c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register addr, 208c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch, 209c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SaveFPRegsMode save_fp, 210c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RememberedSetFinalAction and_then) { 211000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org if (emit_debug_code()) { 212c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label ok; 213c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com JumpIfNotInNewSpace(object, scratch, &ok, Label::kNear); 214c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int3(); 215c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&ok); 216c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 217c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Load store buffer top. 218c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com LoadRoot(scratch, Heap::kStoreBufferTopRootIndex); 219c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Store pointer to buffer. 22043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(Operand(scratch, 0), addr); 221c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Increment buffer top. 222fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org addp(scratch, Immediate(kPointerSize)); 223c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Write back new top of buffer. 224c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com StoreRoot(scratch, Heap::kStoreBufferTopRootIndex); 225c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Call stub on end of buffer. 226c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label done; 227c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check for end of buffer. 2287a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org testp(scratch, Immediate(StoreBuffer::kStoreBufferOverflowBit)); 229c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (and_then == kReturnAtEnd) { 230c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label buffer_overflowed; 231c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(not_equal, &buffer_overflowed, Label::kNear); 232c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ret(0); 233c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&buffer_overflowed); 234c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 235c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(and_then == kFallThroughAtEnd); 236c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(equal, &done, Label::kNear); 237c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 238c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com StoreBufferOverflowStub store_buffer_overflow = 239f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org StoreBufferOverflowStub(isolate(), save_fp); 240c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CallStub(&store_buffer_overflow); 241c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (and_then == kReturnAtEnd) { 242c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ret(0); 243c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 244c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(and_then == kFallThroughAtEnd); 245c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&done); 246ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org } 24730ce411529579186181838984710b0b0980857aaricow@chromium.org} 24830ce411529579186181838984710b0b0980857aaricow@chromium.org 24930ce411529579186181838984710b0b0980857aaricow@chromium.org 25083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::InNewSpace(Register object, 25183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register scratch, 25283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Condition cc, 25383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* branch, 254c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance distance) { 255874aad37f2a832804012c6f56739f4fc6c9283cdmachenbach@chromium.org if (serializer_enabled()) { 25683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Can't do arithmetic on external references if it might get serialized. 25783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // The mask isn't really an address. We load it as an external reference in 25883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // case the size of the new space is different between the snapshot maker 25983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // and the running system. 26083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (scratch.is(object)) { 261e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Move(kScratchRegister, ExternalReference::new_space_mask(isolate())); 262895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org andp(scratch, kScratchRegister); 26383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 264e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Move(scratch, ExternalReference::new_space_mask(isolate())); 265895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org andp(scratch, object); 26683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 267e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Move(kScratchRegister, ExternalReference::new_space_start(isolate())); 2687a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(scratch, kScratchRegister); 269c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(cc, branch, distance); 27083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 271e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org ASSERT(kPointerSize == kInt64Size 272e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org ? is_int32(static_cast<int64_t>(isolate()->heap()->NewSpaceMask())) 273e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org : kPointerSize == kInt32Size); 27483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org intptr_t new_space_start = 275c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org reinterpret_cast<intptr_t>(isolate()->heap()->NewSpaceStart()); 2769cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org Move(kScratchRegister, reinterpret_cast<Address>(-new_space_start), 277af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org Assembler::RelocInfoNone()); 27883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (scratch.is(object)) { 279fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org addp(scratch, kScratchRegister); 28083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 281895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org leap(scratch, Operand(object, kScratchRegister, times_1, 0)); 28283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 283895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org andp(scratch, 284c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org Immediate(static_cast<int32_t>(isolate()->heap()->NewSpaceMask()))); 285c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(cc, branch, distance); 28683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 28783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 28883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 28983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 290c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::RecordWriteField( 291c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register object, 292c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int offset, 293c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register value, 294c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register dst, 295c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SaveFPRegsMode save_fp, 296c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RememberedSetAction remembered_set_action, 297196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org SmiCheck smi_check, 298196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org PointersToHereCheck pointers_to_here_check_for_value) { 29930ce411529579186181838984710b0b0980857aaricow@chromium.org // First, check if a write barrier is even needed. The tests below 300c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // catch stores of Smis. 301b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org Label done; 302b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org 303c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Skip barrier if writing a smi. 304c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (smi_check == INLINE_SMI_CHECK) { 305c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com JumpIfSmi(value, &done); 306c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 307c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 308c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Although the object register is tagged, the offset is relative to the start 309c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // of the object, so so offset must be a multiple of kPointerSize. 310c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(IsAligned(offset, kPointerSize)); 311c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 312895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org leap(dst, FieldOperand(object, offset)); 313c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (emit_debug_code()) { 314c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label ok; 315c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com testb(dst, Immediate((1 << kPointerSizeLog2) - 1)); 316c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(zero, &ok, Label::kNear); 317c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int3(); 318c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&ok); 319c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 320c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 321196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org RecordWrite(object, dst, value, save_fp, remembered_set_action, 322196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org OMIT_SMI_CHECK, pointers_to_here_check_for_value); 323c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3249d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com bind(&done); 325b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 326c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Clobber clobbered input registers when running with the debug-code flag 327c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // turned on to provoke errors. 328badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 329af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org Move(value, kZapValue, Assembler::RelocInfoNone()); 330af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org Move(dst, kZapValue, Assembler::RelocInfoNone()); 331b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 3329d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com} 3339d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com 3349d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com 335196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgvoid MacroAssembler::RecordWriteArray( 336196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Register object, 337196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Register value, 338196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Register index, 339196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org SaveFPRegsMode save_fp, 340196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org RememberedSetAction remembered_set_action, 341196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org SmiCheck smi_check, 342196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org PointersToHereCheck pointers_to_here_check_for_value) { 343394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // First, check if a write barrier is even needed. The tests below 344394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // catch stores of Smis. 345394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Label done; 346394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 347394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Skip barrier if writing a smi. 348394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (smi_check == INLINE_SMI_CHECK) { 349394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com JumpIfSmi(value, &done); 350394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 351394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 352394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Array access: calculate the destination address. Index is not a smi. 353394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register dst = index; 354895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org leap(dst, Operand(object, index, times_pointer_size, 355394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com FixedArray::kHeaderSize - kHeapObjectTag)); 356394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 357196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org RecordWrite(object, dst, value, save_fp, remembered_set_action, 358196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org OMIT_SMI_CHECK, pointers_to_here_check_for_value); 359394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 360394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com bind(&done); 361394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 362394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Clobber clobbered input registers when running with the debug-code flag 363394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // turned on to provoke errors. 364394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (emit_debug_code()) { 365af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org Move(value, kZapValue, Assembler::RelocInfoNone()); 366af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org Move(index, kZapValue, Assembler::RelocInfoNone()); 367394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 368394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com} 369394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 370394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 371196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgvoid MacroAssembler::RecordWriteForMap(Register object, 372196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Register map, 373196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Register dst, 374196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org SaveFPRegsMode fp_mode) { 375196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org ASSERT(!object.is(kScratchRegister)); 376196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org ASSERT(!object.is(map)); 377196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org ASSERT(!object.is(dst)); 378196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org ASSERT(!map.is(dst)); 379196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org AssertNotSmi(object); 380196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org 381196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if (emit_debug_code()) { 382196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Label ok; 383196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if (map.is(kScratchRegister)) pushq(map); 384196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org CompareMap(map, isolate()->factory()->meta_map()); 385196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if (map.is(kScratchRegister)) popq(map); 386196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org j(equal, &ok, Label::kNear); 387196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org int3(); 388196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org bind(&ok); 389196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org } 390196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org 391196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if (!FLAG_incremental_marking) { 392196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org return; 393196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org } 394196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org 395196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if (emit_debug_code()) { 396196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Label ok; 397196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if (map.is(kScratchRegister)) pushq(map); 398196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org cmpp(map, FieldOperand(object, HeapObject::kMapOffset)); 399196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if (map.is(kScratchRegister)) popq(map); 400196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org j(equal, &ok, Label::kNear); 401196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org int3(); 402196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org bind(&ok); 403196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org } 404196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org 405196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org // Compute the address. 406196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org leap(dst, FieldOperand(object, HeapObject::kMapOffset)); 407196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org 408196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org // Count number of write barriers in generated code. 409196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org isolate()->counters()->write_barriers_static()->Increment(); 410196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1); 411196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org 412196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org // First, check if a write barrier is even needed. The tests below 413196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org // catch stores of smis and stores into the young generation. 414196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Label done; 415196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org 416196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org // A single check of the map's pages interesting flag suffices, since it is 417196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org // only set during incremental collection, and then it's also guaranteed that 418196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org // the from object's page's interesting flag is also set. This optimization 419196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org // relies on the fact that maps can never be in new space. 420196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org CheckPageFlag(map, 421196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org map, // Used as scratch. 422196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org MemoryChunk::kPointersToHereAreInterestingMask, 423196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org zero, 424196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org &done, 425196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Label::kNear); 426196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org 427196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org RecordWriteStub stub(isolate(), object, map, dst, OMIT_REMEMBERED_SET, 428196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org fp_mode); 429196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org CallStub(&stub); 430196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org 431196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org bind(&done); 432196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org 433196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org // Clobber clobbered registers when running with the debug-code flag 434196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org // turned on to provoke errors. 435196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if (emit_debug_code()) { 436196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Move(dst, kZapValue, Assembler::RelocInfoNone()); 437196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Move(map, kZapValue, Assembler::RelocInfoNone()); 438196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org } 439196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org} 440196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org 441196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org 442196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgvoid MacroAssembler::RecordWrite( 443196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Register object, 444196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Register address, 445196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Register value, 446196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org SaveFPRegsMode fp_mode, 447196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org RememberedSetAction remembered_set_action, 448196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org SmiCheck smi_check, 449196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org PointersToHereCheck pointers_to_here_check_for_value) { 450c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!object.is(value)); 451c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!object.is(address)); 452c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!value.is(address)); 453c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org AssertNotSmi(object); 454c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 455c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (remembered_set_action == OMIT_REMEMBERED_SET && 456c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com !FLAG_incremental_marking) { 457c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return; 45869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org } 45969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 460000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org if (emit_debug_code()) { 461c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label ok; 4627a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(value, Operand(address, 0)); 463c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(equal, &ok, Label::kNear); 464c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int3(); 465c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&ok); 466c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 46769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 468f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org // Count number of write barriers in generated code. 469f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org isolate()->counters()->write_barriers_static()->Increment(); 470f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1); 471f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org 472c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // First, check if a write barrier is even needed. The tests below 473c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // catch stores of smis and stores into the young generation. 4749d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com Label done; 475b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 476c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (smi_check == INLINE_SMI_CHECK) { 477c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Skip barrier if writing a smi. 478c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com JumpIfSmi(value, &done); 479b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 480b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 481196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org if (pointers_to_here_check_for_value != kPointersToHereAreAlwaysInteresting) { 482196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org CheckPageFlag(value, 483196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org value, // Used as scratch. 484196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org MemoryChunk::kPointersToHereAreInterestingMask, 485196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org zero, 486196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org &done, 487196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org Label::kNear); 488196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org } 489b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org 490c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CheckPageFlag(object, 491c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com value, // Used as scratch. 492c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MemoryChunk::kPointersFromHereAreInterestingMask, 493c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com zero, 494c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com &done, 495c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::kNear); 496e88a9edffbbdbc4ccc9872560ac4d9ea6b188fbdwhesse@chromium.org 497f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org RecordWriteStub stub(isolate(), object, value, address, remembered_set_action, 498f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org fp_mode); 499c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CallStub(&stub); 500b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org 501b9d7da12d4486aa0a9d6660de46d977198076e77sgjesse@chromium.org bind(&done); 502b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 503c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Clobber clobbered registers when running with the debug-code flag 504b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // turned on to provoke errors. 505badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 506af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org Move(address, kZapValue, Assembler::RelocInfoNone()); 507af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org Move(value, kZapValue, Assembler::RelocInfoNone()); 508b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 5095aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org} 5105aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 511c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 512594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid MacroAssembler::Assert(Condition cc, BailoutReason reason) { 513594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org if (emit_debug_code()) Check(cc, reason); 514eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 515eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 516eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 5170b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.orgvoid MacroAssembler::AssertFastElements(Register elements) { 518badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 51983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label ok; 5200b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org CompareRoot(FieldOperand(elements, HeapObject::kMapOffset), 5210b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org Heap::kFixedArrayMapRootIndex); 52283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(equal, &ok, Label::kNear); 5230b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org CompareRoot(FieldOperand(elements, HeapObject::kMapOffset), 52484bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org Heap::kFixedDoubleArrayMapRootIndex); 52584bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org j(equal, &ok, Label::kNear); 52684bcc559ac20fb04f806e97d28a314b20b58fd60svenpanne@chromium.org CompareRoot(FieldOperand(elements, HeapObject::kMapOffset), 5270b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org Heap::kFixedCOWArrayMapRootIndex); 52883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(equal, &ok, Label::kNear); 529594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(kJSObjectWithFastElementsMapHasSlowElements); 5300b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org bind(&ok); 5310b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org } 5320b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org} 5330b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org 5340b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org 535594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid MacroAssembler::Check(Condition cc, BailoutReason reason) { 53683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label L; 53783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(cc, &L, Label::kNear); 538594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(reason); 539c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Control will not return here. 540eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org bind(&L); 541eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 542eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 543eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 544c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.orgvoid MacroAssembler::CheckStackAlignment() { 545c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org int frame_alignment = OS::ActivationFrameAlignment(); 546c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org int frame_alignment_mask = frame_alignment - 1; 547c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org if (frame_alignment > kPointerSize) { 548c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org ASSERT(IsPowerOf2(frame_alignment)); 54983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label alignment_as_expected; 5507a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org testp(rsp, Immediate(frame_alignment_mask)); 55183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(zero, &alignment_as_expected, Label::kNear); 552c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org // Abort if stack is not aligned. 553c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org int3(); 554c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org bind(&alignment_as_expected); 555c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org } 556c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org} 557c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org 558c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org 5595aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.orgvoid MacroAssembler::NegativeZeroTest(Register result, 5605aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org Register op, 5615aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org Label* then_label) { 56283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label ok; 5630b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org testl(result, result); 56483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(not_zero, &ok, Label::kNear); 5650b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org testl(op, op); 5665aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org j(sign, then_label); 5675aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org bind(&ok); 5685aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org} 5695aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 5705aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 571594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.orgvoid MacroAssembler::Abort(BailoutReason reason) { 572052c9560e8a41c723726ebe914a93747d8f13285hpayer@chromium.org#ifdef DEBUG 573f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org const char* msg = GetBailoutReason(reason); 574eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org if (msg != NULL) { 575eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org RecordComment("Abort message: "); 576eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org RecordComment(msg); 577eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org } 5781e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 5791e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org if (FLAG_trap_on_abort) { 5801e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org int3(); 5811e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org return; 5821e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org } 583eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org#endif 5841e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 585f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Move(kScratchRegister, Smi::FromInt(static_cast<int>(reason)), 586af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org Assembler::RelocInfoNone()); 587763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Push(kScratchRegister); 588c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 589c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!has_frame_) { 590c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // We don't actually want to generate a pile of code for this, so just 591c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // claim there is a stack frame, without generating one. 592c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope scope(this, StackFrame::NONE); 593f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CallRuntime(Runtime::kAbort, 1); 594c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 595f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CallRuntime(Runtime::kAbort, 1); 596c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 597c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Control will not return here. 598ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org int3(); 599eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 600eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 601eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 602471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.orgvoid MacroAssembler::CallStub(CodeStub* stub, TypeFeedbackId ast_id) { 603c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(AllowThisStubCall(stub)); // Calls are not allowed in some stubs 604f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org Call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id); 605eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 606eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 607eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 60813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid MacroAssembler::TailCallStub(CodeStub* stub) { 609f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org Jump(stub->GetCode(), RelocInfo::CODE_TARGET); 61013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org} 61113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 61213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 613eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::StubReturn(int argc) { 614eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org ASSERT(argc >= 1 && generating_stub()); 615eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org ret((argc - 1) * kPointerSize); 616eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 617eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 618eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 619c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool MacroAssembler::AllowThisStubCall(CodeStub* stub) { 6208a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org return has_frame_ || !stub->SometimesSetsUpAFrame(); 621c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 622c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 623c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 624d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.orgvoid MacroAssembler::IndexFromHash(Register hash, Register index) { 625d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // The assert checks that the constants for the maximum number of digits 626d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // for an array index cached in the hash field and the number of bits 627d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // reserved for it does not conflict. 628d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) < 629d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org (1 << String::kArrayIndexValueBits)); 630d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org if (!hash.is(index)) { 631d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org movl(index, hash); 632d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org } 633d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org DecodeFieldToSmi<String::ArrayIndexValueBits>(index); 634d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org} 635d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 636d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 637ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgvoid MacroAssembler::CallRuntime(const Runtime::Function* f, 638fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org int num_arguments, 639fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org SaveFPRegsMode save_doubles) { 640eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // If the expected number of arguments of the runtime function is 641eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // constant, we check that the actual number of arguments match the 642eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // expectation. 64329699e37f62a9aa96c100f29bc8ea3668acff099machenbach@chromium.org CHECK(f->nargs < 0 || f->nargs == num_arguments); 644eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 645b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // TODO(1236192): Most runtime routines don't need the number of 646b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // arguments passed in because it is constant. At some point we 647b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // should remove this need and make the runtime routine entry code 648b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // smarter. 64932d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org Set(rax, num_arguments); 650ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org LoadAddress(rbx, ExternalReference(f, isolate())); 651f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CEntryStub ces(isolate(), f->result_size, save_doubles); 652b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org CallStub(&ces); 653eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 654eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 655eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 6565c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid MacroAssembler::CallExternalReference(const ExternalReference& ext, 6575c838251403b0be9a882540f1922577abba4c872ager@chromium.org int num_arguments) { 65832d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org Set(rax, num_arguments); 659ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org LoadAddress(rbx, ext); 6605c838251403b0be9a882540f1922577abba4c872ager@chromium.org 661f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CEntryStub stub(isolate(), 1); 6625c838251403b0be9a882540f1922577abba4c872ager@chromium.org CallStub(&stub); 6635c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 6645c838251403b0be9a882540f1922577abba4c872ager@chromium.org 6655c838251403b0be9a882540f1922577abba4c872ager@chromium.org 666ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgvoid MacroAssembler::TailCallExternalReference(const ExternalReference& ext, 667ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int num_arguments, 668ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int result_size) { 6690b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // ----------- S t a t e ------------- 670c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org // -- rsp[0] : return address 671c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org // -- rsp[8] : argument num_arguments - 1 6720b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // ... 6730b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // -- rsp[8 * num_arguments] : argument 0 (receiver) 6740b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // ----------------------------------- 6750b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 676eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // TODO(1236192): Most runtime routines don't need the number of 677eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // arguments passed in because it is constant. At some point we 678eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // should remove this need and make the runtime routine entry code 679eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // smarter. 68032d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org Set(rax, num_arguments); 681ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org JumpToExternalReference(ext, result_size); 682eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 683eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 684eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 685ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgvoid MacroAssembler::TailCallRuntime(Runtime::FunctionId fid, 686ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int num_arguments, 687ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int result_size) { 688ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org TailCallExternalReference(ExternalReference(fid, isolate()), 689ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org num_arguments, 690ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org result_size); 691ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org} 692ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 693ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 694e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.orgstatic int Offset(ExternalReference ref0, ExternalReference ref1) { 695e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org int64_t offset = (ref0.address() - ref1.address()); 696e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org // Check that fits into int. 697e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org ASSERT(static_cast<int>(offset) == offset); 698e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org return static_cast<int>(offset); 699e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org} 700e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 701e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 702662436e7b124b3535773535c671c53db322070b5verwaest@chromium.orgvoid MacroAssembler::PrepareCallApiFunction(int arg_stack_space) { 7034a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com EnterApiExitFrame(arg_stack_space); 704e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org} 705e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 706e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 707528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid MacroAssembler::CallApiFunctionAndReturn( 708e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org Register function_address, 709a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org ExternalReference thunk_ref, 710528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register thunk_last_arg, 711528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org int stack_space, 712528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Operand return_value_operand, 713528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Operand* context_restore_operand) { 714303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org Label prologue; 715303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org Label promote_scheduled_exception; 716528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Label exception_handled; 717303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org Label delete_allocated_handles; 718303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org Label leave_exit_frame; 719e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org Label write_back; 720e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 721160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org Factory* factory = isolate()->factory(); 722303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org ExternalReference next_address = 72309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org ExternalReference::handle_scope_next_address(isolate()); 724303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org const int kNextOffset = 0; 725303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org const int kLimitOffset = Offset( 72609d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org ExternalReference::handle_scope_limit_address(isolate()), 727303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org next_address); 728303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org const int kLevelOffset = Offset( 72909d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org ExternalReference::handle_scope_level_address(isolate()), 730303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org next_address); 731303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org ExternalReference scheduled_exception_address = 732ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ExternalReference::scheduled_exception_address(isolate()); 733303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org 734e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org ASSERT(rdx.is(function_address) || r8.is(function_address)); 735303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // Allocate HandleScope in callee-save registers. 736303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org Register prev_next_address_reg = r14; 737303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org Register prev_limit_reg = rbx; 738b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org Register base_reg = r15; 739e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Move(base_reg, next_address); 74043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(prev_next_address_reg, Operand(base_reg, kNextOffset)); 74143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(prev_limit_reg, Operand(base_reg, kLimitOffset)); 742303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org addl(Operand(base_reg, kLevelOffset), Immediate(1)); 74383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 74483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org if (FLAG_log_timer_events) { 74583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org FrameScope frame(this, StackFrame::MANUAL); 74683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org PushSafepointRegisters(); 747ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org PrepareCallCFunction(1); 748ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org LoadAddress(arg_reg_1, ExternalReference::isolate_address(isolate())); 749ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org CallCFunction(ExternalReference::log_enter_external_function(isolate()), 1); 75083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org PopSafepointRegisters(); 75183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org } 75283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 753b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 754b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Label profiler_disabled; 755b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Label end_profiler_check; 756a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org Move(rax, ExternalReference::is_profiling_address(isolate())); 757b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org cmpb(Operand(rax, 0), Immediate(0)); 758b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org j(zero, &profiler_disabled); 759b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 760b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // Third parameter is the address of the actual getter function. 761e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org Move(thunk_last_arg, function_address); 762a70700b91bc28abeed6373b856017f7f9cc8273bmachenbach@chromium.org Move(rax, thunk_ref); 763b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org jmp(&end_profiler_check); 764b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 765b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org bind(&profiler_disabled); 766303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // Call the api function! 767e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org Move(rax, function_address); 768b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 769b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org bind(&end_profiler_check); 770b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 771b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org // Call the api function! 772303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org call(rax); 773e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 77483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org if (FLAG_log_timer_events) { 77583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org FrameScope frame(this, StackFrame::MANUAL); 77683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org PushSafepointRegisters(); 777ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org PrepareCallCFunction(1); 778ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org LoadAddress(arg_reg_1, ExternalReference::isolate_address(isolate())); 779ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org CallCFunction(ExternalReference::log_leave_external_function(isolate()), 1); 78083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org PopSafepointRegisters(); 78183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org } 78283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 783bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org // Load the value from ReturnValue 78443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(rax, return_value_operand); 785303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org bind(&prologue); 786303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org 787303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // No more valid handles (the result handle was the last one). Restore 788303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // previous handle scope. 789303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org subl(Operand(base_reg, kLevelOffset), Immediate(1)); 79043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(Operand(base_reg, kNextOffset), prev_next_address_reg); 7917a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(prev_limit_reg, Operand(base_reg, kLimitOffset)); 792303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org j(not_equal, &delete_allocated_handles); 793303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org bind(&leave_exit_frame); 794303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org 795303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // Check if the function scheduled an exception. 796e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Move(rsi, scheduled_exception_address); 797160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org Cmp(Operand(rsi, 0), factory->the_hole_value()); 798303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org j(not_equal, &promote_scheduled_exception); 799528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org bind(&exception_handled); 800303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org 80167255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org#if ENABLE_EXTRA_CHECKS 80267255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org // Check if the function returned a valid JavaScript value. 80367255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org Label ok; 80467255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org Register return_value = rax; 80567255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org Register map = rcx; 80667255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 80767255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org JumpIfSmi(return_value, &ok, Label::kNear); 80843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(map, FieldOperand(return_value, HeapObject::kMapOffset)); 80967255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 81067255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org CmpInstanceType(map, FIRST_NONSTRING_TYPE); 81167255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org j(below, &ok, Label::kNear); 81267255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 81367255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE); 81467255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org j(above_equal, &ok, Label::kNear); 81567255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 81667255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org CompareRoot(map, Heap::kHeapNumberMapRootIndex); 81767255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org j(equal, &ok, Label::kNear); 81867255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 81967255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org CompareRoot(return_value, Heap::kUndefinedValueRootIndex); 82067255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org j(equal, &ok, Label::kNear); 82167255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 82267255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org CompareRoot(return_value, Heap::kTrueValueRootIndex); 82367255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org j(equal, &ok, Label::kNear); 82467255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 82567255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org CompareRoot(return_value, Heap::kFalseValueRootIndex); 82667255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org j(equal, &ok, Label::kNear); 82767255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 82867255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org CompareRoot(return_value, Heap::kNullValueRootIndex); 82967255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org j(equal, &ok, Label::kNear); 83067255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 831594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(kAPICallReturnedInvalidObject); 83267255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 83367255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org bind(&ok); 83467255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org#endif 83567255bead6b3c379ed821d8371271e34779602cajkummerow@chromium.org 836528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org bool restore_context = context_restore_operand != NULL; 837528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (restore_context) { 83843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(rsi, *context_restore_operand); 839528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 840528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org LeaveApiExitFrame(!restore_context); 8414a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com ret(stack_space * kPointerSize); 842e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 843b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org bind(&promote_scheduled_exception); 844528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org { 845528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org FrameScope frame(this, StackFrame::INTERNAL); 846895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org CallRuntime(Runtime::kHiddenPromoteScheduledException, 0); 847528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 848528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org jmp(&exception_handled); 849b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org 850303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // HandleScope limit has changed. Delete allocated extensions. 851303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org bind(&delete_allocated_handles); 85243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(Operand(base_reg, kLimitOffset), prev_limit_reg); 85343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(prev_limit_reg, rax); 854ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org LoadAddress(arg_reg_1, ExternalReference::isolate_address(isolate())); 855ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org LoadAddress(rax, 856ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ExternalReference::delete_handle_scope_extensions(isolate())); 857303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org call(rax); 85843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(rax, prev_limit_reg); 859303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org jmp(&leave_exit_frame); 860e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org} 861e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 862e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 863ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgvoid MacroAssembler::JumpToExternalReference(const ExternalReference& ext, 864ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org int result_size) { 865eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // Set the entry point and jump to the C entry runtime stub. 866ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org LoadAddress(rbx, ext); 867f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CEntryStub ces(isolate(), result_size); 868f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org jmp(ces.GetCode(), RelocInfo::CODE_TARGET); 86971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 87071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 871e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 8723a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, 8733a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org InvokeFlag flag, 874fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org const CallWrapper& call_wrapper) { 875c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // You can't call a builtin without a valid frame. 876c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(flag == JUMP_FUNCTION || has_frame()); 8775aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 8785c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Rely on the assertion to check that the number of provided 8795c838251403b0be9a882540f1922577abba4c872ager@chromium.org // arguments match the expected number of arguments. Fake a 8805c838251403b0be9a882540f1922577abba4c872ager@chromium.org // parameter count to avoid emitting code to do the check. 8815c838251403b0be9a882540f1922577abba4c872ager@chromium.org ParameterCount expected(0); 8825c838251403b0be9a882540f1922577abba4c872ager@chromium.org GetBuiltinEntry(rdx, id); 883e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org InvokeCode(rdx, expected, expected, flag, call_wrapper); 8845aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org} 8855aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 8865c838251403b0be9a882540f1922577abba4c872ager@chromium.org 887145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.comvoid MacroAssembler::GetBuiltinFunction(Register target, 888145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com Builtins::JavaScript id) { 889c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org // Load the builtins object into target register. 89043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(target, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 89143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(target, FieldOperand(target, GlobalObject::kBuiltinsOffset)); 89243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(target, FieldOperand(target, 893145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com JSBuiltinsObject::OffsetOfFunctionWithId(id))); 894145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com} 895c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org 896c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org 897145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.comvoid MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) { 898145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com ASSERT(!target.is(rdi)); 899145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com // Load the JavaScript builtin function from the builtins object. 900145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com GetBuiltinFunction(rdi, id); 90143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(target, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); 9025aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org} 9035aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 9045aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 9051456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org#define REG(Name) { kRegister_ ## Name ## _Code } 9061456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 9071456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgstatic const Register saved_regs[] = { 9081456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org REG(rax), REG(rcx), REG(rdx), REG(rbx), REG(rbp), REG(rsi), REG(rdi), REG(r8), 9091456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org REG(r9), REG(r10), REG(r11) 9101456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org}; 9111456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 9121456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org#undef REG 9131456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 914c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comstatic const int kNumberOfSavedRegs = sizeof(saved_regs) / sizeof(Register); 915c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 916c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 917c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::PushCallerSaved(SaveFPRegsMode fp_mode, 918c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register exclusion1, 919c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register exclusion2, 920c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register exclusion3) { 921c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // We don't allow a GC during a store buffer overflow so there is no need to 922c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // store the registers in any particular way, but we do have to store and 923c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // restore them. 924c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (int i = 0; i < kNumberOfSavedRegs; i++) { 925c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register reg = saved_regs[i]; 926c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!reg.is(exclusion1) && !reg.is(exclusion2) && !reg.is(exclusion3)) { 927763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org pushq(reg); 928c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 929c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 930c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // R12 to r15 are callee save on all platforms. 931c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (fp_mode == kSaveFPRegs) { 932fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org subp(rsp, Immediate(kDoubleSize * XMMRegister::kMaxNumRegisters)); 93394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { 934c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com XMMRegister reg = XMMRegister::from_code(i); 935c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com movsd(Operand(rsp, i * kDoubleSize), reg); 936c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 937c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 938c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 939c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 940c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 941c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::PopCallerSaved(SaveFPRegsMode fp_mode, 942c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register exclusion1, 943c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register exclusion2, 944c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register exclusion3) { 945c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (fp_mode == kSaveFPRegs) { 94694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { 947c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com XMMRegister reg = XMMRegister::from_code(i); 948c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com movsd(reg, Operand(rsp, i * kDoubleSize)); 949c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 950fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org addp(rsp, Immediate(kDoubleSize * XMMRegister::kMaxNumRegisters)); 951c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 952c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (int i = kNumberOfSavedRegs - 1; i >= 0; i--) { 953c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register reg = saved_regs[i]; 954c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!reg.is(exclusion1) && !reg.is(exclusion2) && !reg.is(exclusion3)) { 955763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org popq(reg); 956c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 957c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 958c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 959c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 960c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 961528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid MacroAssembler::Cvtlsi2sd(XMMRegister dst, Register src) { 962528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org xorps(dst, dst); 963528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org cvtlsi2sd(dst, src); 964528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org} 965528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 966528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 967528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid MacroAssembler::Cvtlsi2sd(XMMRegister dst, const Operand& src) { 968528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org xorps(dst, dst); 969528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org cvtlsi2sd(dst, src); 970528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org} 971528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 972528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 973d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.orgvoid MacroAssembler::Load(Register dst, const Operand& src, Representation r) { 974dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org ASSERT(!r.IsDouble()); 975935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org if (r.IsInteger8()) { 976935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org movsxbq(dst, src); 977935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } else if (r.IsUInteger8()) { 978d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org movzxbl(dst, src); 979935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } else if (r.IsInteger16()) { 980935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org movsxwq(dst, src); 981935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } else if (r.IsUInteger16()) { 982935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org movzxwl(dst, src); 983d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } else if (r.IsInteger32()) { 984d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org movl(dst, src); 985d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } else { 98643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(dst, src); 987d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } 988d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org} 989d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 990d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 991d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.orgvoid MacroAssembler::Store(const Operand& dst, Register src, Representation r) { 992dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.org ASSERT(!r.IsDouble()); 993935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org if (r.IsInteger8() || r.IsUInteger8()) { 994d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org movb(dst, src); 995935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org } else if (r.IsInteger16() || r.IsUInteger16()) { 996935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org movw(dst, src); 997d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } else if (r.IsInteger32()) { 998d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org movl(dst, src); 999d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } else { 1000d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org if (r.IsHeapObject()) { 1001d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org AssertNotSmi(src); 1002d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org } else if (r.IsSmi()) { 1003d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org AssertSmi(src); 1004d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org } 100543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(dst, src); 1006d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } 1007d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org} 1008d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 1009d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 1010e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.orgvoid MacroAssembler::Set(Register dst, int64_t x) { 101168ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org if (x == 0) { 101269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org xorl(dst, dst); 1013e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org } else if (is_uint32(x)) { 1014c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org movl(dst, Immediate(static_cast<uint32_t>(x))); 1015a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org } else if (is_int32(x)) { 1016a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org movq(dst, Immediate(static_cast<int32_t>(x))); 1017e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org } else { 1018e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org movq(dst, x); 1019e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org } 1020e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org} 1021e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 1022e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 1023f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvoid MacroAssembler::Set(const Operand& dst, intptr_t x) { 1024f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (kPointerSize == kInt64Size) { 1025f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (is_int32(x)) { 1026f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org movp(dst, Immediate(static_cast<int32_t>(x))); 1027f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } else { 1028f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Set(kScratchRegister, x); 1029f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org movp(dst, kScratchRegister); 1030f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 1031e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org } else { 1032f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org movp(dst, Immediate(static_cast<int32_t>(x))); 1033e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org } 1034e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org} 1035e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 10367a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org 1037dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org// ---------------------------------------------------------------------------- 1038dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org// Smi tagging, untagging and tag detection. 1039dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org 1040dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgbool MacroAssembler::IsUnsafeInt(const int32_t x) { 10417a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org static const int kMaxBits = 17; 10427a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org return !is_intn(x, kMaxBits); 10437a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org} 10447a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org 10457a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org 10467a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.orgvoid MacroAssembler::SafeMove(Register dst, Smi* src) { 10477a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org ASSERT(!dst.is(kScratchRegister)); 10487a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org if (IsUnsafeInt(src->value()) && jit_cookie() != 0) { 1049a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org if (SmiValuesAre32Bits()) { 1050a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // JIT cookie can be converted to Smi. 1051a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org Move(dst, Smi::FromInt(src->value() ^ jit_cookie())); 1052a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org Move(kScratchRegister, Smi::FromInt(jit_cookie())); 1053a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org xorp(dst, kScratchRegister); 1054a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org } else { 1055a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org ASSERT(SmiValuesAre31Bits()); 1056a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org int32_t value = static_cast<int32_t>(reinterpret_cast<intptr_t>(src)); 1057a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org movp(dst, Immediate(value ^ jit_cookie())); 1058a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org xorp(dst, Immediate(jit_cookie())); 1059a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org } 10607a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org } else { 10617a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org Move(dst, src); 10627a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org } 10637a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org} 10647a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org 10657a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org 10667a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.orgvoid MacroAssembler::SafePush(Smi* src) { 10677a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org if (IsUnsafeInt(src->value()) && jit_cookie() != 0) { 1068a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org if (SmiValuesAre32Bits()) { 1069a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // JIT cookie can be converted to Smi. 1070a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org Push(Smi::FromInt(src->value() ^ jit_cookie())); 1071a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org Move(kScratchRegister, Smi::FromInt(jit_cookie())); 1072a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org xorp(Operand(rsp, 0), kScratchRegister); 1073a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org } else { 1074a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org ASSERT(SmiValuesAre31Bits()); 1075a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org int32_t value = static_cast<int32_t>(reinterpret_cast<intptr_t>(src)); 1076a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org Push(Immediate(value ^ jit_cookie())); 1077a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org xorp(Operand(rsp, 0), Immediate(jit_cookie())); 1078a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org } 10797a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org } else { 10807a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org Push(src); 10817a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org } 10827a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org} 10837a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org 10847a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org 108569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.orgRegister MacroAssembler::GetSmiConstant(Smi* source) { 108669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org int value = source->value(); 108769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org if (value == 0) { 108869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org xorl(kScratchRegister, kScratchRegister); 108969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return kScratchRegister; 109069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org } 109169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org if (value == 1) { 109269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return kSmiConstantRegister; 109369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org } 109469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org LoadSmiConstant(kScratchRegister, source); 109569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return kScratchRegister; 109669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org} 109769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 1098e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 109969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.orgvoid MacroAssembler::LoadSmiConstant(Register dst, Smi* source) { 1100badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 1101af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org Move(dst, Smi::FromInt(kSmiConstantRegisterValue), 1102af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org Assembler::RelocInfoNone()); 110369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org cmpq(dst, kSmiConstantRegister); 11048a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org Assert(equal, kUninitializedKSmiConstantRegister); 110569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org } 1106b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org int value = source->value(); 1107b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org if (value == 0) { 110869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org xorl(dst, dst); 110969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return; 111069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org } 111169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org bool negative = value < 0; 111269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org unsigned int uvalue = negative ? -value : value; 111369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 111469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org switch (uvalue) { 111569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org case 9: 1116895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org leap(dst, 1117895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org Operand(kSmiConstantRegister, kSmiConstantRegister, times_8, 0)); 111869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org break; 111969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org case 8: 112069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org xorl(dst, dst); 1121895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org leap(dst, Operand(dst, kSmiConstantRegister, times_8, 0)); 112269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org break; 112369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org case 4: 112469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org xorl(dst, dst); 1125895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org leap(dst, Operand(dst, kSmiConstantRegister, times_4, 0)); 112669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org break; 112769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org case 5: 1128895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org leap(dst, 1129895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org Operand(kSmiConstantRegister, kSmiConstantRegister, times_4, 0)); 113069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org break; 113169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org case 3: 1132895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org leap(dst, 1133895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org Operand(kSmiConstantRegister, kSmiConstantRegister, times_2, 0)); 113469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org break; 113569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org case 2: 1136895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org leap(dst, 1137895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org Operand(kSmiConstantRegister, kSmiConstantRegister, times_1, 0)); 113869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org break; 113969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org case 1: 114043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(dst, kSmiConstantRegister); 114169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org break; 114269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org case 0: 114369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org UNREACHABLE(); 114469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return; 114569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org default: 1146af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org Move(dst, source, Assembler::RelocInfoNone()); 114769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return; 114869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org } 114969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org if (negative) { 11507a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org negp(dst); 115169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org } 115269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org} 115369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 11544af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 1155c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.orgvoid MacroAssembler::Integer32ToSmi(Register dst, Register src) { 115680c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org STATIC_ASSERT(kSmiTag == 0); 11574af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org if (!dst.is(src)) { 11584af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org movl(dst, src); 11594af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 11602f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org shlp(dst, Immediate(kSmiShift)); 11614af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 11624af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 11634af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 11645ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.orgvoid MacroAssembler::Integer32ToSmiField(const Operand& dst, Register src) { 1165badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 11665ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org testb(dst, Immediate(0x01)); 116783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label ok; 116883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(zero, &ok, Label::kNear); 11698a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org Abort(kInteger32ToSmiFieldWritingToNonSmiLocation); 11705ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org bind(&ok); 11715ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org } 117204a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org 117304a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org if (SmiValuesAre32Bits()) { 117404a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org ASSERT(kSmiShift % kBitsPerByte == 0); 117504a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org movl(Operand(dst, kSmiShift / kBitsPerByte), src); 117604a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org } else { 117704a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org ASSERT(SmiValuesAre31Bits()); 117804a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org Integer32ToSmi(kScratchRegister, src); 117904a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org movp(dst, kScratchRegister); 118004a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org } 11815ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org} 11825ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org 11835ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org 11849d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::Integer64PlusConstantToSmi(Register dst, 11859d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com Register src, 11869d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com int constant) { 11879d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (dst.is(src)) { 11887979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org addl(dst, Immediate(constant)); 11899d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } else { 11907979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org leal(dst, Operand(src, constant)); 11919d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } 11922f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org shlp(dst, Immediate(kSmiShift)); 11934af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 11944af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 11954af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 11964af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgvoid MacroAssembler::SmiToInteger32(Register dst, Register src) { 119780c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org STATIC_ASSERT(kSmiTag == 0); 11984af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org if (!dst.is(src)) { 119943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(dst, src); 12004af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 120104a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org 120204a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org if (SmiValuesAre32Bits()) { 120304a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org shrp(dst, Immediate(kSmiShift)); 120404a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org } else { 120504a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org ASSERT(SmiValuesAre31Bits()); 120604a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org sarl(dst, Immediate(kSmiShift)); 120704a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org } 12084af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 12094af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 12104af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 121130ce411529579186181838984710b0b0980857aaricow@chromium.orgvoid MacroAssembler::SmiToInteger32(Register dst, const Operand& src) { 121204a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org if (SmiValuesAre32Bits()) { 121304a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org movl(dst, Operand(src, kSmiShift / kBitsPerByte)); 121404a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org } else { 121504a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org ASSERT(SmiValuesAre31Bits()); 121604a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org movl(dst, src); 121704a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org sarl(dst, Immediate(kSmiShift)); 121804a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org } 121930ce411529579186181838984710b0b0980857aaricow@chromium.org} 122030ce411529579186181838984710b0b0980857aaricow@chromium.org 122130ce411529579186181838984710b0b0980857aaricow@chromium.org 12224af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgvoid MacroAssembler::SmiToInteger64(Register dst, Register src) { 122380c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org STATIC_ASSERT(kSmiTag == 0); 12249d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (!dst.is(src)) { 122543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(dst, src); 12264af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 122704a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org sarp(dst, Immediate(kSmiShift)); 122804a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org if (kPointerSize == kInt32Size) { 122904a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org // Sign extend to 64-bit. 123004a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org movsxlq(dst, dst); 123104a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org } 12324af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 12334af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 12344af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 12355ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.orgvoid MacroAssembler::SmiToInteger64(Register dst, const Operand& src) { 123604a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org if (SmiValuesAre32Bits()) { 123704a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org movsxlq(dst, Operand(src, kSmiShift / kBitsPerByte)); 123804a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org } else { 123904a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org ASSERT(SmiValuesAre31Bits()); 124004a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org movp(dst, src); 124104a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org SmiToInteger64(dst, dst); 124204a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org } 12435ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org} 12445ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org 12455ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org 12469d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::SmiTest(Register src) { 1247ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org AssertSmi(src); 12487a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org testp(src, src); 12494af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 12504af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 12514af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 1252badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.orgvoid MacroAssembler::SmiCompare(Register smi1, Register smi2) { 1253c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org AssertSmi(smi1); 1254c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org AssertSmi(smi2); 12557a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(smi1, smi2); 12564af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 12574af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 12584af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 12599d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::SmiCompare(Register dst, Smi* src) { 1260c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org AssertSmi(dst); 1261badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org Cmp(dst, src); 1262badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org} 1263badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org 1264badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org 1265badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.orgvoid MacroAssembler::Cmp(Register dst, Smi* src) { 12669d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com ASSERT(!dst.is(kScratchRegister)); 12679d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (src->value() == 0) { 12687a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org testp(dst, dst); 12699d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } else { 1270ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org Register constant_reg = GetSmiConstant(src); 12717a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(dst, constant_reg); 12724af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 12734af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 12744af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 12754af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 12769155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.orgvoid MacroAssembler::SmiCompare(Register dst, const Operand& src) { 1277c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org AssertSmi(dst); 1278c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org AssertSmi(src); 12797a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(dst, src); 1280ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org} 1281ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 1282ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 12839d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::SmiCompare(const Operand& dst, Register src) { 1284c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org AssertSmi(dst); 1285c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org AssertSmi(src); 12867a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(dst, src); 1287c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org} 1288c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 1289c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 12909d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::SmiCompare(const Operand& dst, Smi* src) { 1291c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org AssertSmi(dst); 129204a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org if (SmiValuesAre32Bits()) { 129304a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org cmpl(Operand(dst, kSmiShift / kBitsPerByte), Immediate(src->value())); 129404a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org } else { 129504a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org ASSERT(SmiValuesAre31Bits()); 129604a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org cmpl(dst, Immediate(src)); 129704a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org } 12984af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 12994af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 13004af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 1301badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.orgvoid MacroAssembler::Cmp(const Operand& dst, Smi* src) { 1302badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org // The Operand cannot use the smi register. 1303badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org Register smi_reg = GetSmiConstant(src); 1304badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org ASSERT(!dst.AddressUsesRegister(smi_reg)); 13057a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(dst, smi_reg); 1306badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org} 1307badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org 1308badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org 13095ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.orgvoid MacroAssembler::SmiCompareInteger32(const Operand& dst, Register src) { 131004a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org if (SmiValuesAre32Bits()) { 131104a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org cmpl(Operand(dst, kSmiShift / kBitsPerByte), src); 131204a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org } else { 131304a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org ASSERT(SmiValuesAre31Bits()); 131404a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org SmiToInteger32(kScratchRegister, dst); 131504a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org cmpl(kScratchRegister, src); 131604a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org } 13175ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org} 13185ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org 13195ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org 13209d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::PositiveSmiTimesPowerOfTwoToInteger64(Register dst, 13219d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com Register src, 13229d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com int power) { 13239d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com ASSERT(power >= 0); 13249d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com ASSERT(power < 64); 13259d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (power == 0) { 13269d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com SmiToInteger64(dst, src); 13279d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com return; 13289d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } 13299d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (!dst.is(src)) { 133043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(dst, src); 13319d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } 13329d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (power < kSmiShift) { 13332f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org sarp(dst, Immediate(kSmiShift - power)); 13349d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } else if (power > kSmiShift) { 13352f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org shlp(dst, Immediate(power - kSmiShift)); 13369d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } 13374af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 13384af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 13394af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 134030ce411529579186181838984710b0b0980857aaricow@chromium.orgvoid MacroAssembler::PositiveSmiDivPowerOfTwoToInteger32(Register dst, 134130ce411529579186181838984710b0b0980857aaricow@chromium.org Register src, 134230ce411529579186181838984710b0b0980857aaricow@chromium.org int power) { 134330ce411529579186181838984710b0b0980857aaricow@chromium.org ASSERT((0 <= power) && (power < 32)); 134430ce411529579186181838984710b0b0980857aaricow@chromium.org if (dst.is(src)) { 13452f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org shrp(dst, Immediate(power + kSmiShift)); 134630ce411529579186181838984710b0b0980857aaricow@chromium.org } else { 134730ce411529579186181838984710b0b0980857aaricow@chromium.org UNIMPLEMENTED(); // Not used. 134830ce411529579186181838984710b0b0980857aaricow@chromium.org } 134930ce411529579186181838984710b0b0980857aaricow@chromium.org} 135030ce411529579186181838984710b0b0980857aaricow@chromium.org 135130ce411529579186181838984710b0b0980857aaricow@chromium.org 135283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::SmiOrIfSmis(Register dst, Register src1, Register src2, 135383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smis, 135483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 135583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (dst.is(src1) || dst.is(src2)) { 135683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src1.is(kScratchRegister)); 135783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src2.is(kScratchRegister)); 135843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(kScratchRegister, src1); 1359895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org orp(kScratchRegister, src2); 136083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org JumpIfNotSmi(kScratchRegister, on_not_smis, near_jump); 136143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(dst, kScratchRegister); 136283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 136343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(dst, src1); 1364895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org orp(dst, src2); 136583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org JumpIfNotSmi(dst, on_not_smis, near_jump); 136683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 136783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 136883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 136983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 13709d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comCondition MacroAssembler::CheckSmi(Register src) { 137180c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org STATIC_ASSERT(kSmiTag == 0); 13724af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org testb(src, Immediate(kSmiTagMask)); 13739d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com return zero; 13744af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 13754af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 13764af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 13770a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.orgCondition MacroAssembler::CheckSmi(const Operand& src) { 137880c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org STATIC_ASSERT(kSmiTag == 0); 13790a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org testb(src, Immediate(kSmiTagMask)); 13800a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org return zero; 13810a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org} 13820a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 13830a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 1384eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.orgCondition MacroAssembler::CheckNonNegativeSmi(Register src) { 138580c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org STATIC_ASSERT(kSmiTag == 0); 13868f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org // Test that both bits of the mask 0x8000000000000001 are zero. 138743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(kScratchRegister, src); 13882f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org rolp(kScratchRegister, Immediate(1)); 138969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org testb(kScratchRegister, Immediate(3)); 13904af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org return zero; 13914af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 13924af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 13934af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 13944af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgCondition MacroAssembler::CheckBothSmi(Register first, Register second) { 13954af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org if (first.is(second)) { 13964af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org return CheckSmi(first); 13974af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 139880c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org STATIC_ASSERT(kSmiTag == 0 && kHeapObjectTag == 1 && kHeapObjectTagMask == 3); 13994ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org if (SmiValuesAre32Bits()) { 14004ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org leal(kScratchRegister, Operand(first, second, times_1, 0)); 14014ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org testb(kScratchRegister, Immediate(0x03)); 14024ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org } else { 14034ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org ASSERT(SmiValuesAre31Bits()); 14044ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org movl(kScratchRegister, first); 14054ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org orl(kScratchRegister, second); 14064ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org testb(kScratchRegister, Immediate(kSmiTagMask)); 14074ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org } 14089d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com return zero; 14094af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 14104af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 14114af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 1412eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.orgCondition MacroAssembler::CheckBothNonNegativeSmi(Register first, 1413eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org Register second) { 1414b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (first.is(second)) { 1415eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org return CheckNonNegativeSmi(first); 1416b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 141743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(kScratchRegister, first); 1418895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org orp(kScratchRegister, second); 14192f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org rolp(kScratchRegister, Immediate(1)); 1420eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org testl(kScratchRegister, Immediate(3)); 1421b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org return zero; 1422b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 1423b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1424b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1425c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.orgCondition MacroAssembler::CheckEitherSmi(Register first, 1426c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org Register second, 1427c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org Register scratch) { 1428b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (first.is(second)) { 1429b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org return CheckSmi(first); 1430b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 1431c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org if (scratch.is(second)) { 1432c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org andl(scratch, first); 1433c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org } else { 1434c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org if (!scratch.is(first)) { 1435c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org movl(scratch, first); 1436c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org } 1437c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org andl(scratch, second); 1438c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org } 1439c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org testb(scratch, Immediate(kSmiTagMask)); 1440b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org return zero; 1441b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 1442b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1443b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 14444af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgCondition MacroAssembler::CheckIsMinSmi(Register src) { 144569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org ASSERT(!src.is(kScratchRegister)); 144669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org // If we overflow by subtracting one, it's the minimal smi value. 14477a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(src, kSmiConstantRegister); 144869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return overflow; 14494af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 14504af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 1451c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 14524af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgCondition MacroAssembler::CheckInteger32ValidSmiValue(Register src) { 14534ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org if (SmiValuesAre32Bits()) { 14544ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org // A 32-bit integer value can always be converted to a smi. 14554ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org return always; 14564ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org } else { 14574ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org ASSERT(SmiValuesAre31Bits()); 14584ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org cmpl(src, Immediate(0xc0000000)); 14594ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org return positive; 14604ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org } 14614af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 14624af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 14634af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 14643811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.orgCondition MacroAssembler::CheckUInteger32ValidSmiValue(Register src) { 14654ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org if (SmiValuesAre32Bits()) { 14664ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org // An unsigned 32-bit integer value is valid as long as the high bit 14674ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org // is not set. 14684ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org testl(src, src); 14694ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org return positive; 14704ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org } else { 14714ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org ASSERT(SmiValuesAre31Bits()); 14724ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org testl(src, Immediate(0xc0000000)); 14734ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org return zero; 14744ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org } 14753811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org} 14763811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 14773811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 14780ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.orgvoid MacroAssembler::CheckSmiToIndicator(Register dst, Register src) { 14790ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org if (dst.is(src)) { 14800ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org andl(dst, Immediate(kSmiTagMask)); 14810ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } else { 14820ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org movl(dst, Immediate(kSmiTagMask)); 14830ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org andl(dst, src); 14840ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } 14850ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org} 14860ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 14870ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 14880ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.orgvoid MacroAssembler::CheckSmiToIndicator(Register dst, const Operand& src) { 14890ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org if (!(src.AddressUsesRegister(dst))) { 14900ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org movl(dst, Immediate(kSmiTagMask)); 14910ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org andl(dst, src); 14920ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } else { 14930ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org movl(dst, src); 14940ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org andl(dst, Immediate(kSmiTagMask)); 14950ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } 14960ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org} 14970ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 14980ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 1499e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.orgvoid MacroAssembler::JumpIfValidSmiValue(Register src, 1500e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org Label* on_valid, 1501e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org Label::Distance near_jump) { 1502e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org Condition is_valid = CheckInteger32ValidSmiValue(src); 1503e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org j(is_valid, on_valid, near_jump); 1504e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org} 1505e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org 1506e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org 150783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::JumpIfNotValidSmiValue(Register src, 150883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_invalid, 150983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 151083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Condition is_valid = CheckInteger32ValidSmiValue(src); 151183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(NegateCondition(is_valid), on_invalid, near_jump); 151283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 151383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 151483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 1515e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.orgvoid MacroAssembler::JumpIfUIntValidSmiValue(Register src, 1516e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org Label* on_valid, 1517e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org Label::Distance near_jump) { 1518e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org Condition is_valid = CheckUInteger32ValidSmiValue(src); 1519e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org j(is_valid, on_valid, near_jump); 1520e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org} 1521e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org 1522e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org 152383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::JumpIfUIntNotValidSmiValue(Register src, 152483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_invalid, 152583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 152683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Condition is_valid = CheckUInteger32ValidSmiValue(src); 152783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(NegateCondition(is_valid), on_invalid, near_jump); 152883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 152983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 153083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 153183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::JumpIfSmi(Register src, 153283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_smi, 153383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 153483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Condition smi = CheckSmi(src); 153583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(smi, on_smi, near_jump); 153683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 153783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 153883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 153983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::JumpIfNotSmi(Register src, 154083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi, 154183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 154283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Condition smi = CheckSmi(src); 154383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(NegateCondition(smi), on_not_smi, near_jump); 154483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 154583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 154683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 154783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::JumpUnlessNonNegativeSmi( 154883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src, Label* on_not_smi_or_negative, 154983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 155083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Condition non_negative_smi = CheckNonNegativeSmi(src); 155183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(NegateCondition(non_negative_smi), on_not_smi_or_negative, near_jump); 155283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 155383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 155483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 155583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::JumpIfSmiEqualsConstant(Register src, 155683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Smi* constant, 155783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_equals, 155883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 155983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org SmiCompare(src, constant); 156083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(equal, on_equals, near_jump); 156183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 156283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 156383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 156483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::JumpIfNotBothSmi(Register src1, 156583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src2, 156683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_both_smi, 156783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 156883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Condition both_smi = CheckBothSmi(src1, src2); 156983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(NegateCondition(both_smi), on_not_both_smi, near_jump); 157083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 157183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 157283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 157383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::JumpUnlessBothNonNegativeSmi(Register src1, 157483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src2, 157583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_both_smi, 157683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 157783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Condition both_smi = CheckBothNonNegativeSmi(src1, src2); 157883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(NegateCondition(both_smi), on_not_both_smi, near_jump); 157983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 158083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 158183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 15829d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::SmiAddConstant(Register dst, Register src, Smi* constant) { 15839d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (constant->value() == 0) { 15849d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (!dst.is(src)) { 158543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(dst, src); 15869d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } 158769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return; 15889d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } else if (dst.is(src)) { 15899d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com ASSERT(!dst.is(kScratchRegister)); 159069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org switch (constant->value()) { 159169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org case 1: 1592fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org addp(dst, kSmiConstantRegister); 159369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return; 159469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org case 2: 1595895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org leap(dst, Operand(src, kSmiConstantRegister, times_2, 0)); 159669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return; 159769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org case 4: 1598895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org leap(dst, Operand(src, kSmiConstantRegister, times_4, 0)); 159969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return; 160069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org case 8: 1601895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org leap(dst, Operand(src, kSmiConstantRegister, times_8, 0)); 160269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return; 160369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org default: 160469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org Register constant_reg = GetSmiConstant(constant); 1605fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org addp(dst, constant_reg); 160669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return; 160769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org } 16084af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } else { 160969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org switch (constant->value()) { 161069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org case 1: 1611895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org leap(dst, Operand(src, kSmiConstantRegister, times_1, 0)); 161269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return; 161369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org case 2: 1614895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org leap(dst, Operand(src, kSmiConstantRegister, times_2, 0)); 161569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return; 161669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org case 4: 1617895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org leap(dst, Operand(src, kSmiConstantRegister, times_4, 0)); 161869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return; 161969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org case 8: 1620895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org leap(dst, Operand(src, kSmiConstantRegister, times_8, 0)); 162169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return; 162269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org default: 162369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org LoadSmiConstant(dst, constant); 1624fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org addp(dst, src); 162569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org return; 162669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org } 16274af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 16284af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 16294af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 16304af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 16319dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.comvoid MacroAssembler::SmiAddConstant(const Operand& dst, Smi* constant) { 16329dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com if (constant->value() != 0) { 16334ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org if (SmiValuesAre32Bits()) { 16344ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org addl(Operand(dst, kSmiShift / kBitsPerByte), 16354ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org Immediate(constant->value())); 16364ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org } else { 16374ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org ASSERT(SmiValuesAre31Bits()); 16384ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org addp(dst, Immediate(constant)); 16394ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org } 16409dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com } 16419dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com} 16429dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 16439dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 164483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::SmiAddConstant(Register dst, 164583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src, 164683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Smi* constant, 1647e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org SmiOperationExecutionMode mode, 1648e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Label* bailout_label, 164983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 165083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (constant->value() == 0) { 165183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (!dst.is(src)) { 165243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(dst, src); 165383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 165483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else if (dst.is(src)) { 165583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!dst.is(kScratchRegister)); 165683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org LoadSmiConstant(kScratchRegister, constant); 1657fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org addp(dst, kScratchRegister); 1658e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (mode.Contains(BAILOUT_ON_NO_OVERFLOW)) { 1659e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org j(no_overflow, bailout_label, near_jump); 1660e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org ASSERT(mode.Contains(PRESERVE_SOURCE_REGISTER)); 1661fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org subp(dst, kScratchRegister); 1662e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } else if (mode.Contains(BAILOUT_ON_OVERFLOW)) { 1663e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (mode.Contains(PRESERVE_SOURCE_REGISTER)) { 1664e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Label done; 1665e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org j(no_overflow, &done, Label::kNear); 1666fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org subp(dst, kScratchRegister); 1667e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org jmp(bailout_label, near_jump); 1668e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org bind(&done); 1669e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } else { 1670e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // Bailout if overflow without reserving src. 1671e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org j(overflow, bailout_label, near_jump); 1672e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 1673e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } else { 1674e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org CHECK(mode.IsEmpty()); 1675e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 167683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 1677e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org ASSERT(mode.Contains(PRESERVE_SOURCE_REGISTER)); 1678e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org ASSERT(mode.Contains(BAILOUT_ON_OVERFLOW)); 167983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org LoadSmiConstant(dst, constant); 1680fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org addp(dst, src); 1681e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org j(overflow, bailout_label, near_jump); 168283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 168383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 168483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 168583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 16869d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::SmiSubConstant(Register dst, Register src, Smi* constant) { 16879d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (constant->value() == 0) { 16884af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org if (!dst.is(src)) { 168943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(dst, src); 16904af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 16919d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } else if (dst.is(src)) { 16929d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com ASSERT(!dst.is(kScratchRegister)); 169369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org Register constant_reg = GetSmiConstant(constant); 1694fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org subp(dst, constant_reg); 16959d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } else { 16969d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (constant->value() == Smi::kMinValue) { 169769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org LoadSmiConstant(dst, constant); 16985ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org // Adding and subtracting the min-value gives the same result, it only 16995ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org // differs on the overflow bit, which we don't check here. 1700fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org addp(dst, src); 17014af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } else { 17025ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org // Subtract by adding the negation. 170369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org LoadSmiConstant(dst, Smi::FromInt(-constant->value())); 1704fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org addp(dst, src); 17054af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 17064af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 17074af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 17084af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 17094af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 171083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::SmiSubConstant(Register dst, 171183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src, 171283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Smi* constant, 1713e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org SmiOperationExecutionMode mode, 1714e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Label* bailout_label, 171583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 171683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (constant->value() == 0) { 171783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (!dst.is(src)) { 171843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(dst, src); 171983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 172083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else if (dst.is(src)) { 172183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!dst.is(kScratchRegister)); 1722e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org LoadSmiConstant(kScratchRegister, constant); 1723fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org subp(dst, kScratchRegister); 1724e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (mode.Contains(BAILOUT_ON_NO_OVERFLOW)) { 1725e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org j(no_overflow, bailout_label, near_jump); 1726e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org ASSERT(mode.Contains(PRESERVE_SOURCE_REGISTER)); 1727fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org addp(dst, kScratchRegister); 1728e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } else if (mode.Contains(BAILOUT_ON_OVERFLOW)) { 1729e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (mode.Contains(PRESERVE_SOURCE_REGISTER)) { 1730e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Label done; 1731e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org j(no_overflow, &done, Label::kNear); 1732fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org addp(dst, kScratchRegister); 1733e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org jmp(bailout_label, near_jump); 1734e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org bind(&done); 1735e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } else { 1736e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // Bailout if overflow without reserving src. 1737e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org j(overflow, bailout_label, near_jump); 1738e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 173983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 1740e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org CHECK(mode.IsEmpty()); 174183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 174283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 1743e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org ASSERT(mode.Contains(PRESERVE_SOURCE_REGISTER)); 1744e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org ASSERT(mode.Contains(BAILOUT_ON_OVERFLOW)); 174583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (constant->value() == Smi::kMinValue) { 1746e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org ASSERT(!dst.is(kScratchRegister)); 174743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(dst, src); 1748e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org LoadSmiConstant(kScratchRegister, constant); 1749fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org subp(dst, kScratchRegister); 1750e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org j(overflow, bailout_label, near_jump); 175183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 175283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Subtract by adding the negation. 175383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org LoadSmiConstant(dst, Smi::FromInt(-(constant->value()))); 1754fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org addp(dst, src); 1755e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org j(overflow, bailout_label, near_jump); 175683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 175783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 175883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 175983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 176083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 176183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::SmiNeg(Register dst, 176283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src, 176383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_smi_result, 176483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 176583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (dst.is(src)) { 176683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!dst.is(kScratchRegister)); 176743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(kScratchRegister, src); 17687a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org negp(dst); // Low 32 bits are retained as zero by negation. 176983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Test if result is zero or Smi::kMinValue. 17707a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(dst, kScratchRegister); 177183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(not_equal, on_smi_result, near_jump); 177243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(src, kScratchRegister); 177383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 177443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(dst, src); 17757a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org negp(dst); 17767a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(dst, src); 177783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // If the result is zero or Smi::kMinValue, negation failed to create a smi. 177883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(not_equal, on_smi_result, near_jump); 177983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 178083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 178183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 178283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 1783d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.orgtemplate<class T> 1784d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.orgstatic void SmiAddHelper(MacroAssembler* masm, 1785d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Register dst, 1786d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Register src1, 1787d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org T src2, 1788d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Label* on_not_smi_result, 1789d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Label::Distance near_jump) { 1790d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org if (dst.is(src1)) { 1791d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Label done; 1792fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org masm->addp(dst, src2); 1793d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org masm->j(no_overflow, &done, Label::kNear); 1794d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org // Restore src1. 1795fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org masm->subp(dst, src2); 1796d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org masm->jmp(on_not_smi_result, near_jump); 1797d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org masm->bind(&done); 1798d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } else { 179943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org masm->movp(dst, src1); 1800fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org masm->addp(dst, src2); 1801d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org masm->j(overflow, on_not_smi_result, near_jump); 1802d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } 1803d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org} 1804d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 1805d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 180683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::SmiAdd(Register dst, 180783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src1, 180883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src2, 180983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi_result, 181083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 181183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT_NOT_NULL(on_not_smi_result); 181283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!dst.is(src2)); 1813d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org SmiAddHelper<Register>(this, dst, src1, src2, on_not_smi_result, near_jump); 181483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 181583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 181683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 181783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::SmiAdd(Register dst, 181883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src1, 181983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org const Operand& src2, 182083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi_result, 182183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 182283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT_NOT_NULL(on_not_smi_result); 1823d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ASSERT(!src2.AddressUsesRegister(dst)); 1824d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org SmiAddHelper<Operand>(this, dst, src1, src2, on_not_smi_result, near_jump); 182583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 182683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 182783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 1828c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.orgvoid MacroAssembler::SmiAdd(Register dst, 1829c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org Register src1, 1830c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org Register src2) { 1831c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org // No overflow checking. Use only when it's known that 1832c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org // overflowing is impossible. 18337979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org if (!dst.is(src1)) { 1834160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org if (emit_debug_code()) { 183543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(kScratchRegister, src1); 1836fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org addp(kScratchRegister, src2); 1837594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(no_overflow, kSmiAdditionOverflow); 1838160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } 1839895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org leap(dst, Operand(src1, src2, times_1, 0)); 1840160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org } else { 1841fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org addp(dst, src2); 1842594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Assert(no_overflow, kSmiAdditionOverflow); 18434af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 18444af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 18454af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 18464af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 1847c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgtemplate<class T> 1848c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgstatic void SmiSubHelper(MacroAssembler* masm, 1849c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org Register dst, 1850c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org Register src1, 1851c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org T src2, 1852c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org Label* on_not_smi_result, 1853c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org Label::Distance near_jump) { 185483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (dst.is(src1)) { 1855c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org Label done; 1856fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org masm->subp(dst, src2); 1857c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org masm->j(no_overflow, &done, Label::kNear); 1858c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org // Restore src1. 1859fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org masm->addp(dst, src2); 1860c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org masm->jmp(on_not_smi_result, near_jump); 1861c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org masm->bind(&done); 186283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 186343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org masm->movp(dst, src1); 1864fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org masm->subp(dst, src2); 1865c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org masm->j(overflow, on_not_smi_result, near_jump); 186683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 186783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 186883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 186983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 1870c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgvoid MacroAssembler::SmiSub(Register dst, 1871c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org Register src1, 1872c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org Register src2, 1873c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org Label* on_not_smi_result, 1874c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org Label::Distance near_jump) { 1875c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org ASSERT_NOT_NULL(on_not_smi_result); 1876c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org ASSERT(!dst.is(src2)); 1877c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org SmiSubHelper<Register>(this, dst, src1, src2, on_not_smi_result, near_jump); 18784af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 18794af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 18804af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 1881c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.orgvoid MacroAssembler::SmiSub(Register dst, 18824af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src1, 188383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org const Operand& src2, 188483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi_result, 188583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 188683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT_NOT_NULL(on_not_smi_result); 1887c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org ASSERT(!src2.AddressUsesRegister(dst)); 1888c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org SmiSubHelper<Operand>(this, dst, src1, src2, on_not_smi_result, near_jump); 188983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 189083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 189183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 1892c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgtemplate<class T> 1893c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgstatic void SmiSubNoOverflowHelper(MacroAssembler* masm, 1894c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org Register dst, 1895c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org Register src1, 1896c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org T src2) { 1897c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org // No overflow checking. Use only when it's known that 1898c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org // overflowing is impossible (e.g., subtracting two positive smis). 18997979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org if (!dst.is(src1)) { 190043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org masm->movp(dst, src1); 19014af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 1902fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org masm->subp(dst, src2); 1903c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org masm->Assert(no_overflow, kSmiSubtractionOverflow); 1904c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org} 1905c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org 1906c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org 1907c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgvoid MacroAssembler::SmiSub(Register dst, Register src1, Register src2) { 1908c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org ASSERT(!dst.is(src2)); 1909c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org SmiSubNoOverflowHelper<Register>(this, dst, src1, src2); 1910c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org} 1911c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org 1912c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org 1913c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.orgvoid MacroAssembler::SmiSub(Register dst, 1914c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org Register src1, 1915c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org const Operand& src2) { 1916c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org SmiSubNoOverflowHelper<Operand>(this, dst, src1, src2); 19174af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 19184af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 19194af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 192083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::SmiMul(Register dst, 192183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src1, 192283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src2, 192383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi_result, 192483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 192583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!dst.is(src2)); 192683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!dst.is(kScratchRegister)); 192783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src1.is(kScratchRegister)); 192883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src2.is(kScratchRegister)); 192983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 193083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (dst.is(src1)) { 193183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label failure, zero_correct_result; 193243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(kScratchRegister, src1); // Create backup for later testing. 193383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org SmiToInteger64(dst, src1); 1934fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org imulp(dst, src2); 193583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(overflow, &failure, Label::kNear); 193683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 193783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Check for negative zero result. If product is zero, and one 193883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // argument is negative, go to slow case. 193983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label correct_result; 19407a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org testp(dst, dst); 194183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(not_zero, &correct_result, Label::kNear); 194283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 194343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(dst, kScratchRegister); 1944895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org xorp(dst, src2); 194583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Result was positive zero. 194683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(positive, &zero_correct_result, Label::kNear); 194783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 194883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org bind(&failure); // Reused failure exit, restores src1. 194943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(src1, kScratchRegister); 195083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org jmp(on_not_smi_result, near_jump); 195183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 195283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org bind(&zero_correct_result); 195383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Set(dst, 0); 195483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 195583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org bind(&correct_result); 195683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 195783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org SmiToInteger64(dst, src1); 1958fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org imulp(dst, src2); 195983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(overflow, on_not_smi_result, near_jump); 196083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Check for negative zero result. If product is zero, and one 196183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // argument is negative, go to slow case. 196283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label correct_result; 19637a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org testp(dst, dst); 196483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(not_zero, &correct_result, Label::kNear); 196583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // One of src1 and src2 is zero, the check whether the other is 196683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // negative. 196743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(kScratchRegister, src1); 1968895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org xorp(kScratchRegister, src2); 196983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(negative, on_not_smi_result, near_jump); 197083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org bind(&correct_result); 197183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 197283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 197383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 197483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 197583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::SmiDiv(Register dst, 197683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src1, 197783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src2, 197883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi_result, 197983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 198083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src1.is(kScratchRegister)); 198183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src2.is(kScratchRegister)); 198283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!dst.is(kScratchRegister)); 198383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src2.is(rax)); 198483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src2.is(rdx)); 198583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src1.is(rdx)); 198683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 198783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Check for 0 divisor (result is +/-Infinity). 19887a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org testp(src2, src2); 198983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(zero, on_not_smi_result, near_jump); 199083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 199183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (src1.is(rax)) { 199243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(kScratchRegister, src1); 199383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 199483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org SmiToInteger32(rax, src1); 199583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // We need to rule out dividing Smi::kMinValue by -1, since that would 199683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // overflow in idiv and raise an exception. 199783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // We combine this with negative zero test (negative zero only happens 199883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // when dividing zero by a negative number). 199983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 200083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // We overshoot a little and go to slow case if we divide min-value 200183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // by any negative value, not just -1. 200283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label safe_div; 2003e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org testl(rax, Immediate(~Smi::kMinValue)); 200483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(not_zero, &safe_div, Label::kNear); 20057a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org testp(src2, src2); 200683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (src1.is(rax)) { 200783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(positive, &safe_div, Label::kNear); 200843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(src1, kScratchRegister); 200983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org jmp(on_not_smi_result, near_jump); 201083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 201183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(negative, on_not_smi_result, near_jump); 201283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 201383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org bind(&safe_div); 201483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 201583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org SmiToInteger32(src2, src2); 201683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Sign extend src1 into edx:eax. 201783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org cdq(); 201883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org idivl(src2); 201983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Integer32ToSmi(src2, src2); 202083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Check that the remainder is zero. 202183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org testl(rdx, rdx); 202283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (src1.is(rax)) { 202383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label smi_result; 202483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(zero, &smi_result, Label::kNear); 202543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(src1, kScratchRegister); 202683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org jmp(on_not_smi_result, near_jump); 202783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org bind(&smi_result); 202883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 202983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(not_zero, on_not_smi_result, near_jump); 203083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 203183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (!dst.is(src1) && src1.is(rax)) { 203243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(src1, kScratchRegister); 203383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 203483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Integer32ToSmi(dst, rax); 203583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 203683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 203783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 203883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::SmiMod(Register dst, 203983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src1, 204083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src2, 204183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi_result, 204283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 204383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!dst.is(kScratchRegister)); 204483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src1.is(kScratchRegister)); 204583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src2.is(kScratchRegister)); 204683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src2.is(rax)); 204783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src2.is(rdx)); 204883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src1.is(rdx)); 204983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src1.is(src2)); 205083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 20517a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org testp(src2, src2); 205283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(zero, on_not_smi_result, near_jump); 205383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 205483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (src1.is(rax)) { 205543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(kScratchRegister, src1); 205683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 205783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org SmiToInteger32(rax, src1); 205883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org SmiToInteger32(src2, src2); 205983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 206083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Test for the edge case of dividing Smi::kMinValue by -1 (will overflow). 206183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label safe_div; 206283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org cmpl(rax, Immediate(Smi::kMinValue)); 206383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(not_equal, &safe_div, Label::kNear); 206483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org cmpl(src2, Immediate(-1)); 206583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(not_equal, &safe_div, Label::kNear); 206683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Retag inputs and go slow case. 206783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Integer32ToSmi(src2, src2); 206883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (src1.is(rax)) { 206943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(src1, kScratchRegister); 207083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 207183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org jmp(on_not_smi_result, near_jump); 207283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org bind(&safe_div); 207383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 207483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Sign extend eax into edx:eax. 207583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org cdq(); 207683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org idivl(src2); 207783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Restore smi tags on inputs. 207883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Integer32ToSmi(src2, src2); 207983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (src1.is(rax)) { 208043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(src1, kScratchRegister); 208183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 208283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Check for a negative zero result. If the result is zero, and the 208383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // dividend is negative, go slow to return a floating point negative zero. 208483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label smi_result; 208583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org testl(rdx, rdx); 208683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(not_zero, &smi_result, Label::kNear); 20877a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org testp(src1, src1); 208883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(negative, on_not_smi_result, near_jump); 208983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org bind(&smi_result); 209083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Integer32ToSmi(dst, rdx); 209183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 209283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 209383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 20944af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgvoid MacroAssembler::SmiNot(Register dst, Register src) { 20959d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com ASSERT(!dst.is(kScratchRegister)); 20969d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com ASSERT(!src.is(kScratchRegister)); 20974ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org if (SmiValuesAre32Bits()) { 20984ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org // Set tag and padding bits before negating, so that they are zero 20994ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org // afterwards. 21004ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org movl(kScratchRegister, Immediate(~0)); 21014ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org } else { 21024ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org ASSERT(SmiValuesAre31Bits()); 21034ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org movl(kScratchRegister, Immediate(1)); 21044ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org } 21054af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org if (dst.is(src)) { 2106895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org xorp(dst, kScratchRegister); 21074af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } else { 2108895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org leap(dst, Operand(src, kScratchRegister, times_1, 0)); 21094af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 2110895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org notp(dst); 21114af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 21124af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 21134af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 21144af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgvoid MacroAssembler::SmiAnd(Register dst, Register src1, Register src2) { 21159d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com ASSERT(!dst.is(src2)); 21164af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org if (!dst.is(src1)) { 211743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(dst, src1); 21184af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 2119895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org andp(dst, src2); 21204af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 21214af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 21224af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 21239d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::SmiAndConstant(Register dst, Register src, Smi* constant) { 21249d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (constant->value() == 0) { 21255d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Set(dst, 0); 21269d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } else if (dst.is(src)) { 21279d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com ASSERT(!dst.is(kScratchRegister)); 212869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org Register constant_reg = GetSmiConstant(constant); 2129895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org andp(dst, constant_reg); 21309d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } else { 213169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org LoadSmiConstant(dst, constant); 2132895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org andp(dst, src); 21334af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 21344af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 21354af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 21364af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 21374af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgvoid MacroAssembler::SmiOr(Register dst, Register src1, Register src2) { 21384af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org if (!dst.is(src1)) { 213944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org ASSERT(!src1.is(src2)); 214043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(dst, src1); 21414af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 2142895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org orp(dst, src2); 21434af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 21444af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 21454af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 21469d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::SmiOrConstant(Register dst, Register src, Smi* constant) { 21479d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (dst.is(src)) { 21489d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com ASSERT(!dst.is(kScratchRegister)); 214969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org Register constant_reg = GetSmiConstant(constant); 2150895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org orp(dst, constant_reg); 21519d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } else { 215269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org LoadSmiConstant(dst, constant); 2153895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org orp(dst, src); 21544af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 21554af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 21564af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 21579d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com 21584af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgvoid MacroAssembler::SmiXor(Register dst, Register src1, Register src2) { 21594af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org if (!dst.is(src1)) { 216044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org ASSERT(!src1.is(src2)); 216143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(dst, src1); 21624af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 2163895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org xorp(dst, src2); 21644af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 21654af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 21664af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 21679d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comvoid MacroAssembler::SmiXorConstant(Register dst, Register src, Smi* constant) { 21689d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (dst.is(src)) { 21699d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com ASSERT(!dst.is(kScratchRegister)); 217069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org Register constant_reg = GetSmiConstant(constant); 2171895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org xorp(dst, constant_reg); 21729d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } else { 217369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org LoadSmiConstant(dst, constant); 2174895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org xorp(dst, src); 21754af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 21764af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 21774af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 21784af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 21794af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgvoid MacroAssembler::SmiShiftArithmeticRightConstant(Register dst, 21804af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src, 21814af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org int shift_value) { 21829d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com ASSERT(is_uint5(shift_value)); 21834af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org if (shift_value > 0) { 21844af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org if (dst.is(src)) { 21852f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org sarp(dst, Immediate(shift_value + kSmiShift)); 21862f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org shlp(dst, Immediate(kSmiShift)); 21874af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } else { 21884af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org UNIMPLEMENTED(); // Not used. 21894af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 21904af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 21914af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 21924af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 21934af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 21944af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgvoid MacroAssembler::SmiShiftLeftConstant(Register dst, 21954af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src, 2196e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org int shift_value, 2197e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org Label* on_not_smi_result, 2198e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org Label::Distance near_jump) { 2199e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org if (SmiValuesAre32Bits()) { 2200e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org if (!dst.is(src)) { 2201e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org movp(dst, src); 2202e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org } 2203e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org if (shift_value > 0) { 2204e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org // Shift amount specified by lower 5 bits, not six as the shl opcode. 2205e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org shlq(dst, Immediate(shift_value & 0x1f)); 2206e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org } 2207e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org } else { 2208e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org ASSERT(SmiValuesAre31Bits()); 2209e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org if (dst.is(src)) { 2210e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org UNIMPLEMENTED(); // Not used. 2211e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org } else { 2212e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org SmiToInteger32(dst, src); 2213e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org shll(dst, Immediate(shift_value)); 2214e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org JumpIfNotValidSmiValue(dst, on_not_smi_result, near_jump); 2215e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org Integer32ToSmi(dst, dst); 2216e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org } 22174af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 22184af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 22194af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 22204af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 222183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::SmiShiftLogicalRightConstant( 222283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register dst, Register src, int shift_value, 222383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi_result, Label::Distance near_jump) { 222483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Logic right shift interprets its result as an *unsigned* number. 222583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (dst.is(src)) { 222683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org UNIMPLEMENTED(); // Not used. 222783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 222883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (shift_value == 0) { 2229e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org testp(src, src); 223083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(negative, on_not_smi_result, near_jump); 223183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 2232e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org if (SmiValuesAre32Bits()) { 2233e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org movp(dst, src); 2234e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org shrp(dst, Immediate(shift_value + kSmiShift)); 2235e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org shlp(dst, Immediate(kSmiShift)); 2236e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org } else { 2237e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org ASSERT(SmiValuesAre31Bits()); 2238e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org SmiToInteger32(dst, src); 2239e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org shrp(dst, Immediate(shift_value)); 2240e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org JumpIfUIntNotValidSmiValue(dst, on_not_smi_result, near_jump); 2241e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org Integer32ToSmi(dst, dst); 2242e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org } 224383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 224483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 224583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 224683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 22474af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgvoid MacroAssembler::SmiShiftLeft(Register dst, 22484af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src1, 2249e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org Register src2, 2250e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org Label* on_not_smi_result, 2251e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org Label::Distance near_jump) { 2252e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org if (SmiValuesAre32Bits()) { 2253e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org ASSERT(!dst.is(rcx)); 2254e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org if (!dst.is(src1)) { 2255e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org movp(dst, src1); 2256e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org } 2257e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org // Untag shift amount. 2258e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org SmiToInteger32(rcx, src2); 2259e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org // Shift amount specified by lower 5 bits, not six as the shl opcode. 2260e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org andp(rcx, Immediate(0x1f)); 2261e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org shlq_cl(dst); 2262e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org } else { 2263e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org ASSERT(SmiValuesAre31Bits()); 2264e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org ASSERT(!dst.is(kScratchRegister)); 2265e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org ASSERT(!src1.is(kScratchRegister)); 2266e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org ASSERT(!src2.is(kScratchRegister)); 2267e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org ASSERT(!dst.is(src2)); 2268e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org ASSERT(!dst.is(rcx)); 2269e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org 2270e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org if (src1.is(rcx) || src2.is(rcx)) { 2271e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org movq(kScratchRegister, rcx); 2272e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org } 2273e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org if (dst.is(src1)) { 2274e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org UNIMPLEMENTED(); // Not used. 2275e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org } else { 2276e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org Label valid_result; 2277e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org SmiToInteger32(dst, src1); 2278e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org SmiToInteger32(rcx, src2); 2279e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org shll_cl(dst); 2280e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org JumpIfValidSmiValue(dst, &valid_result, Label::kNear); 2281e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org // As src1 or src2 could not be dst, we do not need to restore them for 2282e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org // clobbering dst. 2283e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org if (src1.is(rcx) || src2.is(rcx)) { 2284e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org if (src1.is(rcx)) { 2285e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org movq(src1, kScratchRegister); 2286e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org } else { 2287e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org movq(src2, kScratchRegister); 2288e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org } 2289e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org } 2290e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org jmp(on_not_smi_result, near_jump); 2291e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org bind(&valid_result); 2292e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org Integer32ToSmi(dst, dst); 2293e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org } 22944af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org } 22954af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 22964af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 22974af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 229883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::SmiShiftLogicalRight(Register dst, 229983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src1, 230083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src2, 230183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smi_result, 230283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 230383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!dst.is(kScratchRegister)); 230483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src1.is(kScratchRegister)); 230583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src2.is(kScratchRegister)); 2306e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org ASSERT(!dst.is(src2)); 230783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!dst.is(rcx)); 230883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (src1.is(rcx) || src2.is(rcx)) { 230983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movq(kScratchRegister, rcx); 231083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 2311e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org if (dst.is(src1)) { 2312e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org UNIMPLEMENTED(); // Not used. 231383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 2314e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org Label valid_result; 2315e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org SmiToInteger32(dst, src1); 2316e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org SmiToInteger32(rcx, src2); 2317e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org shrl_cl(dst); 2318e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org JumpIfUIntValidSmiValue(dst, &valid_result, Label::kNear); 2319e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org // As src1 or src2 could not be dst, we do not need to restore them for 2320e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org // clobbering dst. 2321e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org if (src1.is(rcx) || src2.is(rcx)) { 2322e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org if (src1.is(rcx)) { 2323e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org movq(src1, kScratchRegister); 2324e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org } else { 2325e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org movq(src2, kScratchRegister); 2326e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org } 2327e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org } 2328e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org jmp(on_not_smi_result, near_jump); 2329e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org bind(&valid_result); 2330e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org Integer32ToSmi(dst, dst); 233183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 233283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 233383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 233483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 23354af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgvoid MacroAssembler::SmiShiftArithmeticRight(Register dst, 23364af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src1, 23374af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src2) { 23389d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com ASSERT(!dst.is(kScratchRegister)); 23399d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com ASSERT(!src1.is(kScratchRegister)); 23409d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com ASSERT(!src2.is(kScratchRegister)); 23414af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org ASSERT(!dst.is(rcx)); 2342e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org 2343e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org SmiToInteger32(rcx, src2); 23449d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (!dst.is(src1)) { 234543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(dst, src1); 23469d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } 2347e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org SmiToInteger32(dst, dst); 2348e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org sarl_cl(dst); 2349e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org Integer32ToSmi(dst, dst); 23504af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 23514af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 23524af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 235383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::SelectNonSmi(Register dst, 235483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src1, 235583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register src2, 235683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_not_smis, 235783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 235883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!dst.is(kScratchRegister)); 235983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src1.is(kScratchRegister)); 236083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!src2.is(kScratchRegister)); 236183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!dst.is(src1)); 236283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(!dst.is(src2)); 236383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Both operands must not be smis. 236483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org#ifdef DEBUG 23658a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org Condition not_both_smis = NegateCondition(CheckBothSmi(src1, src2)); 23668a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org Check(not_both_smis, kBothRegistersWereSmisInSelectNonSmi); 236783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org#endif 236880c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org STATIC_ASSERT(kSmiTag == 0); 236983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT_EQ(0, Smi::FromInt(0)); 237083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movl(kScratchRegister, Immediate(kSmiTagMask)); 2371895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org andp(kScratchRegister, src1); 237283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org testl(kScratchRegister, src2); 237383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // If non-zero then both are smis. 237483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(not_zero, on_not_smis, near_jump); 237583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 237683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Exactly one operand is a smi. 237783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT_EQ(1, static_cast<int>(kSmiTagMask)); 237883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // kScratchRegister still holds src1 & kSmiTag, which is either zero or one. 2379fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org subp(kScratchRegister, Immediate(1)); 238083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // If src1 is a smi, then scratch register all 1s, else it is all 0s. 238143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(dst, src1); 2382895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org xorp(dst, src2); 2383895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org andp(dst, kScratchRegister); 238483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // If src1 is a smi, dst holds src1 ^ src2, else it is zero. 2385895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org xorp(dst, src1); 238683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // If src1 is a smi, dst is src2, else it is src1, i.e., the non-smi. 238783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 238883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 238983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 23909d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.comSmiIndex MacroAssembler::SmiToIndex(Register dst, 23919d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com Register src, 23929d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com int shift) { 2393a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org if (SmiValuesAre32Bits()) { 2394a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org ASSERT(is_uint6(shift)); 2395a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // There is a possible optimization if shift is in the range 60-63, but that 2396a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // will (and must) never happen. 2397a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org if (!dst.is(src)) { 2398a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org movp(dst, src); 2399a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org } 2400a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org if (shift < kSmiShift) { 2401a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org sarp(dst, Immediate(kSmiShift - shift)); 2402a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org } else { 2403a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org shlp(dst, Immediate(shift - kSmiShift)); 2404a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org } 2405a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org return SmiIndex(dst, times_1); 24069d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } else { 2407a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org ASSERT(SmiValuesAre31Bits()); 2408a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org ASSERT(shift >= times_1 && shift <= (static_cast<int>(times_8) + 1)); 2409a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org if (!dst.is(src)) { 2410a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org movp(dst, src); 2411a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org } 2412a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // We have to sign extend the index register to 64-bit as the SMI might 2413a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // be negative. 2414a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org movsxlq(dst, dst); 2415a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org if (shift == times_1) { 2416a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org sarq(dst, Immediate(kSmiShift)); 2417a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org return SmiIndex(dst, times_1); 2418a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org } 2419a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org return SmiIndex(dst, static_cast<ScaleFactor>(shift - 1)); 24209d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } 24214af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 24224af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 2423a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 24244af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgSmiIndex MacroAssembler::SmiToNegativeIndex(Register dst, 24254af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org Register src, 24264af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org int shift) { 2427a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org if (SmiValuesAre32Bits()) { 2428a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // Register src holds a positive smi. 2429a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org ASSERT(is_uint6(shift)); 2430a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org if (!dst.is(src)) { 2431a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org movp(dst, src); 2432a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org } 2433a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org negp(dst); 2434a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org if (shift < kSmiShift) { 2435a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org sarp(dst, Immediate(kSmiShift - shift)); 2436a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org } else { 2437a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org shlp(dst, Immediate(shift - kSmiShift)); 2438a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org } 2439a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org return SmiIndex(dst, times_1); 24409d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } else { 2441a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org ASSERT(SmiValuesAre31Bits()); 2442a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org ASSERT(shift >= times_1 && shift <= (static_cast<int>(times_8) + 1)); 2443a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org if (!dst.is(src)) { 2444a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org movp(dst, src); 2445a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org } 2446a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org negq(dst); 2447a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org if (shift == times_1) { 2448a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org sarq(dst, Immediate(kSmiShift)); 2449a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org return SmiIndex(dst, times_1); 2450a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org } 2451a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org return SmiIndex(dst, static_cast<ScaleFactor>(shift - 1)); 24529d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } 24534af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 24544af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 24554af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 24567979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.orgvoid MacroAssembler::AddSmiField(Register dst, const Operand& src) { 24574ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org if (SmiValuesAre32Bits()) { 24584ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org ASSERT_EQ(0, kSmiShift % kBitsPerByte); 24594ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org addl(dst, Operand(src, kSmiShift / kBitsPerByte)); 24604ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org } else { 24614ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org ASSERT(SmiValuesAre31Bits()); 24624ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org SmiToInteger32(kScratchRegister, src); 24634ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org addl(dst, kScratchRegister); 24644ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org } 24657979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org} 24667979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 24677979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 2468dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgvoid MacroAssembler::Push(Smi* source) { 2469dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org intptr_t smi = reinterpret_cast<intptr_t>(source); 2470dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org if (is_int32(smi)) { 2471763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Push(Immediate(static_cast<int32_t>(smi))); 2472dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org } else { 2473dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org Register constant = GetSmiConstant(source); 2474763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Push(constant); 2475dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org } 2476dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org} 2477dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org 2478dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org 24792ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgvoid MacroAssembler::PushRegisterAsTwoSmis(Register src, Register scratch) { 24802ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org ASSERT(!src.is(scratch)); 248143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(scratch, src); 2482662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org // High bits. 24832ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org shrp(src, Immediate(kPointerSize * kBitsPerByte - kSmiShift)); 24842f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org shlp(src, Immediate(kSmiShift)); 2485763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Push(src); 2486662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org // Low bits. 24872f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org shlp(scratch, Immediate(kSmiShift)); 2488763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Push(scratch); 2489662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org} 2490662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org 2491662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org 24922ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgvoid MacroAssembler::PopRegisterAsTwoSmis(Register dst, Register scratch) { 24932ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org ASSERT(!dst.is(scratch)); 2494763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Pop(scratch); 2495662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org // Low bits. 24962f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org shrp(scratch, Immediate(kSmiShift)); 2497763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Pop(dst); 24982f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org shrp(dst, Immediate(kSmiShift)); 2499662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org // High bits. 25002ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org shlp(dst, Immediate(kPointerSize * kBitsPerByte - kSmiShift)); 2501895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org orp(dst, scratch); 2502662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org} 2503662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org 2504662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org 2505dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgvoid MacroAssembler::Test(const Operand& src, Smi* source) { 25064ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org if (SmiValuesAre32Bits()) { 25074ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org testl(Operand(src, kIntSize), Immediate(source->value())); 25084ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org } else { 25094ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org ASSERT(SmiValuesAre31Bits()); 25104ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org testl(src, Immediate(source)); 25114ef23eea527ce7f45bdc5edd52bd4d1a989e2359machenbach@chromium.org } 2512dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org} 2513dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org 2514dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org 2515dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org// ---------------------------------------------------------------------------- 2516dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org 2517dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org 2518528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid MacroAssembler::LookupNumberStringCache(Register object, 2519528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register result, 2520528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register scratch1, 2521528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register scratch2, 2522528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Label* not_found) { 2523528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Use of registers. Register result is used as a temporary. 2524528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register number_string_cache = result; 2525528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register mask = scratch1; 2526528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register scratch = scratch2; 2527528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 2528528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Load the number string cache. 2529528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex); 2530528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 2531528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Make the hash mask from the length of the number string cache. It 2532528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // contains two elements (number and string) for each cache entry. 2533528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org SmiToInteger32( 2534528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset)); 2535528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org shrl(mask, Immediate(1)); 2536fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org subp(mask, Immediate(1)); // Make mask. 2537528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 2538528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Calculate the entry in the number string cache. The hash value in the 2539528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // number string cache for smis is just the smi value, and the hash for 2540528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // doubles is the xor of the upper and lower words. See 2541528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Heap::GetNumberStringCache. 2542528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Label is_smi; 2543528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Label load_result_from_cache; 2544528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org JumpIfSmi(object, &is_smi); 2545528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org CheckMap(object, 2546528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org isolate()->factory()->heap_number_map(), 2547528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org not_found, 2548528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org DONT_DO_SMI_CHECK); 2549528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 2550528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org STATIC_ASSERT(8 == kDoubleSize); 2551528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org movl(scratch, FieldOperand(object, HeapNumber::kValueOffset + 4)); 2552895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org xorp(scratch, FieldOperand(object, HeapNumber::kValueOffset)); 2553895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org andp(scratch, mask); 2554528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Each entry in string cache consists of two pointer sized fields, 2555528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // but times_twice_pointer_size (multiplication by 16) scale factor 2556528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // is not supported by addrmode on x64 platform. 2557528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // So we have to premultiply entry index before lookup. 25582f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org shlp(scratch, Immediate(kPointerSizeLog2 + 1)); 2559528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 2560528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register index = scratch; 2561528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register probe = mask; 256243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(probe, 2563528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org FieldOperand(number_string_cache, 2564528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org index, 2565528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org times_1, 2566528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org FixedArray::kHeaderSize)); 2567528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org JumpIfSmi(probe, not_found); 2568528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org movsd(xmm0, FieldOperand(object, HeapNumber::kValueOffset)); 2569528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org ucomisd(xmm0, FieldOperand(probe, HeapNumber::kValueOffset)); 2570528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org j(parity_even, not_found); // Bail out if NaN is involved. 2571528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org j(not_equal, not_found); // The cache did not contain this value. 2572528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org jmp(&load_result_from_cache); 2573528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 2574528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org bind(&is_smi); 2575528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org SmiToInteger32(scratch, object); 2576895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org andp(scratch, mask); 2577528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Each entry in string cache consists of two pointer sized fields, 2578528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // but times_twice_pointer_size (multiplication by 16) scale factor 2579528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // is not supported by addrmode on x64 platform. 2580528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // So we have to premultiply entry index before lookup. 25812f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org shlp(scratch, Immediate(kPointerSizeLog2 + 1)); 2582528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 2583528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Check if the entry is the smi we are looking for. 25847a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(object, 2585528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org FieldOperand(number_string_cache, 2586528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org index, 2587528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org times_1, 2588528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org FixedArray::kHeaderSize)); 2589528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org j(not_equal, not_found); 2590528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 2591528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Get the result from the cache. 2592528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org bind(&load_result_from_cache); 259343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(result, 2594528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org FieldOperand(number_string_cache, 2595528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org index, 2596528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org times_1, 2597528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org FixedArray::kHeaderSize + kPointerSize)); 2598528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org IncrementCounter(isolate()->counters()->number_to_string_native(), 1); 2599528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org} 2600528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 2601528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 260283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::JumpIfNotString(Register object, 260383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register object_map, 260483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* not_string, 260583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 260683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Condition is_smi = CheckSmi(object); 260783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(is_smi, not_string, near_jump); 260883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org CmpObjectType(object, FIRST_NONSTRING_TYPE, object_map); 260983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(above_equal, not_string, near_jump); 261083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 261183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 261283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 261383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::JumpIfNotBothSequentialAsciiStrings( 261483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register first_object, 261583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register second_object, 261683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register scratch1, 261783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register scratch2, 261883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_fail, 261983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 262083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Check that both objects are not smis. 262183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Condition either_smi = CheckEitherSmi(first_object, second_object); 262283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(either_smi, on_fail, near_jump); 262383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 262483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Load instance type for both strings. 262543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(scratch1, FieldOperand(first_object, HeapObject::kMapOffset)); 262643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(scratch2, FieldOperand(second_object, HeapObject::kMapOffset)); 262783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movzxbl(scratch1, FieldOperand(scratch1, Map::kInstanceTypeOffset)); 262883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movzxbl(scratch2, FieldOperand(scratch2, Map::kInstanceTypeOffset)); 262983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 26302efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // Check that both are flat ASCII strings. 263183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(kNotStringTag != 0); 263283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org const int kFlatAsciiStringMask = 263346a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask; 2634c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org const int kFlatAsciiStringTag = 2635c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org kStringTag | kOneByteStringTag | kSeqStringTag; 263683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 263783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org andl(scratch1, Immediate(kFlatAsciiStringMask)); 263883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org andl(scratch2, Immediate(kFlatAsciiStringMask)); 263983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Interleave the bits to check both scratch1 and scratch2 in one test. 264046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org ASSERT_EQ(0, kFlatAsciiStringMask & (kFlatAsciiStringMask << 3)); 2641895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org leap(scratch1, Operand(scratch1, scratch2, times_8, 0)); 264283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org cmpl(scratch1, 264346a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org Immediate(kFlatAsciiStringTag + (kFlatAsciiStringTag << 3))); 264483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(not_equal, on_fail, near_jump); 264583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 264683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 264783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 264883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::JumpIfInstanceTypeIsNotSequentialAscii( 264983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register instance_type, 265083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register scratch, 265183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* failure, 265283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 265383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (!scratch.is(instance_type)) { 265483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org movl(scratch, instance_type); 265583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 265683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 265783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org const int kFlatAsciiStringMask = 265883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask; 265983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 266083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org andl(scratch, Immediate(kFlatAsciiStringMask)); 2661e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org cmpl(scratch, Immediate(kStringTag | kSeqStringTag | kOneByteStringTag)); 266283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(not_equal, failure, near_jump); 266383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 266483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 266583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 266683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialAscii( 266783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register first_object_instance_type, 266883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register second_object_instance_type, 266983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register scratch1, 267083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register scratch2, 267183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* on_fail, 267283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label::Distance near_jump) { 267383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Load instance type for both strings. 267443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(scratch1, first_object_instance_type); 267543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(scratch2, second_object_instance_type); 267683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 26772efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // Check that both are flat ASCII strings. 267883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(kNotStringTag != 0); 267946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org const int kFlatAsciiStringMask = 268046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask; 2681c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org const int kFlatAsciiStringTag = 2682c73d55b355913690124f3ee70c344035431cdd3ayangguo@chromium.org kStringTag | kOneByteStringTag | kSeqStringTag; 268383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 268483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org andl(scratch1, Immediate(kFlatAsciiStringMask)); 268583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org andl(scratch2, Immediate(kFlatAsciiStringMask)); 268683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Interleave the bits to check both scratch1 and scratch2 in one test. 268746a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org ASSERT_EQ(0, kFlatAsciiStringMask & (kFlatAsciiStringMask << 3)); 2688895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org leap(scratch1, Operand(scratch1, scratch2, times_8, 0)); 268983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org cmpl(scratch1, 269046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org Immediate(kFlatAsciiStringTag + (kFlatAsciiStringTag << 3))); 269183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(not_equal, on_fail, near_jump); 269283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 269383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 269483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 26951510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgtemplate<class T> 26961510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgstatic void JumpIfNotUniqueNameHelper(MacroAssembler* masm, 26971510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org T operand_or_register, 26981510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Label* not_unique_name, 26991510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Label::Distance distance) { 2700ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0); 2701ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Label succeed; 2702ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org masm->testb(operand_or_register, 2703ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Immediate(kIsNotStringMask | kIsNotInternalizedMask)); 2704ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org masm->j(zero, &succeed, Label::kNear); 2705ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org masm->cmpb(operand_or_register, Immediate(static_cast<uint8_t>(SYMBOL_TYPE))); 2706ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org masm->j(not_equal, not_unique_name, distance); 2707ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 2708ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org masm->bind(&succeed); 27091510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org} 27101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 27111510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 27121510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid MacroAssembler::JumpIfNotUniqueName(Operand operand, 27131510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Label* not_unique_name, 27141510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Label::Distance distance) { 27151510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org JumpIfNotUniqueNameHelper<Operand>(this, operand, not_unique_name, distance); 27161510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org} 27171510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 27181510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 27191510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgvoid MacroAssembler::JumpIfNotUniqueName(Register reg, 27201510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Label* not_unique_name, 27211510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Label::Distance distance) { 27221510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org JumpIfNotUniqueNameHelper<Register>(this, reg, not_unique_name, distance); 27231510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org} 27241510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 27257979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 27264a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.orgvoid MacroAssembler::Move(Register dst, Register src) { 27274a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org if (!dst.is(src)) { 272843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(dst, src); 27294a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org } 27304a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org} 27314a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 27324a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 27335aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.orgvoid MacroAssembler::Move(Register dst, Handle<Object> source) { 273479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org AllowDeferredHandleDereference smi_check; 27355aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org if (source->IsSmi()) { 27369d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com Move(dst, Smi::cast(*source)); 27375aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org } else { 2738c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org MoveHeapObject(dst, source); 27395aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org } 27405aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org} 27415aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 27425aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 27435aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.orgvoid MacroAssembler::Move(const Operand& dst, Handle<Object> source) { 274479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org AllowDeferredHandleDereference smi_check; 274568ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org if (source->IsSmi()) { 27469d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com Move(dst, Smi::cast(*source)); 274768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } else { 2748c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org MoveHeapObject(kScratchRegister, source); 274943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(dst, kScratchRegister); 275068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 27515aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org} 27525aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 27535aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 27545aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.orgvoid MacroAssembler::Cmp(Register dst, Handle<Object> source) { 275579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org AllowDeferredHandleDereference smi_check; 27569d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com if (source->IsSmi()) { 2757badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org Cmp(dst, Smi::cast(*source)); 27589d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } else { 2759c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org MoveHeapObject(kScratchRegister, source); 27607a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(dst, kScratchRegister); 27619d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com } 27625aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org} 27635aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 27645aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 27653e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgvoid MacroAssembler::Cmp(const Operand& dst, Handle<Object> source) { 276679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org AllowDeferredHandleDereference smi_check; 276768ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org if (source->IsSmi()) { 2768badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org Cmp(dst, Smi::cast(*source)); 276968ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } else { 2770c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org MoveHeapObject(kScratchRegister, source); 27717a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(dst, kScratchRegister); 277268ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 27733e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org} 27743e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 27753e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 27765aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.orgvoid MacroAssembler::Push(Handle<Object> source) { 277779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org AllowDeferredHandleDereference smi_check; 277868ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org if (source->IsSmi()) { 27799d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com Push(Smi::cast(*source)); 278068ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } else { 2781c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org MoveHeapObject(kScratchRegister, source); 2782763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Push(kScratchRegister); 278368ac009f55a85e6891742d58914eaf717f667b26kasperl@chromium.org } 27845aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org} 27855aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 27865aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 2787c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.orgvoid MacroAssembler::MoveHeapObject(Register result, 2788c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org Handle<Object> object) { 278979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org AllowDeferredHandleDereference using_raw_address; 2790c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org ASSERT(object->IsHeapObject()); 279164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (isolate()->heap()->InNewSpace(*object)) { 279241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Handle<Cell> cell = isolate()->factory()->NewCell(object); 27939cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org Move(result, cell, RelocInfo::CELL); 279443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(result, Operand(result, 0)); 279564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else { 27969cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org Move(result, object, RelocInfo::EMBEDDED_OBJECT); 279764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 279864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org} 279964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 280064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 280141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgvoid MacroAssembler::LoadGlobalCell(Register dst, Handle<Cell> cell) { 280264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (dst.is(rax)) { 280379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org AllowDeferredHandleDereference embedding_raw_address; 280441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org load_rax(cell.location(), RelocInfo::CELL); 280564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else { 28069cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org Move(dst, cell, RelocInfo::CELL); 280743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(dst, Operand(dst, 0)); 280864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 280964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org} 281064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 281164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 281213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid MacroAssembler::Drop(int stack_elements) { 281313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org if (stack_elements > 0) { 2814fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org addp(rsp, Immediate(stack_elements * kPointerSize)); 281513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org } 281613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org} 281713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 281813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 2819a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgvoid MacroAssembler::DropUnderReturnAddress(int stack_elements, 2820a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org Register scratch) { 2821a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org ASSERT(stack_elements > 0); 2822a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org if (kPointerSize == kInt64Size && stack_elements == 1) { 2823a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org popq(MemOperand(rsp, 0)); 2824a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org return; 2825a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org } 2826a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 2827a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org PopReturnAddressTo(scratch); 2828a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org Drop(stack_elements); 2829a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org PushReturnAddressFrom(scratch); 2830a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org} 2831a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 2832a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 2833763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.orgvoid MacroAssembler::Push(Register src) { 2834763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org if (kPointerSize == kInt64Size) { 2835763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org pushq(src); 2836763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org } else { 2837763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org // x32 uses 64-bit push for rbp in the prologue. 2838763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org ASSERT(src.code() != rbp.code()); 2839763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org leal(rsp, Operand(rsp, -4)); 2840763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org movp(Operand(rsp, 0), src); 2841763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org } 2842763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org} 2843763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org 2844763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org 2845763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.orgvoid MacroAssembler::Push(const Operand& src) { 2846763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org if (kPointerSize == kInt64Size) { 2847763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org pushq(src); 2848763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org } else { 2849763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org movp(kScratchRegister, src); 2850763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org leal(rsp, Operand(rsp, -4)); 2851763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org movp(Operand(rsp, 0), kScratchRegister); 2852763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org } 2853763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org} 2854763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org 2855763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org 2856a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgvoid MacroAssembler::PushQuad(const Operand& src) { 2857a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org if (kPointerSize == kInt64Size) { 2858a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org pushq(src); 2859a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org } else { 2860a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org movp(kScratchRegister, src); 2861a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org pushq(kScratchRegister); 2862a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org } 2863a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org} 2864a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 2865a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 2866763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.orgvoid MacroAssembler::Push(Immediate value) { 2867763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org if (kPointerSize == kInt64Size) { 2868763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org pushq(value); 2869763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org } else { 2870763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org leal(rsp, Operand(rsp, -4)); 2871763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org movp(Operand(rsp, 0), value); 2872763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org } 2873763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org} 2874763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org 2875763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org 2876763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.orgvoid MacroAssembler::PushImm32(int32_t imm32) { 2877763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org if (kPointerSize == kInt64Size) { 2878763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org pushq_imm32(imm32); 2879763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org } else { 2880763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org leal(rsp, Operand(rsp, -4)); 2881763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org movp(Operand(rsp, 0), Immediate(imm32)); 2882763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org } 2883763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org} 2884763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org 2885763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org 2886763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.orgvoid MacroAssembler::Pop(Register dst) { 2887763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org if (kPointerSize == kInt64Size) { 2888763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org popq(dst); 2889763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org } else { 2890763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org // x32 uses 64-bit pop for rbp in the epilogue. 2891763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org ASSERT(dst.code() != rbp.code()); 2892763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org movp(dst, Operand(rsp, 0)); 2893763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org leal(rsp, Operand(rsp, 4)); 2894763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org } 2895763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org} 2896763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org 2897763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org 2898763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.orgvoid MacroAssembler::Pop(const Operand& dst) { 2899763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org if (kPointerSize == kInt64Size) { 2900763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org popq(dst); 2901763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org } else { 2902763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Register scratch = dst.AddressUsesRegister(kScratchRegister) 2903763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org ? kSmiConstantRegister : kScratchRegister; 2904763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org movp(scratch, Operand(rsp, 0)); 2905763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org movp(dst, scratch); 2906763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org leal(rsp, Operand(rsp, 4)); 2907763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org if (scratch.is(kSmiConstantRegister)) { 2908763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org // Restore kSmiConstantRegister. 2909fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org movp(kSmiConstantRegister, 2910fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org reinterpret_cast<void*>(Smi::FromInt(kSmiConstantRegisterValue)), 2911763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Assembler::RelocInfoNone()); 2912763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org } 2913763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org } 2914763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org} 2915763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org 2916763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org 2917a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgvoid MacroAssembler::PopQuad(const Operand& dst) { 2918a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org if (kPointerSize == kInt64Size) { 2919a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org popq(dst); 2920a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org } else { 2921a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org popq(kScratchRegister); 2922a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org movp(dst, kScratchRegister); 2923a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org } 2924a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org} 2925a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 2926a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 292704a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.orgvoid MacroAssembler::LoadSharedFunctionInfoSpecialField(Register dst, 292804a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org Register base, 292904a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org int offset) { 293004a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org ASSERT(offset > SharedFunctionInfo::kLengthOffset && 293104a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org offset <= SharedFunctionInfo::kSize && 293204a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org (((offset - SharedFunctionInfo::kLengthOffset) / kIntSize) % 2 == 1)); 293304a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org if (kPointerSize == kInt64Size) { 293404a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org movsxlq(dst, FieldOperand(base, offset)); 293504a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org } else { 293604a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org movp(dst, FieldOperand(base, offset)); 293704a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org SmiToInteger32(dst, dst); 293804a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org } 293904a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org} 294004a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org 294104a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org 294204a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.orgvoid MacroAssembler::TestBitSharedFunctionInfoSpecialField(Register base, 294304a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org int offset, 294404a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org int bits) { 294504a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org ASSERT(offset > SharedFunctionInfo::kLengthOffset && 294604a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org offset <= SharedFunctionInfo::kSize && 294704a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org (((offset - SharedFunctionInfo::kLengthOffset) / kIntSize) % 2 == 1)); 294804a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org if (kPointerSize == kInt32Size) { 294904a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org // On x32, this field is represented by SMI. 295004a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org bits += kSmiShift; 295104a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org } 2952394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com int byte_offset = bits / kBitsPerByte; 2953394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com int bit_in_byte = bits & (kBitsPerByte - 1); 295404a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org testb(FieldOperand(base, offset + byte_offset), Immediate(1 << bit_in_byte)); 2955394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com} 2956394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 2957394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 2958eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::Jump(ExternalReference ext) { 2959ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org LoadAddress(kScratchRegister, ext); 2960eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org jmp(kScratchRegister); 2961eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 2962eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 2963eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 2964f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvoid MacroAssembler::Jump(const Operand& op) { 2965f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (kPointerSize == kInt64Size) { 2966f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org jmp(op); 2967f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } else { 2968f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org movp(kScratchRegister, op); 2969f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org jmp(kScratchRegister); 2970f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 2971f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 2972f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 2973f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 2974eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::Jump(Address destination, RelocInfo::Mode rmode) { 29759cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org Move(kScratchRegister, destination, rmode); 2976eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org jmp(kScratchRegister); 2977eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 2978eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 2979eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 29805aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.orgvoid MacroAssembler::Jump(Handle<Code> code_object, RelocInfo::Mode rmode) { 2981c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // TODO(X64): Inline this 2982c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org jmp(code_object, rmode); 29835aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org} 29845aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 29855aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 2986ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgint MacroAssembler::CallSize(ExternalReference ext) { 2987ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Opcode for call kScratchRegister is: Rex.B FF D4 (three bytes). 2988594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org return LoadAddressSize(ext) + 2989594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Assembler::kCallScratchRegisterInstructionLength; 2990ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org} 2991ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 2992ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 2993eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::Call(ExternalReference ext) { 2994eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org#ifdef DEBUG 2995ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org int end_position = pc_offset() + CallSize(ext); 2996eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org#endif 2997ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org LoadAddress(kScratchRegister, ext); 2998eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org call(kScratchRegister); 2999eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org#ifdef DEBUG 3000ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org CHECK_EQ(end_position, pc_offset()); 3001eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org#endif 3002eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 3003eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3004eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3005f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvoid MacroAssembler::Call(const Operand& op) { 3006f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org if (kPointerSize == kInt64Size) { 3007f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org call(op); 3008f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } else { 3009f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org movp(kScratchRegister, op); 3010f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org call(kScratchRegister); 3011f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 3012f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} 3013f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 3014f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 3015eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::Call(Address destination, RelocInfo::Mode rmode) { 3016eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org#ifdef DEBUG 3017af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org int end_position = pc_offset() + CallSize(destination); 3018eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org#endif 30199cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org Move(kScratchRegister, destination, rmode); 3020eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org call(kScratchRegister); 3021eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org#ifdef DEBUG 3022ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org CHECK_EQ(pc_offset(), end_position); 3023eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org#endif 3024eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 3025eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3026eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 30278e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.orgvoid MacroAssembler::Call(Handle<Code> code_object, 30288e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org RelocInfo::Mode rmode, 3029471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org TypeFeedbackId ast_id) { 3030eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org#ifdef DEBUG 3031ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org int end_position = pc_offset() + CallSize(code_object); 3032eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org#endif 3033c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org ASSERT(RelocInfo::IsCodeTarget(rmode) || 3034c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org rmode == RelocInfo::CODE_AGE_SEQUENCE); 30358e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org call(code_object, rmode, ast_id); 3036eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org#ifdef DEBUG 3037ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org CHECK_EQ(end_position, pc_offset()); 3038eb96f4fd17b379ad2247264f82af1100f448779bricow@chromium.org#endif 30395aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org} 30405aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 30415aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 30420a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.orgvoid MacroAssembler::Pushad() { 3043763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Push(rax); 3044763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Push(rcx); 3045763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Push(rdx); 3046763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Push(rbx); 30470a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // Not pushing rsp or rbp. 3048763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Push(rsi); 3049763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Push(rdi); 3050763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Push(r8); 3051763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Push(r9); 30520a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // r10 is kScratchRegister. 3053763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Push(r11); 3054b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org // r12 is kSmiConstantRegister. 30550a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org // r13 is kRootRegister. 3056763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Push(r14); 3057763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Push(r15); 305849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org STATIC_ASSERT(11 == kNumSafepointSavedRegisters); 305949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // Use lea for symmetry with Popad. 30603a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org int sp_delta = 30613a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org (kNumSafepointRegisters - kNumSafepointSavedRegisters) * kPointerSize; 3062895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org leap(rsp, Operand(rsp, -sp_delta)); 30630a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org} 30640a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 30650a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 30660a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.orgvoid MacroAssembler::Popad() { 306749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // Popad must not change the flags, so use lea instead of addq. 30683a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org int sp_delta = 30693a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org (kNumSafepointRegisters - kNumSafepointSavedRegisters) * kPointerSize; 3070895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org leap(rsp, Operand(rsp, sp_delta)); 3071763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Pop(r15); 3072763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Pop(r14); 3073763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Pop(r11); 3074763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Pop(r9); 3075763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Pop(r8); 3076763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Pop(rdi); 3077763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Pop(rsi); 3078763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Pop(rbx); 3079763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Pop(rdx); 3080763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Pop(rcx); 3081763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Pop(rax); 30820a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org} 30830a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 30840a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org 30850ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.orgvoid MacroAssembler::Dropad() { 3086fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org addp(rsp, Immediate(kNumSafepointRegisters * kPointerSize)); 30870ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org} 30880ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 30890ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 30900ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org// Order general registers are pushed by Pushad: 3091b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org// rax, rcx, rdx, rbx, rsi, rdi, r8, r9, r11, r14, r15. 30921456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgconst int 30931456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgMacroAssembler::kSafepointPushRegisterIndices[Register::kNumRegisters] = { 30940ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 0, 30950ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 1, 30960ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 2, 30970ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 3, 30980ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org -1, 30990ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org -1, 31000ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 4, 31010ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 5, 31020ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 6, 31030ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 7, 31040ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org -1, 31050ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 8, 31060ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org -1, 3107b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org -1, 3108b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 9, 3109b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org 10 31100ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org}; 31110ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 31120ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org 311346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgvoid MacroAssembler::StoreToSafepointRegisterSlot(Register dst, 311446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org const Immediate& imm) { 311543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(SafepointRegisterSlot(dst), imm); 311646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org} 311746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 311846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 31193a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid MacroAssembler::StoreToSafepointRegisterSlot(Register dst, Register src) { 312043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(SafepointRegisterSlot(dst), src); 31213a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 31223a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 31233a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 31245d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.orgvoid MacroAssembler::LoadFromSafepointRegisterSlot(Register dst, Register src) { 312543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(dst, SafepointRegisterSlot(src)); 31265d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org} 31275d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org 31285d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org 31293a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgOperand MacroAssembler::SafepointRegisterSlot(Register reg) { 31303a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org return Operand(rsp, SafepointRegisterStackIndex(reg.code()) * kPointerSize); 31313a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org} 31323a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 31333a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 313478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.orgvoid MacroAssembler::PushTryHandler(StackHandler::Kind kind, 313504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org int handler_index) { 3136eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // Adjust this code if not the case. 3137d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize + 3138d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org kFPOnStackSize); 313904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); 314004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kCodeOffset == 1 * kPointerSize); 314104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kStateOffset == 2 * kPointerSize); 314204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kContextOffset == 3 * kPointerSize); 314304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize); 314404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 314504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // We will build up the handler from the bottom by pushing on the stack. 314678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // First push the frame pointer and context. 314778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org if (kind == StackHandler::JS_ENTRY) { 314804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // The frame pointer does not point to a JS frame so we save NULL for 314904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // rbp. We expect the code throwing an exception to check rbp before 315004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // dereferencing it to restore the context. 3151763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org pushq(Immediate(0)); // NULL frame pointer. 31524acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org Push(Smi::FromInt(0)); // No context. 315378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org } else { 3154763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org pushq(rbp); 3155763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Push(rsi); 3156e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org } 315704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 315804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Push the state and the code object. 315978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org unsigned state = 316078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org StackHandler::IndexField::encode(handler_index) | 316178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org StackHandler::KindField::encode(kind); 3162763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Push(Immediate(state)); 316304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org Push(CodeObject()); 316404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 316504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Link the current handler as the next handler. 316604e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); 3167763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Push(ExternalOperand(handler_address)); 316804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Set this new handler as the current one. 316943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(ExternalOperand(handler_address), rsp); 3170e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org} 3171e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 3172e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org 317313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid MacroAssembler::PopTryHandler() { 317404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); 317504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); 3176763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Pop(ExternalOperand(handler_address)); 3177fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org addp(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize)); 317813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org} 317913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 318013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 318104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.orgvoid MacroAssembler::JumpToHandlerEntry() { 318204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Compute the handler entry address and jump to it. The handler table is 318304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // a fixed array of (smi-tagged) code offsets. 318404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // rax = exception, rdi = code object, rdx = state. 318543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(rbx, FieldOperand(rdi, Code::kHandlerTableOffset)); 31862f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org shrp(rdx, Immediate(StackHandler::kKindWidth)); 318743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(rdx, 31881510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org FieldOperand(rbx, rdx, times_pointer_size, FixedArray::kHeaderSize)); 318904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org SmiToInteger64(rdx, rdx); 3190895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org leap(rdi, FieldOperand(rdi, rdx, times_1, Code::kHeaderSize)); 319104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org jmp(rdi); 319204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org} 319304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 319404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 319549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.orgvoid MacroAssembler::Throw(Register value) { 31964acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org // Adjust this code if not the case. 3197d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize + 3198d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org kFPOnStackSize); 319904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); 320004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kCodeOffset == 1 * kPointerSize); 320104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kStateOffset == 2 * kPointerSize); 320204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kContextOffset == 3 * kPointerSize); 320304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize); 320404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 320504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // The exception is expected in rax. 320649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org if (!value.is(rax)) { 320743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(rax, value); 320849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org } 320904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Drop the stack pointer to the top of the top handler. 321083e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); 321143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(rsp, ExternalOperand(handler_address)); 321204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Restore the next handler. 3213763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Pop(ExternalOperand(handler_address)); 321404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 321504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Remove the code object and state, compute the handler address in rdi. 3216763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Pop(rdi); // Code object. 3217763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Pop(rdx); // Offset and state. 321804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 321904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Restore the context and frame pointer. 3220763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Pop(rsi); // Context. 3221763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org popq(rbp); // Frame pointer. 322249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 32234acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org // If the handler is a JS frame, restore the context to the frame. 322404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // (kind == ENTRY) == (rbp == 0) == (rsi == 0), so we could test either 322504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // rbp or rsi. 322683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label skip; 32277a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org testp(rsi, rsi); 322804e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org j(zero, &skip, Label::kNear); 322943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(Operand(rbp, StandardFrameConstants::kContextOffset), rsi); 323049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org bind(&skip); 32314acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org 323204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org JumpToHandlerEntry(); 323349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org} 323449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 323549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 323665a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.orgvoid MacroAssembler::ThrowUncatchable(Register value) { 32374acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org // Adjust this code if not the case. 3238d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize + 3239d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org kFPOnStackSize); 324004e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); 324104e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kCodeOffset == 1 * kPointerSize); 324204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kStateOffset == 2 * kPointerSize); 324304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kContextOffset == 3 * kPointerSize); 324404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize); 324549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 3246c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // The exception is expected in rax. 324765a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org if (!value.is(rax)) { 324843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(rax, value); 324949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org } 3250c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // Drop the stack pointer to the top of the top stack handler. 3251c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); 3252c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org Load(rsp, handler_address); 325349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 3254c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // Unwind the handlers until the top ENTRY handler is found. 3255c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org Label fetch_next, check_kind; 3256c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org jmp(&check_kind, Label::kNear); 3257c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org bind(&fetch_next); 325843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(rsp, Operand(rsp, StackHandlerConstants::kNextOffset)); 3259c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org 3260c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org bind(&check_kind); 326178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org STATIC_ASSERT(StackHandler::JS_ENTRY == 0); 326204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org testl(Operand(rsp, StackHandlerConstants::kStateOffset), 326304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org Immediate(StackHandler::KindField::kMask)); 326404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org j(not_zero, &fetch_next); 3265c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org 3266c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // Set the top handler address to next handler past the top ENTRY handler. 3267763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Pop(ExternalOperand(handler_address)); 3268c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org 326904e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Remove the code object and state, compute the handler address in rdi. 3270763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Pop(rdi); // Code object. 3271763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Pop(rdx); // Offset and state. 327204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org 327304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org // Clear the context pointer and frame pointer (0 was saved in the handler). 3274763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Pop(rsi); 3275763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org popq(rbp); 327649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 327704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org JumpToHandlerEntry(); 327849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org} 327949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 328049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 3281eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::Ret() { 3282eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org ret(0); 3283eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 3284eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3285eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3286d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.comvoid MacroAssembler::Ret(int bytes_dropped, Register scratch) { 3287d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com if (is_uint16(bytes_dropped)) { 3288d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com ret(bytes_dropped); 3289d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } else { 3290594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org PopReturnAddressTo(scratch); 3291fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org addp(rsp, Immediate(bytes_dropped)); 3292594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org PushReturnAddressFrom(scratch); 3293d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com ret(0); 3294d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com } 3295d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com} 3296d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 3297d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com 32983e87580939cb78c5802369f723680d4a16cc2902ager@chromium.orgvoid MacroAssembler::FCmp() { 32993811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org fucomip(); 330040b9da37a45dabf86bd82a39e885f2921f47fc08fschneider@chromium.org fstp(0); 33013e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org} 33023e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 33033e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 3304eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::CmpObjectType(Register heap_object, 3305eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org InstanceType type, 3306eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org Register map) { 330743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(map, FieldOperand(heap_object, HeapObject::kMapOffset)); 3308eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org CmpInstanceType(map, type); 3309eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 3310eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3311eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3312eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::CmpInstanceType(Register map, InstanceType type) { 3313eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org cmpb(FieldOperand(map, Map::kInstanceTypeOffset), 3314eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org Immediate(static_cast<int8_t>(type))); 3315eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 3316eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3317eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3318d6076d96a1411932548838e5960b594564264010erik.corry@gmail.comvoid MacroAssembler::CheckFastElements(Register map, 3319d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com Label* fail, 3320d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com Label::Distance distance) { 3321830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); 3322830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); 3323830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_ELEMENTS == 2); 3324830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); 3325c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmpb(FieldOperand(map, Map::kBitField2Offset), 3326830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Immediate(Map::kMaximumBitField2FastHoleyElementValue)); 3327c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(above, fail, distance); 3328c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 3329c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3330c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3331c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::CheckFastObjectElements(Register map, 3332c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* fail, 3333c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance distance) { 3334830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); 3335830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); 3336830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_ELEMENTS == 2); 3337830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); 3338c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmpb(FieldOperand(map, Map::kBitField2Offset), 3339830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Immediate(Map::kMaximumBitField2FastHoleySmiElementValue)); 3340c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(below_equal, fail, distance); 3341d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com cmpb(FieldOperand(map, Map::kBitField2Offset), 3342830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Immediate(Map::kMaximumBitField2FastHoleyElementValue)); 3343d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com j(above, fail, distance); 3344d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com} 3345d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com 3346d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com 3347830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.orgvoid MacroAssembler::CheckFastSmiElements(Register map, 3348830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Label* fail, 3349830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Label::Distance distance) { 3350830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); 3351830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); 3352c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmpb(FieldOperand(map, Map::kBitField2Offset), 3353830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Immediate(Map::kMaximumBitField2FastHoleySmiElementValue)); 3354c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(above, fail, distance); 3355c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 3356c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3357c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3358c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::StoreNumberToDoubleElements( 3359c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register maybe_number, 3360c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register elements, 3361394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register index, 3362c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com XMMRegister xmm_scratch, 3363fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org Label* fail, 3364fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org int elements_offset) { 3365c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label smi_value, is_nan, maybe_nan, not_nan, have_double_value, done; 3366c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3367c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com JumpIfSmi(maybe_number, &smi_value, Label::kNear); 3368c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3369c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CheckMap(maybe_number, 3370c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com isolate()->factory()->heap_number_map(), 3371c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com fail, 3372c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com DONT_DO_SMI_CHECK); 3373c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3374c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Double value, canonicalize NaN. 3375c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com uint32_t offset = HeapNumber::kValueOffset + sizeof(kHoleNanLower32); 3376c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmpl(FieldOperand(maybe_number, offset), 3377c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Immediate(kNaNOrInfinityLowerBoundUpper32)); 3378c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(greater_equal, &maybe_nan, Label::kNear); 3379c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3380c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(¬_nan); 3381c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com movsd(xmm_scratch, FieldOperand(maybe_number, HeapNumber::kValueOffset)); 3382c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&have_double_value); 3383fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org movsd(FieldOperand(elements, index, times_8, 3384fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org FixedDoubleArray::kHeaderSize - elements_offset), 3385c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com xmm_scratch); 3386c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com jmp(&done); 3387c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3388c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&maybe_nan); 3389c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Could be NaN or Infinity. If fraction is not zero, it's NaN, otherwise 3390c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // it's an Infinity, and the non-NaN code path applies. 3391c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(greater, &is_nan, Label::kNear); 3392c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com cmpl(FieldOperand(maybe_number, HeapNumber::kValueOffset), Immediate(0)); 3393c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(zero, ¬_nan); 3394c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&is_nan); 3395c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Convert all NaNs to the same canonical NaN value when they are stored in 3396c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // the double array. 3397c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Set(kScratchRegister, BitCast<uint64_t>( 3398c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FixedDoubleArray::canonical_not_the_hole_nan_as_double())); 3399c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com movq(xmm_scratch, kScratchRegister); 3400c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com jmp(&have_double_value, Label::kNear); 3401c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3402c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&smi_value); 3403c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Value is a smi. convert to a double and store. 3404c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Preserve original value. 3405c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com SmiToInteger32(kScratchRegister, maybe_number); 3406528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Cvtlsi2sd(xmm_scratch, kScratchRegister); 3407fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org movsd(FieldOperand(elements, index, times_8, 3408fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org FixedDoubleArray::kHeaderSize - elements_offset), 3409c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com xmm_scratch); 3410c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&done); 3411c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 3412c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3413c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3414935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.orgvoid MacroAssembler::CompareMap(Register obj, Handle<Map> map) { 3415f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com Cmp(FieldOperand(obj, HeapObject::kMapOffset), map); 3416f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com} 3417f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 3418f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 34195c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid MacroAssembler::CheckMap(Register obj, 34205c838251403b0be9a882540f1922577abba4c872ager@chromium.org Handle<Map> map, 34215c838251403b0be9a882540f1922577abba4c872ager@chromium.org Label* fail, 3422a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org SmiCheckType smi_check_type) { 3423c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (smi_check_type == DO_SMI_CHECK) { 34245c838251403b0be9a882540f1922577abba4c872ager@chromium.org JumpIfSmi(obj, fail); 34255c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 3426f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 3427935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org CompareMap(obj, map); 34285c838251403b0be9a882540f1922577abba4c872ager@chromium.org j(not_equal, fail); 34295c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 34305c838251403b0be9a882540f1922577abba4c872ager@chromium.org 34315c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3432c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.orgvoid MacroAssembler::ClampUint8(Register reg) { 3433c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label done; 3434c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org testl(reg, Immediate(0xFFFFFF00)); 3435c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org j(zero, &done, Label::kNear); 3436c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org setcc(negative, reg); // 1 if negative, 0 if positive. 3437c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org decb(reg); // 0 if negative, 255 if positive. 3438c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org bind(&done); 3439c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org} 3440c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 3441c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 3442c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.orgvoid MacroAssembler::ClampDoubleToUint8(XMMRegister input_reg, 3443c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org XMMRegister temp_xmm_reg, 344489e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org Register result_reg) { 3445c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label done; 344689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org Label conv_failure; 3447c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org xorps(temp_xmm_reg, temp_xmm_reg); 344846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org cvtsd2si(result_reg, input_reg); 3449c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org testl(result_reg, Immediate(0xFFFFFF00)); 3450c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org j(zero, &done, Label::kNear); 3451a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org cmpl(result_reg, Immediate(1)); 3452a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org j(overflow, &conv_failure, Label::kNear); 345389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org movl(result_reg, Immediate(0)); 3454a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org setcc(sign, result_reg); 345589e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org subl(result_reg, Immediate(1)); 345689e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org andl(result_reg, Immediate(255)); 345789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org jmp(&done, Label::kNear); 345889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org bind(&conv_failure); 345989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org Set(result_reg, 0); 346089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org ucomisd(input_reg, temp_xmm_reg); 346189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org j(below, &done, Label::kNear); 3462c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Set(result_reg, 255); 3463c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org bind(&done); 3464c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org} 3465c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 3466c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 346746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgvoid MacroAssembler::LoadUint32(XMMRegister dst, 34687e6132b924829c353864933f29124419916db550machenbach@chromium.org Register src) { 34692f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org if (FLAG_debug_code) { 34702f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org cmpq(src, Immediate(0xffffffff)); 3471594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Assert(below_equal, kInputGPRIsExpectedToHaveUpper32Cleared); 34722f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org } 34732f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org cvtqsi2sd(dst, src); 347446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org} 347546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 347646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 3477c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.orgvoid MacroAssembler::SlowTruncateToI(Register result_reg, 3478c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org Register input_reg, 3479c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org int offset) { 3480f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org DoubleToIStub stub(isolate(), input_reg, result_reg, offset, true); 3481f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org call(stub.GetCode(), RelocInfo::CODE_TARGET); 3482c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org} 3483c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 3484c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 3485c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.orgvoid MacroAssembler::TruncateHeapNumberToI(Register result_reg, 3486c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org Register input_reg) { 3487c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org Label done; 3488c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 3489c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org cvttsd2siq(result_reg, xmm0); 3490a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org cmpq(result_reg, Immediate(1)); 3491a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org j(no_overflow, &done, Label::kNear); 3492c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 3493c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // Slow case. 3494c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org if (input_reg.is(result_reg)) { 3495fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org subp(rsp, Immediate(kDoubleSize)); 3496c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org movsd(MemOperand(rsp, 0), xmm0); 3497c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org SlowTruncateToI(result_reg, rsp, 0); 3498fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org addp(rsp, Immediate(kDoubleSize)); 3499c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org } else { 3500c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org SlowTruncateToI(result_reg, input_reg); 3501c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org } 3502c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 3503c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org bind(&done); 35042ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org // Keep our invariant that the upper 32 bits are zero. 35052ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org movl(result_reg, result_reg); 3506c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org} 3507c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 3508c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 3509c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.orgvoid MacroAssembler::TruncateDoubleToI(Register result_reg, 3510c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org XMMRegister input_reg) { 3511c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org Label done; 3512c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org cvttsd2siq(result_reg, input_reg); 3513a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org cmpq(result_reg, Immediate(1)); 3514a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org j(no_overflow, &done, Label::kNear); 3515c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 3516fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org subp(rsp, Immediate(kDoubleSize)); 3517c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org movsd(MemOperand(rsp, 0), input_reg); 3518c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org SlowTruncateToI(result_reg, rsp, 0); 3519fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org addp(rsp, Immediate(kDoubleSize)); 3520c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 3521c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org bind(&done); 35222ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org // Keep our invariant that the upper 32 bits are zero. 35232ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org movl(result_reg, result_reg); 3524c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org} 3525c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 3526c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 3527c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.orgvoid MacroAssembler::DoubleToI(Register result_reg, 3528c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org XMMRegister input_reg, 3529c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org XMMRegister scratch, 3530c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org MinusZeroMode minus_zero_mode, 3531c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org Label* conversion_failed, 3532c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org Label::Distance dst) { 3533c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org cvttsd2si(result_reg, input_reg); 3534528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Cvtlsi2sd(xmm0, result_reg); 3535c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org ucomisd(xmm0, input_reg); 3536c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org j(not_equal, conversion_failed, dst); 3537c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org j(parity_even, conversion_failed, dst); // NaN. 3538c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org if (minus_zero_mode == FAIL_ON_MINUS_ZERO) { 3539c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org Label done; 3540c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // The integer converted back is equal to the original. We 3541c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // only have to test if we got -0 as an input. 3542c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org testl(result_reg, result_reg); 3543c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org j(not_zero, &done, Label::kNear); 3544c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org movmskpd(result_reg, input_reg); 3545c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // Bit 0 contains the sign of the double in input_reg. 3546c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // If input was positive, we are ok and return 0, otherwise 3547c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // jump to conversion_failed. 3548c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org andl(result_reg, Immediate(1)); 3549c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org j(not_zero, conversion_failed, dst); 3550c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org bind(&done); 3551c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org } 3552c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org} 3553c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 3554c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 3555c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.orgvoid MacroAssembler::TaggedToI(Register result_reg, 3556c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org Register input_reg, 3557c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org XMMRegister temp, 3558c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org MinusZeroMode minus_zero_mode, 3559c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org Label* lost_precision, 3560c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org Label::Distance dst) { 3561c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org Label done; 3562c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org ASSERT(!temp.is(xmm0)); 3563c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 3564c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // Heap number map check. 3565c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), 3566c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org Heap::kHeapNumberMapRootIndex); 3567c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org j(not_equal, lost_precision, dst); 3568c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 3569c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 3570c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org cvttsd2si(result_reg, xmm0); 3571528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Cvtlsi2sd(temp, result_reg); 3572c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org ucomisd(xmm0, temp); 3573c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org RecordComment("Deferred TaggedToI: lost precision"); 3574c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org j(not_equal, lost_precision, dst); 3575c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org RecordComment("Deferred TaggedToI: NaN"); 3576c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org j(parity_even, lost_precision, dst); // NaN. 3577c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org if (minus_zero_mode == FAIL_ON_MINUS_ZERO) { 3578c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org testl(result_reg, result_reg); 3579c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org j(not_zero, &done, Label::kNear); 3580c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org movmskpd(result_reg, xmm0); 3581c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org andl(result_reg, Immediate(1)); 3582c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org j(not_zero, lost_precision, dst); 3583c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org } 3584c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org bind(&done); 3585c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org} 3586c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 3587c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 358840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.orgvoid MacroAssembler::LoadInstanceDescriptors(Register map, 358940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org Register descriptors) { 359043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(descriptors, FieldOperand(map, Map::kDescriptorsOffset)); 359140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org} 359240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 359340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 359406ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.orgvoid MacroAssembler::NumberOfOwnDescriptors(Register dst, Register map) { 35953c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org movl(dst, FieldOperand(map, Map::kBitField3Offset)); 359606ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org DecodeField<Map::NumberOfOwnDescriptorsBits>(dst); 359706ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org} 359806ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org 359906ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org 3600355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.orgvoid MacroAssembler::EnumLength(Register dst, Register map) { 3601355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org STATIC_ASSERT(Map::EnumLengthBits::kShift == 0); 36023c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org movl(dst, FieldOperand(map, Map::kBitField3Offset)); 36033c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org andl(dst, Immediate(Map::EnumLengthBits::kMask)); 36043c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org Integer32ToSmi(dst, dst); 3605355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org} 3606355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 3607355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 3608ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.orgvoid MacroAssembler::DispatchMap(Register obj, 36092bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register unused, 3610ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org Handle<Map> map, 3611ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org Handle<Code> success, 3612ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org SmiCheckType smi_check_type) { 3613ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org Label fail; 3614ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org if (smi_check_type == DO_SMI_CHECK) { 3615ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org JumpIfSmi(obj, &fail); 3616ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org } 3617ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org Cmp(FieldOperand(obj, HeapObject::kMapOffset), map); 3618ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org j(equal, success, RelocInfo::CODE_TARGET); 3619ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 3620ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org bind(&fail); 3621ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org} 3622ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 3623ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 3624c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid MacroAssembler::AssertNumber(Register object) { 3625c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org if (emit_debug_code()) { 3626c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Label ok; 3627c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Condition is_smi = CheckSmi(object); 3628c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org j(is_smi, &ok, Label::kNear); 3629c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Cmp(FieldOperand(object, HeapObject::kMapOffset), 3630c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org isolate()->factory()->heap_number_map()); 3631594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(equal, kOperandIsNotANumber); 3632c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org bind(&ok); 3633c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org } 36345c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 36355c838251403b0be9a882540f1922577abba4c872ager@chromium.org 36365c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3637c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid MacroAssembler::AssertNotSmi(Register object) { 3638c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org if (emit_debug_code()) { 3639c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Condition is_smi = CheckSmi(object); 3640594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(NegateCondition(is_smi), kOperandIsASmi); 3641c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org } 3642ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org} 3643ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 3644ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 3645c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid MacroAssembler::AssertSmi(Register object) { 3646c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org if (emit_debug_code()) { 3647c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Condition is_smi = CheckSmi(object); 3648594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(is_smi, kOperandIsNotASmi); 3649c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org } 3650badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org} 3651badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org 3652badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org 3653c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid MacroAssembler::AssertSmi(const Operand& object) { 3654c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org if (emit_debug_code()) { 3655c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Condition is_smi = CheckSmi(object); 3656594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(is_smi, kOperandIsNotASmi); 3657c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org } 365825156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org} 365925156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org 366025156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org 3661c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid MacroAssembler::AssertZeroExtended(Register int32_register) { 3662c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org if (emit_debug_code()) { 3663c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org ASSERT(!int32_register.is(kScratchRegister)); 3664e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org movq(kScratchRegister, V8_INT64_C(0x0000000100000000)); 3665c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org cmpq(kScratchRegister, int32_register); 3666594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(above_equal, k32BitValueInRegisterIsNotZeroExtended); 3667c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org } 3668f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org} 3669f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 3670f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 3671c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid MacroAssembler::AssertString(Register object) { 3672c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org if (emit_debug_code()) { 3673c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org testb(object, Immediate(kSmiTagMask)); 3674594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(not_equal, kOperandIsASmiAndNotAString); 3675763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Push(object); 367643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(object, FieldOperand(object, HeapObject::kMapOffset)); 3677c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org CmpInstanceType(object, FIRST_NONSTRING_TYPE); 3678763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Pop(object); 3679594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(below, kOperandIsNotAString); 3680c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org } 368149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org} 368249edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 368349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 3684750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgvoid MacroAssembler::AssertName(Register object) { 3685750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (emit_debug_code()) { 3686750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org testb(object, Immediate(kSmiTagMask)); 3687594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(not_equal, kOperandIsASmiAndNotAName); 3688763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Push(object); 368943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(object, FieldOperand(object, HeapObject::kMapOffset)); 3690750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org CmpInstanceType(object, LAST_NAME_TYPE); 3691763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Pop(object); 3692594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(below_equal, kOperandIsNotAName); 3693750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org } 3694750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org} 3695750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 3696750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 36972904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.orgvoid MacroAssembler::AssertUndefinedOrAllocationSite(Register object) { 36982904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org if (emit_debug_code()) { 36992904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org Label done_checking; 37002904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org AssertNotSmi(object); 37012904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org Cmp(object, isolate()->factory()->undefined_value()); 37022904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org j(equal, &done_checking); 37032904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org Cmp(FieldOperand(object, 0), isolate()->factory()->allocation_site_map()); 37042904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org Assert(equal, kExpectedUndefinedOrCell); 37052904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org bind(&done_checking); 37062904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org } 37072904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org} 37082904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org 37092904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org 3710c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgvoid MacroAssembler::AssertRootValue(Register src, 3711c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org Heap::RootListIndex root_value_index, 3712594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org BailoutReason reason) { 3713c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org if (emit_debug_code()) { 3714c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org ASSERT(!src.is(kScratchRegister)); 3715c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org LoadRoot(kScratchRegister, root_value_index); 37167a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(src, kScratchRegister); 3717594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(equal, reason); 3718c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org } 37195ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org} 37205ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org 37215ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org 37225ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org 3723b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgCondition MacroAssembler::IsObjectStringType(Register heap_object, 3724b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Register map, 3725b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Register instance_type) { 372643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(map, FieldOperand(heap_object, HeapObject::kMapOffset)); 3727b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org movzxbl(instance_type, FieldOperand(map, Map::kInstanceTypeOffset)); 372880c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org STATIC_ASSERT(kNotStringTag != 0); 3729b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org testb(instance_type, Immediate(kIsNotStringMask)); 3730b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org return zero; 3731b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 3732b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 3733b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 3734750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgCondition MacroAssembler::IsObjectNameType(Register heap_object, 3735750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Register map, 3736750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Register instance_type) { 373743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(map, FieldOperand(heap_object, HeapObject::kMapOffset)); 3738750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org movzxbl(instance_type, FieldOperand(map, Map::kInstanceTypeOffset)); 3739750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org cmpb(instance_type, Immediate(static_cast<uint8_t>(LAST_NAME_TYPE))); 3740750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org return below_equal; 3741750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org} 3742750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 3743750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 374486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.orgvoid MacroAssembler::TryGetFunctionPrototype(Register function, 374586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org Register result, 3746394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Label* miss, 3747394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com bool miss_on_bound_function) { 374886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // Check that the receiver isn't a smi. 374986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org testl(function, Immediate(kSmiTagMask)); 375086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org j(zero, miss); 375186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org 375286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // Check that the function really is a function. 375386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org CmpObjectType(function, JS_FUNCTION_TYPE, result); 375486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org j(not_equal, miss); 375586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org 3756394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (miss_on_bound_function) { 375743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(kScratchRegister, 3758394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); 3759394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // It's not smi-tagged (stored in the top half of a smi-tagged 8-byte 3760394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // field). 376104a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org TestBitSharedFunctionInfoSpecialField(kScratchRegister, 376204a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org SharedFunctionInfo::kCompilerHintsOffset, 376304a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org SharedFunctionInfo::kBoundFunction); 3764394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com j(not_zero, miss); 3765394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 3766394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 376786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // Make sure that the function has an instance prototype. 376883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label non_instance; 376986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org testb(FieldOperand(result, Map::kBitFieldOffset), 377086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org Immediate(1 << Map::kHasNonInstancePrototype)); 377183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(not_zero, &non_instance, Label::kNear); 377286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org 377386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // Get the prototype or initial map from the function. 377443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(result, 377586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); 377686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org 377786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // If the prototype or initial map is the hole, don't return it and 377886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // simply miss the cache instead. This will allow us to allocate a 377986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // prototype object on-demand in the runtime system. 378018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org CompareRoot(result, Heap::kTheHoleValueRootIndex); 378186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org j(equal, miss); 378286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org 378386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // If the function does not have an initial map, we're done. 378483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label done; 378586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org CmpObjectType(result, MAP_TYPE, kScratchRegister); 378683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(not_equal, &done, Label::kNear); 378786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org 378886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // Get the prototype from the initial map. 378943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(result, FieldOperand(result, Map::kPrototypeOffset)); 379083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org jmp(&done, Label::kNear); 379186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org 379286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // Non-instance prototype: Fetch prototype from constructor field 379386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // in initial map. 379486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org bind(&non_instance); 379543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(result, FieldOperand(result, Map::kConstructorOffset)); 379686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org 379786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // All done. 379886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org bind(&done); 379986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org} 380086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org 3801eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3802eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::SetCounter(StatsCounter* counter, int value) { 3803eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org if (FLAG_native_code_counters && counter->Enabled()) { 3804ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Operand counter_operand = ExternalOperand(ExternalReference(counter)); 3805a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org movl(counter_operand, Immediate(value)); 3806eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org } 3807eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 3808eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3809eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3810eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::IncrementCounter(StatsCounter* counter, int value) { 3811eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org ASSERT(value > 0); 3812eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org if (FLAG_native_code_counters && counter->Enabled()) { 3813ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Operand counter_operand = ExternalOperand(ExternalReference(counter)); 3814eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org if (value == 1) { 3815ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org incl(counter_operand); 3816eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org } else { 3817ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org addl(counter_operand, Immediate(value)); 3818eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org } 3819eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org } 3820eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 3821eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3822eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3823eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::DecrementCounter(StatsCounter* counter, int value) { 3824eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org ASSERT(value > 0); 3825eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org if (FLAG_native_code_counters && counter->Enabled()) { 3826ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Operand counter_operand = ExternalOperand(ExternalReference(counter)); 3827eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org if (value == 1) { 3828ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org decl(counter_operand); 3829eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org } else { 3830ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org subl(counter_operand, Immediate(value)); 3831eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org } 3832eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org } 3833eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 3834eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3835eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 38365c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid MacroAssembler::DebugBreak() { 38375d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Set(rax, 0); // No arguments. 3838ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org LoadAddress(rbx, ExternalReference(Runtime::kDebugBreak, isolate())); 3839f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CEntryStub ces(isolate(), 1); 3840c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(AllowThisStubCall(&ces)); 3841f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org Call(ces.GetCode(), RelocInfo::DEBUG_BREAK); 38423e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org} 38433e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 38443e87580939cb78c5802369f723680d4a16cc2902ager@chromium.org 3845eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::InvokeCode(Register code, 3846eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org const ParameterCount& expected, 3847eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org const ParameterCount& actual, 38483a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org InvokeFlag flag, 3849e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org const CallWrapper& call_wrapper) { 3850c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // You can't call a function without a valid frame. 3851c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(flag == JUMP_FUNCTION || has_frame()); 3852c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 385383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label done; 38542efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org bool definitely_mismatches = false; 38553a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org InvokePrologue(expected, 38563a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org actual, 38573a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Handle<Code>::null(), 38583a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org code, 38593a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org &done, 38602efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org &definitely_mismatches, 38613a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org flag, 386240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org Label::kNear, 3863e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org call_wrapper); 38642efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org if (!definitely_mismatches) { 38652efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org if (flag == CALL_FUNCTION) { 38662efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org call_wrapper.BeforeCall(CallSize(code)); 38672efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org call(code); 38682efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org call_wrapper.AfterCall(); 38692efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } else { 38702efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org ASSERT(flag == JUMP_FUNCTION); 38712efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org jmp(code); 38722efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } 38732efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org bind(&done); 3874eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org } 3875eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 3876eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3877eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3878eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::InvokeFunction(Register function, 3879eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org const ParameterCount& actual, 38803a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org InvokeFlag flag, 3881e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org const CallWrapper& call_wrapper) { 3882c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // You can't call a function without a valid frame. 3883c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(flag == JUMP_FUNCTION || has_frame()); 3884c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 3885eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org ASSERT(function.is(rdi)); 388643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(rdx, FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); 388743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(rsi, FieldOperand(function, JSFunction::kContextOffset)); 388804a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org LoadSharedFunctionInfoSpecialField(rbx, rdx, 388904a34e6171ac922cb1a4c5162cf471809c468ad0machenbach@chromium.org SharedFunctionInfo::kFormalParameterCountOffset); 38905aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org // Advances rdx to the end of the Code object header, to the start of 3891eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // the executable code. 389243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); 3893eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3894eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org ParameterCount expected(rbx); 3895e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org InvokeCode(rdx, expected, actual, flag, call_wrapper); 3896eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 3897eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 3898eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 38998a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.orgvoid MacroAssembler::InvokeFunction(Register function, 390032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org const ParameterCount& expected, 39015c838251403b0be9a882540f1922577abba4c872ager@chromium.org const ParameterCount& actual, 39023a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org InvokeFlag flag, 3903e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org const CallWrapper& call_wrapper) { 3904c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // You can't call a function without a valid frame. 3905c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(flag == JUMP_FUNCTION || has_frame()); 3906c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 39078a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org ASSERT(function.is(rdi)); 390843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(rsi, FieldOperand(function, JSFunction::kContextOffset)); 39098a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org // Advances rdx to the end of the Code object header, to the start of 39108a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org // the executable code. 391143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); 39128a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org 3913e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org InvokeCode(rdx, expected, actual, flag, call_wrapper); 39145c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 39155c838251403b0be9a882540f1922577abba4c872ager@chromium.org 39165c838251403b0be9a882540f1922577abba4c872ager@chromium.org 39178a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.orgvoid MacroAssembler::InvokeFunction(Handle<JSFunction> function, 39188a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org const ParameterCount& expected, 39198a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org const ParameterCount& actual, 39208a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org InvokeFlag flag, 3921e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org const CallWrapper& call_wrapper) { 39228a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org Move(rdi, function); 3923e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org InvokeFunction(rdi, expected, actual, flag, call_wrapper); 39248a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org} 39258a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org 39268a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org 392783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgvoid MacroAssembler::InvokePrologue(const ParameterCount& expected, 392883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org const ParameterCount& actual, 392983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Handle<Code> code_constant, 393083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Register code_register, 393183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label* done, 39322efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org bool* definitely_mismatches, 393383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org InvokeFlag flag, 393440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org Label::Distance near_jump, 3935e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org const CallWrapper& call_wrapper) { 393683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org bool definitely_matches = false; 39372efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org *definitely_mismatches = false; 393883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label invoke; 393983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (expected.is_immediate()) { 394083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(actual.is_immediate()); 394183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (expected.immediate() == actual.immediate()) { 394283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org definitely_matches = true; 394383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 394483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Set(rax, actual.immediate()); 394583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (expected.immediate() == 394683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org SharedFunctionInfo::kDontAdaptArgumentsSentinel) { 394783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Don't worry about adapting arguments for built-ins that 394883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // don't want that done. Skip adaption code by making it look 394983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // like we have a match between expected and actual number of 395083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // arguments. 395183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org definitely_matches = true; 395283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 39532efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org *definitely_mismatches = true; 395483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Set(rbx, expected.immediate()); 395583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 395683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 395783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 395883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (actual.is_immediate()) { 395983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Expected is in register, actual is immediate. This is the 396083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // case when we invoke function values without going through the 396183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // IC mechanism. 39627a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(expected.reg(), Immediate(actual.immediate())); 396383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(equal, &invoke, Label::kNear); 396483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(expected.reg().is(rbx)); 396583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Set(rax, actual.immediate()); 396683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else if (!expected.reg().is(actual.reg())) { 396783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // Both expected and actual are in (different) registers. This 396883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org // is the case when we invoke functions using call and apply. 39697a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(expected.reg(), actual.reg()); 397083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org j(equal, &invoke, Label::kNear); 397183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(actual.reg().is(rax)); 397283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org ASSERT(expected.reg().is(rbx)); 397383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 397483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 397583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 397683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (!definitely_matches) { 397783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Handle<Code> adaptor = isolate()->builtins()->ArgumentsAdaptorTrampoline(); 397883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (!code_constant.is_null()) { 39799cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org Move(rdx, code_constant, RelocInfo::EMBEDDED_OBJECT); 3980fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org addp(rdx, Immediate(Code::kHeaderSize - kHeapObjectTag)); 398183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else if (!code_register.is(rdx)) { 398243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(rdx, code_register); 398383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 398483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 398583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org if (flag == CALL_FUNCTION) { 398683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org call_wrapper.BeforeCall(CallSize(adaptor)); 398783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Call(adaptor, RelocInfo::CODE_TARGET); 398883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org call_wrapper.AfterCall(); 39892efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org if (!*definitely_mismatches) { 39902efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org jmp(done, near_jump); 39912efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org } 399283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } else { 399383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Jump(adaptor, RelocInfo::CODE_TARGET); 399483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 399583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org bind(&invoke); 399683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 399783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org} 399883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 399983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org 4000285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.orgvoid MacroAssembler::StubPrologue() { 4001763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org pushq(rbp); // Caller's frame pointer. 400243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(rbp, rsp); 4003763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Push(rsi); // Callee's context. 4004c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org Push(Smi::FromInt(StackFrame::STUB)); 4005285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org} 4006285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org 4007285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org 4008285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.orgvoid MacroAssembler::Prologue(bool code_pre_aging) { 4009285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org PredictableCodeSizeScope predictible_code_size_scope(this, 4010285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org kNoCodeAgeSequenceLength); 4011285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org if (code_pre_aging) { 4012285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org // Pre-age the code. 4013285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org Call(isolate()->builtins()->MarkCodeAsExecutedOnce(), 4014285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org RelocInfo::CODE_AGE_SEQUENCE); 4015285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org Nop(kNoCodeAgeSequenceLength - Assembler::kShortCallInstructionLength); 4016c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org } else { 4017285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org pushq(rbp); // Caller's frame pointer. 4018285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org movp(rbp, rsp); 4019285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org Push(rsi); // Callee's context. 4020285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org Push(rdi); // Callee's JS function. 4021c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org } 4022c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org} 4023c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 4024c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 4025eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::EnterFrame(StackFrame::Type type) { 4026763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org pushq(rbp); 402743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(rbp, rsp); 4028763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Push(rsi); // Context. 40299d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com Push(Smi::FromInt(type)); 40309cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org Move(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); 4031763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Push(kScratchRegister); 4032badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 40339cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org Move(kScratchRegister, 4034160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org isolate()->factory()->undefined_value(), 4035eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org RelocInfo::EMBEDDED_OBJECT); 40367a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(Operand(rsp, 0), kScratchRegister); 4037594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(not_equal, kCodeObjectNotProperlyPatched); 4038eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org } 4039eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 4040eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 4041eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 4042eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.orgvoid MacroAssembler::LeaveFrame(StackFrame::Type type) { 4043badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 40449d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com Move(kScratchRegister, Smi::FromInt(type)); 40457a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(Operand(rbp, StandardFrameConstants::kMarkerOffset), kScratchRegister); 4046594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(equal, kStackFrameTypesMustMatch); 4047eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org } 404843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(rsp, rbp); 4049763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org popq(rbp); 4050eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 4051eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 4052eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 4053d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.orgvoid MacroAssembler::EnterExitFramePrologue(bool save_rax) { 4054f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Set up the frame structure on the stack. 405586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org // All constants are relative to the frame pointer of the exit frame. 4056d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ASSERT(ExitFrameConstants::kCallerSPDisplacement == 4057d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org kFPOnStackSize + kPCOnStackSize); 4058d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ASSERT(ExitFrameConstants::kCallerPCOffset == kFPOnStackSize); 4059d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ASSERT(ExitFrameConstants::kCallerFPOffset == 0 * kPointerSize); 4060763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org pushq(rbp); 406143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(rbp, rsp); 4062eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 4063d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org // Reserve room for entry stack pointer and push the code object. 40649d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com ASSERT(ExitFrameConstants::kSPOffset == -1 * kPointerSize); 4065763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Push(Immediate(0)); // Saved entry sp, patched before call. 40669cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org Move(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); 4067763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Push(kScratchRegister); // Accessed from EditFrame::code_slot. 4068eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 4069eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // Save the frame pointer and the context in top. 4070e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org if (save_rax) { 407143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(r14, rax); // Backup rax in callee-save register. 4072e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org } 4073eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 407483e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org Store(ExternalReference(Isolate::kCEntryFPAddress, isolate()), rbp); 407583e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org Store(ExternalReference(Isolate::kContextAddress, isolate()), rsi); 4076e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org} 4077eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 40784a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 40790ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.orgvoid MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space, 40800ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org bool save_doubles) { 4081a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org#ifdef _WIN64 40820ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org const int kShadowSpace = 4; 40830ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org arg_stack_space += kShadowSpace; 4084a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org#endif 40850ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org // Optionally save all XMM registers. 40860ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org if (save_doubles) { 4087c3669763e2617aefdac84a072327b201b3dff129jkummerow@chromium.org int space = XMMRegister::kMaxNumAllocatableRegisters * kDoubleSize + 408843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org arg_stack_space * kRegisterSize; 4089fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org subp(rsp, Immediate(space)); 40900ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org int offset = -2 * kPointerSize; 4091a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org for (int i = 0; i < XMMRegister::NumAllocatableRegisters(); i++) { 40920ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org XMMRegister reg = XMMRegister::FromAllocationIndex(i); 40930ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org movsd(Operand(rbp, offset - ((i + 1) * kDoubleSize)), reg); 40940ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } 40950ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } else if (arg_stack_space > 0) { 4096fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org subp(rsp, Immediate(arg_stack_space * kRegisterSize)); 40974a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com } 4098a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org 4099eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // Get the required frame alignment for the OS. 4100ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org const int kFrameAlignment = OS::ActivationFrameAlignment(); 4101eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org if (kFrameAlignment > 0) { 4102eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org ASSERT(IsPowerOf2(kFrameAlignment)); 4103a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org ASSERT(is_int8(kFrameAlignment)); 4104895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org andp(rsp, Immediate(-kFrameAlignment)); 4105eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org } 4106eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 4107eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // Patch the saved entry sp. 410843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(Operand(rbp, ExitFrameConstants::kSPOffset), rsp); 4109eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 4110eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 4111eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 41120ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.orgvoid MacroAssembler::EnterExitFrame(int arg_stack_space, bool save_doubles) { 4113d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org EnterExitFramePrologue(true); 4114e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 4115f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Set up argv in callee-saved register r15. It is reused in LeaveExitFrame, 4116e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org // so it must be retained across the C-call. 4117e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; 4118895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org leap(r15, Operand(rbp, r14, times_pointer_size, offset)); 4119e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 41200ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org EnterExitFrameEpilogue(arg_stack_space, save_doubles); 4121e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org} 4122e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 4123e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 41244a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.comvoid MacroAssembler::EnterApiExitFrame(int arg_stack_space) { 4125d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org EnterExitFramePrologue(false); 41260ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org EnterExitFrameEpilogue(arg_stack_space, false); 4127e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org} 4128e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 4129e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 41300ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.orgvoid MacroAssembler::LeaveExitFrame(bool save_doubles) { 4131eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // Registers: 4132b08986cb66c3f6687247cb6da186c1e73057e399whesse@chromium.org // r15 : argv 41330ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org if (save_doubles) { 41340ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org int offset = -2 * kPointerSize; 4135a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org for (int i = 0; i < XMMRegister::NumAllocatableRegisters(); i++) { 41360ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org XMMRegister reg = XMMRegister::FromAllocationIndex(i); 41370ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org movsd(reg, Operand(rbp, offset - ((i + 1) * kDoubleSize))); 41380ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } 41390ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org } 4140eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // Get the return address from the stack and restore the frame pointer. 414143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(rcx, Operand(rbp, kFPOnStackSize)); 414243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(rbp, Operand(rbp, 0 * kPointerSize)); 4143eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 41440ee099beef2c2b38743d657b84a30b626d9178ecager@chromium.org // Drop everything up to and including the arguments and the receiver 4145a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // from the caller stack. 4146895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org leap(rsp, Operand(r15, 1 * kPointerSize)); 4147eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 4148594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org PushReturnAddressFrom(rcx); 41494a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 4150528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org LeaveExitFrameEpilogue(true); 41514a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com} 41524a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 41534a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 4154528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid MacroAssembler::LeaveApiExitFrame(bool restore_context) { 415543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(rsp, rbp); 4156763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org popq(rbp); 41574a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 4158528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org LeaveExitFrameEpilogue(restore_context); 41594a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com} 41604a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 41614a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 4162528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid MacroAssembler::LeaveExitFrameEpilogue(bool restore_context) { 4163eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // Restore current context from top and clear it in debug mode. 416483e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org ExternalReference context_address(Isolate::kContextAddress, isolate()); 4165ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Operand context_operand = ExternalOperand(context_address); 4166528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (restore_context) { 416743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(rsi, context_operand); 4168528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 4169eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org#ifdef DEBUG 417043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(context_operand, Immediate(0)); 4171eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org#endif 4172eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 4173eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org // Clear the top frame. 417483e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress, 4175ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate()); 4176ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Operand c_entry_fp_operand = ExternalOperand(c_entry_fp_address); 417743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(c_entry_fp_operand, Immediate(0)); 4178eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org} 4179eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 4180eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org 4181e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.orgvoid MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, 4182e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org Register scratch, 4183e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org Label* miss) { 4184e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org Label same_contexts; 4185e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 4186e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org ASSERT(!holder_reg.is(scratch)); 4187e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org ASSERT(!scratch.is(kScratchRegister)); 4188e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // Load current lexical context from the stack frame. 418943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(scratch, Operand(rbp, StandardFrameConstants::kContextOffset)); 4190e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 4191e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // When generating debug code, make sure the lexical context is set. 4192badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 41937a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(scratch, Immediate(0)); 4194594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(not_equal, kWeShouldNotHaveAnEmptyLexicalContext); 4195e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org } 419646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Load the native context of the current context. 419746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org int offset = 419846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize; 419943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(scratch, FieldOperand(scratch, offset)); 420043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(scratch, FieldOperand(scratch, GlobalObject::kNativeContextOffset)); 4201e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 420246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Check the context is a native context. 4203badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 4204e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org Cmp(FieldOperand(scratch, HeapObject::kMapOffset), 420546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org isolate()->factory()->native_context_map()); 4206594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(equal, kJSGlobalObjectNativeContextShouldBeANativeContext); 4207e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org } 4208e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 4209e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // Check if both contexts are the same. 42107a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(scratch, FieldOperand(holder_reg, JSGlobalProxy::kNativeContextOffset)); 4211e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org j(equal, &same_contexts); 4212e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 4213e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // Compare security tokens. 4214e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // Check that the security token in the calling global object is 4215e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // compatible with the security token in the receiving global 4216e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // object. 4217e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 421846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Check the context is a native context. 4219badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 4220e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // Preserve original value of holder_reg. 4221763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Push(holder_reg); 422243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(holder_reg, 422346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org FieldOperand(holder_reg, JSGlobalProxy::kNativeContextOffset)); 422418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org CompareRoot(holder_reg, Heap::kNullValueRootIndex); 4225594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(not_equal, kJSGlobalProxyContextShouldNotBeNull); 4226e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 422746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Read the first word and compare to native_context_map(), 422843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(holder_reg, FieldOperand(holder_reg, HeapObject::kMapOffset)); 422946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org CompareRoot(holder_reg, Heap::kNativeContextMapRootIndex); 4230594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(equal, kJSGlobalObjectNativeContextShouldBeANativeContext); 4231763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Pop(holder_reg); 4232e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org } 4233e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 423443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(kScratchRegister, 423546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org FieldOperand(holder_reg, JSGlobalProxy::kNativeContextOffset)); 42369d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com int token_offset = 42379d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com Context::kHeaderSize + Context::SECURITY_TOKEN_INDEX * kPointerSize; 423843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(scratch, FieldOperand(scratch, token_offset)); 42397a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(scratch, FieldOperand(kScratchRegister, token_offset)); 4240e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org j(not_equal, miss); 4241e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 4242e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org bind(&same_contexts); 4243e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org} 4244e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 4245e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 4246ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org// Compute the hash code from the untagged key. This must be kept in sync with 4247ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org// ComputeIntegerHash in utils.h and KeyedLoadGenericElementStub in 4248ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org// code-stub-hydrogen.cc 4249f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.comvoid MacroAssembler::GetNumberHash(Register r0, Register scratch) { 4250f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // First of all we assign the hash seed to scratch. 4251f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com LoadRoot(scratch, Heap::kHashSeedRootIndex); 4252f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com SmiToInteger32(scratch, scratch); 4253f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 4254f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Xor original key with a seed. 4255f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com xorl(r0, scratch); 4256f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 4257f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Compute the hash code from the untagged key. This must be kept in sync 4258f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // with ComputeIntegerHash in utils.h. 4259f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // 4260f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // hash = ~hash + (hash << 15); 4261f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com movl(scratch, r0); 4262f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com notl(r0); 4263f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com shll(scratch, Immediate(15)); 4264f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com addl(r0, scratch); 4265f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // hash = hash ^ (hash >> 12); 4266f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com movl(scratch, r0); 4267f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com shrl(scratch, Immediate(12)); 4268f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com xorl(r0, scratch); 4269f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // hash = hash + (hash << 2); 4270f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com leal(r0, Operand(r0, r0, times_4, 0)); 4271f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // hash = hash ^ (hash >> 4); 4272f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com movl(scratch, r0); 4273f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com shrl(scratch, Immediate(4)); 4274f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com xorl(r0, scratch); 4275f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // hash = hash * 2057; 4276f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com imull(r0, r0, Immediate(2057)); 4277f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // hash = hash ^ (hash >> 16); 4278f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com movl(scratch, r0); 4279f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com shrl(scratch, Immediate(16)); 4280f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com xorl(r0, scratch); 4281f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com} 4282f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 4283f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 4284f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 42856db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.orgvoid MacroAssembler::LoadFromNumberDictionary(Label* miss, 42866db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register elements, 42876db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register key, 42886db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register r0, 42896db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register r1, 42906db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register r2, 42916db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register result) { 42926db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Register use: 42936db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // 42946db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // elements - holds the slow-case elements of the receiver on entry. 42956db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Unchanged unless 'result' is the same register. 42966db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // 42976db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // key - holds the smi key on entry. 42986db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Unchanged unless 'result' is the same register. 42996db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // 43006db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Scratch registers: 43016db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // 43026db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // r0 - holds the untagged key on entry and holds the hash once computed. 43036db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // 43046db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // r1 - used to hold the capacity mask of the dictionary 43056db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // 43066db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // r2 - used for the index into the dictionary. 43076db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // 43086db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // result - holds the result on exit if the load succeeded. 43096db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Allowed to be the same as 'key' or 'result'. 43106db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Unchanged on bailout so 'key' or 'result' can be used 43116db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // in further computation. 43126db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 43136db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Label done; 43146db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 4315f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com GetNumberHash(r0, r1); 43166db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 43176db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Compute capacity mask. 4318f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com SmiToInteger32(r1, FieldOperand(elements, 4319f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com SeededNumberDictionary::kCapacityOffset)); 43206db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org decl(r1); 43216db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 43226db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Generate an unrolled loop that performs a few probes before giving up. 4323ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org for (int i = 0; i < kNumberDictionaryProbes; i++) { 43246db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Use r2 for index calculations and keep the hash intact in r0. 432543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(r2, r0); 43266db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Compute the masked index: (hash + i + i * i) & mask. 43276db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org if (i > 0) { 4328f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com addl(r2, Immediate(SeededNumberDictionary::GetProbeOffset(i))); 43296db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org } 4330895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org andp(r2, r1); 43316db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 43326db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Scale the index by multiplying by the entry size. 4333f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com ASSERT(SeededNumberDictionary::kEntrySize == 3); 4334895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org leap(r2, Operand(r2, r2, times_2, 0)); // r2 = r2 * 3 43356db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 43366db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Check if the key matches. 43377a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(key, FieldOperand(elements, 43386db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org r2, 43396db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org times_pointer_size, 4340f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com SeededNumberDictionary::kElementsStartOffset)); 4341ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org if (i != (kNumberDictionaryProbes - 1)) { 43426db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org j(equal, &done); 43436db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org } else { 43446db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org j(not_equal, miss); 43456db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org } 43466db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org } 43476db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 43486db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org bind(&done); 43496db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Check that the value is a normal propety. 43506db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org const int kDetailsOffset = 4351f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com SeededNumberDictionary::kElementsStartOffset + 2 * kPointerSize; 43526db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org ASSERT_EQ(NORMAL, 0); 43536db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset), 435483e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org Smi::FromInt(PropertyDetails::TypeField::kMask)); 43556db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org j(not_zero, miss); 43566db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 43576db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Get the value at the masked, scaled index. 43586db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org const int kValueOffset = 4359f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com SeededNumberDictionary::kElementsStartOffset + kPointerSize; 436043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(result, FieldOperand(elements, r2, times_pointer_size, kValueOffset)); 43616db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org} 43626db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 43636db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 4364a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.orgvoid MacroAssembler::LoadAllocationTopHelper(Register result, 4365a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org Register scratch, 4366a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org AllocationFlags flags) { 43672bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org ExternalReference allocation_top = 43682bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org AllocationUtils::GetAllocationTopReference(isolate(), flags); 436918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 437018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Just return if allocation top is already known. 4371a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org if ((flags & RESULT_CONTAINS_TOP) != 0) { 437218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // No use of scratch if allocation top is provided. 4373ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org ASSERT(!scratch.is_valid()); 4374a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org#ifdef DEBUG 4375a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // Assert that result actually contains top on entry. 43762bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Operand top_operand = ExternalOperand(allocation_top); 43777a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(result, top_operand); 4378594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(equal, kUnexpectedAllocationTop); 4379a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org#endif 438018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org return; 438118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 438218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 4383ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org // Move address of new object to result. Use scratch register if available, 4384ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org // and keep address in scratch until call to UpdateAllocationTopHelper. 4385ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org if (scratch.is_valid()) { 43862bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org LoadAddress(scratch, allocation_top); 438743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(result, Operand(scratch, 0)); 4388ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org } else { 43892bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Load(result, allocation_top); 439018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 439118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 439218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 439318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 439438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.orgvoid MacroAssembler::MakeSureDoubleAlignedHelper(Register result, 439538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org Register scratch, 439638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org Label* gc_required, 439738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org AllocationFlags flags) { 439838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org if (kPointerSize == kDoubleSize) { 439938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org if (FLAG_debug_code) { 440038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org testl(result, Immediate(kDoubleAlignmentMask)); 440138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org Check(zero, kAllocationIsNotDoubleAligned); 440238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org } 440338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org } else { 440438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org // Align the next allocation. Storing the filler map without checking top 440538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org // is safe in new-space because the limit of the heap is aligned there. 440638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org ASSERT(kPointerSize * 2 == kDoubleSize); 440738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org ASSERT((flags & PRETENURE_OLD_POINTER_SPACE) == 0); 440838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org ASSERT(kPointerAlignment * 2 == kDoubleAlignment); 440938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org // Make sure scratch is not clobbered by this function as it might be 441038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org // used in UpdateAllocationTopHelper later. 441138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org ASSERT(!scratch.is(kScratchRegister)); 441238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org Label aligned; 441338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org testl(result, Immediate(kDoubleAlignmentMask)); 441438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org j(zero, &aligned, Label::kNear); 441538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org if ((flags & PRETENURE_OLD_DATA_SPACE) != 0) { 441638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org ExternalReference allocation_limit = 441738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org AllocationUtils::GetAllocationLimitReference(isolate(), flags); 441838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org cmpp(result, ExternalOperand(allocation_limit)); 441938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org j(above_equal, gc_required); 442038de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org } 442138de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org LoadRoot(kScratchRegister, Heap::kOnePointerFillerMapRootIndex); 442238de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org movp(Operand(result, 0), kScratchRegister); 442338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org addp(result, Immediate(kDoubleSize / 2)); 442438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org bind(&aligned); 442538de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org } 442638de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org} 442738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org 442838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org 442918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid MacroAssembler::UpdateAllocationTopHelper(Register result_end, 44302bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register scratch, 44312bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org AllocationFlags flags) { 4432badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 44337a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org testp(result_end, Immediate(kObjectAlignmentMask)); 4434594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(zero, kUnalignedAllocationInNewSpace); 4435ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org } 4436ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 44372bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org ExternalReference allocation_top = 44382bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org AllocationUtils::GetAllocationTopReference(isolate(), flags); 443918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 444018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Update new top. 4441ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (scratch.is_valid()) { 4442ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Scratch already contains address of allocation top. 444343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(Operand(scratch, 0), result_end); 444418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } else { 44452bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Store(allocation_top, result_end); 444618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 444718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 444818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 444918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 44502bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.orgvoid MacroAssembler::Allocate(int object_size, 44512bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register result, 44522bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register result_end, 44532bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register scratch, 44542bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Label* gc_required, 44552bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org AllocationFlags flags) { 44564cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org ASSERT((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0); 4457ef9a2b9208396fda21c01fdff922975fe35d9c4amachenbach@chromium.org ASSERT(object_size <= Page::kMaxRegularHeapObjectSize); 4458b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (!FLAG_inline_new) { 4459badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 4460303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // Trash the registers to simulate an allocation failure. 4461303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org movl(result, Immediate(0x7091)); 4462303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org if (result_end.is_valid()) { 4463303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org movl(result_end, Immediate(0x7191)); 4464303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 4465303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org if (scratch.is_valid()) { 4466303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org movl(scratch, Immediate(0x7291)); 4467303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 4468303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 4469303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org jmp(gc_required); 4470303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org return; 4471303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 447218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org ASSERT(!result.is(result_end)); 447318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 447418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Load address of new object into result. 4475beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org LoadAllocationTopHelper(result, scratch, flags); 447618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 447738de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org if ((flags & DOUBLE_ALIGNMENT) != 0) { 447838de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org MakeSureDoubleAlignedHelper(result, scratch, gc_required, flags); 44794cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org } 44804cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org 448118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Calculate new top and bail out if new space is exhausted. 44822bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org ExternalReference allocation_limit = 44832bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org AllocationUtils::GetAllocationLimitReference(isolate(), flags); 4484ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 4485ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org Register top_reg = result_end.is_valid() ? result_end : result; 4486ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 4487d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com if (!top_reg.is(result)) { 448843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(top_reg, result); 4489ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org } 4490fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org addp(top_reg, Immediate(object_size)); 4491d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com j(carry, gc_required); 44922bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Operand limit_operand = ExternalOperand(allocation_limit); 44937a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(top_reg, limit_operand); 449418ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org j(above, gc_required); 449518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 449618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Update allocation top. 44972bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org UpdateAllocationTopHelper(top_reg, scratch, flags); 4498a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org 44994cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org bool tag_result = (flags & TAG_OBJECT) != 0; 4500ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org if (top_reg.is(result)) { 45014cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org if (tag_result) { 4502fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org subp(result, Immediate(object_size - kHeapObjectTag)); 4503ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org } else { 4504fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org subp(result, Immediate(object_size)); 4505ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org } 45064cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org } else if (tag_result) { 4507ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org // Tag the result if requested. 45084cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org ASSERT(kHeapObjectTag == 1); 45097a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org incp(result); 4510a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org } 451118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 451218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 451318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 4514f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.orgvoid MacroAssembler::Allocate(int header_size, 4515f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org ScaleFactor element_size, 4516f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register element_count, 4517f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register result, 4518f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register result_end, 4519f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register scratch, 4520f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Label* gc_required, 4521f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org AllocationFlags flags) { 45224cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org ASSERT((flags & SIZE_IN_WORDS) == 0); 4523895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org leap(result_end, Operand(element_count, element_size, header_size)); 4524e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org Allocate(result_end, result, result_end, scratch, gc_required, flags); 4525a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org} 452618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 452718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 4528f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.orgvoid MacroAssembler::Allocate(Register object_size, 4529f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register result, 4530f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register result_end, 4531f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Register scratch, 4532f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Label* gc_required, 4533f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org AllocationFlags flags) { 4534e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org ASSERT((flags & SIZE_IN_WORDS) == 0); 4535b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (!FLAG_inline_new) { 4536badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 4537303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // Trash the registers to simulate an allocation failure. 4538303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org movl(result, Immediate(0x7091)); 4539303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org movl(result_end, Immediate(0x7191)); 4540303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org if (scratch.is_valid()) { 4541303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org movl(scratch, Immediate(0x7291)); 4542303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 4543303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // object_size is left unchanged by this function. 4544303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 4545303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org jmp(gc_required); 4546303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org return; 4547303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 4548303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org ASSERT(!result.is(result_end)); 4549303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org 455018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Load address of new object into result. 4551beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org LoadAllocationTopHelper(result, scratch, flags); 455218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 455338de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org if ((flags & DOUBLE_ALIGNMENT) != 0) { 455438de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org MakeSureDoubleAlignedHelper(result, scratch, gc_required, flags); 4555e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org } 4556e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 455718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Calculate new top and bail out if new space is exhausted. 4558f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org ExternalReference allocation_limit = 4559f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org AllocationUtils::GetAllocationLimitReference(isolate(), flags); 456018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (!object_size.is(result_end)) { 456143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(result_end, object_size); 456218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 4563fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org addp(result_end, result); 4564d91075f76b836c2cfa4f4e4cc0fb31170df864ccerik.corry@gmail.com j(carry, gc_required); 4565f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Operand limit_operand = ExternalOperand(allocation_limit); 45667a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(result_end, limit_operand); 456718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org j(above, gc_required); 456818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 456918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Update allocation top. 45702bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org UpdateAllocationTopHelper(result_end, scratch, flags); 4571a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org 4572a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // Tag the result if requested. 4573a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org if ((flags & TAG_OBJECT) != 0) { 4574fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org addp(result, Immediate(kHeapObjectTag)); 4575a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org } 457618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 457718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 457818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 457918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.orgvoid MacroAssembler::UndoAllocationInNewSpace(Register object) { 458018ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org ExternalReference new_space_allocation_top = 4581ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ExternalReference::new_space_allocation_top_address(isolate()); 458218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 458318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org // Make sure the object has no tag before resetting top. 4584895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org andp(object, Immediate(~kHeapObjectTagMask)); 4585ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Operand top_operand = ExternalOperand(new_space_allocation_top); 458618ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org#ifdef DEBUG 45877a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(object, top_operand); 4588594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(below, kUndoAllocationOfNonAllocatedMemory); 458918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org#endif 459043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(top_operand, object); 459118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org} 459218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 459318ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 45943811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.orgvoid MacroAssembler::AllocateHeapNumber(Register result, 45953811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org Register scratch, 45963811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org Label* gc_required) { 45973811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Allocate heap number in new space. 45982bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Allocate(HeapNumber::kSize, result, scratch, no_reg, gc_required, TAG_OBJECT); 45993811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 46003811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Set the map. 46013811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org LoadRoot(kScratchRegister, Heap::kHeapNumberMapRootIndex); 460243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); 46033811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org} 46043811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 46053811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 460613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid MacroAssembler::AllocateTwoByteString(Register result, 460713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register length, 460813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register scratch1, 460913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register scratch2, 461013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register scratch3, 461113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Label* gc_required) { 461213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // Calculate the number of bytes needed for the characters in the string while 461313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // observing object alignment. 4614ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org const int kHeaderAlignment = SeqTwoByteString::kHeaderSize & 4615ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org kObjectAlignmentMask; 461613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org ASSERT(kShortSize == 2); 461713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // scratch1 = length * 2 + kObjectAlignmentMask. 4618895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org leap(scratch1, Operand(length, length, times_1, kObjectAlignmentMask + 4619ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org kHeaderAlignment)); 4620895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org andp(scratch1, Immediate(~kObjectAlignmentMask)); 4621ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org if (kHeaderAlignment > 0) { 4622fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org subp(scratch1, Immediate(kHeaderAlignment)); 4623ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org } 462413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 462513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // Allocate two byte string in new space. 4626f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Allocate(SeqTwoByteString::kHeaderSize, 4627f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org times_1, 4628f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org scratch1, 4629f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org result, 4630f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org scratch2, 4631f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org scratch3, 4632f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org gc_required, 4633f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org TAG_OBJECT); 463413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 463513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // Set the map, length and hash field. 463613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org LoadRoot(kScratchRegister, Heap::kStringMapRootIndex); 463743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); 4638ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org Integer32ToSmi(scratch1, length); 463943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(FieldOperand(result, String::kLengthOffset), scratch1); 464043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(FieldOperand(result, String::kHashFieldOffset), 464113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Immediate(String::kEmptyHashField)); 464213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org} 464313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 464413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 464513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid MacroAssembler::AllocateAsciiString(Register result, 464613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register length, 464713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register scratch1, 464813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register scratch2, 464913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register scratch3, 465013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Label* gc_required) { 465113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // Calculate the number of bytes needed for the characters in the string while 465213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // observing object alignment. 4653fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org const int kHeaderAlignment = SeqOneByteString::kHeaderSize & 4654ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org kObjectAlignmentMask; 465513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org movl(scratch1, length); 465613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org ASSERT(kCharSize == 1); 4657fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org addp(scratch1, Immediate(kObjectAlignmentMask + kHeaderAlignment)); 4658895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org andp(scratch1, Immediate(~kObjectAlignmentMask)); 4659ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org if (kHeaderAlignment > 0) { 4660fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org subp(scratch1, Immediate(kHeaderAlignment)); 4661ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org } 466213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 46632efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // Allocate ASCII string in new space. 4664f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Allocate(SeqOneByteString::kHeaderSize, 4665f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org times_1, 4666f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org scratch1, 4667f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org result, 4668f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org scratch2, 4669f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org scratch3, 4670f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org gc_required, 4671f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org TAG_OBJECT); 467213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 467313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // Set the map, length and hash field. 467413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org LoadRoot(kScratchRegister, Heap::kAsciiStringMapRootIndex); 467543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); 4676ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org Integer32ToSmi(scratch1, length); 467743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(FieldOperand(result, String::kLengthOffset), scratch1); 467843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(FieldOperand(result, String::kHashFieldOffset), 467913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Immediate(String::kEmptyHashField)); 468013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org} 468113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 468213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 46831805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.orgvoid MacroAssembler::AllocateTwoByteConsString(Register result, 468413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register scratch1, 468513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register scratch2, 468613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Label* gc_required) { 468713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // Allocate heap number in new space. 46882bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, 46892bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org TAG_OBJECT); 469013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 469113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // Set the map. The other fields are left uninitialized. 469213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org LoadRoot(kScratchRegister, Heap::kConsStringMapRootIndex); 469343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); 469413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org} 469513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 469613bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 469713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.orgvoid MacroAssembler::AllocateAsciiConsString(Register result, 469813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register scratch1, 469913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Register scratch2, 470013bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org Label* gc_required) { 470157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Allocate(ConsString::kSize, 470257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org result, 470357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org scratch1, 470457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org scratch2, 470557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org gc_required, 47067e6132b924829c353864933f29124419916db550machenbach@chromium.org TAG_OBJECT); 470713bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 470813bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org // Set the map. The other fields are left uninitialized. 470913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org LoadRoot(kScratchRegister, Heap::kConsAsciiStringMapRootIndex); 471043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); 471113bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org} 471213bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 471313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org 47141805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.orgvoid MacroAssembler::AllocateTwoByteSlicedString(Register result, 47151805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org Register scratch1, 47161805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org Register scratch2, 47171805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org Label* gc_required) { 47181805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // Allocate heap number in new space. 47192bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, 47202bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org TAG_OBJECT); 47211805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 47221805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // Set the map. The other fields are left uninitialized. 47231805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org LoadRoot(kScratchRegister, Heap::kSlicedStringMapRootIndex); 472443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); 47251805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org} 47261805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 47271805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 47281805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.orgvoid MacroAssembler::AllocateAsciiSlicedString(Register result, 47291805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org Register scratch1, 47301805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org Register scratch2, 47311805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org Label* gc_required) { 47321805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // Allocate heap number in new space. 47332bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, 47342bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org TAG_OBJECT); 47351805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 47361805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org // Set the map. The other fields are left uninitialized. 47371805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org LoadRoot(kScratchRegister, Heap::kSlicedAsciiStringMapRootIndex); 473843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); 47391805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org} 47401805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 47411805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org 47427979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org// Copy memory, byte-by-byte, from source to destination. Not optimized for 47437979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org// long or aligned copies. The contents of scratch and length are destroyed. 47447979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org// Destination is incremented by length, source, length and scratch are 47457979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org// clobbered. 47467979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org// A simpler loop is faster on small copies, but slower on large ones. 47477979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org// The cld() instruction must have been emitted, to set the direction flag(), 47487979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org// before calling this function. 47497979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.orgvoid MacroAssembler::CopyBytes(Register destination, 47507979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Register source, 47517979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Register length, 47527979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org int min_length, 47537979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Register scratch) { 47547979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org ASSERT(min_length >= 0); 4755000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org if (emit_debug_code()) { 47567979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org cmpl(length, Immediate(min_length)); 4757594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Assert(greater_equal, kInvalidMinLength); 47587979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org } 47590cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org Label short_loop, len8, len16, len24, done, short_string; 47607979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 47610cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org const int kLongStringLimit = 4 * kPointerSize; 47627979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org if (min_length <= kLongStringLimit) { 47630cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org cmpl(length, Immediate(kPointerSize)); 47640cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org j(below, &short_string, Label::kNear); 47657979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org } 47667979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 47677979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org ASSERT(source.is(rsi)); 47687979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org ASSERT(destination.is(rdi)); 47697979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org ASSERT(length.is(rcx)); 47707979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 47710cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org if (min_length <= kLongStringLimit) { 47720cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org cmpl(length, Immediate(2 * kPointerSize)); 47730cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org j(below_equal, &len8, Label::kNear); 47740cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org cmpl(length, Immediate(3 * kPointerSize)); 47750cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org j(below_equal, &len16, Label::kNear); 47760cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org cmpl(length, Immediate(4 * kPointerSize)); 47770cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org j(below_equal, &len24, Label::kNear); 47780cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org } 47790cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 47807979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Because source is 8-byte aligned in our uses of this function, 47817979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // we keep source aligned for the rep movs operation by copying the odd bytes 47827979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // at the end of the ranges. 478343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(scratch, length); 478493a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org shrl(length, Immediate(kPointerSizeLog2)); 4785895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org repmovsp(); 47867979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org // Move remaining bytes of length. 478793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org andl(scratch, Immediate(kPointerSize - 1)); 478843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(length, Operand(source, scratch, times_1, -kPointerSize)); 478943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(Operand(destination, scratch, times_1, -kPointerSize), length); 4790fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org addp(destination, scratch); 47917979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 47927979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org if (min_length <= kLongStringLimit) { 47930cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org jmp(&done, Label::kNear); 47940cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org bind(&len24); 479543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(scratch, Operand(source, 2 * kPointerSize)); 479643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(Operand(destination, 2 * kPointerSize), scratch); 47970cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org bind(&len16); 479843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(scratch, Operand(source, kPointerSize)); 479943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(Operand(destination, kPointerSize), scratch); 48000cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org bind(&len8); 480143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(scratch, Operand(source, 0)); 480243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(Operand(destination, 0), scratch); 48030cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org // Move remaining bytes of length. 480443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(scratch, Operand(source, length, times_1, -kPointerSize)); 480543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(Operand(destination, length, times_1, -kPointerSize), scratch); 4806fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org addp(destination, length); 48070cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org jmp(&done, Label::kNear); 48087979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 48097979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org bind(&short_string); 48107979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org if (min_length == 0) { 48117979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org testl(length, length); 48120cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org j(zero, &done, Label::kNear); 48137979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org } 48147979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 48157979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org bind(&short_loop); 48160cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org movb(scratch, Operand(source, 0)); 48170cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org movb(Operand(destination, 0), scratch); 48187a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org incp(source); 48197a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org incp(destination); 48200cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org decl(length); 48210cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org j(not_zero, &short_loop); 48227979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org } 48230cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org 48240cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org bind(&done); 48257979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org} 48267979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 48277979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 4828c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::InitializeFieldsWithFiller(Register start_offset, 4829c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register end_offset, 4830c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register filler) { 4831c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label loop, entry; 4832c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com jmp(&entry); 4833c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&loop); 483443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(Operand(start_offset, 0), filler); 4835fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org addp(start_offset, Immediate(kPointerSize)); 4836c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&entry); 48377a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(start_offset, end_offset); 4838c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(less, &loop); 4839c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 4840c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 4841c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 4842ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.orgvoid MacroAssembler::LoadContext(Register dst, int context_chain_length) { 4843ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org if (context_chain_length > 0) { 4844ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org // Move up the chain of contexts to the context containing the slot. 484543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(dst, Operand(rsi, Context::SlotOffset(Context::PREVIOUS_INDEX))); 4846ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org for (int i = 1; i < context_chain_length; i++) { 484743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(dst, Operand(dst, Context::SlotOffset(Context::PREVIOUS_INDEX))); 4848ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org } 48495d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org } else { 48505d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // Slot is in the current function context. Move it into the 48515d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // destination register in case we store into it (the write barrier 48525d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org // cannot be allowed to destroy the context in rsi). 485343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(dst, rsi); 48545d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org } 48555d6c1f5b20195b800bc6db146920fd6f878d1fd4vegorov@chromium.org 48564f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // We should not have found a with context by walking the context 48574f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // chain (i.e., the static scope chain and runtime context chain do 48584f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // not agree). A variable occurring in such a scope should have 48594f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org // slot type LOOKUP and not CONTEXT. 4860badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 48613cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org CompareRoot(FieldOperand(dst, HeapObject::kMapOffset), 48623cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org Heap::kWithContextMapRootIndex); 4863594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Check(not_equal, kVariableResolvedToWithContext); 4864ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org } 4865ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org} 4866ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 4867fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org 48681145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.orgvoid MacroAssembler::LoadTransitionedArrayMapConditional( 48691145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org ElementsKind expected_kind, 48701145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org ElementsKind transitioned_kind, 48711145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org Register map_in_out, 48721145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org Register scratch, 48731145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org Label* no_map_match) { 48741145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org // Load the global or builtins object from the current context. 487543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(scratch, 487646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 487743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(scratch, FieldOperand(scratch, GlobalObject::kNativeContextOffset)); 48781145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org 48791145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org // Check that the function's map is the same as the expected cached map. 488043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(scratch, Operand(scratch, 4881830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Context::SlotOffset(Context::JS_ARRAY_MAPS_INDEX))); 4882830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org 4883830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org int offset = expected_kind * kPointerSize + 4884830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org FixedArrayBase::kHeaderSize; 48857a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(map_in_out, FieldOperand(scratch, offset)); 48861145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org j(not_equal, no_map_match); 48871145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org 48881145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org // Use the transitioned cached map. 4889830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org offset = transitioned_kind * kPointerSize + 4890830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org FixedArrayBase::kHeaderSize; 489143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(map_in_out, FieldOperand(scratch, offset)); 48921145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org} 48931145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org 48941145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org 4895ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org#ifdef _WIN64 4896ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic const int kRegisterPassedArguments = 4; 4897ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org#else 4898ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic const int kRegisterPassedArguments = 6; 4899ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org#endif 490030ce411529579186181838984710b0b0980857aaricow@chromium.org 49015f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvoid MacroAssembler::LoadGlobalFunction(int index, Register function) { 49025f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // Load the global or builtins object from the current context. 490343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(function, 490446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 490546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Load the native context from the global or builtins object. 490643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(function, FieldOperand(function, GlobalObject::kNativeContextOffset)); 490746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Load the function from the native context. 490843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(function, Operand(function, Context::SlotOffset(index))); 49095f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org} 49105f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 49115f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 49125f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.orgvoid MacroAssembler::LoadGlobalFunctionInitialMap(Register function, 49135f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org Register map) { 49145f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org // Load the initial map. The global functions all have initial maps. 491543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(map, FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); 4916badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 49175f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org Label ok, fail; 4918c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org CheckMap(map, isolate()->factory()->meta_map(), &fail, DO_SMI_CHECK); 49195f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org jmp(&ok); 49205f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org bind(&fail); 4921594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Abort(kGlobalFunctionsMustHaveInitialMap); 49225f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org bind(&ok); 49235f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org } 49245f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org} 49255f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 49265f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org 4927b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgint MacroAssembler::ArgumentStackSlotsForCFunctionCall(int num_arguments) { 492830ce411529579186181838984710b0b0980857aaricow@chromium.org // On Windows 64 stack slots are reserved by the caller for all arguments 492930ce411529579186181838984710b0b0980857aaricow@chromium.org // including the ones passed in registers, and space is always allocated for 493030ce411529579186181838984710b0b0980857aaricow@chromium.org // the four register arguments even if the function takes fewer than four 493130ce411529579186181838984710b0b0980857aaricow@chromium.org // arguments. 493230ce411529579186181838984710b0b0980857aaricow@chromium.org // On AMD64 ABI (Linux/Mac) the first six arguments are passed in registers 493330ce411529579186181838984710b0b0980857aaricow@chromium.org // and the caller does not reserve stack slots for them. 4934b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ASSERT(num_arguments >= 0); 4935b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#ifdef _WIN64 4936ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org const int kMinimumStackSlots = kRegisterPassedArguments; 493730ce411529579186181838984710b0b0980857aaricow@chromium.org if (num_arguments < kMinimumStackSlots) return kMinimumStackSlots; 493830ce411529579186181838984710b0b0980857aaricow@chromium.org return num_arguments; 4939b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#else 494030ce411529579186181838984710b0b0980857aaricow@chromium.org if (num_arguments < kRegisterPassedArguments) return 0; 494130ce411529579186181838984710b0b0980857aaricow@chromium.org return num_arguments - kRegisterPassedArguments; 4942b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#endif 4943b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 4944b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 494530ce411529579186181838984710b0b0980857aaricow@chromium.org 49469af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.orgvoid MacroAssembler::EmitSeqStringSetCharCheck(Register string, 49479af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org Register index, 49489af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org Register value, 49499af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org uint32_t encoding_mask) { 49509af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org Label is_object; 49519af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org JumpIfNotSmi(string, &is_object); 495205150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org Abort(kNonObject); 49539af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org bind(&is_object); 49549af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 4955763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Push(value); 495643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(value, FieldOperand(string, HeapObject::kMapOffset)); 4957895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org movzxbp(value, FieldOperand(value, Map::kInstanceTypeOffset)); 49589af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 49599af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org andb(value, Immediate(kStringRepresentationMask | kStringEncodingMask)); 49607a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(value, Immediate(encoding_mask)); 4961763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Pop(value); 496205150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org Check(equal, kUnexpectedStringType); 49639af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 49649af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org // The index is assumed to be untagged coming in, tag it to compare with the 49659af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org // string length without using a temp register, it is restored at the end of 49669af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org // this function. 49679af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org Integer32ToSmi(index, index); 49689af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org SmiCompare(index, FieldOperand(string, String::kLengthOffset)); 496905150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org Check(less, kIndexIsTooLarge); 49709af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 49719af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org SmiCompare(index, Smi::FromInt(0)); 497205150ab746caefd8e734c394ecc7863200ca04cfmachenbach@chromium.org Check(greater_equal, kIndexIsNegative); 49739af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 49749af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org // Restore the index 49759af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org SmiToInteger32(index, index); 49769af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org} 49779af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 49789af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org 4979b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid MacroAssembler::PrepareCallCFunction(int num_arguments) { 4980b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org int frame_alignment = OS::ActivationFrameAlignment(); 4981b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ASSERT(frame_alignment != 0); 4982b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ASSERT(num_arguments >= 0); 4983ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 4984b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Make stack end at alignment and allocate space for arguments and old rsp. 498543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(kScratchRegister, rsp); 4986b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ASSERT(IsPowerOf2(frame_alignment)); 4987b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org int argument_slots_on_stack = 4988b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ArgumentStackSlotsForCFunctionCall(num_arguments); 4989fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org subp(rsp, Immediate((argument_slots_on_stack + 1) * kRegisterSize)); 4990895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org andp(rsp, Immediate(-frame_alignment)); 499143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(Operand(rsp, argument_slots_on_stack * kRegisterSize), kScratchRegister); 4992b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 4993b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4994b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4995b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid MacroAssembler::CallCFunction(ExternalReference function, 4996b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org int num_arguments) { 4997ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org LoadAddress(rax, function); 4998b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org CallCFunction(rax, num_arguments); 4999b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 5000b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 5001b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 5002b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid MacroAssembler::CallCFunction(Register function, int num_arguments) { 5003c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(has_frame()); 5004c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org // Check stack alignment. 5005badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org if (emit_debug_code()) { 5006c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org CheckStackAlignment(); 5007c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org } 5008c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org 5009b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org call(function); 5010b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ASSERT(OS::ActivationFrameAlignment() != 0); 5011b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ASSERT(num_arguments >= 0); 5012b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org int argument_slots_on_stack = 5013b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ArgumentStackSlotsForCFunctionCall(num_arguments); 501443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(rsp, Operand(rsp, argument_slots_on_stack * kRegisterSize)); 5015b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 5016b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 5017ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org 5018c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.combool AreAliased(Register r1, Register r2, Register r3, Register r4) { 5019c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (r1.is(r2)) return true; 5020c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (r1.is(r3)) return true; 5021c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (r1.is(r4)) return true; 5022c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (r2.is(r3)) return true; 5023c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (r2.is(r4)) return true; 5024c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (r3.is(r4)) return true; 5025c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return false; 5026c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 5027c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 5028c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 50294af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgCodePatcher::CodePatcher(byte* address, int size) 5030c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org : address_(address), 5031c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org size_(size), 5032212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org masm_(NULL, address, size + Assembler::kGap) { 50334af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Create a new macro assembler pointing to the address of the code to patch. 50344af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // The size is adjusted with kGap on order for the assembler to generate size 50354af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // bytes of instructions without failing with buffer size constraints. 50364af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 50374af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 50384af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 50394af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 50404af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgCodePatcher::~CodePatcher() { 50414af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Indicate that code has changed. 50424af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org CPU::FlushICache(address_, size_); 50434af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 50444af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org // Check that the code was patched as expected. 50454af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org ASSERT(masm_.pc_ == address_ + size_); 50464af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 50474af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org} 50484af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org 5049c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 5050c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::CheckPageFlag( 5051c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register object, 5052c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch, 5053c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int mask, 5054c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Condition cc, 5055c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* condition_met, 5056c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance condition_met_distance) { 5057c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(cc == zero || cc == not_zero); 5058c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (scratch.is(object)) { 5059895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org andp(scratch, Immediate(~Page::kPageAlignmentMask)); 5060c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 506143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(scratch, Immediate(~Page::kPageAlignmentMask)); 5062895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org andp(scratch, object); 5063c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 5064c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (mask < (1 << kBitsPerByte)) { 5065c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com testb(Operand(scratch, MemoryChunk::kFlagsOffset), 5066c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Immediate(static_cast<uint8_t>(mask))); 5067c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 5068c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com testl(Operand(scratch, MemoryChunk::kFlagsOffset), Immediate(mask)); 5069c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 5070c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(cc, condition_met, condition_met_distance); 5071c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 5072c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 5073c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 5074f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.orgvoid MacroAssembler::CheckMapDeprecated(Handle<Map> map, 5075f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org Register scratch, 5076f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org Label* if_deprecated) { 5077f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org if (map->CanBeDeprecated()) { 5078f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org Move(scratch, map); 50793c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org movl(scratch, FieldOperand(scratch, Map::kBitField3Offset)); 50803c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org andl(scratch, Immediate(Map::Deprecated::kMask)); 5081f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org j(not_zero, if_deprecated); 5082f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 5083f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org} 5084f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 5085f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 5086c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::JumpIfBlack(Register object, 5087c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register bitmap_scratch, 5088c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register mask_scratch, 5089c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* on_black, 5090c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance on_black_distance) { 5091c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!AreAliased(object, bitmap_scratch, mask_scratch, rcx)); 5092c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com GetMarkBits(object, bitmap_scratch, mask_scratch); 5093c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 5094c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(strcmp(Marking::kBlackBitPattern, "10") == 0); 5095c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // The mask_scratch register contains a 1 at the position of the first bit 5096c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // and a 0 at all other positions, including the position of the second bit. 509743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(rcx, mask_scratch); 5098c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Make rcx into a mask that covers both marking bits using the operation 5099c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // rcx = mask | (mask << 1). 5100895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org leap(rcx, Operand(mask_scratch, mask_scratch, times_2, 0)); 5101c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Note that we are using a 4-byte aligned 8-byte load. 5102895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org andp(rcx, Operand(bitmap_scratch, MemoryChunk::kHeaderSize)); 51037a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(mask_scratch, rcx); 5104c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(equal, on_black, on_black_distance); 5105c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 5106c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 5107c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 5108c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// Detect some, but not all, common pointer-free objects. This is used by the 5109c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// incremental write barrier which doesn't care about oddballs (they are always 5110c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// marked black immediately so this code is not hit). 5111c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::JumpIfDataObject( 5112c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register value, 5113c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register scratch, 5114c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* not_data_object, 5115c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance not_data_object_distance) { 5116c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label is_data_object; 511743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(scratch, FieldOperand(value, HeapObject::kMapOffset)); 5118c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CompareRoot(scratch, Heap::kHeapNumberMapRootIndex); 5119c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(equal, &is_data_object, Label::kNear); 5120c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(kIsIndirectStringTag == 1 && kIsIndirectStringMask == 1); 5121c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(kNotStringTag == 0x80 && kIsNotStringMask == 0x80); 5122c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // If it's a string and it's not a cons string then it's an object containing 5123c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // no GC pointers. 5124c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com testb(FieldOperand(scratch, Map::kInstanceTypeOffset), 5125c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Immediate(kIsIndirectStringMask | kIsNotStringMask)); 5126c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(not_zero, not_data_object, not_data_object_distance); 5127c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&is_data_object); 5128c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 5129c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 5130c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 5131c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::GetMarkBits(Register addr_reg, 5132c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register bitmap_reg, 5133c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register mask_reg) { 5134c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!AreAliased(addr_reg, bitmap_reg, mask_reg, rcx)); 513543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(bitmap_reg, addr_reg); 5136c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Sign extended 32 bit immediate. 5137895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org andp(bitmap_reg, Immediate(~Page::kPageAlignmentMask)); 513843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(rcx, addr_reg); 5139c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int shift = 5140c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Bitmap::kBitsPerCellLog2 + kPointerSizeLog2 - Bitmap::kBytesPerCellLog2; 5141c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com shrl(rcx, Immediate(shift)); 5142895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org andp(rcx, 5143c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Immediate((Page::kPageAlignmentMask >> shift) & 5144c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ~(Bitmap::kBytesPerCell - 1))); 5145c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 5146fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org addp(bitmap_reg, rcx); 514743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(rcx, addr_reg); 5148c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com shrl(rcx, Immediate(kPointerSizeLog2)); 5149895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org andp(rcx, Immediate((1 << Bitmap::kBitsPerCellLog2) - 1)); 5150c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com movl(mask_reg, Immediate(1)); 51512f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org shlp_cl(mask_reg); 5152c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 5153c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 5154c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 5155c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comvoid MacroAssembler::EnsureNotWhite( 5156c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register value, 5157c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register bitmap_scratch, 5158c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register mask_scratch, 5159c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label* value_is_white_and_not_data, 5160c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label::Distance distance) { 5161c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!AreAliased(value, bitmap_scratch, mask_scratch, rcx)); 5162c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com GetMarkBits(value, bitmap_scratch, mask_scratch); 5163c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 5164c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // If the value is black or grey we don't need to do anything. 5165c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(strcmp(Marking::kWhiteBitPattern, "00") == 0); 5166c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(strcmp(Marking::kBlackBitPattern, "10") == 0); 5167c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(strcmp(Marking::kGreyBitPattern, "11") == 0); 5168c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(strcmp(Marking::kImpossibleBitPattern, "01") == 0); 5169c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 5170c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label done; 5171c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 5172c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Since both black and grey have a 1 in the first position and white does 5173c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // not have a 1 there we only need to check one bit. 51747a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org testp(Operand(bitmap_scratch, MemoryChunk::kHeaderSize), mask_scratch); 5175c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(not_zero, &done, Label::kNear); 5176c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 5177000f7fbc1dfa59e414332fd2898b5da4d44eedd6jkummerow@chromium.org if (emit_debug_code()) { 5178c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check for impossible bit pattern. 5179c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label ok; 5180763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Push(mask_scratch); 5181c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // shl. May overflow making the check conservative. 5182fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org addp(mask_scratch, mask_scratch); 51837a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org testp(Operand(bitmap_scratch, MemoryChunk::kHeaderSize), mask_scratch); 5184c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(zero, &ok, Label::kNear); 5185c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int3(); 5186c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&ok); 5187763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org Pop(mask_scratch); 5188c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 5189c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 5190c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Value is white. We check whether it is data that doesn't need scanning. 5191c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Currently only checks for HeapNumber and non-cons strings. 5192c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register map = rcx; // Holds map while checking type. 5193c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register length = rcx; // Holds length of object after checking type. 5194c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label not_heap_number; 5195c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label is_data_object; 5196c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 5197c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check for heap-number 519843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(map, FieldOperand(value, HeapObject::kMapOffset)); 5199c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CompareRoot(map, Heap::kHeapNumberMapRootIndex); 5200c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(not_equal, ¬_heap_number, Label::kNear); 520143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(length, Immediate(HeapNumber::kSize)); 5202c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com jmp(&is_data_object, Label::kNear); 5203c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 5204c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(¬_heap_number); 5205c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check for strings. 5206c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(kIsIndirectStringTag == 1 && kIsIndirectStringMask == 1); 5207c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(kNotStringTag == 0x80 && kIsNotStringMask == 0x80); 5208c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // If it's a string and it's not a cons string then it's an object containing 5209c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // no GC pointers. 5210c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register instance_type = rcx; 5211c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com movzxbl(instance_type, FieldOperand(map, Map::kInstanceTypeOffset)); 5212c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com testb(instance_type, Immediate(kIsIndirectStringMask | kIsNotStringMask)); 5213c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(not_zero, value_is_white_and_not_data); 5214c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // It's a non-indirect (non-cons and non-slice) string. 5215c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // If it's external, the length is just ExternalString::kSize. 5216c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Otherwise it's String::kHeaderSize + string->length() * (1 or 2). 5217c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label not_external; 5218c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // External strings are the only ones with the kExternalStringTag bit 5219c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // set. 5220c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT_EQ(0, kSeqStringTag & kExternalStringTag); 5221c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT_EQ(0, kConsStringTag & kExternalStringTag); 5222c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com testb(instance_type, Immediate(kExternalStringTag)); 5223c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com j(zero, ¬_external, Label::kNear); 522443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(length, Immediate(ExternalString::kSize)); 5225c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com jmp(&is_data_object, Label::kNear); 5226c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 5227c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(¬_external); 5228c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Sequential string, either ASCII or UC16. 5229e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org ASSERT(kOneByteStringTag == 0x04); 5230895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org andp(length, Immediate(kStringEncodingMask)); 5231895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org xorp(length, Immediate(kStringEncodingMask)); 5232fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org addp(length, Immediate(0x04)); 5233c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Value now either 4 (if ASCII) or 8 (if UC16), i.e. char-size shifted by 2. 5234fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org imulp(length, FieldOperand(value, String::kLengthOffset)); 52352f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org shrp(length, Immediate(2 + kSmiTagSize + kSmiShiftSize)); 5236fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org addp(length, Immediate(SeqString::kHeaderSize + kObjectAlignmentMask)); 5237895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org andp(length, Immediate(~kObjectAlignmentMask)); 5238c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 5239c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&is_data_object); 5240c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Value is a data object, and it is white. Mark it black. Since we know 5241c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // that the object is white we can make it black by flipping one bit. 5242895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org orp(Operand(bitmap_scratch, MemoryChunk::kHeaderSize), mask_scratch); 5243c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 5244895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org andp(bitmap_scratch, Immediate(~Page::kPageAlignmentMask)); 5245c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com addl(Operand(bitmap_scratch, MemoryChunk::kLiveBytesOffset), length); 5246c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 5247c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com bind(&done); 5248c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 5249c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 5250be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5251be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.orgvoid MacroAssembler::CheckEnumCache(Register null_value, Label* call_runtime) { 5252355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org Label next, start; 5253be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org Register empty_fixed_array_value = r8; 5254be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org LoadRoot(empty_fixed_array_value, Heap::kEmptyFixedArrayRootIndex); 525543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(rcx, rax); 5256be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5257355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // Check if the enum length field is properly initialized, indicating that 5258355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // there is an enum cache. 525943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(rbx, FieldOperand(rcx, HeapObject::kMapOffset)); 5260657d53b99cb4d261f8245bcb4248c39eb0a2b10frossberg@chromium.org 5261355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org EnumLength(rdx, rbx); 5262af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org Cmp(rdx, Smi::FromInt(kInvalidEnumCacheSentinel)); 5263de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org j(equal, call_runtime); 5264de64f721c489207a7b9018406d39c7fb04bb9424verwaest@chromium.org 5265355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org jmp(&start); 5266355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 5267355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org bind(&next); 5268355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 526943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(rbx, FieldOperand(rcx, HeapObject::kMapOffset)); 5270be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5271be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org // For all objects but the receiver, check that the cache is empty. 5272355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org EnumLength(rdx, rbx); 5273355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org Cmp(rdx, Smi::FromInt(0)); 5274355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org j(not_equal, call_runtime); 5275355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 5276355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org bind(&start); 5277355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org 5278355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // Check that there are no elements. Register rcx contains the current JS 5279355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org // object we've reached through the prototype chain. 52806d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org Label no_elements; 52817a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(empty_fixed_array_value, 5282355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org FieldOperand(rcx, JSObject::kElementsOffset)); 52836d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org j(equal, &no_elements); 52846d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org 52856d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org // Second chance, the object may be using the empty slow element dictionary. 52866d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org LoadRoot(kScratchRegister, Heap::kEmptySlowElementDictionaryRootIndex); 52877a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(kScratchRegister, FieldOperand(rcx, JSObject::kElementsOffset)); 5288be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org j(not_equal, call_runtime); 5289be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 52906d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org bind(&no_elements); 529143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(rcx, FieldOperand(rbx, Map::kPrototypeOffset)); 52927a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(rcx, null_value); 5293be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org j(not_equal, &next); 5294be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org} 5295be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5296ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgvoid MacroAssembler::TestJSArrayForAllocationMemento( 529759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org Register receiver_reg, 5298b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org Register scratch_reg, 5299b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org Label* no_memento_found) { 530059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org ExternalReference new_space_start = 530159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org ExternalReference::new_space_start(isolate()); 530259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org ExternalReference new_space_allocation_top = 530359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org ExternalReference::new_space_allocation_top_address(isolate()); 530459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 5305895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org leap(scratch_reg, Operand(receiver_reg, 5306ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org JSArray::kSize + AllocationMemento::kSize - kHeapObjectTag)); 5307e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Move(kScratchRegister, new_space_start); 53087a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(scratch_reg, kScratchRegister); 5309b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org j(less, no_memento_found); 53107a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(scratch_reg, ExternalOperand(new_space_allocation_top)); 5311b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org j(greater, no_memento_found); 5312ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org CompareRoot(MemOperand(scratch_reg, -AllocationMemento::kSize), 5313ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Heap::kAllocationMementoMapRootIndex); 531459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org} 531559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 5316be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org 5317e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.orgvoid MacroAssembler::JumpIfDictionaryInPrototypeChain( 5318e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Register object, 5319e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Register scratch0, 5320e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Register scratch1, 5321e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Label* found) { 5322e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org ASSERT(!(scratch0.is(kScratchRegister) && scratch1.is(kScratchRegister))); 5323e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org ASSERT(!scratch1.is(scratch0)); 5324e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Register current = scratch0; 5325e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Label loop_again; 5326e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 532743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(current, object); 5328e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 5329e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // Loop based on the map going up the prototype chain. 5330e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org bind(&loop_again); 533143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(current, FieldOperand(current, HeapObject::kMapOffset)); 533243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(scratch1, FieldOperand(current, Map::kBitField2Offset)); 5333d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org DecodeField<Map::ElementsKindBits>(scratch1); 53347a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org cmpp(scratch1, Immediate(DICTIONARY_ELEMENTS)); 5335e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org j(equal, found); 533643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org movp(current, FieldOperand(current, Map::kPrototypeOffset)); 5337e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org CompareRoot(current, Heap::kNullValueRootIndex); 5338e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org j(not_equal, &loop_again); 5339e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org} 5340e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 5341e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 5342763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.orgvoid MacroAssembler::TruncatingDiv(Register dividend, int32_t divisor) { 5343bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org ASSERT(!dividend.is(rax)); 5344bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org ASSERT(!dividend.is(rdx)); 5345bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org MultiplierAndShift ms(divisor); 5346bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org movl(rax, Immediate(ms.multiplier())); 5347bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org imull(dividend); 5348bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org if (divisor > 0 && ms.multiplier() < 0) addl(rdx, dividend); 5349bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org if (divisor < 0 && ms.multiplier() > 0) subl(rdx, dividend); 5350bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org if (ms.shift() > 0) sarl(rdx, Immediate(ms.shift())); 5351763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org movl(rax, dividend); 5352763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org shrl(rax, Immediate(31)); 5353763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org addl(rdx, rax); 5354bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org} 5355bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 5356bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 535771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} } // namespace v8::internal 53589dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 53599dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#endif // V8_TARGET_ARCH_X64 5360