macro-assembler-x64.cc revision 014dc512cdd3e367bee49a713fdc5ed92584a3e5
13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if V8_TARGET_ARCH_X64 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/bits.h" 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/division-by-constant.h" 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/bootstrapper.h" 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/codegen.h" 11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/debug/debug.h" 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/heap/heap.h" 13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/register-configuration.h" 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/x64/assembler-x64.h" 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/x64/macro-assembler-x64.h" 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochMacroAssembler::MacroAssembler(Isolate* arg_isolate, void* buffer, int size, 21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CodeObjectRequired create_code_object) 228b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch : Assembler(arg_isolate, buffer, size), 233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block generating_stub_(false), 243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch has_frame_(false), 258b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch root_array_available_(true) { 26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (create_code_object == CodeObjectRequired::kYes) { 27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch code_object_ = 28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object>::New(isolate()->heap()->undefined_value(), isolate()); 298b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 3044f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 3144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 3244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const int64_t kInvalidRootRegisterDelta = -1; 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint64_t MacroAssembler::RootRegisterDelta(ExternalReference other) { 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (predictable_code_size() && 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (other.address() < reinterpret_cast<Address>(isolate()) || 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch other.address() >= reinterpret_cast<Address>(isolate() + 1))) { 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return kInvalidRootRegisterDelta; 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Address roots_register_value = kRootRegisterBias + 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<Address>(isolate()->heap()->roots_array_start()); 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int64_t delta = kInvalidRootRegisterDelta; // Bogus initialization. 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (kPointerSize == kInt64Size) { 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delta = other.address() - roots_register_value; 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // For x32, zero extend the address to 64-bit and calculate the delta. 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint64_t o = static_cast<uint32_t>( 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<intptr_t>(other.address())); 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint64_t r = static_cast<uint32_t>( 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<intptr_t>(roots_register_value)); 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delta = o - r; 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5644f0eee88ff00398ff7f715fab053374d808c90dSteve Block return delta; 5744f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 5844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 5944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 6044f0eee88ff00398ff7f715fab053374d808c90dSteve BlockOperand MacroAssembler::ExternalOperand(ExternalReference target, 6144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register scratch) { 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (root_array_available_ && !serializer_enabled()) { 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int64_t delta = RootRegisterDelta(target); 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (delta != kInvalidRootRegisterDelta && is_int32(delta)) { 6544f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Operand(kRootRegister, static_cast<int32_t>(delta)); 6644f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 6744f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(scratch, target); 6944f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Operand(scratch, 0); 7044f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 7144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 7244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 7344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid MacroAssembler::Load(Register destination, ExternalReference source) { 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (root_array_available_ && !serializer_enabled()) { 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int64_t delta = RootRegisterDelta(source); 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (delta != kInvalidRootRegisterDelta && is_int32(delta)) { 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(destination, Operand(kRootRegister, static_cast<int32_t>(delta))); 7844f0eee88ff00398ff7f715fab053374d808c90dSteve Block return; 7944f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 8044f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 8144f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Safe code. 8244f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (destination.is(rax)) { 8344f0eee88ff00398ff7f715fab053374d808c90dSteve Block load_rax(source); 8444f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else { 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(kScratchRegister, source); 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(destination, Operand(kScratchRegister, 0)); 8744f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 8844f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 8944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 9044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 9144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid MacroAssembler::Store(ExternalReference destination, Register source) { 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (root_array_available_ && !serializer_enabled()) { 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int64_t delta = RootRegisterDelta(destination); 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (delta != kInvalidRootRegisterDelta && is_int32(delta)) { 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(kRootRegister, static_cast<int32_t>(delta)), source); 9644f0eee88ff00398ff7f715fab053374d808c90dSteve Block return; 9744f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 9844f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 9944f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Safe code. 10044f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (source.is(rax)) { 10144f0eee88ff00398ff7f715fab053374d808c90dSteve Block store_rax(destination); 10244f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else { 103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(kScratchRegister, destination); 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(kScratchRegister, 0), source); 10544f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 10644f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 10744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 10844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 10944f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid MacroAssembler::LoadAddress(Register destination, 11044f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExternalReference source) { 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (root_array_available_ && !serializer_enabled()) { 112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int64_t delta = RootRegisterDelta(source); 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (delta != kInvalidRootRegisterDelta && is_int32(delta)) { 114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(destination, Operand(kRootRegister, static_cast<int32_t>(delta))); 11544f0eee88ff00398ff7f715fab053374d808c90dSteve Block return; 11644f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 11744f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 11844f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Safe code. 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(destination, source); 12044f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 12144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 12244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 12344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockint MacroAssembler::LoadAddressSize(ExternalReference source) { 124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (root_array_available_ && !serializer_enabled()) { 12544f0eee88ff00398ff7f715fab053374d808c90dSteve Block // This calculation depends on the internals of LoadAddress. 12644f0eee88ff00398ff7f715fab053374d808c90dSteve Block // It's correctness is ensured by the asserts in the Call 12744f0eee88ff00398ff7f715fab053374d808c90dSteve Block // instruction below. 128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int64_t delta = RootRegisterDelta(source); 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (delta != kInvalidRootRegisterDelta && is_int32(delta)) { 130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Operand is leap(scratch, Operand(kRootRegister, delta)); 13144f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Opcodes : REX.W 8D ModRM Disp8/Disp32 - 4 or 7. 13244f0eee88ff00398ff7f715fab053374d808c90dSteve Block int size = 4; 13344f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!is_int8(static_cast<int32_t>(delta))) { 13444f0eee88ff00398ff7f715fab053374d808c90dSteve Block size += 3; // Need full four-byte displacement in lea. 13544f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 13644f0eee88ff00398ff7f715fab053374d808c90dSteve Block return size; 13744f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 13844f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Size of movp(destination, src); 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Assembler::kMoveAddressIntoScratchRegisterInstructionLength; 141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::PushAddress(ExternalReference source) { 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int64_t address = reinterpret_cast<int64_t>(source.address()); 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (is_int32(address) && !serializer_enabled()) { 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(kScratchRegister, kZapValue, Assembler::RelocInfoNone()); 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(Immediate(static_cast<int32_t>(address))); 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadAddress(kScratchRegister, source); 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(kScratchRegister); 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1583ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::LoadRoot(Register destination, Heap::RootListIndex index) { 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(root_array_available_); 160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(destination, Operand(kRootRegister, 161e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch (index << kPointerSizeLog2) - kRootRegisterBias)); 162e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 163e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 164e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 165e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochvoid MacroAssembler::LoadRootIndexed(Register destination, 166e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Register variable_offset, 167e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int fixed_offset) { 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(root_array_available_); 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(destination, 170e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Operand(kRootRegister, 171e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch variable_offset, times_pointer_size, 172e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch (fixed_offset << kPointerSizeLog2) - kRootRegisterBias)); 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 17625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsenvoid MacroAssembler::StoreRoot(Register source, Heap::RootListIndex index) { 177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(Heap::RootCanBeWrittenAfterInitialization(index)); 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(root_array_available_); 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(kRootRegister, (index << kPointerSizeLog2) - kRootRegisterBias), 180e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch source); 18125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen} 18225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 18325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::PushRoot(Heap::RootListIndex index) { 185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(root_array_available_); 186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(Operand(kRootRegister, (index << kPointerSizeLog2) - kRootRegisterBias)); 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::CompareRoot(Register with, Heap::RootListIndex index) { 191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(root_array_available_); 192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(with, Operand(kRootRegister, 193e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch (index << kPointerSizeLog2) - kRootRegisterBias)); 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1971e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::CompareRoot(const Operand& with, 1981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Heap::RootListIndex index) { 199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(root_array_available_); 200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!with.AddressUsesRegister(kScratchRegister)); 201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LoadRoot(kScratchRegister, index); 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(with, kScratchRegister); 203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::RememberedSetHelper(Register object, // For debug tests. 2073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register addr, 2083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch, 2093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SaveFPRegsMode save_fp, 2103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RememberedSetFinalAction and_then) { 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 2123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label ok; 2133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JumpIfNotInNewSpace(object, scratch, &ok, Label::kNear); 2143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int3(); 2153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bind(&ok); 2163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Load store buffer top. 2183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LoadRoot(scratch, Heap::kStoreBufferTopRootIndex); 2193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Store pointer to buffer. 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(scratch, 0), addr); 2213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Increment buffer top. 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(scratch, Immediate(kPointerSize)); 2233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Write back new top of buffer. 2243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StoreRoot(scratch, Heap::kStoreBufferTopRootIndex); 2253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Call stub on end of buffer. 2263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label done; 2273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check for end of buffer. 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(scratch, Immediate(StoreBuffer::kStoreBufferOverflowBit)); 2293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (and_then == kReturnAtEnd) { 2303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label buffer_overflowed; 2313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(not_equal, &buffer_overflowed, Label::kNear); 2323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ret(0); 2333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bind(&buffer_overflowed); 2343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(and_then == kFallThroughAtEnd); 2363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(equal, &done, Label::kNear); 2373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StoreBufferOverflowStub store_buffer_overflow(isolate(), save_fp); 2393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallStub(&store_buffer_overflow); 2403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (and_then == kReturnAtEnd) { 2413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ret(0); 2423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(and_then == kFallThroughAtEnd); 2443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bind(&done); 2456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 2467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 249257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::InNewSpace(Register object, 250257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register scratch, 251257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Condition cc, 252257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* branch, 2533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label::Distance distance) { 254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (serializer_enabled()) { 255257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Can't do arithmetic on external references if it might get serialized. 256257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // The mask isn't really an address. We load it as an external reference in 257257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // case the size of the new space is different between the snapshot maker 258257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // and the running system. 259257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (scratch.is(object)) { 260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(kScratchRegister, ExternalReference::new_space_mask(isolate())); 261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(scratch, kScratchRegister); 262257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(scratch, ExternalReference::new_space_mask(isolate())); 264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(scratch, object); 265257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(kScratchRegister, ExternalReference::new_space_start(isolate())); 267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(scratch, kScratchRegister); 2683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(cc, branch, distance); 269257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(kPointerSize == kInt64Size 271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? is_int32(static_cast<int64_t>(isolate()->heap()->NewSpaceMask())) 272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : kPointerSize == kInt32Size); 273257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch intptr_t new_space_start = 274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<intptr_t>(isolate()->heap()->NewSpaceStart()); 275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(kScratchRegister, reinterpret_cast<Address>(-new_space_start), 276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler::RelocInfoNone()); 277257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (scratch.is(object)) { 278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(scratch, kScratchRegister); 279257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(scratch, Operand(object, kScratchRegister, times_1, 0)); 281257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(scratch, 283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Immediate(static_cast<int32_t>(isolate()->heap()->NewSpaceMask()))); 2843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(cc, branch, distance); 285257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 286257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 287257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 288257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::RecordWriteField( 2903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register object, 2913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int offset, 2923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register value, 2933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register dst, 2943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SaveFPRegsMode save_fp, 2953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RememberedSetAction remembered_set_action, 296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiCheck smi_check, 297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PointersToHereCheck pointers_to_here_check_for_value) { 2987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // First, check if a write barrier is even needed. The tests below 2993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // catch stores of Smis. 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label done; 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Skip barrier if writing a smi. 3033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (smi_check == INLINE_SMI_CHECK) { 3043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JumpIfSmi(value, &done); 3053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Although the object register is tagged, the offset is relative to the start 3083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // of the object, so so offset must be a multiple of kPointerSize. 309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsAligned(offset, kPointerSize)); 3103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(dst, FieldOperand(object, offset)); 3123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (emit_debug_code()) { 3133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label ok; 3143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch testb(dst, Immediate((1 << kPointerSizeLog2) - 1)); 3153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(zero, &ok, Label::kNear); 3163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int3(); 3173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bind(&ok); 3183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RecordWrite(object, dst, value, save_fp, remembered_set_action, 321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OMIT_SMI_CHECK, pointers_to_here_check_for_value); 3223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block bind(&done); 3244515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 3253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Clobber clobbered input registers when running with the debug-code flag 3263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // turned on to provoke errors. 32744f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(value, kZapValue, Assembler::RelocInfoNone()); 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(dst, kZapValue, Assembler::RelocInfoNone()); 3304515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } 3313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 3323ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 3333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::RecordWriteArray( 335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register object, 336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register value, 337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register index, 338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SaveFPRegsMode save_fp, 339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RememberedSetAction remembered_set_action, 340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiCheck smi_check, 341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PointersToHereCheck pointers_to_here_check_for_value) { 3428defd9ff6930b4e24729971a61cf7469daf119beSteve Block // First, check if a write barrier is even needed. The tests below 3433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // catch stores of Smis. 3448defd9ff6930b4e24729971a61cf7469daf119beSteve Block Label done; 3458defd9ff6930b4e24729971a61cf7469daf119beSteve Block 3463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Skip barrier if writing a smi. 3473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (smi_check == INLINE_SMI_CHECK) { 3483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JumpIfSmi(value, &done); 3493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3508defd9ff6930b4e24729971a61cf7469daf119beSteve Block 3513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Array access: calculate the destination address. Index is not a smi. 3523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register dst = index; 353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(dst, Operand(object, index, times_pointer_size, 3543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArray::kHeaderSize - kHeapObjectTag)); 3553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RecordWrite(object, dst, value, save_fp, remembered_set_action, 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OMIT_SMI_CHECK, pointers_to_here_check_for_value); 3588defd9ff6930b4e24729971a61cf7469daf119beSteve Block 3598defd9ff6930b4e24729971a61cf7469daf119beSteve Block bind(&done); 3608defd9ff6930b4e24729971a61cf7469daf119beSteve Block 3613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Clobber clobbered input registers when running with the debug-code flag 3628defd9ff6930b4e24729971a61cf7469daf119beSteve Block // turned on to provoke errors. 36344f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(value, kZapValue, Assembler::RelocInfoNone()); 365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(index, kZapValue, Assembler::RelocInfoNone()); 3668defd9ff6930b4e24729971a61cf7469daf119beSteve Block } 3678defd9ff6930b4e24729971a61cf7469daf119beSteve Block} 3688defd9ff6930b4e24729971a61cf7469daf119beSteve Block 3698defd9ff6930b4e24729971a61cf7469daf119beSteve Block 370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::RecordWriteForMap(Register object, 371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register map, 372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register dst, 373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SaveFPRegsMode fp_mode) { 374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!object.is(kScratchRegister)); 375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!object.is(map)); 376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!object.is(dst)); 377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!map.is(dst)); 378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertNotSmi(object); 3794515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 38044f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label ok; 382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (map.is(kScratchRegister)) pushq(map); 383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompareMap(map, isolate()->factory()->meta_map()); 384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (map.is(kScratchRegister)) popq(map); 385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(equal, &ok, Label::kNear); 386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int3(); 387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&ok); 3884515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } 3894515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!FLAG_incremental_marking) { 391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label ok; 396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (map.is(kScratchRegister)) pushq(map); 397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(map, FieldOperand(object, HeapObject::kMapOffset)); 398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (map.is(kScratchRegister)) popq(map); 399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(equal, &ok, Label::kNear); 400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int3(); 401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&ok); 402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute the address. 405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(dst, FieldOperand(object, HeapObject::kMapOffset)); 406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // First, check if a write barrier is even needed. The tests below 408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // catch stores of smis and stores into the young generation. 409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done; 410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // A single check of the map's pages interesting flag suffices, since it is 412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // only set during incremental collection, and then it's also guaranteed that 413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the from object's page's interesting flag is also set. This optimization 414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // relies on the fact that maps can never be in new space. 415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CheckPageFlag(map, 416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map, // Used as scratch. 417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemoryChunk::kPointersToHereAreInterestingMask, 418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch zero, 419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &done, 420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::kNear); 421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RecordWriteStub stub(isolate(), object, map, dst, OMIT_REMEMBERED_SET, 423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fp_mode); 424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallStub(&stub); 425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&done); 427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Count number of write barriers in generated code. 429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->counters()->write_barriers_static()->Increment(); 430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1); 431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Clobber clobbered registers when running with the debug-code flag 433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // turned on to provoke errors. 434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(dst, kZapValue, Assembler::RelocInfoNone()); 436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(map, kZapValue, Assembler::RelocInfoNone()); 437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::RecordWrite( 442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register object, 443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register address, 444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register value, 445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SaveFPRegsMode fp_mode, 446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RememberedSetAction remembered_set_action, 447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiCheck smi_check, 448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PointersToHereCheck pointers_to_here_check_for_value) { 449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!object.is(value)); 450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!object.is(address)); 451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!value.is(address)); 452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertNotSmi(object); 453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (remembered_set_action == OMIT_REMEMBERED_SET && 4553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch !FLAG_incremental_marking) { 4563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return; 4573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 4603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label ok; 461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(value, Operand(address, 0)); 4623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(equal, &ok, Label::kNear); 4633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int3(); 4643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bind(&ok); 4653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 4673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // First, check if a write barrier is even needed. The tests below 4683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // catch stores of smis and stores into the young generation. 4693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label done; 4703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (smi_check == INLINE_SMI_CHECK) { 4723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Skip barrier if writing a smi. 4733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JumpIfSmi(value, &done); 474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (pointers_to_here_check_for_value != kPointersToHereAreAlwaysInteresting) { 477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CheckPageFlag(value, 478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value, // Used as scratch. 479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemoryChunk::kPointersToHereAreInterestingMask, 480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch zero, 481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &done, 482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::kNear); 483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CheckPageFlag(object, 4863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch value, // Used as scratch. 4873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MemoryChunk::kPointersFromHereAreInterestingMask, 4883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch zero, 4893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch &done, 4903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label::kNear); 4913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RecordWriteStub stub(isolate(), object, value, address, remembered_set_action, 493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fp_mode); 4943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallStub(&stub); 495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bind(&done); 4974515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Count number of write barriers in generated code. 499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->counters()->write_barriers_static()->Increment(); 500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1); 501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Clobber clobbered registers when running with the debug-code flag 5034515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // turned on to provoke errors. 50444f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(address, kZapValue, Assembler::RelocInfoNone()); 506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(value, kZapValue, Assembler::RelocInfoNone()); 5076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 5086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 5096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 5103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Assert(Condition cc, BailoutReason reason) { 512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) Check(cc, reason); 513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 516756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickvoid MacroAssembler::AssertFastElements(Register elements) { 51744f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 518257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label ok; 519756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CompareRoot(FieldOperand(elements, HeapObject::kMapOffset), 520756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick Heap::kFixedArrayMapRootIndex); 521257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(equal, &ok, Label::kNear); 522756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CompareRoot(FieldOperand(elements, HeapObject::kMapOffset), 5233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Heap::kFixedDoubleArrayMapRootIndex); 5243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch j(equal, &ok, Label::kNear); 5253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CompareRoot(FieldOperand(elements, HeapObject::kMapOffset), 526756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick Heap::kFixedCOWArrayMapRootIndex); 527257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(equal, &ok, Label::kNear); 528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Abort(kJSObjectWithFastElementsMapHasSlowElements); 529756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick bind(&ok); 530756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 531756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick} 532756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 533756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Check(Condition cc, BailoutReason reason) { 535257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label L; 536257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(cc, &L, Label::kNear); 537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Abort(reason); 5383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Control will not return here. 539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bind(&L); 540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5436ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid MacroAssembler::CheckStackAlignment() { 544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int frame_alignment = base::OS::ActivationFrameAlignment(); 5456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int frame_alignment_mask = frame_alignment - 1; 5466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (frame_alignment > kPointerSize) { 547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(base::bits::IsPowerOfTwo32(frame_alignment)); 548257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label alignment_as_expected; 549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(rsp, Immediate(frame_alignment_mask)); 550257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(zero, &alignment_as_expected, Label::kNear); 5516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Abort if stack is not aligned. 5526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int3(); 5536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block bind(&alignment_as_expected); 5546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 5556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 5566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 5576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::NegativeZeroTest(Register result, 559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register op, 560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label* then_label) { 561257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label ok; 562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block testl(result, result); 563257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_zero, &ok, Label::kNear); 564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block testl(op, op); 565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block j(sign, then_label); 566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bind(&ok); 567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Abort(BailoutReason reason) { 571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* msg = GetBailoutReason(reason); 573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (msg != NULL) { 574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RecordComment("Abort message: "); 575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RecordComment(msg); 576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_trap_on_abort) { 579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int3(); 580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(kScratchRegister, Smi::FromInt(static_cast<int>(reason)), 585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler::RelocInfoNone()); 586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(kScratchRegister); 5873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!has_frame_) { 5893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // We don't actually want to generate a pile of code for this, so just 5903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // claim there is a stack frame, without generating one. 5913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FrameScope scope(this, StackFrame::NONE); 592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallRuntime(Runtime::kAbort, 1); 5933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallRuntime(Runtime::kAbort, 1); 5953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Control will not return here. 597d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block int3(); 598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::CallStub(CodeStub* stub, TypeFeedbackId ast_id) { 602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(AllowThisStubCall(stub)); // Calls are not allowed in some stubs 603257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id); 604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 607e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid MacroAssembler::TailCallStub(CodeStub* stub) { 608e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Jump(stub->GetCode(), RelocInfo::CODE_TARGET); 609e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 610e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 611e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 61285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochvoid MacroAssembler::StubReturn(int argc) { 613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(argc >= 1 && generating_stub()); 61485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch ret((argc - 1) * kPointerSize); 615592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch} 616592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 617592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 6183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool MacroAssembler::AllowThisStubCall(CodeStub* stub) { 619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return has_frame_ || !stub->SometimesSetsUpAFrame(); 620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 62380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenvoid MacroAssembler::IndexFromHash(Register hash, Register index) { 62480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // The assert checks that the constants for the maximum number of digits 62580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // for an array index cached in the hash field and the number of bits 62680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // reserved for it does not conflict. 627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(TenToThe(String::kMaxCachedArrayIndexLength) < 62880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen (1 << String::kArrayIndexValueBits)); 629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!hash.is(index)) { 630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(index, hash); 631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DecodeFieldToSmi<String::ArrayIndexValueBits>(index); 6331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 6341e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 6351e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 63644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid MacroAssembler::CallRuntime(const Runtime::Function* f, 637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int num_arguments, 638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SaveFPRegsMode save_doubles) { 639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the expected number of arguments of the runtime function is 640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // constant, we check that the actual number of arguments match the 641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // expectation. 642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(f->nargs < 0 || f->nargs == num_arguments); 643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6444515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // TODO(1236192): Most runtime routines don't need the number of 6454515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // arguments passed in because it is constant. At some point we 6464515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // should remove this need and make the runtime routine entry code 6474515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // smarter. 6488defd9ff6930b4e24729971a61cf7469daf119beSteve Block Set(rax, num_arguments); 64944f0eee88ff00398ff7f715fab053374d808c90dSteve Block LoadAddress(rbx, ExternalReference(f, isolate())); 650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CEntryStub ces(isolate(), f->result_size, save_doubles); 6514515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke CallStub(&ces); 652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 655402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuvoid MacroAssembler::CallExternalReference(const ExternalReference& ext, 656402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu int num_arguments) { 6578defd9ff6930b4e24729971a61cf7469daf119beSteve Block Set(rax, num_arguments); 65844f0eee88ff00398ff7f715fab053374d808c90dSteve Block LoadAddress(rbx, ext); 659402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CEntryStub stub(isolate(), 1); 661402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu CallStub(&stub); 662402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu} 663402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 664402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::TailCallRuntime(Runtime::FunctionId fid) { 666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ----------- S t a t e ------------- 667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // -- rsp[0] : return address 668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // -- rsp[8] : argument num_arguments - 1 669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ... 670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // -- rsp[8 * num_arguments] : argument 0 (receiver) 671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // For runtime functions with variable arguments: 673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // -- rax : number of arguments 674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ----------------------------------- 675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Runtime::Function* function = Runtime::FunctionForId(fid); 677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(1, function->result_size); 678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (function->nargs >= 0) { 679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(rax, function->nargs); 680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JumpToExternalReference(ExternalReference(fid, isolate())); 682bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch} 683bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 684bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::JumpToExternalReference(const ExternalReference& ext) { 686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set the entry point and jump to the C entry runtime stub. 68744f0eee88ff00398ff7f715fab053374d808c90dSteve Block LoadAddress(rbx, ext); 688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CEntryStub ces(isolate(), 1); 6893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block jmp(ces.GetCode(), RelocInfo::CODE_TARGET); 690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::InvokeBuiltin(int native_context_index, InvokeFlag flag, 694257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch const CallWrapper& call_wrapper) { 6953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // You can't call a builtin without a valid frame. 696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(flag == JUMP_FUNCTION || has_frame()); 697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Fake a parameter count to avoid emitting code to do the check. 699402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu ParameterCount expected(0); 700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoadNativeContextSlot(native_context_index, rdi); 701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InvokeFunctionCode(rdi, no_reg, expected, expected, flag, call_wrapper); 702791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block} 7036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 7046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define REG(Name) \ 706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { Register::kCode_##Name } 7073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic const Register saved_regs[] = { 7093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch REG(rax), REG(rcx), REG(rdx), REG(rbx), REG(rbp), REG(rsi), REG(rdi), REG(r8), 7103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch REG(r9), REG(r10), REG(r11) 7113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 7123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#undef REG 7143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic const int kNumberOfSavedRegs = sizeof(saved_regs) / sizeof(Register); 7163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::PushCallerSaved(SaveFPRegsMode fp_mode, 7193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register exclusion1, 7203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register exclusion2, 7213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register exclusion3) { 7223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // We don't allow a GC during a store buffer overflow so there is no need to 7233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // store the registers in any particular way, but we do have to store and 7243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // restore them. 7253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < kNumberOfSavedRegs; i++) { 7263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register reg = saved_regs[i]; 7273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!reg.is(exclusion1) && !reg.is(exclusion2) && !reg.is(exclusion3)) { 728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pushq(reg); 7293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // R12 to r15 are callee save on all platforms. 7323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (fp_mode == kSaveFPRegs) { 733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(rsp, Immediate(kDoubleSize * XMMRegister::kMaxNumRegisters)); 734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { 7353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch XMMRegister reg = XMMRegister::from_code(i); 736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movsd(Operand(rsp, i * kDoubleSize), reg); 7373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 7403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::PopCallerSaved(SaveFPRegsMode fp_mode, 7433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register exclusion1, 7443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register exclusion2, 7453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register exclusion3) { 7463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (fp_mode == kSaveFPRegs) { 747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { 7483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch XMMRegister reg = XMMRegister::from_code(i); 749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movsd(reg, Operand(rsp, i * kDoubleSize)); 7503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(rsp, Immediate(kDoubleSize * XMMRegister::kMaxNumRegisters)); 7523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = kNumberOfSavedRegs - 1; i >= 0; i--) { 7543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register reg = saved_regs[i]; 7553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!reg.is(exclusion1) && !reg.is(exclusion2) && !reg.is(exclusion3)) { 756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch popq(reg); 757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtss2sd(XMMRegister dst, XMMRegister src) { 763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvtss2sd(dst, src, src); 766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvtss2sd(dst, src); 768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtss2sd(XMMRegister dst, const Operand& src) { 773014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvtss2sd(dst, dst, src); 776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvtss2sd(dst, src); 778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtsd2ss(XMMRegister dst, XMMRegister src) { 783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvtsd2ss(dst, src, src); 786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvtsd2ss(dst, src); 788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 789014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtsd2ss(XMMRegister dst, const Operand& src) { 793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvtsd2ss(dst, dst, src); 796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvtsd2ss(dst, src); 798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Cvtlsi2sd(XMMRegister dst, Register src) { 803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vxorpd(dst, dst, dst); 806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvtlsi2sd(dst, dst, src); 807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch xorpd(dst, dst); 809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvtlsi2sd(dst, src); 810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Cvtlsi2sd(XMMRegister dst, const Operand& src) { 815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vxorpd(dst, dst, dst); 818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvtlsi2sd(dst, dst, src); 819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch xorpd(dst, dst); 821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvtlsi2sd(dst, src); 822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtqsi2ss(XMMRegister dst, Register src) { 827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vxorps(dst, dst, dst); 830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvtqsi2ss(dst, dst, src); 831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch xorps(dst, dst); 833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvtqsi2ss(dst, src); 834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtqsi2ss(XMMRegister dst, const Operand& src) { 839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vxorps(dst, dst, dst); 842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvtqsi2ss(dst, dst, src); 843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch xorps(dst, dst); 845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvtqsi2ss(dst, src); 846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtqsi2sd(XMMRegister dst, Register src) { 851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vxorpd(dst, dst, dst); 854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvtqsi2sd(dst, dst, src); 855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch xorpd(dst, dst); 857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvtqsi2sd(dst, src); 858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtqsi2sd(XMMRegister dst, const Operand& src) { 863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vxorpd(dst, dst, dst); 866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvtqsi2sd(dst, dst, src); 867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch xorpd(dst, dst); 869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvtqsi2sd(dst, src); 870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtqui2ss(XMMRegister dst, Register src, Register tmp) { 875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label msb_set_src; 876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label jmp_return; 877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch testq(src, src); 878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(sign, &msb_set_src, Label::kNear); 879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cvtqsi2ss(dst, src); 880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jmp(&jmp_return, Label::kNear); 881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(&msb_set_src); 882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movq(tmp, src); 883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch shrq(src, Immediate(1)); 884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Recover the least significant bit to avoid rounding errors. 885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch andq(tmp, Immediate(1)); 886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch orq(src, tmp); 887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cvtqsi2ss(dst, src); 888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch addss(dst, dst); 889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(&jmp_return); 890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtqui2sd(XMMRegister dst, Register src, Register tmp) { 894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label msb_set_src; 895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label jmp_return; 896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch testq(src, src); 897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(sign, &msb_set_src, Label::kNear); 898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cvtqsi2sd(dst, src); 899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jmp(&jmp_return, Label::kNear); 900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(&msb_set_src); 901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movq(tmp, src); 902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch shrq(src, Immediate(1)); 903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch andq(tmp, Immediate(1)); 904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch orq(src, tmp); 905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cvtqsi2sd(dst, src); 906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch addsd(dst, dst); 907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(&jmp_return); 908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtsd2si(Register dst, XMMRegister src) { 912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvtsd2si(dst, src); 915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvtsd2si(dst, src); 917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvttsd2si(Register dst, XMMRegister src) { 922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvttsd2si(dst, src); 925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvttsd2si(dst, src); 927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvttsd2si(Register dst, const Operand& src) { 932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvttsd2si(dst, src); 935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvttsd2si(dst, src); 937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvttss2siq(Register dst, XMMRegister src) { 942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvttss2siq(dst, src); 945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvttss2siq(dst, src); 947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvttss2siq(Register dst, const Operand& src) { 952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvttss2siq(dst, src); 955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvttss2siq(dst, src); 957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvttsd2siq(Register dst, XMMRegister src) { 962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvttsd2siq(dst, src); 965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvttsd2siq(dst, src); 967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvttsd2siq(Register dst, const Operand& src) { 972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvttsd2siq(dst, src); 975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvttsd2siq(dst, src); 977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Load(Register dst, const Operand& src, Representation r) { 982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!r.IsDouble()); 983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (r.IsInteger8()) { 984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movsxbq(dst, src); 985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (r.IsUInteger8()) { 986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movzxbl(dst, src); 987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (r.IsInteger16()) { 988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movsxwq(dst, src); 989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (r.IsUInteger16()) { 990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movzxwl(dst, src); 991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (r.IsInteger32()) { 992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(dst, src); 993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Store(const Operand& dst, Register src, Representation r) { 1000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!r.IsDouble()); 1001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (r.IsInteger8() || r.IsUInteger8()) { 1002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movb(dst, src); 1003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (r.IsInteger16() || r.IsUInteger16()) { 1004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movw(dst, src); 1005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (r.IsInteger32()) { 1006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(dst, src); 1007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (r.IsHeapObject()) { 1009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertNotSmi(src); 1010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (r.IsSmi()) { 1011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertSmi(src); 10123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 10143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 10153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 10163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Set(Register dst, int64_t x) { 1019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (x == 0) { 10208defd9ff6930b4e24729971a61cf7469daf119beSteve Block xorl(dst, dst); 1021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (is_uint32(x)) { 1022d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block movl(dst, Immediate(static_cast<uint32_t>(x))); 10238b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } else if (is_int32(x)) { 10248b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch movq(dst, Immediate(static_cast<int32_t>(x))); 1025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movq(dst, x); 1027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Set(const Operand& dst, intptr_t x) { 1032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (kPointerSize == kInt64Size) { 1033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (is_int32(x)) { 1034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, Immediate(static_cast<int32_t>(x))); 1035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Set(kScratchRegister, x); 1037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, kScratchRegister); 1038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, Immediate(static_cast<int32_t>(x))); 1041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ---------------------------------------------------------------------------- 1046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Smi tagging, untagging and tag detection. 1047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool MacroAssembler::IsUnsafeInt(const int32_t x) { 1049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kMaxBits = 17; 1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return !is_intn(x, kMaxBits); 1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::SafeMove(Register dst, Smi* src) { 1055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 1056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsUnsafeInt(src->value()) && jit_cookie() != 0) { 1057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // JIT cookie can be converted to Smi. 1059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(dst, Smi::FromInt(src->value() ^ jit_cookie())); 1060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(kScratchRegister, Smi::FromInt(jit_cookie())); 1061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch xorp(dst, kScratchRegister); 1062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 1064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t value = static_cast<int32_t>(reinterpret_cast<intptr_t>(src)); 1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, Immediate(value ^ jit_cookie())); 1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch xorp(dst, Immediate(jit_cookie())); 1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(dst, src); 1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::SafePush(Smi* src) { 1075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsUnsafeInt(src->value()) && jit_cookie() != 0) { 1076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // JIT cookie can be converted to Smi. 1078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(Smi::FromInt(src->value() ^ jit_cookie())); 1079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(kScratchRegister, Smi::FromInt(jit_cookie())); 1080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch xorp(Operand(rsp, 0), kScratchRegister); 1081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 1083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t value = static_cast<int32_t>(reinterpret_cast<intptr_t>(src)); 1084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(Immediate(value ^ jit_cookie())); 1085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch xorp(Operand(rsp, 0), Immediate(jit_cookie())); 1086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(src); 1089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10938defd9ff6930b4e24729971a61cf7469daf119beSteve BlockRegister MacroAssembler::GetSmiConstant(Smi* source) { 1094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STATIC_ASSERT(kSmiTag == 0); 10958defd9ff6930b4e24729971a61cf7469daf119beSteve Block int value = source->value(); 10968defd9ff6930b4e24729971a61cf7469daf119beSteve Block if (value == 0) { 10978defd9ff6930b4e24729971a61cf7469daf119beSteve Block xorl(kScratchRegister, kScratchRegister); 10988defd9ff6930b4e24729971a61cf7469daf119beSteve Block return kScratchRegister; 10998defd9ff6930b4e24729971a61cf7469daf119beSteve Block } 11008defd9ff6930b4e24729971a61cf7469daf119beSteve Block LoadSmiConstant(kScratchRegister, source); 11018defd9ff6930b4e24729971a61cf7469daf119beSteve Block return kScratchRegister; 11028defd9ff6930b4e24729971a61cf7469daf119beSteve Block} 11038defd9ff6930b4e24729971a61cf7469daf119beSteve Block 1104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11058defd9ff6930b4e24729971a61cf7469daf119beSteve Blockvoid MacroAssembler::LoadSmiConstant(Register dst, Smi* source) { 1106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STATIC_ASSERT(kSmiTag == 0); 110744f0eee88ff00398ff7f715fab053374d808c90dSteve Block int value = source->value(); 110844f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (value == 0) { 11098defd9ff6930b4e24729971a61cf7469daf119beSteve Block xorl(dst, dst); 1110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Move(dst, source, Assembler::RelocInfoNone()); 11128defd9ff6930b4e24729971a61cf7469daf119beSteve Block } 11138defd9ff6930b4e24729971a61cf7469daf119beSteve Block} 11148defd9ff6930b4e24729971a61cf7469daf119beSteve Block 1115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 11160d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid MacroAssembler::Integer32ToSmi(Register dst, Register src) { 111769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch STATIC_ASSERT(kSmiTag == 0); 1118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!dst.is(src)) { 1119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block movl(dst, src); 1120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlp(dst, Immediate(kSmiShift)); 1122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 11259dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenvoid MacroAssembler::Integer32ToSmiField(const Operand& dst, Register src) { 112644f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 11279dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen testb(dst, Immediate(0x01)); 1128257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label ok; 1129257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(zero, &ok, Label::kNear); 1130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Abort(kInteger32ToSmiFieldWritingToNonSmiLocation); 11319dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen bind(&ok); 11329dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 1133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(kSmiShift % kBitsPerByte == 0); 1136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(Operand(dst, kSmiShift / kBitsPerByte), src); 1137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 1139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Integer32ToSmi(kScratchRegister, src); 1140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, kScratchRegister); 1141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11429dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen} 11439dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 11449dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 11453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::Integer64PlusConstantToSmi(Register dst, 11463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Register src, 11473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int constant) { 11483ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (dst.is(src)) { 114944f0eee88ff00398ff7f715fab053374d808c90dSteve Block addl(dst, Immediate(constant)); 11503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 115144f0eee88ff00398ff7f715fab053374d808c90dSteve Block leal(dst, Operand(src, constant)); 11523ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 1153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlp(dst, Immediate(kSmiShift)); 1154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiToInteger32(Register dst, Register src) { 115869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch STATIC_ASSERT(kSmiTag == 0); 1159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!dst.is(src)) { 1160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 1161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shrp(dst, Immediate(kSmiShift)); 1165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 1167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sarl(dst, Immediate(kSmiShift)); 1168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 11727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid MacroAssembler::SmiToInteger32(Register dst, const Operand& src) { 1173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(dst, Operand(src, kSmiShift / kBitsPerByte)); 1175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 1177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(dst, src); 1178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sarl(dst, Immediate(kSmiShift)); 1179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 11807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 11817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 11827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiToInteger64(Register dst, Register src) { 118469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch STATIC_ASSERT(kSmiTag == 0); 11853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (!dst.is(src)) { 1186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 1187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sarp(dst, Immediate(kSmiShift)); 1189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (kPointerSize == kInt32Size) { 1190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Sign extend to 64-bit. 1191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movsxlq(dst, dst); 1192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 11969dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenvoid MacroAssembler::SmiToInteger64(Register dst, const Operand& src) { 1197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movsxlq(dst, Operand(src, kSmiShift / kBitsPerByte)); 1199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 1201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 1202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger64(dst, dst); 1203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 12049dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen} 12059dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 12069dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 12073ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::SmiTest(Register src) { 1208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertSmi(src); 1209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(src, src); 1210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 121344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid MacroAssembler::SmiCompare(Register smi1, Register smi2) { 1214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertSmi(smi1); 1215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertSmi(smi2); 1216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(smi1, smi2); 1217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 12203ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::SmiCompare(Register dst, Smi* src) { 1221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertSmi(dst); 122244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Cmp(dst, src); 122344f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 122444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 122544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 122644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid MacroAssembler::Cmp(Register dst, Smi* src) { 1227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 12283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (src->value() == 0) { 1229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(dst, dst); 12303ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 1231756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick Register constant_reg = GetSmiConstant(src); 1232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(dst, constant_reg); 1233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1237f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkevoid MacroAssembler::SmiCompare(Register dst, const Operand& src) { 1238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertSmi(dst); 1239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertSmi(src); 1240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(dst, src); 12416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 12426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 12436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 12443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::SmiCompare(const Operand& dst, Register src) { 1245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertSmi(dst); 1246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertSmi(src); 1247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(dst, src); 1248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 12513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::SmiCompare(const Operand& dst, Smi* src) { 1252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertSmi(dst); 1253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpl(Operand(dst, kSmiShift / kBitsPerByte), Immediate(src->value())); 1255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 1257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpl(dst, Immediate(src)); 125844f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 1259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 126244f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid MacroAssembler::Cmp(const Operand& dst, Smi* src) { 126344f0eee88ff00398ff7f715fab053374d808c90dSteve Block // The Operand cannot use the smi register. 126444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register smi_reg = GetSmiConstant(src); 1265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.AddressUsesRegister(smi_reg)); 1266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(dst, smi_reg); 126744f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 126844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 126944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 12709dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenvoid MacroAssembler::SmiCompareInteger32(const Operand& dst, Register src) { 1271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpl(Operand(dst, kSmiShift / kBitsPerByte), src); 1273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 1275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(kScratchRegister, dst); 1276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpl(kScratchRegister, src); 1277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 12789dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen} 12799dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 12809dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 12813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::PositiveSmiTimesPowerOfTwoToInteger64(Register dst, 12823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Register src, 12833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int power) { 1284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(power >= 0); 1285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(power < 64); 12863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (power == 0) { 12873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block SmiToInteger64(dst, src); 12883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return; 12893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 12903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (!dst.is(src)) { 1291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 12923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 12933ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (power < kSmiShift) { 1294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sarp(dst, Immediate(kSmiShift - power)); 12953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else if (power > kSmiShift) { 1296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlp(dst, Immediate(power - kSmiShift)); 12973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 1298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 13017f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid MacroAssembler::PositiveSmiDivPowerOfTwoToInteger32(Register dst, 13027f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Register src, 13037f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch int power) { 1304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((0 <= power) && (power < 32)); 13057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (dst.is(src)) { 1306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shrp(dst, Immediate(power + kSmiShift)); 13077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else { 13087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch UNIMPLEMENTED(); // Not used. 13097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 13107f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 13117f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 13127f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1313257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SmiOrIfSmis(Register dst, Register src1, Register src2, 1314257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_smis, 1315257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1316257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (dst.is(src1) || dst.is(src2)) { 1317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(kScratchRegister)); 1318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.is(kScratchRegister)); 1319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, src1); 1320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch orp(kScratchRegister, src2); 1321257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch JumpIfNotSmi(kScratchRegister, on_not_smis, near_jump); 1322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, kScratchRegister); 1323257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 1324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src1); 1325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch orp(dst, src2); 1326257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch JumpIfNotSmi(dst, on_not_smis, near_jump); 1327257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1328257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1329257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1330257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 13313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockCondition MacroAssembler::CheckSmi(Register src) { 133269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch STATIC_ASSERT(kSmiTag == 0); 1333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block testb(src, Immediate(kSmiTagMask)); 13343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return zero; 1335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 13381e0659c275bb392c045087af4f6b0d7565cb3d77Steve BlockCondition MacroAssembler::CheckSmi(const Operand& src) { 133969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch STATIC_ASSERT(kSmiTag == 0); 13401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block testb(src, Immediate(kSmiTagMask)); 13411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block return zero; 13421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 13431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 13441e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1345f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochCondition MacroAssembler::CheckNonNegativeSmi(Register src) { 134669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch STATIC_ASSERT(kSmiTag == 0); 1347e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Test that both bits of the mask 0x8000000000000001 are zero. 1348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, src); 1349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch rolp(kScratchRegister, Immediate(1)); 13508defd9ff6930b4e24729971a61cf7469daf119beSteve Block testb(kScratchRegister, Immediate(3)); 1351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return zero; 1352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCondition MacroAssembler::CheckBothSmi(Register first, Register second) { 1356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (first.is(second)) { 1357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return CheckSmi(first); 1358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 135969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch STATIC_ASSERT(kSmiTag == 0 && kHeapObjectTag == 1 && kHeapObjectTagMask == 3); 1360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leal(kScratchRegister, Operand(first, second, times_1, 0)); 1362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testb(kScratchRegister, Immediate(0x03)); 1363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 1365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(kScratchRegister, first); 1366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch orl(kScratchRegister, second); 1367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testb(kScratchRegister, Immediate(kSmiTagMask)); 1368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 13693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return zero; 1370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1373f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochCondition MacroAssembler::CheckBothNonNegativeSmi(Register first, 1374f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Register second) { 1375d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (first.is(second)) { 1376f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return CheckNonNegativeSmi(first); 1377d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, first); 1379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch orp(kScratchRegister, second); 1380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch rolp(kScratchRegister, Immediate(1)); 1381f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch testl(kScratchRegister, Immediate(3)); 1382d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return zero; 1383d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1384d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1385d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1386bb769b257e753aafcbd96767abb2abc645eaa20cBen MurdochCondition MacroAssembler::CheckEitherSmi(Register first, 1387bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch Register second, 1388bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch Register scratch) { 1389e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (first.is(second)) { 1390e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return CheckSmi(first); 1391e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 1392bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch if (scratch.is(second)) { 1393bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch andl(scratch, first); 1394bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } else { 1395bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch if (!scratch.is(first)) { 1396bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch movl(scratch, first); 1397bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } 1398bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch andl(scratch, second); 1399bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } 1400bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch testb(scratch, Immediate(kSmiTagMask)); 1401e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return zero; 1402e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 1403e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 1404e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 14053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockCondition MacroAssembler::CheckInteger32ValidSmiValue(Register src) { 1406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // A 32-bit integer value can always be converted to a smi. 1408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return always; 1409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 1411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpl(src, Immediate(0xc0000000)); 1412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return positive; 1413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 14173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockCondition MacroAssembler::CheckUInteger32ValidSmiValue(Register src) { 1418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // An unsigned 32-bit integer value is valid as long as the high bit 1420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // is not set. 1421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testl(src, src); 1422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return positive; 1423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 1425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testl(src, Immediate(0xc0000000)); 1426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return zero; 1427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 14311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::CheckSmiToIndicator(Register dst, Register src) { 14321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (dst.is(src)) { 14331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block andl(dst, Immediate(kSmiTagMask)); 14341e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } else { 14351e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block movl(dst, Immediate(kSmiTagMask)); 14361e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block andl(dst, src); 14371e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 14381e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 14391e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 14401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 14411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::CheckSmiToIndicator(Register dst, const Operand& src) { 14421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (!(src.AddressUsesRegister(dst))) { 14431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block movl(dst, Immediate(kSmiTagMask)); 14441e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block andl(dst, src); 14451e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } else { 14461e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block movl(dst, src); 14471e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block andl(dst, Immediate(kSmiTagMask)); 14481e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 14491e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 14501e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 14511e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::JumpIfValidSmiValue(Register src, 1453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* on_valid, 1454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::Distance near_jump) { 1455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition is_valid = CheckInteger32ValidSmiValue(src); 1456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(is_valid, on_valid, near_jump); 1457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1460257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::JumpIfNotValidSmiValue(Register src, 1461257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_invalid, 1462257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1463257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Condition is_valid = CheckInteger32ValidSmiValue(src); 1464257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(NegateCondition(is_valid), on_invalid, near_jump); 1465257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1466257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1467257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::JumpIfUIntValidSmiValue(Register src, 1469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* on_valid, 1470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::Distance near_jump) { 1471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition is_valid = CheckUInteger32ValidSmiValue(src); 1472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(is_valid, on_valid, near_jump); 1473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1476257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::JumpIfUIntNotValidSmiValue(Register src, 1477257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_invalid, 1478257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1479257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Condition is_valid = CheckUInteger32ValidSmiValue(src); 1480257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(NegateCondition(is_valid), on_invalid, near_jump); 1481257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1482257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1483257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1484257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::JumpIfSmi(Register src, 1485257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_smi, 1486257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1487257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Condition smi = CheckSmi(src); 1488257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(smi, on_smi, near_jump); 1489257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1490257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1491257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1492257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::JumpIfNotSmi(Register src, 1493257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_smi, 1494257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1495257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Condition smi = CheckSmi(src); 1496257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(NegateCondition(smi), on_not_smi, near_jump); 1497257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1498257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1499257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1500257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::JumpUnlessNonNegativeSmi( 1501257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src, Label* on_not_smi_or_negative, 1502257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1503257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Condition non_negative_smi = CheckNonNegativeSmi(src); 1504257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(NegateCondition(non_negative_smi), on_not_smi_or_negative, near_jump); 1505257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1506257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1507257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1508257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::JumpIfSmiEqualsConstant(Register src, 1509257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Smi* constant, 1510257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_equals, 1511257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1512257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch SmiCompare(src, constant); 1513257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(equal, on_equals, near_jump); 1514257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1515257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1516257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1517257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::JumpIfNotBothSmi(Register src1, 1518257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src2, 1519257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_both_smi, 1520257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1521257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Condition both_smi = CheckBothSmi(src1, src2); 1522257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(NegateCondition(both_smi), on_not_both_smi, near_jump); 1523257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1524257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1525257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1526257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::JumpUnlessBothNonNegativeSmi(Register src1, 1527257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src2, 1528257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_both_smi, 1529257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1530257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Condition both_smi = CheckBothNonNegativeSmi(src1, src2); 1531257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(NegateCondition(both_smi), on_not_both_smi, near_jump); 1532257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1533257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1534257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 15353ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::SmiAddConstant(Register dst, Register src, Smi* constant) { 15363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (constant->value() == 0) { 15373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (!dst.is(src)) { 1538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 15393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 15408defd9ff6930b4e24729971a61cf7469daf119beSteve Block return; 15413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else if (dst.is(src)) { 1542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 1543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register constant_reg = GetSmiConstant(constant); 1544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch addp(dst, constant_reg); 1545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoadSmiConstant(dst, constant); 1547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch addp(dst, src); 1548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1552f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkevoid MacroAssembler::SmiAddConstant(const Operand& dst, Smi* constant) { 1553f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke if (constant->value() != 0) { 1554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addl(Operand(dst, kSmiShift / kBitsPerByte), 1556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Immediate(constant->value())); 1557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 1559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(dst, Immediate(constant)); 1560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1561f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke } 1562f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke} 1563f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1564f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::SmiAddConstant(Register dst, Register src, Smi* constant, 1566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SmiOperationConstraints constraints, 1567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* bailout_label, 1568257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1569257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (constant->value() == 0) { 1570257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!dst.is(src)) { 1571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 1572257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1573257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else if (dst.is(src)) { 1574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 1575257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch LoadSmiConstant(kScratchRegister, constant); 1576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(dst, kScratchRegister); 1577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (constraints & SmiOperationConstraint::kBailoutOnNoOverflow) { 1578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(no_overflow, bailout_label, near_jump); 1579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(constraints & SmiOperationConstraint::kPreserveSourceRegister); 1580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(dst, kScratchRegister); 1581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (constraints & SmiOperationConstraint::kBailoutOnOverflow) { 1582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (constraints & SmiOperationConstraint::kPreserveSourceRegister) { 1583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done; 1584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(no_overflow, &done, Label::kNear); 1585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(dst, kScratchRegister); 1586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jmp(bailout_label, near_jump); 1587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&done); 1588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Bailout if overflow without reserving src. 1590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(overflow, bailout_label, near_jump); 1591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 1594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1595257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 1596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(constraints & SmiOperationConstraint::kPreserveSourceRegister); 1597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(constraints & SmiOperationConstraint::kBailoutOnOverflow); 1598257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch LoadSmiConstant(dst, constant); 1599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(dst, src); 1600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(overflow, bailout_label, near_jump); 1601257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1602257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1603257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1604257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 16053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::SmiSubConstant(Register dst, Register src, Smi* constant) { 16063ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (constant->value() == 0) { 1607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!dst.is(src)) { 1608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 1609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 16103ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else if (dst.is(src)) { 1611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 16128defd9ff6930b4e24729971a61cf7469daf119beSteve Block Register constant_reg = GetSmiConstant(constant); 1613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(dst, constant_reg); 16143ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 16153ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (constant->value() == Smi::kMinValue) { 16168defd9ff6930b4e24729971a61cf7469daf119beSteve Block LoadSmiConstant(dst, constant); 16179dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen // Adding and subtracting the min-value gives the same result, it only 16189dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen // differs on the overflow bit, which we don't check here. 1619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(dst, src); 1620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 16219dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen // Subtract by adding the negation. 16228defd9ff6930b4e24729971a61cf7469daf119beSteve Block LoadSmiConstant(dst, Smi::FromInt(-constant->value())); 1623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(dst, src); 1624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::SmiSubConstant(Register dst, Register src, Smi* constant, 1630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SmiOperationConstraints constraints, 1631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* bailout_label, 1632257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1633257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (constant->value() == 0) { 1634257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!dst.is(src)) { 1635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 1636257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1637257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else if (dst.is(src)) { 1638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 1639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadSmiConstant(kScratchRegister, constant); 1640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(dst, kScratchRegister); 1641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (constraints & SmiOperationConstraint::kBailoutOnNoOverflow) { 1642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(no_overflow, bailout_label, near_jump); 1643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(constraints & SmiOperationConstraint::kPreserveSourceRegister); 1644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(dst, kScratchRegister); 1645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (constraints & SmiOperationConstraint::kBailoutOnOverflow) { 1646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (constraints & SmiOperationConstraint::kPreserveSourceRegister) { 1647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done; 1648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(no_overflow, &done, Label::kNear); 1649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(dst, kScratchRegister); 1650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jmp(bailout_label, near_jump); 1651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&done); 1652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Bailout if overflow without reserving src. 1654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(overflow, bailout_label, near_jump); 1655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1656257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 1657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 1658257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1659257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 1660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(constraints & SmiOperationConstraint::kPreserveSourceRegister); 1661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(constraints & SmiOperationConstraint::kBailoutOnOverflow); 1662257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (constant->value() == Smi::kMinValue) { 1663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 1664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 1665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadSmiConstant(kScratchRegister, constant); 1666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(dst, kScratchRegister); 1667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(overflow, bailout_label, near_jump); 1668257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 1669257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Subtract by adding the negation. 1670257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch LoadSmiConstant(dst, Smi::FromInt(-(constant->value()))); 1671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(dst, src); 1672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(overflow, bailout_label, near_jump); 1673257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1674257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1675257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1676257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1677257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1678257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SmiNeg(Register dst, 1679257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src, 1680257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_smi_result, 1681257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1682257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (dst.is(src)) { 1683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 1684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, src); 1685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch negp(dst); // Low 32 bits are retained as zero by negation. 1686257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Test if result is zero or Smi::kMinValue. 1687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(dst, kScratchRegister); 1688257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_equal, on_smi_result, near_jump); 1689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(src, kScratchRegister); 1690257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 1691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 1692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch negp(dst); 1693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(dst, src); 1694257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // If the result is zero or Smi::kMinValue, negation failed to create a smi. 1695257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_equal, on_smi_result, near_jump); 1696257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1697257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1698257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1699257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<class T> 1701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void SmiAddHelper(MacroAssembler* masm, 1702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register dst, 1703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register src1, 1704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch T src2, 1705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* on_not_smi_result, 1706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::Distance near_jump) { 1707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (dst.is(src1)) { 1708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done; 1709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->addp(dst, src2); 1710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->j(no_overflow, &done, Label::kNear); 1711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Restore src1. 1712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->subp(dst, src2); 1713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->jmp(on_not_smi_result, near_jump); 1714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->bind(&done); 1715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->movp(dst, src1); 1717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->addp(dst, src2); 1718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->j(overflow, on_not_smi_result, near_jump); 1719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1723257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SmiAdd(Register dst, 1724257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src1, 1725257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src2, 1726257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_smi_result, 1727257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NOT_NULL(on_not_smi_result); 1729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(src2)); 1730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiAddHelper<Register>(this, dst, src1, src2, on_not_smi_result, near_jump); 1731257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1732257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1733257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1734257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SmiAdd(Register dst, 1735257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src1, 1736257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch const Operand& src2, 1737257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_smi_result, 1738257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NOT_NULL(on_not_smi_result); 1740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.AddressUsesRegister(dst)); 1741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiAddHelper<Operand>(this, dst, src1, src2, on_not_smi_result, near_jump); 1742257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1743257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1744257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 17450d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid MacroAssembler::SmiAdd(Register dst, 17460d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Register src1, 17470d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Register src2) { 17480d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // No overflow checking. Use only when it's known that 17490d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // overflowing is impossible. 175044f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!dst.is(src1)) { 1751257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (emit_debug_code()) { 1752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, src1); 1753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(kScratchRegister, src2); 1754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(no_overflow, kSmiAdditionOverflow); 1755257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(dst, Operand(src1, src2, times_1, 0)); 1757257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 1758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(dst, src2); 1759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assert(no_overflow, kSmiAdditionOverflow); 1760257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1761257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1762257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1763257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<class T> 1765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void SmiSubHelper(MacroAssembler* masm, 1766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register dst, 1767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register src1, 1768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch T src2, 1769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* on_not_smi_result, 1770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::Distance near_jump) { 1771257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (dst.is(src1)) { 1772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done; 1773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->subp(dst, src2); 1774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->j(no_overflow, &done, Label::kNear); 1775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Restore src1. 1776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->addp(dst, src2); 1777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->jmp(on_not_smi_result, near_jump); 1778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->bind(&done); 1779257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 1780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->movp(dst, src1); 1781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->subp(dst, src2); 1782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->j(overflow, on_not_smi_result, near_jump); 1783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::SmiSub(Register dst, 1788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register src1, 1789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register src2, 1790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* on_not_smi_result, 1791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::Distance near_jump) { 1792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NOT_NULL(on_not_smi_result); 1793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(src2)); 1794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiSubHelper<Register>(this, dst, src1, src2, on_not_smi_result, near_jump); 1795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 17980d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid MacroAssembler::SmiSub(Register dst, 1799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register src1, 1800257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch const Operand& src2, 1801257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_smi_result, 1802257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NOT_NULL(on_not_smi_result); 1804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.AddressUsesRegister(dst)); 1805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiSubHelper<Operand>(this, dst, src1, src2, on_not_smi_result, near_jump); 1806257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1807257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1808257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<class T> 1810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void SmiSubNoOverflowHelper(MacroAssembler* masm, 1811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register dst, 1812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register src1, 1813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch T src2) { 18140d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // No overflow checking. Use only when it's known that 18150d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // overflowing is impossible (e.g., subtracting two positive smis). 181644f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!dst.is(src1)) { 1817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->movp(dst, src1); 1818a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->subp(dst, src2); 1820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->Assert(no_overflow, kSmiSubtractionOverflow); 1821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::SmiSub(Register dst, Register src1, Register src2) { 1825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(src2)); 1826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiSubNoOverflowHelper<Register>(this, dst, src1, src2); 1827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::SmiSub(Register dst, 1831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register src1, 1832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& src2) { 1833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiSubNoOverflowHelper<Operand>(this, dst, src1, src2); 1834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1837257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SmiMul(Register dst, 1838257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src1, 1839257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src2, 1840257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_smi_result, 1841257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(src2)); 1843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 1844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(kScratchRegister)); 1845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.is(kScratchRegister)); 1846257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1847257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (dst.is(src1)) { 1848257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label failure, zero_correct_result; 1849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, src1); // Create backup for later testing. 1850257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch SmiToInteger64(dst, src1); 1851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch imulp(dst, src2); 1852257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(overflow, &failure, Label::kNear); 1853257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1854257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Check for negative zero result. If product is zero, and one 1855257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // argument is negative, go to slow case. 1856257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label correct_result; 1857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(dst, dst); 1858257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_zero, &correct_result, Label::kNear); 1859257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, kScratchRegister); 1861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch xorp(dst, src2); 1862257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Result was positive zero. 1863257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(positive, &zero_correct_result, Label::kNear); 1864257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1865257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&failure); // Reused failure exit, restores src1. 1866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(src1, kScratchRegister); 1867257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch jmp(on_not_smi_result, near_jump); 1868257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1869257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&zero_correct_result); 1870257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Set(dst, 0); 1871257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1872257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&correct_result); 1873257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 1874257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch SmiToInteger64(dst, src1); 1875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch imulp(dst, src2); 1876257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(overflow, on_not_smi_result, near_jump); 1877257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Check for negative zero result. If product is zero, and one 1878257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // argument is negative, go to slow case. 1879257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label correct_result; 1880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(dst, dst); 1881257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_zero, &correct_result, Label::kNear); 1882257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // One of src1 and src2 is zero, the check whether the other is 1883257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // negative. 1884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, src1); 1885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch xorp(kScratchRegister, src2); 1886257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(negative, on_not_smi_result, near_jump); 1887257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&correct_result); 1888257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1889257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1890257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1891257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1892257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SmiDiv(Register dst, 1893257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src1, 1894257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src2, 1895257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_smi_result, 1896257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(kScratchRegister)); 1898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.is(kScratchRegister)); 1899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 1900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.is(rax)); 1901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.is(rdx)); 1902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(rdx)); 1903257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1904257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Check for 0 divisor (result is +/-Infinity). 1905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(src2, src2); 1906257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(zero, on_not_smi_result, near_jump); 1907257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1908257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (src1.is(rax)) { 1909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, src1); 1910257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1911257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch SmiToInteger32(rax, src1); 1912257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // We need to rule out dividing Smi::kMinValue by -1, since that would 1913257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // overflow in idiv and raise an exception. 1914257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // We combine this with negative zero test (negative zero only happens 1915257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // when dividing zero by a negative number). 1916257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1917257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // We overshoot a little and go to slow case if we divide min-value 1918257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // by any negative value, not just -1. 1919257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label safe_div; 1920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testl(rax, Immediate(~Smi::kMinValue)); 1921257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_zero, &safe_div, Label::kNear); 1922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(src2, src2); 1923257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (src1.is(rax)) { 1924257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(positive, &safe_div, Label::kNear); 1925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(src1, kScratchRegister); 1926257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch jmp(on_not_smi_result, near_jump); 1927257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 1928257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(negative, on_not_smi_result, near_jump); 1929257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1930257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&safe_div); 1931257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1932257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch SmiToInteger32(src2, src2); 1933257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Sign extend src1 into edx:eax. 1934257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch cdq(); 1935257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch idivl(src2); 1936257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Integer32ToSmi(src2, src2); 1937257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Check that the remainder is zero. 1938257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch testl(rdx, rdx); 1939257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (src1.is(rax)) { 1940257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label smi_result; 1941257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(zero, &smi_result, Label::kNear); 1942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(src1, kScratchRegister); 1943257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch jmp(on_not_smi_result, near_jump); 1944257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&smi_result); 1945257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 1946257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_zero, on_not_smi_result, near_jump); 1947257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1948257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!dst.is(src1) && src1.is(rax)) { 1949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(src1, kScratchRegister); 1950257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1951257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Integer32ToSmi(dst, rax); 1952257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1953257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1954257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1955257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SmiMod(Register dst, 1956257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src1, 1957257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src2, 1958257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_smi_result, 1959257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 1961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(kScratchRegister)); 1962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.is(kScratchRegister)); 1963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.is(rax)); 1964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.is(rdx)); 1965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(rdx)); 1966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(src2)); 1967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(src2, src2); 1969257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(zero, on_not_smi_result, near_jump); 1970257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1971257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (src1.is(rax)) { 1972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, src1); 1973257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1974257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch SmiToInteger32(rax, src1); 1975257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch SmiToInteger32(src2, src2); 1976257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1977257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Test for the edge case of dividing Smi::kMinValue by -1 (will overflow). 1978257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label safe_div; 1979257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch cmpl(rax, Immediate(Smi::kMinValue)); 1980257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_equal, &safe_div, Label::kNear); 1981257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch cmpl(src2, Immediate(-1)); 1982257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_equal, &safe_div, Label::kNear); 1983257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Retag inputs and go slow case. 1984257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Integer32ToSmi(src2, src2); 1985257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (src1.is(rax)) { 1986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(src1, kScratchRegister); 1987257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1988257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch jmp(on_not_smi_result, near_jump); 1989257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&safe_div); 1990257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1991257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Sign extend eax into edx:eax. 1992257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch cdq(); 1993257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch idivl(src2); 1994257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Restore smi tags on inputs. 1995257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Integer32ToSmi(src2, src2); 1996257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (src1.is(rax)) { 1997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(src1, kScratchRegister); 1998257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1999257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Check for a negative zero result. If the result is zero, and the 2000257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // dividend is negative, go slow to return a floating point negative zero. 2001257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label smi_result; 2002257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch testl(rdx, rdx); 2003257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_zero, &smi_result, Label::kNear); 2004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(src1, src1); 2005257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(negative, on_not_smi_result, near_jump); 2006257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&smi_result); 2007257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Integer32ToSmi(dst, rdx); 2008257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 2009257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2010257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiNot(Register dst, Register src) { 2012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 2013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src.is(kScratchRegister)); 2014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 2015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set tag and padding bits before negating, so that they are zero 2016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // afterwards. 2017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(kScratchRegister, Immediate(~0)); 2018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 2020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(kScratchRegister, Immediate(1)); 2021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (dst.is(src)) { 2023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch xorp(dst, kScratchRegister); 2024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(dst, Operand(src, kScratchRegister, times_1, 0)); 2026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch notp(dst); 2028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiAnd(Register dst, Register src1, Register src2) { 2032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(src2)); 2033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!dst.is(src1)) { 2034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src1); 2035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(dst, src2); 2037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 20403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::SmiAndConstant(Register dst, Register src, Smi* constant) { 20413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (constant->value() == 0) { 20429fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block Set(dst, 0); 20433ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else if (dst.is(src)) { 2044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 20458defd9ff6930b4e24729971a61cf7469daf119beSteve Block Register constant_reg = GetSmiConstant(constant); 2046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(dst, constant_reg); 20473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 20488defd9ff6930b4e24729971a61cf7469daf119beSteve Block LoadSmiConstant(dst, constant); 2049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(dst, src); 2050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiOr(Register dst, Register src1, Register src2) { 2055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!dst.is(src1)) { 2056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(src2)); 2057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src1); 2058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch orp(dst, src2); 2060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 20633ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::SmiOrConstant(Register dst, Register src, Smi* constant) { 20643ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (dst.is(src)) { 2065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 20668defd9ff6930b4e24729971a61cf7469daf119beSteve Block Register constant_reg = GetSmiConstant(constant); 2067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch orp(dst, constant_reg); 20683ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 20698defd9ff6930b4e24729971a61cf7469daf119beSteve Block LoadSmiConstant(dst, constant); 2070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch orp(dst, src); 2071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 20743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 2075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiXor(Register dst, Register src1, Register src2) { 2076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!dst.is(src1)) { 2077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(src2)); 2078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src1); 2079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch xorp(dst, src2); 2081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 20843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::SmiXorConstant(Register dst, Register src, Smi* constant) { 20853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (dst.is(src)) { 2086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 20878defd9ff6930b4e24729971a61cf7469daf119beSteve Block Register constant_reg = GetSmiConstant(constant); 2088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch xorp(dst, constant_reg); 20893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 20908defd9ff6930b4e24729971a61cf7469daf119beSteve Block LoadSmiConstant(dst, constant); 2091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch xorp(dst, src); 2092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiShiftArithmeticRightConstant(Register dst, 2097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register src, 2098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int shift_value) { 2099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_uint5(shift_value)); 2100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (shift_value > 0) { 2101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (dst.is(src)) { 2102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sarp(dst, Immediate(shift_value + kSmiShift)); 2103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlp(dst, Immediate(kSmiShift)); 2104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block UNIMPLEMENTED(); // Not used. 2106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiShiftLeftConstant(Register dst, 2112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register src, 2113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int shift_value, 2114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* on_not_smi_result, 2115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::Distance near_jump) { 2116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 2117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!dst.is(src)) { 2118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 2119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (shift_value > 0) { 2121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Shift amount specified by lower 5 bits, not six as the shl opcode. 2122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlq(dst, Immediate(shift_value & 0x1f)); 2123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 2126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (dst.is(src)) { 2127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNIMPLEMENTED(); // Not used. 2128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(dst, src); 2130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shll(dst, Immediate(shift_value)); 2131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JumpIfNotValidSmiValue(dst, on_not_smi_result, near_jump); 2132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Integer32ToSmi(dst, dst); 2133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2138257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SmiShiftLogicalRightConstant( 2139257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register dst, Register src, int shift_value, 2140257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_smi_result, Label::Distance near_jump) { 2141257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Logic right shift interprets its result as an *unsigned* number. 2142257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (dst.is(src)) { 2143257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch UNIMPLEMENTED(); // Not used. 2144257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 2145257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (shift_value == 0) { 2146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(src, src); 2147257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(negative, on_not_smi_result, near_jump); 2148257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 2149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 2150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 2151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shrp(dst, Immediate(shift_value + kSmiShift)); 2152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlp(dst, Immediate(kSmiShift)); 2153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 2155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(dst, src); 2156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shrp(dst, Immediate(shift_value)); 2157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JumpIfUIntNotValidSmiValue(dst, on_not_smi_result, near_jump); 2158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Integer32ToSmi(dst, dst); 2159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2160257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 2161257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 2162257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2163257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiShiftLeft(Register dst, 2165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register src1, 2166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register src2, 2167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* on_not_smi_result, 2168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::Distance near_jump) { 2169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 2170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(rcx)); 2171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!dst.is(src1)) { 2172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src1); 2173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Untag shift amount. 2175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(rcx, src2); 2176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Shift amount specified by lower 5 bits, not six as the shl opcode. 2177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(rcx, Immediate(0x1f)); 2178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlq_cl(dst); 2179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 2181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 2182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(kScratchRegister)); 2183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.is(kScratchRegister)); 2184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(src2)); 2185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(rcx)); 2186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (src1.is(rcx) || src2.is(rcx)) { 2188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movq(kScratchRegister, rcx); 2189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (dst.is(src1)) { 2191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNIMPLEMENTED(); // Not used. 2192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label valid_result; 2194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(dst, src1); 2195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(rcx, src2); 2196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shll_cl(dst); 2197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JumpIfValidSmiValue(dst, &valid_result, Label::kNear); 2198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // As src1 or src2 could not be dst, we do not need to restore them for 2199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // clobbering dst. 2200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (src1.is(rcx) || src2.is(rcx)) { 2201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (src1.is(rcx)) { 2202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movq(src1, kScratchRegister); 2203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movq(src2, kScratchRegister); 2205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jmp(on_not_smi_result, near_jump); 2208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&valid_result); 2209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Integer32ToSmi(dst, dst); 2210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2215257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SmiShiftLogicalRight(Register dst, 2216257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src1, 2217257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src2, 2218257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_smi_result, 2219257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 2220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 2221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(kScratchRegister)); 2222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.is(kScratchRegister)); 2223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(src2)); 2224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(rcx)); 2225257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (src1.is(rcx) || src2.is(rcx)) { 2226257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch movq(kScratchRegister, rcx); 2227257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 2228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (dst.is(src1)) { 2229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNIMPLEMENTED(); // Not used. 2230257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 2231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label valid_result; 2232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(dst, src1); 2233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(rcx, src2); 2234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shrl_cl(dst); 2235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JumpIfUIntValidSmiValue(dst, &valid_result, Label::kNear); 2236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // As src1 or src2 could not be dst, we do not need to restore them for 2237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // clobbering dst. 2238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (src1.is(rcx) || src2.is(rcx)) { 2239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (src1.is(rcx)) { 2240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movq(src1, kScratchRegister); 2241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movq(src2, kScratchRegister); 2243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jmp(on_not_smi_result, near_jump); 2246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&valid_result); 2247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Integer32ToSmi(dst, dst); 2248257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 2249257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 2250257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2251257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiShiftArithmeticRight(Register dst, 2253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register src1, 2254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register src2) { 2255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 2256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(kScratchRegister)); 2257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.is(kScratchRegister)); 2258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(rcx)); 2259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SmiToInteger32(rcx, src2); 2261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!dst.is(src1)) { 2262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src1); 22633ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 2264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(dst, dst); 2265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sarl_cl(dst); 2266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Integer32ToSmi(dst, dst); 2267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2270257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SelectNonSmi(Register dst, 2271257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src1, 2272257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src2, 2273257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_smis, 2274257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 2275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 2276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(kScratchRegister)); 2277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.is(kScratchRegister)); 2278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(src1)); 2279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(src2)); 2280257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Both operands must not be smis. 2281257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#ifdef DEBUG 2282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition not_both_smis = NegateCondition(CheckBothSmi(src1, src2)); 2283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(not_both_smis, kBothRegistersWereSmisInSelectNonSmi); 2284257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#endif 228569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch STATIC_ASSERT(kSmiTag == 0); 2286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(static_cast<Smi*>(0), Smi::FromInt(0)); 2287257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch movl(kScratchRegister, Immediate(kSmiTagMask)); 2288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(kScratchRegister, src1); 2289257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch testl(kScratchRegister, src2); 2290257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // If non-zero then both are smis. 2291257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_zero, on_not_smis, near_jump); 2292257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2293257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Exactly one operand is a smi. 2294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(1, static_cast<int>(kSmiTagMask)); 2295257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // kScratchRegister still holds src1 & kSmiTag, which is either zero or one. 2296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(kScratchRegister, Immediate(1)); 2297257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // If src1 is a smi, then scratch register all 1s, else it is all 0s. 2298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src1); 2299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch xorp(dst, src2); 2300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(dst, kScratchRegister); 2301257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // If src1 is a smi, dst holds src1 ^ src2, else it is zero. 2302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch xorp(dst, src1); 2303257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // If src1 is a smi, dst is src2, else it is src1, i.e., the non-smi. 2304257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 2305257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2306257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 23073ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockSmiIndex MacroAssembler::SmiToIndex(Register dst, 23083ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Register src, 23093ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int shift) { 2310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 2311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_uint6(shift)); 2312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // There is a possible optimization if shift is in the range 60-63, but that 2313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // will (and must) never happen. 2314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!dst.is(src)) { 2315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 2316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (shift < kSmiShift) { 2318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sarp(dst, Immediate(kSmiShift - shift)); 2319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlp(dst, Immediate(shift - kSmiShift)); 2321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return SmiIndex(dst, times_1); 23233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 2324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 2325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(shift >= times_1 && shift <= (static_cast<int>(times_8) + 1)); 2326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!dst.is(src)) { 2327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 2328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We have to sign extend the index register to 64-bit as the SMI might 2330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // be negative. 2331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movsxlq(dst, dst); 2332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (shift == times_1) { 2333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sarq(dst, Immediate(kSmiShift)); 2334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return SmiIndex(dst, times_1); 2335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return SmiIndex(dst, static_cast<ScaleFactor>(shift - 1)); 23373ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 2338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockSmiIndex MacroAssembler::SmiToNegativeIndex(Register dst, 2342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register src, 2343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int shift) { 2344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 2345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Register src holds a positive smi. 2346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_uint6(shift)); 2347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!dst.is(src)) { 2348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 2349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch negp(dst); 2351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (shift < kSmiShift) { 2352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sarp(dst, Immediate(kSmiShift - shift)); 2353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlp(dst, Immediate(shift - kSmiShift)); 2355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return SmiIndex(dst, times_1); 23573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 2358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 2359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(shift >= times_1 && shift <= (static_cast<int>(times_8) + 1)); 2360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!dst.is(src)) { 2361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 2362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch negq(dst); 2364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (shift == times_1) { 2365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sarq(dst, Immediate(kSmiShift)); 2366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return SmiIndex(dst, times_1); 2367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return SmiIndex(dst, static_cast<ScaleFactor>(shift - 1)); 23693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 2370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 237344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid MacroAssembler::AddSmiField(Register dst, const Operand& src) { 2374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 2375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(0, kSmiShift % kBitsPerByte); 2376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addl(dst, Operand(src, kSmiShift / kBitsPerByte)); 2377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 2379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(kScratchRegister, src); 2380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addl(dst, kScratchRegister); 2381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Push(Smi* source) { 2386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch intptr_t smi = reinterpret_cast<intptr_t>(source); 2387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (is_int32(smi)) { 2388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(Immediate(static_cast<int32_t>(smi))); 2389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register constant = GetSmiConstant(source); 2391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(constant); 2392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::PushRegisterAsTwoSmis(Register src, Register scratch) { 2397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src.is(scratch)); 2398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch, src); 2399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // High bits. 2400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shrp(src, Immediate(kPointerSize * kBitsPerByte - kSmiShift)); 2401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlp(src, Immediate(kSmiShift)); 2402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(src); 2403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Low bits. 2404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlp(scratch, Immediate(kSmiShift)); 2405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(scratch); 2406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::PopRegisterAsTwoSmis(Register dst, Register scratch) { 2410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(scratch)); 2411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(scratch); 2412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Low bits. 2413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shrp(scratch, Immediate(kSmiShift)); 2414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(dst); 2415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shrp(dst, Immediate(kSmiShift)); 2416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // High bits. 2417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlp(dst, Immediate(kPointerSize * kBitsPerByte - kSmiShift)); 2418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch orp(dst, scratch); 2419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Test(const Operand& src, Smi* source) { 2423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 2424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testl(Operand(src, kIntSize), Immediate(source->value())); 2425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 2427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testl(src, Immediate(source)); 2428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ---------------------------------------------------------------------------- 2433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2435257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::JumpIfNotString(Register object, 2436257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register object_map, 2437257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* not_string, 2438257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 2439257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Condition is_smi = CheckSmi(object); 2440257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(is_smi, not_string, near_jump); 2441257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CmpObjectType(object, FIRST_NONSTRING_TYPE, object_map); 2442257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(above_equal, not_string, near_jump); 2443257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 2444257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2445257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::JumpIfNotBothSequentialOneByteStrings( 2447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register first_object, Register second_object, Register scratch1, 2448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch2, Label* on_fail, Label::Distance near_jump) { 2449257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Check that both objects are not smis. 2450257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Condition either_smi = CheckEitherSmi(first_object, second_object); 2451257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(either_smi, on_fail, near_jump); 2452257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2453257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Load instance type for both strings. 2454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch1, FieldOperand(first_object, HeapObject::kMapOffset)); 2455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch2, FieldOperand(second_object, HeapObject::kMapOffset)); 2456257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch movzxbl(scratch1, FieldOperand(scratch1, Map::kInstanceTypeOffset)); 2457257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch movzxbl(scratch2, FieldOperand(scratch2, Map::kInstanceTypeOffset)); 2458257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check that both are flat one-byte strings. 2460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(kNotStringTag != 0); 2461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int kFlatOneByteStringMask = 2462257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask; 2463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int kFlatOneByteStringTag = 2464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kStringTag | kOneByteStringTag | kSeqStringTag; 2465257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andl(scratch1, Immediate(kFlatOneByteStringMask)); 2467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andl(scratch2, Immediate(kFlatOneByteStringMask)); 2468257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Interleave the bits to check both scratch1 and scratch2 in one test. 2469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(0, kFlatOneByteStringMask & (kFlatOneByteStringMask << 3)); 2470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(scratch1, Operand(scratch1, scratch2, times_8, 0)); 2471257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch cmpl(scratch1, 2472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Immediate(kFlatOneByteStringTag + (kFlatOneByteStringTag << 3))); 2473257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_equal, on_fail, near_jump); 2474257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 2475257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2476257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::JumpIfInstanceTypeIsNotSequentialOneByte( 2478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register instance_type, Register scratch, Label* failure, 2479257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 2480257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!scratch.is(instance_type)) { 2481257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch movl(scratch, instance_type); 2482257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 2483257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int kFlatOneByteStringMask = 2485257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask; 2486257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andl(scratch, Immediate(kFlatOneByteStringMask)); 2488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpl(scratch, Immediate(kStringTag | kSeqStringTag | kOneByteStringTag)); 2489257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_equal, failure, near_jump); 2490257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 2491257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2492257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialOneByte( 2494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register first_object_instance_type, Register second_object_instance_type, 2495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, Register scratch2, Label* on_fail, 2496257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 2497257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Load instance type for both strings. 2498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch1, first_object_instance_type); 2499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch2, second_object_instance_type); 2500257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check that both are flat one-byte strings. 2502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(kNotStringTag != 0); 2503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int kFlatOneByteStringMask = 2504257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask; 2505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int kFlatOneByteStringTag = 2506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kStringTag | kOneByteStringTag | kSeqStringTag; 2507257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andl(scratch1, Immediate(kFlatOneByteStringMask)); 2509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andl(scratch2, Immediate(kFlatOneByteStringMask)); 2510257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Interleave the bits to check both scratch1 and scratch2 in one test. 2511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(0, kFlatOneByteStringMask & (kFlatOneByteStringMask << 3)); 2512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(scratch1, Operand(scratch1, scratch2, times_8, 0)); 2513257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch cmpl(scratch1, 2514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Immediate(kFlatOneByteStringTag + (kFlatOneByteStringTag << 3))); 2515257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_equal, on_fail, near_jump); 2516257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 2517257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2518257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<class T> 2520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void JumpIfNotUniqueNameHelper(MacroAssembler* masm, 2521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch T operand_or_register, 2522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* not_unique_name, 2523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::Distance distance) { 2524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0); 2525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label succeed; 2526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->testb(operand_or_register, 2527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Immediate(kIsNotStringMask | kIsNotInternalizedMask)); 2528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->j(zero, &succeed, Label::kNear); 2529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->cmpb(operand_or_register, Immediate(static_cast<uint8_t>(SYMBOL_TYPE))); 2530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->j(not_equal, not_unique_name, distance); 2531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->bind(&succeed); 2533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::JumpIfNotUniqueNameInstanceType(Operand operand, 2537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* not_unique_name, 2538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::Distance distance) { 2539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JumpIfNotUniqueNameHelper<Operand>(this, operand, not_unique_name, distance); 2540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::JumpIfNotUniqueNameInstanceType(Register reg, 2544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* not_unique_name, 2545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::Distance distance) { 2546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JumpIfNotUniqueNameHelper<Register>(this, reg, not_unique_name, distance); 2547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 254944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 25500d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid MacroAssembler::Move(Register dst, Register src) { 25510d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (!dst.is(src)) { 2552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 25536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 25546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 25556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 25566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Move(Register dst, Handle<Object> source) { 2558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllowDeferredHandleDereference smi_check; 2559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (source->IsSmi()) { 25603ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Move(dst, Smi::cast(*source)); 2561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MoveHeapObject(dst, source); 2563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Move(const Operand& dst, Handle<Object> source) { 2568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllowDeferredHandleDereference smi_check; 2569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (source->IsSmi()) { 25703ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Move(dst, Smi::cast(*source)); 2571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MoveHeapObject(kScratchRegister, source); 2573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, kScratchRegister); 2574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2578958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid MacroAssembler::Move(XMMRegister dst, uint32_t src) { 2579958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (src == 0) { 2580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Xorpd(dst, dst); 2581958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 2582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch unsigned pop = base::bits::CountPopulation32(src); 2583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_NE(0u, pop); 2584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (pop == 32) { 2585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pcmpeqd(dst, dst); 2586958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 2587958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier movl(kScratchRegister, Immediate(src)); 2588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movq(dst, kScratchRegister); 2589958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2590958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2591958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2592958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2593958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2594958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid MacroAssembler::Move(XMMRegister dst, uint64_t src) { 2595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (src == 0) { 2596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Xorpd(dst, dst); 2597958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 2598958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier unsigned nlz = base::bits::CountLeadingZeros64(src); 2599958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier unsigned ntz = base::bits::CountTrailingZeros64(src); 2600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch unsigned pop = base::bits::CountPopulation64(src); 2601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_NE(0u, pop); 2602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (pop == 64) { 2603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pcmpeqd(dst, dst); 2604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (pop + ntz == 64) { 2605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pcmpeqd(dst, dst); 2606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Psllq(dst, ntz); 2607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (pop + nlz == 64) { 2608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pcmpeqd(dst, dst); 2609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Psrlq(dst, nlz); 2610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t lower = static_cast<uint32_t>(src); 2612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t upper = static_cast<uint32_t>(src >> 32); 2613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (upper == 0) { 2614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Move(dst, lower); 2615958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 2616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movq(kScratchRegister, src); 2617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movq(dst, kScratchRegister); 2618958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2619958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2620958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2621958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2622958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2623958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movaps(XMMRegister dst, XMMRegister src) { 2625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovaps(dst, src); 26283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 2629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movaps(dst, src); 26303ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 2631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movapd(XMMRegister dst, XMMRegister src) { 2635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovapd(dst, src); 2638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movapd(dst, src); 2640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movsd(XMMRegister dst, XMMRegister src) { 2645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovsd(dst, dst, src); 2648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movsd(dst, src); 2650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movsd(XMMRegister dst, const Operand& src) { 2655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovsd(dst, src); 26583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 2659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movsd(dst, src); 26603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 26613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 26623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 26633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2664014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movsd(const Operand& dst, XMMRegister src) { 2665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovsd(dst, src); 26683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 2669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movsd(dst, src); 26703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 26713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 26723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 26733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movss(XMMRegister dst, XMMRegister src) { 2675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovss(dst, dst, src); 2678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movss(dst, src); 2680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2681958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2682958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2683958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movss(XMMRegister dst, const Operand& src) { 2685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovss(dst, src); 2688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movss(dst, src); 2690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2691958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2692958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2693958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movss(const Operand& dst, XMMRegister src) { 2695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovss(dst, src); 2698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movss(dst, src); 2700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movd(XMMRegister dst, Register src) { 2705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovd(dst, src); 2708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movd(dst, src); 2710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movd(XMMRegister dst, const Operand& src) { 2715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovd(dst, src); 27183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 2719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movd(dst, src); 27203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 27213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 27223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 27233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movd(Register dst, XMMRegister src) { 2725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovd(dst, src); 27283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 2729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movd(dst, src); 27303ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 27313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 27323ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 27333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 2734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movq(XMMRegister dst, Register src) { 2735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovq(dst, src); 2738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movq(dst, src); 2740e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 2741e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 2742e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2743e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movq(Register dst, XMMRegister src) { 2745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovq(dst, src); 2748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movq(dst, src); 2750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movmskpd(Register dst, XMMRegister src) { 2755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovmskpd(dst, src); 2758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movmskpd(dst, src); 2760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Roundss(XMMRegister dst, XMMRegister src, 2765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RoundingMode mode) { 2766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vroundss(dst, dst, src, mode); 2769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch roundss(dst, src, mode); 2771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Roundsd(XMMRegister dst, XMMRegister src, 2776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RoundingMode mode) { 2777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vroundsd(dst, dst, src, mode); 2780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch roundsd(dst, src, mode); 2782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Sqrtsd(XMMRegister dst, XMMRegister src) { 2787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2789014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsqrtsd(dst, dst, src); 2790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch sqrtsd(dst, src); 2792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Sqrtsd(XMMRegister dst, const Operand& src) { 2797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsqrtsd(dst, dst, src); 2800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch sqrtsd(dst, src); 2802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Ucomiss(XMMRegister src1, XMMRegister src2) { 2807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vucomiss(src1, src2); 2810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ucomiss(src1, src2); 2812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Ucomiss(XMMRegister src1, const Operand& src2) { 2817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vucomiss(src1, src2); 2820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ucomiss(src1, src2); 2822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Ucomisd(XMMRegister src1, XMMRegister src2) { 2827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vucomisd(src1, src2); 2830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ucomisd(src1, src2); 2832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Ucomisd(XMMRegister src1, const Operand& src2) { 2837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vucomisd(src1, src2); 2840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ucomisd(src1, src2); 2842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cmp(Register dst, Handle<Object> source) { 2847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AllowDeferredHandleDereference smi_check; 2848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (source->IsSmi()) { 2849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cmp(dst, Smi::cast(*source)); 2850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MoveHeapObject(kScratchRegister, source); 2852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cmpp(dst, kScratchRegister); 2853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cmp(const Operand& dst, Handle<Object> source) { 2858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AllowDeferredHandleDereference smi_check; 2859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (source->IsSmi()) { 2860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cmp(dst, Smi::cast(*source)); 2861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MoveHeapObject(kScratchRegister, source); 2863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cmpp(dst, kScratchRegister); 2864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Push(Handle<Object> source) { 2869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AllowDeferredHandleDereference smi_check; 2870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (source->IsSmi()) { 2871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(Smi::cast(*source)); 2872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MoveHeapObject(kScratchRegister, source); 2874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(kScratchRegister); 2875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::MoveHeapObject(Register result, 2880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> object) { 2881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AllowDeferredHandleDereference using_raw_address; 2882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(object->IsHeapObject()); 2883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (isolate()->heap()->InNewSpace(*object)) { 2884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Cell> cell = isolate()->factory()->NewCell(object); 2885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Move(result, cell, RelocInfo::CELL); 2886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(result, Operand(result, 0)); 2887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Move(result, object, RelocInfo::EMBEDDED_OBJECT); 2889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::LoadGlobalCell(Register dst, Handle<Cell> cell) { 2894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (dst.is(rax)) { 2895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AllowDeferredHandleDereference embedding_raw_address; 2896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch load_rax(cell.location(), RelocInfo::CELL); 2897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Move(dst, cell, RelocInfo::CELL); 2899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(dst, Operand(dst, 0)); 2900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::CmpWeakValue(Register value, Handle<WeakCell> cell, 2905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register scratch) { 2906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Move(scratch, cell, RelocInfo::EMBEDDED_OBJECT); 2907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cmpp(value, FieldOperand(scratch, WeakCell::kValueOffset)); 2908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::GetWeakValue(Register value, Handle<WeakCell> cell) { 2912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Move(value, cell, RelocInfo::EMBEDDED_OBJECT); 2913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(value, FieldOperand(value, WeakCell::kValueOffset)); 2914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::LoadWeakValue(Register value, Handle<WeakCell> cell, 2918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label* miss) { 2919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GetWeakValue(value, cell); 2920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JumpIfSmi(value, miss); 2921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Drop(int stack_elements) { 2925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (stack_elements > 0) { 2926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch addp(rsp, Immediate(stack_elements * kPointerSize)); 2927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::DropUnderReturnAddress(int stack_elements, 2932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register scratch) { 2933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(stack_elements > 0); 2934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize == kInt64Size && stack_elements == 1) { 2935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch popq(MemOperand(rsp, 0)); 2936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 2937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PopReturnAddressTo(scratch); 2940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Drop(stack_elements); 2941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PushReturnAddressFrom(scratch); 2942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Push(Register src) { 2946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize == kInt64Size) { 2947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pushq(src); 2948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // x32 uses 64-bit push for rbp in the prologue. 2950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(src.code() != rbp.code()); 2951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch leal(rsp, Operand(rsp, -4)); 2952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(Operand(rsp, 0), src); 2953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Push(const Operand& src) { 2958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize == kInt64Size) { 2959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pushq(src); 2960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(kScratchRegister, src); 2962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch leal(rsp, Operand(rsp, -4)); 2963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(Operand(rsp, 0), kScratchRegister); 2964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::PushQuad(const Operand& src) { 2969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize == kInt64Size) { 2970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pushq(src); 2971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(kScratchRegister, src); 2973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pushq(kScratchRegister); 2974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Push(Immediate value) { 2979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize == kInt64Size) { 2980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pushq(value); 2981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch leal(rsp, Operand(rsp, -4)); 2983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(Operand(rsp, 0), value); 2984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::PushImm32(int32_t imm32) { 2989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize == kInt64Size) { 2990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pushq_imm32(imm32); 2991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch leal(rsp, Operand(rsp, -4)); 2993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(Operand(rsp, 0), Immediate(imm32)); 2994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Pop(Register dst) { 2999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize == kInt64Size) { 3000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch popq(dst); 3001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // x32 uses 64-bit pop for rbp in the epilogue. 3003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(dst.code() != rbp.code()); 3004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(dst, Operand(rsp, 0)); 3005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch leal(rsp, Operand(rsp, 4)); 3006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Pop(const Operand& dst) { 3011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize == kInt64Size) { 3012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch popq(dst); 3013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register scratch = dst.AddressUsesRegister(kScratchRegister) 3015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? kRootRegister : kScratchRegister; 3016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(scratch, Operand(rsp, 0)); 3017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(dst, scratch); 3018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch leal(rsp, Operand(rsp, 4)); 3019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (scratch.is(kRootRegister)) { 3020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Restore kRootRegister. 3021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InitializeRootRegister(); 3022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::PopQuad(const Operand& dst) { 3028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (kPointerSize == kInt64Size) { 3029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch popq(dst); 3030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch popq(kScratchRegister); 3032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, kScratchRegister); 3033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::LoadSharedFunctionInfoSpecialField(Register dst, 3038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register base, 3039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int offset) { 3040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(offset > SharedFunctionInfo::kLengthOffset && 3041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch offset <= SharedFunctionInfo::kSize && 3042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (((offset - SharedFunctionInfo::kLengthOffset) / kIntSize) % 2 == 1)); 3043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (kPointerSize == kInt64Size) { 3044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movsxlq(dst, FieldOperand(base, offset)); 3045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, FieldOperand(base, offset)); 3047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(dst, dst); 3048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::TestBitSharedFunctionInfoSpecialField(Register base, 3053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int offset, 3054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int bits) { 3055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(offset > SharedFunctionInfo::kLengthOffset && 3056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch offset <= SharedFunctionInfo::kSize && 3057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (((offset - SharedFunctionInfo::kLengthOffset) / kIntSize) % 2 == 1)); 3058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (kPointerSize == kInt32Size) { 3059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // On x32, this field is represented by SMI. 3060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bits += kSmiShift; 3061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 30623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int byte_offset = bits / kBitsPerByte; 30633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int bit_in_byte = bits & (kBitsPerByte - 1); 3064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testb(FieldOperand(base, offset + byte_offset), Immediate(1 << bit_in_byte)); 30653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 30663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 30673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Jump(ExternalReference ext) { 306944f0eee88ff00398ff7f715fab053374d808c90dSteve Block LoadAddress(kScratchRegister, ext); 3070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block jmp(kScratchRegister); 3071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Jump(const Operand& op) { 3075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (kPointerSize == kInt64Size) { 3076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jmp(op); 3077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, op); 3079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jmp(kScratchRegister); 3080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Jump(Address destination, RelocInfo::Mode rmode) { 3085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(kScratchRegister, destination, rmode); 3086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block jmp(kScratchRegister); 3087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Jump(Handle<Code> code_object, RelocInfo::Mode rmode) { 30913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // TODO(X64): Inline this 30923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block jmp(code_object, rmode); 3093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 309644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockint MacroAssembler::CallSize(ExternalReference ext) { 309744f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Opcode for call kScratchRegister is: Rex.B FF D4 (three bytes). 3098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return LoadAddressSize(ext) + 3099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler::kCallScratchRegisterInstructionLength; 310044f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 310144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 310244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 3103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Call(ExternalReference ext) { 310444f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG 310544f0eee88ff00398ff7f715fab053374d808c90dSteve Block int end_position = pc_offset() + CallSize(ext); 310644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 310744f0eee88ff00398ff7f715fab053374d808c90dSteve Block LoadAddress(kScratchRegister, ext); 3108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block call(kScratchRegister); 310944f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG 311044f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(end_position, pc_offset()); 311144f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 3112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Call(const Operand& op) { 3116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize == kInt64Size && !CpuFeatures::IsSupported(ATOM)) { 3117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch call(op); 3118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, op); 3120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch call(kScratchRegister); 3121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Call(Address destination, RelocInfo::Mode rmode) { 312644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG 3127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int end_position = pc_offset() + CallSize(destination); 312844f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 3129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(kScratchRegister, destination, rmode); 3130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block call(kScratchRegister); 313144f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG 313244f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(pc_offset(), end_position); 313344f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 3134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3137257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::Call(Handle<Code> code_object, 3138257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch RelocInfo::Mode rmode, 3139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TypeFeedbackId ast_id) { 314044f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG 314144f0eee88ff00398ff7f715fab053374d808c90dSteve Block int end_position = pc_offset() + CallSize(code_object); 314244f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 3143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(RelocInfo::IsCodeTarget(rmode) || 3144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch rmode == RelocInfo::CODE_AGE_SEQUENCE); 3145257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch call(code_object, rmode, ast_id); 314644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG 314744f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(end_position, pc_offset()); 314844f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 3149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Pextrd(Register dst, XMMRegister src, int8_t imm8) { 3153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (imm8 == 0) { 3154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movd(dst, src); 3155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(1, imm8); 3158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(SSE4_1)) { 3159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope sse_scope(this, SSE4_1); 3160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pextrd(dst, src, imm8); 3161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movq(dst, src); 3164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch shrq(dst, Immediate(32)); 3165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Pinsrd(XMMRegister dst, Register src, int8_t imm8) { 3169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(SSE4_1)) { 3170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope sse_scope(this, SSE4_1); 3171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pinsrd(dst, src, imm8); 3172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movd(xmm0, src); 3175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (imm8 == 1) { 3176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch punpckldq(dst, xmm0); 3177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(0, imm8); 3179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movss(dst, xmm0); 3180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Pinsrd(XMMRegister dst, const Operand& src, int8_t imm8) { 3185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(imm8 == 0 || imm8 == 1); 3186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(SSE4_1)) { 3187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope sse_scope(this, SSE4_1); 3188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pinsrd(dst, src, imm8); 3189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movd(xmm0, src); 3192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (imm8 == 1) { 3193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch punpckldq(dst, xmm0); 3194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(0, imm8); 3196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movss(dst, xmm0); 3197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Lzcntl(Register dst, Register src) { 3202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(LZCNT)) { 3203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, LZCNT); 3204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch lzcntl(dst, src); 3205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label not_zero_src; 3208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bsrl(dst, src); 3209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(not_zero, ¬_zero_src, Label::kNear); 3210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(dst, 63); // 63^31 == 32 3211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(¬_zero_src); 3212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch xorl(dst, Immediate(31)); // for x in [0..31], 31^x == 31 - x 3213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Lzcntl(Register dst, const Operand& src) { 3217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(LZCNT)) { 3218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, LZCNT); 3219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch lzcntl(dst, src); 3220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label not_zero_src; 3223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bsrl(dst, src); 3224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(not_zero, ¬_zero_src, Label::kNear); 3225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(dst, 63); // 63^31 == 32 3226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(¬_zero_src); 3227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch xorl(dst, Immediate(31)); // for x in [0..31], 31^x == 31 - x 3228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Lzcntq(Register dst, Register src) { 3232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(LZCNT)) { 3233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, LZCNT); 3234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch lzcntq(dst, src); 3235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label not_zero_src; 3238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bsrq(dst, src); 3239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(not_zero, ¬_zero_src, Label::kNear); 3240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(dst, 127); // 127^63 == 64 3241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(¬_zero_src); 3242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch xorl(dst, Immediate(63)); // for x in [0..63], 63^x == 63 - x 3243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Lzcntq(Register dst, const Operand& src) { 3247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(LZCNT)) { 3248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, LZCNT); 3249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch lzcntq(dst, src); 3250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label not_zero_src; 3253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bsrq(dst, src); 3254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(not_zero, ¬_zero_src, Label::kNear); 3255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(dst, 127); // 127^63 == 64 3256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(¬_zero_src); 3257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch xorl(dst, Immediate(63)); // for x in [0..63], 63^x == 63 - x 3258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Tzcntq(Register dst, Register src) { 3262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(BMI1)) { 3263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, BMI1); 3264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch tzcntq(dst, src); 3265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label not_zero_src; 3268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bsfq(dst, src); 3269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(not_zero, ¬_zero_src, Label::kNear); 3270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Define the result of tzcnt(0) separately, because bsf(0) is undefined. 3271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(dst, 64); 3272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(¬_zero_src); 3273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Tzcntq(Register dst, const Operand& src) { 3277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(BMI1)) { 3278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, BMI1); 3279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch tzcntq(dst, src); 3280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label not_zero_src; 3283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bsfq(dst, src); 3284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(not_zero, ¬_zero_src, Label::kNear); 3285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Define the result of tzcnt(0) separately, because bsf(0) is undefined. 3286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(dst, 64); 3287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(¬_zero_src); 3288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Tzcntl(Register dst, Register src) { 3292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(BMI1)) { 3293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, BMI1); 3294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch tzcntl(dst, src); 3295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label not_zero_src; 3298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bsfl(dst, src); 3299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(not_zero, ¬_zero_src, Label::kNear); 3300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(dst, 32); // The result of tzcnt is 32 if src = 0. 3301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(¬_zero_src); 3302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Tzcntl(Register dst, const Operand& src) { 3306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(BMI1)) { 3307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, BMI1); 3308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch tzcntl(dst, src); 3309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label not_zero_src; 3312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bsfl(dst, src); 3313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(not_zero, ¬_zero_src, Label::kNear); 3314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(dst, 32); // The result of tzcnt is 32 if src = 0. 3315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(¬_zero_src); 3316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Popcntl(Register dst, Register src) { 3320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(POPCNT)) { 3321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, POPCNT); 3322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch popcntl(dst, src); 3323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 3326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Popcntl(Register dst, const Operand& src) { 3330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(POPCNT)) { 3331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, POPCNT); 3332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch popcntl(dst, src); 3333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 3336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Popcntq(Register dst, Register src) { 3340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(POPCNT)) { 3341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, POPCNT); 3342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch popcntq(dst, src); 3343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 3346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Popcntq(Register dst, const Operand& src) { 3350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(POPCNT)) { 3351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, POPCNT); 3352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch popcntq(dst, src); 3353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 3356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 33591e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::Pushad() { 3360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(rax); 3361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(rcx); 3362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(rdx); 3363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(rbx); 33641e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Not pushing rsp or rbp. 3365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(rsi); 3366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(rdi); 3367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(r8); 3368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(r9); 33691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // r10 is kScratchRegister. 3370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(r11); 3371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(r12); 33721e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // r13 is kRootRegister. 3373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(r14); 3374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(r15); 3375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STATIC_ASSERT(12 == kNumSafepointSavedRegisters); 3376e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Use lea for symmetry with Popad. 3377e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int sp_delta = 3378e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch (kNumSafepointRegisters - kNumSafepointSavedRegisters) * kPointerSize; 3379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(rsp, Operand(rsp, -sp_delta)); 33801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 33811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 33821e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 33831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::Popad() { 3384e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Popad must not change the flags, so use lea instead of addq. 3385e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int sp_delta = 3386e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch (kNumSafepointRegisters - kNumSafepointSavedRegisters) * kPointerSize; 3387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(rsp, Operand(rsp, sp_delta)); 3388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(r15); 3389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(r14); 3390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pop(r12); 3391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(r11); 3392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(r9); 3393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(r8); 3394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(rdi); 3395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(rsi); 3396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(rbx); 3397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(rdx); 3398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(rcx); 3399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(rax); 34001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 34011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 34021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 34031e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::Dropad() { 3404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(rsp, Immediate(kNumSafepointRegisters * kPointerSize)); 34051e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 34061e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 34071e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 34081e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// Order general registers are pushed by Pushad: 340944f0eee88ff00398ff7f715fab053374d808c90dSteve Block// rax, rcx, rdx, rbx, rsi, rdi, r8, r9, r11, r14, r15. 34103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int 34113ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochMacroAssembler::kSafepointPushRegisterIndices[Register::kNumRegisters] = { 34121e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 0, 34131e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1, 34141e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 2, 34151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 3, 34161e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block -1, 34171e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block -1, 34181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 4, 34191e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 5, 34201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 6, 34211e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 7, 34221e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block -1, 34231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 8, 342444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 9, 3425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch -1, 3426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 10, 3427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 11 34281e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}; 34291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 34301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 3431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::StoreToSafepointRegisterSlot(Register dst, 3432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Immediate& imm) { 3433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(SafepointRegisterSlot(dst), imm); 3434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3437e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochvoid MacroAssembler::StoreToSafepointRegisterSlot(Register dst, Register src) { 3438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(SafepointRegisterSlot(dst), src); 3439e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 3440e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3441e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3442e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochvoid MacroAssembler::LoadFromSafepointRegisterSlot(Register dst, Register src) { 3443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, SafepointRegisterSlot(src)); 3444e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 3445e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3446e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3447e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochOperand MacroAssembler::SafepointRegisterSlot(Register reg) { 3448e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return Operand(rsp, SafepointRegisterStackIndex(reg.code()) * kPointerSize); 3449e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 3450e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3451e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::PushStackHandler() { 3453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Adjust this code if not the case. 3454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STATIC_ASSERT(StackHandlerConstants::kSize == 1 * kPointerSize); 34553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); 34563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 34573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Link the current handler as the next handler. 34583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); 3459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(ExternalOperand(handler_address)); 3460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 34613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Set this new handler as the current one. 3462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(ExternalOperand(handler_address), rsp); 3463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::PopStackHandler() { 34673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); 34683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); 3469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(ExternalOperand(handler_address)); 3470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize)); 3471e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 3472e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 3473e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 3474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Ret() { 3475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ret(0); 3476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 34791e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::Ret(int bytes_dropped, Register scratch) { 34801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (is_uint16(bytes_dropped)) { 34811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block ret(bytes_dropped); 34821e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } else { 3483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PopReturnAddressTo(scratch); 3484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(rsp, Immediate(bytes_dropped)); 3485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushReturnAddressFrom(scratch); 34861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block ret(0); 34871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 34881e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 34891e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 34901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 3491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::FCmp() { 34923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block fucomip(); 34938defd9ff6930b4e24729971a61cf7469daf119beSteve Block fstp(0); 3494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::CmpObjectType(Register heap_object, 3498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InstanceType type, 3499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register map) { 3500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(map, FieldOperand(heap_object, HeapObject::kMapOffset)); 3501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CmpInstanceType(map, type); 3502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::CmpInstanceType(Register map, InstanceType type) { 3506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block cmpb(FieldOperand(map, Map::kInstanceTypeOffset), 3507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Immediate(static_cast<int8_t>(type))); 3508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 35113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid MacroAssembler::CheckFastElements(Register map, 35123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Label* fail, 35133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Label::Distance distance) { 3514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); 3515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); 3516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(FAST_ELEMENTS == 2); 3517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); 35183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cmpb(FieldOperand(map, Map::kBitField2Offset), 3519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Immediate(Map::kMaximumBitField2FastHoleyElementValue)); 35203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(above, fail, distance); 35213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 35223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 35233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 35243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::CheckFastObjectElements(Register map, 35253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* fail, 35263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label::Distance distance) { 3527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); 3528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); 3529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(FAST_ELEMENTS == 2); 3530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); 35313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cmpb(FieldOperand(map, Map::kBitField2Offset), 3532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Immediate(Map::kMaximumBitField2FastHoleySmiElementValue)); 35333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(below_equal, fail, distance); 3534592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch cmpb(FieldOperand(map, Map::kBitField2Offset), 3535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Immediate(Map::kMaximumBitField2FastHoleyElementValue)); 3536592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch j(above, fail, distance); 3537592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch} 3538592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 3539592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 3540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::CheckFastSmiElements(Register map, 3541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* fail, 3542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::Distance distance) { 3543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); 3544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); 35453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cmpb(FieldOperand(map, Map::kBitField2Offset), 3546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Immediate(Map::kMaximumBitField2FastHoleySmiElementValue)); 35473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(above, fail, distance); 35483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 35493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 35503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 35513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::StoreNumberToDoubleElements( 35523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register maybe_number, 35533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register elements, 35543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register index, 35553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch XMMRegister xmm_scratch, 3556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* fail, 3557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int elements_offset) { 3558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label smi_value, done; 35593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 35603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JumpIfSmi(maybe_number, &smi_value, Label::kNear); 35613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 35623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CheckMap(maybe_number, 35633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate()->factory()->heap_number_map(), 35643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch fail, 35653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DONT_DO_SMI_CHECK); 35663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Double value, turn potential sNaN into qNaN. 3568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Move(xmm_scratch, 1.0); 3569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch mulsd(xmm_scratch, FieldOperand(maybe_number, HeapNumber::kValueOffset)); 3570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jmp(&done, Label::kNear); 35713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 35723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bind(&smi_value); 35733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Value is a smi. convert to a double and store. 35743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Preserve original value. 35753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SmiToInteger32(kScratchRegister, maybe_number); 3576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Cvtlsi2sd(xmm_scratch, kScratchRegister); 3577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(&done); 3578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movsd(FieldOperand(elements, index, times_8, 3579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedDoubleArray::kHeaderSize - elements_offset), 35803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch xmm_scratch); 35813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 35823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 35833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::CompareMap(Register obj, Handle<Map> map) { 35853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Cmp(FieldOperand(obj, HeapObject::kMapOffset), map); 35863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 35873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 35883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 35893100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid MacroAssembler::CheckMap(Register obj, 35903100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Handle<Map> map, 35913100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Label* fail, 3592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiCheckType smi_check_type) { 3593257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (smi_check_type == DO_SMI_CHECK) { 35943100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu JumpIfSmi(obj, fail); 35953100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 35963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompareMap(obj, map); 35983100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu j(not_equal, fail); 35993100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 36003100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 36013100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3602257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::ClampUint8(Register reg) { 3603257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label done; 3604257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch testl(reg, Immediate(0xFFFFFF00)); 3605257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(zero, &done, Label::kNear); 3606257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch setcc(negative, reg); // 1 if negative, 0 if positive. 3607257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch decb(reg); // 0 if negative, 255 if positive. 3608257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&done); 3609257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 3610257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3611257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3612257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::ClampDoubleToUint8(XMMRegister input_reg, 3613257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch XMMRegister temp_xmm_reg, 3614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register result_reg) { 3615257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label done; 3616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label conv_failure; 3617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Xorpd(temp_xmm_reg, temp_xmm_reg); 3618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cvtsd2si(result_reg, input_reg); 3619257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch testl(result_reg, Immediate(0xFFFFFF00)); 3620257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(zero, &done, Label::kNear); 3621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpl(result_reg, Immediate(1)); 3622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(overflow, &conv_failure, Label::kNear); 3623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(result_reg, Immediate(0)); 3624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch setcc(sign, result_reg); 3625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subl(result_reg, Immediate(1)); 3626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andl(result_reg, Immediate(255)); 3627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jmp(&done, Label::kNear); 3628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&conv_failure); 3629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Set(result_reg, 0); 3630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Ucomisd(input_reg, temp_xmm_reg); 3631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(below, &done, Label::kNear); 3632257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Set(result_reg, 255); 3633257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&done); 3634257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 3635257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3636257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::LoadUint32(XMMRegister dst, 3638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register src) { 3639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_debug_code) { 3640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpq(src, Immediate(0xffffffff)); 3641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assert(below_equal, kInputGPRIsExpectedToHaveUpper32Cleared); 3642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cvtqsi2sd(dst, src); 3644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::SlowTruncateToI(Register result_reg, 3648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register input_reg, 3649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int offset) { 3650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DoubleToIStub stub(isolate(), input_reg, result_reg, offset, true); 3651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch call(stub.GetCode(), RelocInfo::CODE_TARGET); 3652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::TruncateHeapNumberToI(Register result_reg, 3656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register input_reg) { 3657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done; 3658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 3659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cvttsd2siq(result_reg, xmm0); 3660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpq(result_reg, Immediate(1)); 3661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(no_overflow, &done, Label::kNear); 3662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Slow case. 3664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (input_reg.is(result_reg)) { 3665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(rsp, Immediate(kDoubleSize)); 3666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movsd(MemOperand(rsp, 0), xmm0); 3667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SlowTruncateToI(result_reg, rsp, 0); 3668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(rsp, Immediate(kDoubleSize)); 3669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SlowTruncateToI(result_reg, input_reg); 3671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&done); 3674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Keep our invariant that the upper 32 bits are zero. 3675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(result_reg, result_reg); 3676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::TruncateDoubleToI(Register result_reg, 3680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch XMMRegister input_reg) { 3681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done; 3682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cvttsd2siq(result_reg, input_reg); 3683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpq(result_reg, Immediate(1)); 3684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(no_overflow, &done, Label::kNear); 3685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(rsp, Immediate(kDoubleSize)); 3687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movsd(MemOperand(rsp, 0), input_reg); 3688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SlowTruncateToI(result_reg, rsp, 0); 3689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(rsp, Immediate(kDoubleSize)); 3690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&done); 3692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Keep our invariant that the upper 32 bits are zero. 3693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(result_reg, result_reg); 3694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::DoubleToI(Register result_reg, XMMRegister input_reg, 3698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch XMMRegister scratch, 3699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MinusZeroMode minus_zero_mode, 3700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* lost_precision, Label* is_nan, 3701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* minus_zero, Label::Distance dst) { 3702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cvttsd2si(result_reg, input_reg); 3703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Cvtlsi2sd(xmm0, result_reg); 3704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Ucomisd(xmm0, input_reg); 3705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(not_equal, lost_precision, dst); 3706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(parity_even, is_nan, dst); // NaN. 3707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (minus_zero_mode == FAIL_ON_MINUS_ZERO) { 3708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done; 3709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The integer converted back is equal to the original. We 3710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // only have to test if we got -0 as an input. 3711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testl(result_reg, result_reg); 3712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(not_zero, &done, Label::kNear); 3713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movmskpd(result_reg, input_reg); 3714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Bit 0 contains the sign of the double in input_reg. 3715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If input was positive, we are ok and return 0, otherwise 3716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // jump to minus_zero. 3717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andl(result_reg, Immediate(1)); 3718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(not_zero, minus_zero, dst); 3719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&done); 3720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3724257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::LoadInstanceDescriptors(Register map, 3725257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register descriptors) { 3726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(descriptors, FieldOperand(map, Map::kDescriptorsOffset)); 3727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::NumberOfOwnDescriptors(Register dst, Register map) { 3731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(dst, FieldOperand(map, Map::kBitField3Offset)); 3732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DecodeField<Map::NumberOfOwnDescriptorsBits>(dst); 3733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::EnumLength(Register dst, Register map) { 3737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(Map::EnumLengthBits::kShift == 0); 3738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(dst, FieldOperand(map, Map::kBitField3Offset)); 3739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andl(dst, Immediate(Map::EnumLengthBits::kMask)); 3740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Integer32ToSmi(dst, dst); 3741257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 3742257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3743257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::LoadAccessor(Register dst, Register holder, 3745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int accessor_index, 3746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AccessorComponent accessor) { 3747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(dst, FieldOperand(holder, HeapObject::kMapOffset)); 3748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoadInstanceDescriptors(dst, dst); 3749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(dst, FieldOperand(dst, DescriptorArray::GetValueOffset(accessor_index))); 3750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int offset = accessor == ACCESSOR_GETTER ? AccessorPair::kGetterOffset 3751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : AccessorPair::kSetterOffset; 3752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(dst, FieldOperand(dst, offset)); 3753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3756958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid MacroAssembler::DispatchWeakMap(Register obj, Register scratch1, 3757958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register scratch2, Handle<WeakCell> cell, 3758958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Code> success, 3759958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SmiCheckType smi_check_type) { 3760257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label fail; 3761257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (smi_check_type == DO_SMI_CHECK) { 3762257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch JumpIfSmi(obj, &fail); 3763257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 3764958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier movq(scratch1, FieldOperand(obj, HeapObject::kMapOffset)); 3765958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CmpWeakValue(scratch1, cell, scratch2); 3766257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(equal, success, RelocInfo::CODE_TARGET); 3767257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&fail); 3768257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 3769257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3770257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertNumber(Register object) { 3772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 3773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label ok; 3774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition is_smi = CheckSmi(object); 3775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(is_smi, &ok, Label::kNear); 3776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Cmp(FieldOperand(object, HeapObject::kMapOffset), 3777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->factory()->heap_number_map()); 3778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(equal, kOperandIsNotANumber); 3779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&ok); 3780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3781402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu} 3782402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 3783402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 3784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertNotSmi(Register object) { 3785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 3786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition is_smi = CheckSmi(object); 3787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(NegateCondition(is_smi), kOperandIsASmi); 3788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3789756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick} 3790756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 3791756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 3792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertSmi(Register object) { 3793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 3794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition is_smi = CheckSmi(object); 3795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(is_smi, kOperandIsNotASmi); 3796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 379744f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 379844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 379944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 3800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertSmi(const Operand& object) { 3801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 3802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition is_smi = CheckSmi(object); 3803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(is_smi, kOperandIsNotASmi); 3804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertZeroExtended(Register int32_register) { 3809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 3810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!int32_register.is(kScratchRegister)); 3811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movq(kScratchRegister, V8_INT64_C(0x0000000100000000)); 3812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpq(kScratchRegister, int32_register); 3813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(above_equal, k32BitValueInRegisterIsNotZeroExtended); 3814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertString(Register object) { 3819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 3820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testb(object, Immediate(kSmiTagMask)); 3821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(not_equal, kOperandIsASmiAndNotAString); 3822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(object); 3823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(object, FieldOperand(object, HeapObject::kMapOffset)); 3824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CmpInstanceType(object, FIRST_NONSTRING_TYPE); 3825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(object); 3826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(below, kOperandIsNotAString); 3827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 38286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 38296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 38306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertName(Register object) { 3832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 3833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testb(object, Immediate(kSmiTagMask)); 3834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(not_equal, kOperandIsASmiAndNotAName); 3835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(object); 3836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(object, FieldOperand(object, HeapObject::kMapOffset)); 3837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CmpInstanceType(object, LAST_NAME_TYPE); 3838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(object); 3839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(below_equal, kOperandIsNotAName); 3840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 38413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 38423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 38433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::AssertFunction(Register object) { 3845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (emit_debug_code()) { 3846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch testb(object, Immediate(kSmiTagMask)); 3847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Check(not_equal, kOperandIsASmiAndNotAFunction); 3848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(object); 3849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CmpObjectType(object, JS_FUNCTION_TYPE, object); 3850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pop(object); 3851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Check(equal, kOperandIsNotAFunction); 3852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::AssertBoundFunction(Register object) { 3857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (emit_debug_code()) { 3858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch testb(object, Immediate(kSmiTagMask)); 3859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Check(not_equal, kOperandIsASmiAndNotABoundFunction); 3860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(object); 3861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CmpObjectType(object, JS_BOUND_FUNCTION_TYPE, object); 3862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pop(object); 3863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Check(equal, kOperandIsNotABoundFunction); 3864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertUndefinedOrAllocationSite(Register object) { 3869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 3870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done_checking; 3871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertNotSmi(object); 3872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Cmp(object, isolate()->factory()->undefined_value()); 3873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(equal, &done_checking); 3874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Cmp(FieldOperand(object, 0), isolate()->factory()->allocation_site_map()); 3875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assert(equal, kExpectedUndefinedOrCell); 3876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&done_checking); 3877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3878e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 3879e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3880e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertRootValue(Register src, 3882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap::RootListIndex root_value_index, 3883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutReason reason) { 3884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 3885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src.is(kScratchRegister)); 3886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadRoot(kScratchRegister, root_value_index); 3887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(src, kScratchRegister); 3888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(equal, reason); 3889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 38909dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen} 38919dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 38929dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 38939dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 3894d91b9f7d46489a9ee00f9cb415630299c76a502bLeon ClarkeCondition MacroAssembler::IsObjectStringType(Register heap_object, 3895d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Register map, 3896d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Register instance_type) { 3897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(map, FieldOperand(heap_object, HeapObject::kMapOffset)); 38984515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke movzxbl(instance_type, FieldOperand(map, Map::kInstanceTypeOffset)); 389969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch STATIC_ASSERT(kNotStringTag != 0); 3900d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke testb(instance_type, Immediate(kIsNotStringMask)); 3901d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return zero; 3902d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 3903d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 3904d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 3905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochCondition MacroAssembler::IsObjectNameType(Register heap_object, 3906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register map, 3907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register instance_type) { 3908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(map, FieldOperand(heap_object, HeapObject::kMapOffset)); 3909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movzxbl(instance_type, FieldOperand(map, Map::kInstanceTypeOffset)); 3910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpb(instance_type, Immediate(static_cast<uint8_t>(LAST_NAME_TYPE))); 3911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return below_equal; 3912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::GetMapConstructor(Register result, Register map, 3916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register temp) { 3917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label done, loop; 3918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(result, FieldOperand(map, Map::kConstructorOrBackPointerOffset)); 3919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(&loop); 3920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JumpIfSmi(result, &done, Label::kNear); 3921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CmpObjectType(result, MAP_TYPE, temp); 3922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(not_equal, &done, Label::kNear); 3923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(result, FieldOperand(result, Map::kConstructorOrBackPointerOffset)); 3924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jmp(&loop); 3925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(&done); 3926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 39273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::TryGetFunctionPrototype(Register function, Register result, 3930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label* miss) { 3931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the prototype or initial map from the function. 3932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(result, 3933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); 3934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the prototype or initial map is the hole, don't return it and 3936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // simply miss the cache instead. This will allow us to allocate a 3937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // prototype object on-demand in the runtime system. 3938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompareRoot(result, Heap::kTheHoleValueRootIndex); 3939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block j(equal, miss); 3940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the function does not have an initial map, we're done. 3942257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label done; 3943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CmpObjectType(result, MAP_TYPE, kScratchRegister); 3944257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_equal, &done, Label::kNear); 3945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the prototype from the initial map. 3947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(result, FieldOperand(result, Map::kPrototypeOffset)); 3948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // All done. 3950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bind(&done); 3951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SetCounter(StatsCounter* counter, int value) { 3955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_native_code_counters && counter->Enabled()) { 395644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Operand counter_operand = ExternalOperand(ExternalReference(counter)); 39578b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch movl(counter_operand, Immediate(value)); 3958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::IncrementCounter(StatsCounter* counter, int value) { 3963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(value > 0); 3964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_native_code_counters && counter->Enabled()) { 396544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Operand counter_operand = ExternalOperand(ExternalReference(counter)); 3966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (value == 1) { 396744f0eee88ff00398ff7f715fab053374d808c90dSteve Block incl(counter_operand); 3968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 396944f0eee88ff00398ff7f715fab053374d808c90dSteve Block addl(counter_operand, Immediate(value)); 3970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3971a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::DecrementCounter(StatsCounter* counter, int value) { 3976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(value > 0); 3977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_native_code_counters && counter->Enabled()) { 397844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Operand counter_operand = ExternalOperand(ExternalReference(counter)); 3979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (value == 1) { 398044f0eee88ff00398ff7f715fab053374d808c90dSteve Block decl(counter_operand); 3981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 398244f0eee88ff00398ff7f715fab053374d808c90dSteve Block subl(counter_operand, Immediate(value)); 3983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3988402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuvoid MacroAssembler::DebugBreak() { 39899fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block Set(rax, 0); // No arguments. 3990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoadAddress(rbx, 3991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ExternalReference(Runtime::kHandleDebuggerStatement, isolate())); 3992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CEntryStub ces(isolate(), 1); 3993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(AllowThisStubCall(&ces)); 3994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Call(ces.GetCode(), RelocInfo::DEBUGGER_STATEMENT); 3995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::InvokeFunction(Register function, 3999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register new_target, 4000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& actual, 4001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InvokeFlag flag, 4002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const CallWrapper& call_wrapper) { 4003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(rbx, FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); 4004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoadSharedFunctionInfoSpecialField( 4005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch rbx, rbx, SharedFunctionInfo::kFormalParameterCountOffset); 4006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ParameterCount expected(rbx); 4008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InvokeFunction(function, new_target, expected, actual, flag, call_wrapper); 4009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 4010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::InvokeFunction(Handle<JSFunction> function, 4013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& expected, 4014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& actual, 4015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InvokeFlag flag, 4016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const CallWrapper& call_wrapper) { 4017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Move(rdi, function); 4018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InvokeFunction(rdi, no_reg, expected, actual, flag, call_wrapper); 4019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4020257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 4021257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 4022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::InvokeFunction(Register function, 4023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register new_target, 4024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& expected, 4025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& actual, 4026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InvokeFlag flag, 4027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const CallWrapper& call_wrapper) { 4028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(function.is(rdi)); 4029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(rsi, FieldOperand(function, JSFunction::kContextOffset)); 4030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InvokeFunctionCode(rdi, new_target, expected, actual, flag, call_wrapper); 4031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 4032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::InvokeFunctionCode(Register function, Register new_target, 4035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& expected, 4036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& actual, 4037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InvokeFlag flag, 4038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const CallWrapper& call_wrapper) { 40393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // You can't call a function without a valid frame. 4040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(flag == JUMP_FUNCTION || has_frame()); 4041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(function.is(rdi)); 4042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_IMPLIES(new_target.is_valid(), new_target.is(rdx)); 4043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (call_wrapper.NeedsDebugStepCheck()) { 4045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FloodFunctionIfStepping(function, new_target, expected, actual); 4046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Clear the new.target register if not given. 4049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!new_target.is_valid()) { 4050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoadRoot(rdx, Heap::kUndefinedValueRootIndex); 4051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 40523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4053257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label done; 40543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool definitely_mismatches = false; 4055e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch InvokePrologue(expected, 4056e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch actual, 4057e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch &done, 40583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch &definitely_mismatches, 4059e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch flag, 4060257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::kNear, 4061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch call_wrapper); 40623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!definitely_mismatches) { 4063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // We call indirectly through the code field in the function to 4064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // allow recompilation to take effect without changing any of the 4065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // call sites. 4066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand code = FieldOperand(function, JSFunction::kCodeEntryOffset); 40673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (flag == CALL_FUNCTION) { 40683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch call_wrapper.BeforeCall(CallSize(code)); 40693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch call(code); 40703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch call_wrapper.AfterCall(); 40713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 4072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(flag == JUMP_FUNCTION); 40733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch jmp(code); 40743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 40753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bind(&done); 4076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4080257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::InvokePrologue(const ParameterCount& expected, 4081257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch const ParameterCount& actual, 4082257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* done, 40833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool* definitely_mismatches, 4084257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch InvokeFlag flag, 4085257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump, 4086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const CallWrapper& call_wrapper) { 4087257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bool definitely_matches = false; 40883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *definitely_mismatches = false; 4089257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label invoke; 4090257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (expected.is_immediate()) { 4091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(actual.is_immediate()); 4092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(rax, actual.immediate()); 4093257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (expected.immediate() == actual.immediate()) { 4094257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch definitely_matches = true; 4095257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 4096257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (expected.immediate() == 4097257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch SharedFunctionInfo::kDontAdaptArgumentsSentinel) { 4098257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Don't worry about adapting arguments for built-ins that 4099257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // don't want that done. Skip adaption code by making it look 4100257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // like we have a match between expected and actual number of 4101257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // arguments. 4102257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch definitely_matches = true; 4103257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 41043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *definitely_mismatches = true; 4105257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Set(rbx, expected.immediate()); 4106257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 4107257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 4108257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 4109257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (actual.is_immediate()) { 4110257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Expected is in register, actual is immediate. This is the 4111257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // case when we invoke function values without going through the 4112257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // IC mechanism. 4113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(rax, actual.immediate()); 4114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(expected.reg(), Immediate(actual.immediate())); 4115257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(equal, &invoke, Label::kNear); 4116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(expected.reg().is(rbx)); 4117257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else if (!expected.reg().is(actual.reg())) { 4118257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Both expected and actual are in (different) registers. This 4119257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // is the case when we invoke functions using call and apply. 4120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(expected.reg(), actual.reg()); 4121257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(equal, &invoke, Label::kNear); 4122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(actual.reg().is(rax)); 4123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(expected.reg().is(rbx)); 4124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 4125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Move(rax, actual.reg()); 4126257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 4127257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 4128257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 4129257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!definitely_matches) { 4130257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<Code> adaptor = isolate()->builtins()->ArgumentsAdaptorTrampoline(); 4131257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (flag == CALL_FUNCTION) { 4132257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch call_wrapper.BeforeCall(CallSize(adaptor)); 4133257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Call(adaptor, RelocInfo::CODE_TARGET); 4134257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch call_wrapper.AfterCall(); 41353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!*definitely_mismatches) { 41363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch jmp(done, near_jump); 41373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4138257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 4139257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Jump(adaptor, RelocInfo::CODE_TARGET); 4140257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 4141257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&invoke); 41421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 4143402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu} 4144402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 4145402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 4146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::FloodFunctionIfStepping(Register fun, Register new_target, 4147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& expected, 4148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& actual) { 4149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label skip_flooding; 4150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ExternalReference step_in_enabled = 4151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ExternalReference::debug_step_in_enabled_address(isolate()); 4152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand step_in_enabled_operand = ExternalOperand(step_in_enabled); 4153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cmpb(step_in_enabled_operand, Immediate(0)); 4154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(equal, &skip_flooding); 4155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { 4156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FrameScope frame(this, 4157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch has_frame() ? StackFrame::NONE : StackFrame::INTERNAL); 4158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (expected.is_reg()) { 4159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Integer32ToSmi(expected.reg(), expected.reg()); 4160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(expected.reg()); 4161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (actual.is_reg()) { 4163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Integer32ToSmi(actual.reg(), actual.reg()); 4164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(actual.reg()); 4165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (new_target.is_valid()) { 4167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(new_target); 4168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(fun); 4170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(fun); 4171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallRuntime(Runtime::kDebugPrepareStepInIfStepping, 1); 4172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pop(fun); 4173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (new_target.is_valid()) { 4174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pop(new_target); 4175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (actual.is_reg()) { 4177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pop(actual.reg()); 4178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SmiToInteger64(actual.reg(), actual.reg()); 4179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (expected.is_reg()) { 4181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pop(expected.reg()); 4182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SmiToInteger64(expected.reg(), expected.reg()); 4183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(&skip_flooding); 4186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 4187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::StubPrologue() { 4190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pushq(rbp); // Caller's frame pointer. 4191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rbp, rsp); 4192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(rsi); // Callee's context. 4193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(Smi::FromInt(StackFrame::STUB)); 4194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Prologue(bool code_pre_aging) { 4198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PredictableCodeSizeScope predictible_code_size_scope(this, 4199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kNoCodeAgeSequenceLength); 4200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (code_pre_aging) { 4201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Pre-age the code. 4202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Call(isolate()->builtins()->MarkCodeAsExecutedOnce(), 4203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfo::CODE_AGE_SEQUENCE); 4204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Nop(kNoCodeAgeSequenceLength - Assembler::kShortCallInstructionLength); 4205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pushq(rbp); // Caller's frame pointer. 4207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rbp, rsp); 4208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(rsi); // Callee's context. 4209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(rdi); // Callee's JS function. 4210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::EmitLoadTypeFeedbackVector(Register vector) { 4215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(vector, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 4216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(vector, FieldOperand(vector, JSFunction::kSharedFunctionInfoOffset)); 4217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(vector, FieldOperand(vector, SharedFunctionInfo::kFeedbackVectorOffset)); 4218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 4219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4221958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid MacroAssembler::EnterFrame(StackFrame::Type type, 4222958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool load_constant_pool_pointer_reg) { 4223958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Out-of-line constant pool not implemented on x64. 4224958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNREACHABLE(); 4225958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 4226958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 4227958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 4228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::EnterFrame(StackFrame::Type type) { 4229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pushq(rbp); 4230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rbp, rsp); 4231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(rsi); // Context. 42323ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Push(Smi::FromInt(type)); 4233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); 4234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(kScratchRegister); 423544f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 4236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(kScratchRegister, 4237257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch isolate()->factory()->undefined_value(), 4238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfo::EMBEDDED_OBJECT); 4239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(Operand(rsp, 0), kScratchRegister); 4240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(not_equal, kCodeObjectNotProperlyPatched); 4241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::LeaveFrame(StackFrame::Type type) { 424644f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 42473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Move(kScratchRegister, Smi::FromInt(type)); 4248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(Operand(rbp, StandardFrameConstants::kMarkerOffset), kScratchRegister); 4249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(equal, kStackFrameTypesMustMatch); 4250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rsp, rbp); 4252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch popq(rbp); 4253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 425680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenvoid MacroAssembler::EnterExitFramePrologue(bool save_rax) { 42573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Set up the frame structure on the stack. 4258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // All constants are relative to the frame pointer of the exit frame. 4259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(ExitFrameConstants::kCallerSPDisplacement == 4260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kFPOnStackSize + kPCOnStackSize); 4261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(ExitFrameConstants::kCallerPCOffset == kFPOnStackSize); 4262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(ExitFrameConstants::kCallerFPOffset == 0 * kPointerSize); 4263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pushq(rbp); 4264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rbp, rsp); 4265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 426680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Reserve room for entry stack pointer and push the code object. 4267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(ExitFrameConstants::kSPOffset == -1 * kPointerSize); 4268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(Immediate(0)); // Saved entry sp, patched before call. 4269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); 4270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(kScratchRegister); // Accessed from EditFrame::code_slot. 4271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Save the frame pointer and the context in top. 4273bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch if (save_rax) { 4274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(r14, rax); // Backup rax in callee-save register. 4275bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } 4276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4277589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Store(ExternalReference(Isolate::kCEntryFPAddress, isolate()), rbp); 4278589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Store(ExternalReference(Isolate::kContextAddress, isolate()), rsi); 4279958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Store(ExternalReference(Isolate::kCFunctionAddress, isolate()), rbx); 4280bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch} 4281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 42828a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 42831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space, 42841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block bool save_doubles) { 4285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef _WIN64 42861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block const int kShadowSpace = 4; 42871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block arg_stack_space += kShadowSpace; 4288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 42891e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Optionally save all XMM registers. 42901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (save_doubles) { 4291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int space = XMMRegister::kMaxNumRegisters * kDoubleSize + 4292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch arg_stack_space * kRegisterSize; 4293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(rsp, Immediate(space)); 42941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block int offset = -2 * kPointerSize; 4295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const RegisterConfiguration* config = 4296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RegisterConfiguration::ArchDefault(RegisterConfiguration::CRANKSHAFT); 4297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < config->num_allocatable_double_registers(); ++i) { 4298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister reg = 4299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister::from_code(config->GetAllocatableDoubleCode(i)); 4300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movsd(Operand(rbp, offset - ((i + 1) * kDoubleSize)), reg); 43011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 43021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } else if (arg_stack_space > 0) { 4303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(rsp, Immediate(arg_stack_space * kRegisterSize)); 43048a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang } 4305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the required frame alignment for the OS. 4307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int kFrameAlignment = base::OS::ActivationFrameAlignment(); 4308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (kFrameAlignment > 0) { 4309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(base::bits::IsPowerOfTwo32(kFrameAlignment)); 4310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_int8(kFrameAlignment)); 4311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(rsp, Immediate(-kFrameAlignment)); 4312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Patch the saved entry sp. 4315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(rbp, ExitFrameConstants::kSPOffset), rsp); 4316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 43191e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::EnterExitFrame(int arg_stack_space, bool save_doubles) { 432080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen EnterExitFramePrologue(true); 4321bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 43223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Set up argv in callee-saved register r15. It is reused in LeaveExitFrame, 4323bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch // so it must be retained across the C-call. 4324bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; 4325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(r15, Operand(rbp, r14, times_pointer_size, offset)); 4326bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 43271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block EnterExitFrameEpilogue(arg_stack_space, save_doubles); 4328bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch} 4329bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 4330bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 43318a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wangvoid MacroAssembler::EnterApiExitFrame(int arg_stack_space) { 433280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen EnterExitFramePrologue(false); 43331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block EnterExitFrameEpilogue(arg_stack_space, false); 4334bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch} 4335bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 4336bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 4337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::LeaveExitFrame(bool save_doubles, bool pop_arguments) { 4338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Registers: 433944f0eee88ff00398ff7f715fab053374d808c90dSteve Block // r15 : argv 43401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (save_doubles) { 43411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block int offset = -2 * kPointerSize; 4342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const RegisterConfiguration* config = 4343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RegisterConfiguration::ArchDefault(RegisterConfiguration::CRANKSHAFT); 4344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < config->num_allocatable_double_registers(); ++i) { 4345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister reg = 4346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister::from_code(config->GetAllocatableDoubleCode(i)); 4347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movsd(reg, Operand(rbp, offset - ((i + 1) * kDoubleSize))); 43481e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 43491e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 4350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (pop_arguments) { 4352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Get the return address from the stack and restore the frame pointer. 4353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(rcx, Operand(rbp, kFPOnStackSize)); 4354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(rbp, Operand(rbp, 0 * kPointerSize)); 4355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Drop everything up to and including the arguments and the receiver 4357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // from the caller stack. 4358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch leap(rsp, Operand(r15, 1 * kPointerSize)); 4359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PushReturnAddressFrom(rcx); 4361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 4362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Otherwise just leave the exit frame. 4363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch leave(); 4364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 43658a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 4366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LeaveExitFrameEpilogue(true); 43678a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang} 43688a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 43698a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 4370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::LeaveApiExitFrame(bool restore_context) { 4371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rsp, rbp); 4372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch popq(rbp); 43738a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 4374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LeaveExitFrameEpilogue(restore_context); 43758a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang} 43768a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 43778a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 4378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::LeaveExitFrameEpilogue(bool restore_context) { 4379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Restore current context from top and clear it in debug mode. 4380589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch ExternalReference context_address(Isolate::kContextAddress, isolate()); 438144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Operand context_operand = ExternalOperand(context_address); 4382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (restore_context) { 4383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rsi, context_operand); 4384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 4386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(context_operand, Immediate(0)); 4387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 4388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear the top frame. 4390589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress, 439144f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate()); 439244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Operand c_entry_fp_operand = ExternalOperand(c_entry_fp_address); 4393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(c_entry_fp_operand, Immediate(0)); 4394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, 4398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch, 4399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label* miss) { 4400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label same_contexts; 4401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!holder_reg.is(scratch)); 4403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!scratch.is(kScratchRegister)); 4404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Load current lexical context from the stack frame. 4405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch, Operand(rbp, StandardFrameConstants::kContextOffset)); 4406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // When generating debug code, make sure the lexical context is set. 440844f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 4409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(scratch, Immediate(0)); 4410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(not_equal, kWeShouldNotHaveAnEmptyLexicalContext); 4411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load the native context of the current context. 4413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(scratch, ContextOperand(scratch, Context::NATIVE_CONTEXT_INDEX)); 4414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check the context is a native context. 441644f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 4417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Cmp(FieldOperand(scratch, HeapObject::kMapOffset), 4418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->factory()->native_context_map()); 4419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(equal, kJSGlobalObjectNativeContextShouldBeANativeContext); 4420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check if both contexts are the same. 4423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(scratch, FieldOperand(holder_reg, JSGlobalProxy::kNativeContextOffset)); 4424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block j(equal, &same_contexts); 4425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compare security tokens. 4427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that the security token in the calling global object is 4428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // compatible with the security token in the receiving global 4429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // object. 4430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check the context is a native context. 443244f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 4433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Preserve original value of holder_reg. 4434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(holder_reg); 4435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(holder_reg, 4436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FieldOperand(holder_reg, JSGlobalProxy::kNativeContextOffset)); 4437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompareRoot(holder_reg, Heap::kNullValueRootIndex); 4438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(not_equal, kJSGlobalProxyContextShouldNotBeNull); 4439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Read the first word and compare to native_context_map(), 4441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(holder_reg, FieldOperand(holder_reg, HeapObject::kMapOffset)); 4442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompareRoot(holder_reg, Heap::kNativeContextMapRootIndex); 4443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(equal, kJSGlobalObjectNativeContextShouldBeANativeContext); 4444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(holder_reg); 4445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, 4448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FieldOperand(holder_reg, JSGlobalProxy::kNativeContextOffset)); 44493ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int token_offset = 44503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Context::kHeaderSize + Context::SECURITY_TOKEN_INDEX * kPointerSize; 4451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch, FieldOperand(scratch, token_offset)); 4452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(scratch, FieldOperand(kScratchRegister, token_offset)); 4453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block j(not_equal, miss); 4454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bind(&same_contexts); 4456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Compute the hash code from the untagged key. This must be kept in sync with 4460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ComputeIntegerHash in utils.h and KeyedLoadGenericStub in 4461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// code-stub-hydrogen.cc 4462c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdochvoid MacroAssembler::GetNumberHash(Register r0, Register scratch) { 4463c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // First of all we assign the hash seed to scratch. 4464c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch LoadRoot(scratch, Heap::kHashSeedRootIndex); 4465c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch SmiToInteger32(scratch, scratch); 4466c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch 4467c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // Xor original key with a seed. 4468c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch xorl(r0, scratch); 4469c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch 4470c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // Compute the hash code from the untagged key. This must be kept in sync 4471c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // with ComputeIntegerHash in utils.h. 4472c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // 4473c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // hash = ~hash + (hash << 15); 4474c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch movl(scratch, r0); 4475c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch notl(r0); 4476c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch shll(scratch, Immediate(15)); 4477c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch addl(r0, scratch); 4478c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // hash = hash ^ (hash >> 12); 4479c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch movl(scratch, r0); 4480c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch shrl(scratch, Immediate(12)); 4481c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch xorl(r0, scratch); 4482c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // hash = hash + (hash << 2); 4483c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch leal(r0, Operand(r0, r0, times_4, 0)); 4484c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // hash = hash ^ (hash >> 4); 4485c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch movl(scratch, r0); 4486c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch shrl(scratch, Immediate(4)); 4487c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch xorl(r0, scratch); 4488c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // hash = hash * 2057; 4489c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch imull(r0, r0, Immediate(2057)); 4490c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // hash = hash ^ (hash >> 16); 4491c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch movl(scratch, r0); 4492c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch shrl(scratch, Immediate(16)); 4493c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch xorl(r0, scratch); 4494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch andl(r0, Immediate(0x3fffffff)); 4495c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch} 4496c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch 4497c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch 4498c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch 44993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid MacroAssembler::LoadFromNumberDictionary(Label* miss, 45003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Register elements, 45013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Register key, 45023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Register r0, 45033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Register r1, 45043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Register r2, 45053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Register result) { 45063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Register use: 45073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // 45083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // elements - holds the slow-case elements of the receiver on entry. 45093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Unchanged unless 'result' is the same register. 45103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // 45113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // key - holds the smi key on entry. 45123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Unchanged unless 'result' is the same register. 45133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // 45143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Scratch registers: 45153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // 45163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // r0 - holds the untagged key on entry and holds the hash once computed. 45173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // 45183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // r1 - used to hold the capacity mask of the dictionary 45193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // 45203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // r2 - used for the index into the dictionary. 45213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // 45223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // result - holds the result on exit if the load succeeded. 45233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Allowed to be the same as 'key' or 'result'. 45243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Unchanged on bailout so 'key' or 'result' can be used 45253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // in further computation. 45263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 45273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Label done; 45283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4529c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch GetNumberHash(r0, r1); 45303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 45313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Compute capacity mask. 4532c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch SmiToInteger32(r1, FieldOperand(elements, 4533c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch SeededNumberDictionary::kCapacityOffset)); 45343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch decl(r1); 45353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 45363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Generate an unrolled loop that performs a few probes before giving up. 4537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < kNumberDictionaryProbes; i++) { 45383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Use r2 for index calculations and keep the hash intact in r0. 4539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(r2, r0); 45403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Compute the masked index: (hash + i + i * i) & mask. 45413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (i > 0) { 4542c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch addl(r2, Immediate(SeededNumberDictionary::GetProbeOffset(i))); 45433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 4544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(r2, r1); 45453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 45463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Scale the index by multiplying by the entry size. 4547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SeededNumberDictionary::kEntrySize == 3); 4548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(r2, Operand(r2, r2, times_2, 0)); // r2 = r2 * 3 45493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 45503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Check if the key matches. 4551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(key, FieldOperand(elements, 45523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch r2, 45533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch times_pointer_size, 4554c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch SeededNumberDictionary::kElementsStartOffset)); 4555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (i != (kNumberDictionaryProbes - 1)) { 45563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch j(equal, &done); 45573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 45583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch j(not_equal, miss); 45593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 45603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 45613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 45623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bind(&done); 4563958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Check that the value is a field property. 45643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const int kDetailsOffset = 4565c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch SeededNumberDictionary::kElementsStartOffset + 2 * kPointerSize; 4566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(DATA, 0); 45673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset), 4568589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Smi::FromInt(PropertyDetails::TypeField::kMask)); 45693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch j(not_zero, miss); 45703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 45713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Get the value at the masked, scaled index. 45723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const int kValueOffset = 4573c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch SeededNumberDictionary::kElementsStartOffset + kPointerSize; 4574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(result, FieldOperand(elements, r2, times_pointer_size, kValueOffset)); 45753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 45763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 45773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::LoadAllocationTopHelper(Register result, 4579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch, 4580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AllocationFlags flags) { 4581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference allocation_top = 4582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationUtils::GetAllocationTopReference(isolate(), flags); 4583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Just return if allocation top is already known. 4585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if ((flags & RESULT_CONTAINS_TOP) != 0) { 4586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // No use of scratch if allocation top is provided. 4587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!scratch.is_valid()); 4588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 4589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Assert that result actually contains top on entry. 4590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand top_operand = ExternalOperand(allocation_top); 4591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(result, top_operand); 4592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(equal, kUnexpectedAllocationTop); 4593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 4594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 4595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 45976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Move address of new object to result. Use scratch register if available, 45986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // and keep address in scratch until call to UpdateAllocationTopHelper. 45996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (scratch.is_valid()) { 4600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadAddress(scratch, allocation_top); 4601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(result, Operand(scratch, 0)); 4602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Load(result, allocation_top); 4604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::MakeSureDoubleAlignedHelper(Register result, 4609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 4610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required, 4611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationFlags flags) { 4612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (kPointerSize == kDoubleSize) { 4613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_debug_code) { 4614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testl(result, Immediate(kDoubleAlignmentMask)); 4615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(zero, kAllocationIsNotDoubleAligned); 4616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 46176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } else { 4618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Align the next allocation. Storing the filler map without checking top 4619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // is safe in new-space because the limit of the heap is aligned there. 4620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(kPointerSize * 2 == kDoubleSize); 4621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(kPointerAlignment * 2 == kDoubleAlignment); 4622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Make sure scratch is not clobbered by this function as it might be 4623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // used in UpdateAllocationTopHelper later. 4624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!scratch.is(kScratchRegister)); 4625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label aligned; 4626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testl(result, Immediate(kDoubleAlignmentMask)); 4627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(zero, &aligned, Label::kNear); 4628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if ((flags & PRETENURE) != 0) { 4629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference allocation_limit = 4630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationUtils::GetAllocationLimitReference(isolate(), flags); 4631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(result, ExternalOperand(allocation_limit)); 4632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(above_equal, gc_required); 4633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadRoot(kScratchRegister, Heap::kOnePointerFillerMapRootIndex); 4635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(result, 0), kScratchRegister); 4636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(result, Immediate(kDoubleSize / 2)); 4637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&aligned); 4638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::UpdateAllocationTopHelper(Register result_end, 4643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 4644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationFlags flags) { 464544f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 4646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(result_end, Immediate(kObjectAlignmentMask)); 4647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(zero, kUnalignedAllocationInNewSpace); 4648d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 4649d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 4650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference allocation_top = 4651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationUtils::GetAllocationTopReference(isolate(), flags); 4652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Update new top. 465444f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (scratch.is_valid()) { 465544f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Scratch already contains address of allocation top. 4656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(scratch, 0), result_end); 4657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 4658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Store(allocation_top, result_end); 4659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Allocate(int object_size, 4664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register result, 4665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register result_end, 4666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 4667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required, 4668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationFlags flags) { 4669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0); 4670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(object_size <= Page::kMaxRegularHeapObjectSize); 46715913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck if (!FLAG_inline_new) { 467244f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 46735913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck // Trash the registers to simulate an allocation failure. 46745913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck movl(result, Immediate(0x7091)); 46755913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck if (result_end.is_valid()) { 46765913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck movl(result_end, Immediate(0x7191)); 46775913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } 46785913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck if (scratch.is_valid()) { 46795913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck movl(scratch, Immediate(0x7291)); 46805913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } 46815913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } 46825913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck jmp(gc_required); 46835913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck return; 46845913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } 4685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!result.is(result_end)); 4686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Load address of new object into result. 46888a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang LoadAllocationTopHelper(result, scratch, flags); 4689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((flags & DOUBLE_ALIGNMENT) != 0) { 4691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MakeSureDoubleAlignedHelper(result, scratch, gc_required, flags); 4692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Calculate new top and bail out if new space is exhausted. 4695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference allocation_limit = 4696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationUtils::GetAllocationLimitReference(isolate(), flags); 46976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 46986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Register top_reg = result_end.is_valid() ? result_end : result; 46996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 47001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (!top_reg.is(result)) { 4701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(top_reg, result); 47026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 4703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(top_reg, Immediate(object_size)); 47041e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block j(carry, gc_required); 4705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand limit_operand = ExternalOperand(allocation_limit); 4706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(top_reg, limit_operand); 4707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block j(above, gc_required); 4708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Update allocation top. 4710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UpdateAllocationTopHelper(top_reg, scratch, flags); 4711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool tag_result = (flags & TAG_OBJECT) != 0; 47136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (top_reg.is(result)) { 4714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (tag_result) { 4715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(result, Immediate(object_size - kHeapObjectTag)); 47166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } else { 4717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(result, Immediate(object_size)); 47186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 4719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (tag_result) { 47206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Tag the result if requested. 4721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(kHeapObjectTag == 1); 4722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch incp(result); 4723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Allocate(int header_size, 4728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ScaleFactor element_size, 4729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register element_count, 4730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register result, 4731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register result_end, 4732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 4733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required, 4734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationFlags flags) { 4735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((flags & SIZE_IN_WORDS) == 0); 4736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(result_end, Operand(element_count, element_size, header_size)); 4737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Allocate(result_end, result, result_end, scratch, gc_required, flags); 4738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Allocate(Register object_size, 4742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register result, 4743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register result_end, 4744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 4745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required, 4746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationFlags flags) { 4747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((flags & SIZE_IN_WORDS) == 0); 47485913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck if (!FLAG_inline_new) { 474944f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 47505913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck // Trash the registers to simulate an allocation failure. 47515913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck movl(result, Immediate(0x7091)); 47525913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck movl(result_end, Immediate(0x7191)); 47535913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck if (scratch.is_valid()) { 47545913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck movl(scratch, Immediate(0x7291)); 47555913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } 47565913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck // object_size is left unchanged by this function. 47575913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } 47585913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck jmp(gc_required); 47595913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck return; 47605913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } 4761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!result.is(result_end)); 47625913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck 4763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Load address of new object into result. 47648a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang LoadAllocationTopHelper(result, scratch, flags); 4765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((flags & DOUBLE_ALIGNMENT) != 0) { 4767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MakeSureDoubleAlignedHelper(result, scratch, gc_required, flags); 4768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Calculate new top and bail out if new space is exhausted. 4771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference allocation_limit = 4772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationUtils::GetAllocationLimitReference(isolate(), flags); 4773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!object_size.is(result_end)) { 4774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(result_end, object_size); 4775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(result_end, result); 47771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block j(carry, gc_required); 4778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand limit_operand = ExternalOperand(allocation_limit); 4779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(result_end, limit_operand); 4780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block j(above, gc_required); 4781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Update allocation top. 4783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UpdateAllocationTopHelper(result_end, scratch, flags); 4784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Tag the result if requested. 4786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if ((flags & TAG_OBJECT) != 0) { 4787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(result, Immediate(kHeapObjectTag)); 4788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 47923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::AllocateHeapNumber(Register result, 47933ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Register scratch, 4794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required, 4795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MutableMode mode) { 47963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Allocate heap number in new space. 4797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Allocate(HeapNumber::kSize, result, scratch, no_reg, gc_required, TAG_OBJECT); 4798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap::RootListIndex map_index = mode == MUTABLE 4800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? Heap::kMutableHeapNumberMapRootIndex 4801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : Heap::kHeapNumberMapRootIndex; 48023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 48033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Set the map. 4804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadRoot(kScratchRegister, map_index); 4805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); 48063ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 48073ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 48083ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 4809e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid MacroAssembler::AllocateTwoByteString(Register result, 4810e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Register length, 4811e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Register scratch1, 4812e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Register scratch2, 4813e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Register scratch3, 4814e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Label* gc_required) { 4815e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Calculate the number of bytes needed for the characters in the string while 4816e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // observing object alignment. 48176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block const int kHeaderAlignment = SeqTwoByteString::kHeaderSize & 48186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block kObjectAlignmentMask; 4819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(kShortSize == 2); 4820e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // scratch1 = length * 2 + kObjectAlignmentMask. 4821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(scratch1, Operand(length, length, times_1, kObjectAlignmentMask + 48226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block kHeaderAlignment)); 4823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(scratch1, Immediate(~kObjectAlignmentMask)); 48246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (kHeaderAlignment > 0) { 4825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(scratch1, Immediate(kHeaderAlignment)); 48266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 4827e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 4828e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Allocate two byte string in new space. 4829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Allocate(SeqTwoByteString::kHeaderSize, 4830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch times_1, 4831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch scratch1, 4832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result, 4833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch scratch2, 4834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch scratch3, 4835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch gc_required, 4836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TAG_OBJECT); 4837e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 4838e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Set the map, length and hash field. 4839e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke LoadRoot(kScratchRegister, Heap::kStringMapRootIndex); 4840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); 48416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Integer32ToSmi(scratch1, length); 4842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(FieldOperand(result, String::kLengthOffset), scratch1); 4843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(FieldOperand(result, String::kHashFieldOffset), 4844e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Immediate(String::kEmptyHashField)); 4845e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 4846e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 4847e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 4848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AllocateOneByteString(Register result, Register length, 4849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, Register scratch2, 4850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch3, 4851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required) { 4852e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Calculate the number of bytes needed for the characters in the string while 4853e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // observing object alignment. 4854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int kHeaderAlignment = SeqOneByteString::kHeaderSize & 48556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block kObjectAlignmentMask; 4856e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke movl(scratch1, length); 4857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(kCharSize == 1); 4858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(scratch1, Immediate(kObjectAlignmentMask + kHeaderAlignment)); 4859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(scratch1, Immediate(~kObjectAlignmentMask)); 48606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (kHeaderAlignment > 0) { 4861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(scratch1, Immediate(kHeaderAlignment)); 48626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 4863e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 4864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate one-byte string in new space. 4865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Allocate(SeqOneByteString::kHeaderSize, 4866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch times_1, 4867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch scratch1, 4868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result, 4869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch scratch2, 4870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch scratch3, 4871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch gc_required, 4872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TAG_OBJECT); 4873e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 4874e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Set the map, length and hash field. 4875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadRoot(kScratchRegister, Heap::kOneByteStringMapRootIndex); 4876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); 48776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Integer32ToSmi(scratch1, length); 4878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(FieldOperand(result, String::kLengthOffset), scratch1); 4879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(FieldOperand(result, String::kHashFieldOffset), 4880e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Immediate(String::kEmptyHashField)); 4881e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 4882e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 4883e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 4884589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochvoid MacroAssembler::AllocateTwoByteConsString(Register result, 4885e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Register scratch1, 4886e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Register scratch2, 4887e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Label* gc_required) { 4888e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Allocate heap number in new space. 4889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, 4890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TAG_OBJECT); 4891e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 4892e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Set the map. The other fields are left uninitialized. 4893e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke LoadRoot(kScratchRegister, Heap::kConsStringMapRootIndex); 4894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); 4895e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 4896e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 4897e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 4898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AllocateOneByteConsString(Register result, 4899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, 4900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch2, 4901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required) { 4902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Allocate(ConsString::kSize, 4903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result, 4904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch scratch1, 4905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch scratch2, 4906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch gc_required, 4907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TAG_OBJECT); 4908e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 4909e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Set the map. The other fields are left uninitialized. 4910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadRoot(kScratchRegister, Heap::kConsOneByteStringMapRootIndex); 4911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); 4912e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 4913e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 4914e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 4915589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochvoid MacroAssembler::AllocateTwoByteSlicedString(Register result, 4916589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Register scratch1, 4917589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Register scratch2, 4918589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Label* gc_required) { 4919589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Allocate heap number in new space. 4920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, 4921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TAG_OBJECT); 4922589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 4923589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Set the map. The other fields are left uninitialized. 4924589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch LoadRoot(kScratchRegister, Heap::kSlicedStringMapRootIndex); 4925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); 4926589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch} 4927589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 4928589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 4929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AllocateOneByteSlicedString(Register result, 4930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, 4931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch2, 4932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required) { 4933589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Allocate heap number in new space. 4934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, 4935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TAG_OBJECT); 4936589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 4937589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Set the map. The other fields are left uninitialized. 4938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadRoot(kScratchRegister, Heap::kSlicedOneByteStringMapRootIndex); 4939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); 4940589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch} 4941589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 4942589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 4943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::AllocateJSValue(Register result, Register constructor, 4944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register value, Register scratch, 4945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label* gc_required) { 4946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!result.is(constructor)); 4947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!result.is(scratch)); 4948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!result.is(value)); 4949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Allocate JSValue in new space. 4951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Allocate(JSValue::kSize, result, scratch, no_reg, gc_required, TAG_OBJECT); 4952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Initialize the JSValue. 4954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoadGlobalFunctionInitialMap(constructor, scratch); 4955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(FieldOperand(result, HeapObject::kMapOffset), scratch); 4956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoadRoot(scratch, Heap::kEmptyFixedArrayRootIndex); 4957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(FieldOperand(result, JSObject::kPropertiesOffset), scratch); 4958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(FieldOperand(result, JSObject::kElementsOffset), scratch); 4959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(FieldOperand(result, JSValue::kValueOffset), value); 4960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); 4961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 4962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 496444f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Copy memory, byte-by-byte, from source to destination. Not optimized for 496544f0eee88ff00398ff7f715fab053374d808c90dSteve Block// long or aligned copies. The contents of scratch and length are destroyed. 496644f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Destination is incremented by length, source, length and scratch are 496744f0eee88ff00398ff7f715fab053374d808c90dSteve Block// clobbered. 496844f0eee88ff00398ff7f715fab053374d808c90dSteve Block// A simpler loop is faster on small copies, but slower on large ones. 496944f0eee88ff00398ff7f715fab053374d808c90dSteve Block// The cld() instruction must have been emitted, to set the direction flag(), 497044f0eee88ff00398ff7f715fab053374d808c90dSteve Block// before calling this function. 497144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid MacroAssembler::CopyBytes(Register destination, 497244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register source, 497344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register length, 497444f0eee88ff00398ff7f715fab053374d808c90dSteve Block int min_length, 497544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register scratch) { 4976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(min_length >= 0); 4977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 497844f0eee88ff00398ff7f715fab053374d808c90dSteve Block cmpl(length, Immediate(min_length)); 4979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assert(greater_equal, kInvalidMinLength); 498044f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 4981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label short_loop, len8, len16, len24, done, short_string; 498244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 4983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int kLongStringLimit = 4 * kPointerSize; 498444f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (min_length <= kLongStringLimit) { 4985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpl(length, Immediate(kPointerSize)); 4986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(below, &short_string, Label::kNear); 498744f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 498844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 4989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(source.is(rsi)); 4990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(destination.is(rdi)); 4991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(length.is(rcx)); 4992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (min_length <= kLongStringLimit) { 4994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpl(length, Immediate(2 * kPointerSize)); 4995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(below_equal, &len8, Label::kNear); 4996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpl(length, Immediate(3 * kPointerSize)); 4997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(below_equal, &len16, Label::kNear); 4998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpl(length, Immediate(4 * kPointerSize)); 4999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(below_equal, &len24, Label::kNear); 5000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 500144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 500244f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Because source is 8-byte aligned in our uses of this function, 500344f0eee88ff00398ff7f715fab053374d808c90dSteve Block // we keep source aligned for the rep movs operation by copying the odd bytes 500444f0eee88ff00398ff7f715fab053374d808c90dSteve Block // at the end of the ranges. 5005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch, length); 5006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shrl(length, Immediate(kPointerSizeLog2)); 5007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch repmovsp(); 500844f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Move remaining bytes of length. 5009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andl(scratch, Immediate(kPointerSize - 1)); 5010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(length, Operand(source, scratch, times_1, -kPointerSize)); 5011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(destination, scratch, times_1, -kPointerSize), length); 5012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(destination, scratch); 501344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 501444f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (min_length <= kLongStringLimit) { 5015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jmp(&done, Label::kNear); 5016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&len24); 5017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch, Operand(source, 2 * kPointerSize)); 5018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(destination, 2 * kPointerSize), scratch); 5019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&len16); 5020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch, Operand(source, kPointerSize)); 5021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(destination, kPointerSize), scratch); 5022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&len8); 5023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch, Operand(source, 0)); 5024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(destination, 0), scratch); 5025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Move remaining bytes of length. 5026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch, Operand(source, length, times_1, -kPointerSize)); 5027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(destination, length, times_1, -kPointerSize), scratch); 5028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(destination, length); 5029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jmp(&done, Label::kNear); 503044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 503144f0eee88ff00398ff7f715fab053374d808c90dSteve Block bind(&short_string); 503244f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (min_length == 0) { 503344f0eee88ff00398ff7f715fab053374d808c90dSteve Block testl(length, length); 5034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(zero, &done, Label::kNear); 503544f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 503644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 503744f0eee88ff00398ff7f715fab053374d808c90dSteve Block bind(&short_loop); 5038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movb(scratch, Operand(source, 0)); 5039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movb(Operand(destination, 0), scratch); 5040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch incp(source); 5041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch incp(destination); 5042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch decl(length); 5043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(not_zero, &short_loop); 504444f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 5045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&done); 504744f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 504844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 504944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 5050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::InitializeFieldsWithFiller(Register current_address, 5051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register end_address, 50523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register filler) { 50533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label loop, entry; 50543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch jmp(&entry); 50553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bind(&loop); 5056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(Operand(current_address, 0), filler); 5057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch addp(current_address, Immediate(kPointerSize)); 50583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bind(&entry); 5059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cmpp(current_address, end_address); 5060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(below, &loop); 50613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 50623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 50633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5064d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockvoid MacroAssembler::LoadContext(Register dst, int context_chain_length) { 5065d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (context_chain_length > 0) { 5066d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Move up the chain of contexts to the context containing the slot. 5067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, Operand(rsi, Context::SlotOffset(Context::PREVIOUS_INDEX))); 5068d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block for (int i = 1; i < context_chain_length; i++) { 5069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, Operand(dst, Context::SlotOffset(Context::PREVIOUS_INDEX))); 5070d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 5071e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else { 5072e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Slot is in the current function context. Move it into the 5073e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // destination register in case we store into it (the write barrier 5074e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // cannot be allowed to destroy the context in rsi). 5075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, rsi); 5076e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 5077e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 50783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // We should not have found a with context by walking the context 50793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // chain (i.e., the static scope chain and runtime context chain do 50803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // not agree). A variable occurring in such a scope should have 50813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // slot type LOOKUP and not CONTEXT. 508244f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 50833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CompareRoot(FieldOperand(dst, HeapObject::kMapOffset), 50843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Heap::kWithContextMapRootIndex); 5085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(not_equal, kVariableResolvedToWithContext); 5086d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 5087d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 5088d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 50893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 50903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::LoadTransitionedArrayMapConditional( 50913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKind expected_kind, 50923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKind transitioned_kind, 50933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register map_in_out, 50943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch, 50953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* no_map_match) { 5096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsFastElementsKind(expected_kind)); 5097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsFastElementsKind(transitioned_kind)); 50983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 50993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check that the function's map is the same as the expected cached map. 5100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(scratch, NativeContextOperand()); 5101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cmpp(map_in_out, 5102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ContextOperand(scratch, Context::ArrayMapIndex(expected_kind))); 51033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(not_equal, no_map_match); 51043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 51053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Use the transitioned cached map. 5106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(map_in_out, 5107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ContextOperand(scratch, Context::ArrayMapIndex(transitioned_kind))); 51083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 51093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 51103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 511144f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef _WIN64 511244f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic const int kRegisterPassedArguments = 4; 511344f0eee88ff00398ff7f715fab053374d808c90dSteve Block#else 511444f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic const int kRegisterPassedArguments = 6; 511544f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 51167f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 5118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::LoadNativeContextSlot(int index, Register dst) { 5119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(dst, NativeContextOperand()); 5120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(dst, ContextOperand(dst, index)); 5121b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 5122b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 5123b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 5124b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid MacroAssembler::LoadGlobalFunctionInitialMap(Register function, 5125b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Register map) { 5126b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Load the initial map. The global functions all have initial maps. 5127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(map, FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); 512844f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 5129b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Label ok, fail; 5130257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CheckMap(map, isolate()->factory()->meta_map(), &fail, DO_SMI_CHECK); 5131b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch jmp(&ok); 5132b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bind(&fail); 5133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Abort(kGlobalFunctionsMustHaveInitialMap); 5134b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bind(&ok); 5135b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 5136b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 5137b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 5138b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 51394515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkeint MacroAssembler::ArgumentStackSlotsForCFunctionCall(int num_arguments) { 51407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // On Windows 64 stack slots are reserved by the caller for all arguments 51417f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // including the ones passed in registers, and space is always allocated for 51427f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // the four register arguments even if the function takes fewer than four 51437f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // arguments. 51447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // On AMD64 ABI (Linux/Mac) the first six arguments are passed in registers 51457f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // and the caller does not reserve stack slots for them. 5146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(num_arguments >= 0); 51474515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke#ifdef _WIN64 514844f0eee88ff00398ff7f715fab053374d808c90dSteve Block const int kMinimumStackSlots = kRegisterPassedArguments; 51497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (num_arguments < kMinimumStackSlots) return kMinimumStackSlots; 51507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch return num_arguments; 51514515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke#else 51527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (num_arguments < kRegisterPassedArguments) return 0; 51537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch return num_arguments - kRegisterPassedArguments; 51544515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke#endif 51554515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke} 51564515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 51577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::EmitSeqStringSetCharCheck(Register string, 5159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register index, 5160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register value, 5161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t encoding_mask) { 5162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label is_object; 5163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JumpIfNotSmi(string, &is_object); 5164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Abort(kNonObject); 5165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&is_object); 5166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(value); 5168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(value, FieldOperand(string, HeapObject::kMapOffset)); 5169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movzxbp(value, FieldOperand(value, Map::kInstanceTypeOffset)); 5170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andb(value, Immediate(kStringRepresentationMask | kStringEncodingMask)); 5172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(value, Immediate(encoding_mask)); 5173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(value); 5174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(equal, kUnexpectedStringType); 5175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The index is assumed to be untagged coming in, tag it to compare with the 5177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // string length without using a temp register, it is restored at the end of 5178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // this function. 5179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Integer32ToSmi(index, index); 5180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiCompare(index, FieldOperand(string, String::kLengthOffset)); 5181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(less, kIndexIsTooLarge); 5182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiCompare(index, Smi::FromInt(0)); 5184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(greater_equal, kIndexIsNegative); 5185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Restore the index 5187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(index, index); 5188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 51914515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkevoid MacroAssembler::PrepareCallCFunction(int num_arguments) { 5192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int frame_alignment = base::OS::ActivationFrameAlignment(); 5193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(frame_alignment != 0); 5194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(num_arguments >= 0); 519544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 51964515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // Make stack end at alignment and allocate space for arguments and old rsp. 5197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, rsp); 5198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(base::bits::IsPowerOfTwo32(frame_alignment)); 51994515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke int argument_slots_on_stack = 52004515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke ArgumentStackSlotsForCFunctionCall(num_arguments); 5201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(rsp, Immediate((argument_slots_on_stack + 1) * kRegisterSize)); 5202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(rsp, Immediate(-frame_alignment)); 5203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(rsp, argument_slots_on_stack * kRegisterSize), kScratchRegister); 52044515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke} 52054515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 52064515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 52074515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkevoid MacroAssembler::CallCFunction(ExternalReference function, 52084515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke int num_arguments) { 520944f0eee88ff00398ff7f715fab053374d808c90dSteve Block LoadAddress(rax, function); 52104515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke CallCFunction(rax, num_arguments); 52114515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke} 52124515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 52134515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 52144515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkevoid MacroAssembler::CallCFunction(Register function, int num_arguments) { 5215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(has_frame()); 52166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Check stack alignment. 521744f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 52186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CheckStackAlignment(); 52196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 52206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 52214515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke call(function); 5222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(base::OS::ActivationFrameAlignment() != 0); 5223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(num_arguments >= 0); 52244515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke int argument_slots_on_stack = 52254515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke ArgumentStackSlotsForCFunctionCall(num_arguments); 5226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rsp, Operand(rsp, argument_slots_on_stack * kRegisterSize)); 52274515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke} 52284515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 5229d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 5230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 5231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool AreAliased(Register reg1, 5232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg2, 5233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg3, 5234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg4, 5235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg5, 5236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg6, 5237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg7, 5238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg8) { 5239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int n_of_valid_regs = reg1.is_valid() + reg2.is_valid() + 5240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reg3.is_valid() + reg4.is_valid() + reg5.is_valid() + reg6.is_valid() + 5241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reg7.is_valid() + reg8.is_valid(); 5242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RegList regs = 0; 5244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reg1.is_valid()) regs |= reg1.bit(); 5245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reg2.is_valid()) regs |= reg2.bit(); 5246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reg3.is_valid()) regs |= reg3.bit(); 5247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reg4.is_valid()) regs |= reg4.bit(); 5248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reg5.is_valid()) regs |= reg5.bit(); 5249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reg6.is_valid()) regs |= reg6.bit(); 5250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reg7.is_valid()) regs |= reg7.bit(); 5251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reg8.is_valid()) regs |= reg8.bit(); 5252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int n_of_non_aliasing_regs = NumRegs(regs); 5253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return n_of_valid_regs != n_of_non_aliasing_regs; 52553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 5256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 52573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 52583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochCodePatcher::CodePatcher(Isolate* isolate, byte* address, int size) 52608b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch : address_(address), 52618b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch size_(size), 5262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch masm_(isolate, address, size + Assembler::kGap, CodeObjectRequired::kNo) { 5263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a new macro assembler pointing to the address of the code to patch. 5264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The size is adjusted with kGap on order for the assembler to generate size 5265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // bytes of instructions without failing with buffer size constraints. 5266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 5267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCodePatcher::~CodePatcher() { 5271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Indicate that code has changed. 5272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Assembler::FlushICache(masm_.isolate(), address_, size_); 5273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that the code was patched as expected. 5275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(masm_.pc_ == address_ + size_); 5276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 5277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 52793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 52803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::CheckPageFlag( 52813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register object, 52823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch, 52833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int mask, 52843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Condition cc, 52853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* condition_met, 52863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label::Distance condition_met_distance) { 5287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(cc == zero || cc == not_zero); 52883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (scratch.is(object)) { 5289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(scratch, Immediate(~Page::kPageAlignmentMask)); 52903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 5291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch, Immediate(~Page::kPageAlignmentMask)); 5292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(scratch, object); 52933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 52943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (mask < (1 << kBitsPerByte)) { 52953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch testb(Operand(scratch, MemoryChunk::kFlagsOffset), 52963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Immediate(static_cast<uint8_t>(mask))); 52973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 52983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch testl(Operand(scratch, MemoryChunk::kFlagsOffset), Immediate(mask)); 52993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 53003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(cc, condition_met, condition_met_distance); 53013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 53023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 53033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 53043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::JumpIfBlack(Register object, 53053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register bitmap_scratch, 53063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register mask_scratch, 53073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* on_black, 53083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label::Distance on_black_distance) { 5309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!AreAliased(object, bitmap_scratch, mask_scratch, rcx)); 5310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 53113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GetMarkBits(object, bitmap_scratch, mask_scratch); 53123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(strcmp(Marking::kBlackBitPattern, "11") == 0); 53143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // The mask_scratch register contains a 1 at the position of the first bit 5315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // and a 1 at a position of the second bit. All other positions are zero. 5316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rcx, mask_scratch); 5317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(rcx, Operand(bitmap_scratch, MemoryChunk::kHeaderSize)); 5318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(mask_scratch, rcx); 53193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(equal, on_black, on_black_distance); 53203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 53213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 53223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 53233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::GetMarkBits(Register addr_reg, 53243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register bitmap_reg, 53253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register mask_reg) { 5326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!AreAliased(addr_reg, bitmap_reg, mask_reg, rcx)); 5327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(bitmap_reg, addr_reg); 53283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Sign extended 32 bit immediate. 5329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(bitmap_reg, Immediate(~Page::kPageAlignmentMask)); 5330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rcx, addr_reg); 53313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int shift = 53323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Bitmap::kBitsPerCellLog2 + kPointerSizeLog2 - Bitmap::kBytesPerCellLog2; 53333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch shrl(rcx, Immediate(shift)); 5334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(rcx, 53353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Immediate((Page::kPageAlignmentMask >> shift) & 53363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ~(Bitmap::kBytesPerCell - 1))); 53373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(bitmap_reg, rcx); 5339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rcx, addr_reg); 53403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch shrl(rcx, Immediate(kPointerSizeLog2)); 5341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(rcx, Immediate((1 << Bitmap::kBitsPerCellLog2) - 1)); 5342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movl(mask_reg, Immediate(3)); 5343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlp_cl(mask_reg); 53443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 53453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 53463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::JumpIfWhite(Register value, Register bitmap_scratch, 5348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register mask_scratch, Label* value_is_white, 5349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label::Distance distance) { 5350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!AreAliased(value, bitmap_scratch, mask_scratch, rcx)); 53513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GetMarkBits(value, bitmap_scratch, mask_scratch); 53523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 53533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // If the value is black or grey we don't need to do anything. 5354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(strcmp(Marking::kWhiteBitPattern, "00") == 0); 5355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(strcmp(Marking::kBlackBitPattern, "11") == 0); 5356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(strcmp(Marking::kGreyBitPattern, "10") == 0); 5357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(strcmp(Marking::kImpossibleBitPattern, "01") == 0); 53583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 53593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Since both black and grey have a 1 in the first position and white does 53603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // not have a 1 there we only need to check one bit. 5361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(Operand(bitmap_scratch, MemoryChunk::kHeaderSize), mask_scratch); 5362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(zero, value_is_white, distance); 53633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 53643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 53653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 53663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::CheckEnumCache(Register null_value, Label* call_runtime) { 5367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label next, start; 53683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register empty_fixed_array_value = r8; 53693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LoadRoot(empty_fixed_array_value, Heap::kEmptyFixedArrayRootIndex); 5370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rcx, rax); 5371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if the enum length field is properly initialized, indicating that 5373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // there is an enum cache. 5374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rbx, FieldOperand(rcx, HeapObject::kMapOffset)); 5375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EnumLength(rdx, rbx); 5377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Cmp(rdx, Smi::FromInt(kInvalidEnumCacheSentinel)); 5378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(equal, call_runtime); 5379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jmp(&start); 5381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 53823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bind(&next); 53833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rbx, FieldOperand(rcx, HeapObject::kMapOffset)); 5385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // For all objects but the receiver, check that the cache is empty. 5387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EnumLength(rdx, rbx); 5388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Cmp(rdx, Smi::FromInt(0)); 53893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(not_equal, call_runtime); 53903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&start); 53923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check that there are no elements. Register rcx contains the current JS 5394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // object we've reached through the prototype chain. 5395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label no_elements; 5396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(empty_fixed_array_value, 5397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FieldOperand(rcx, JSObject::kElementsOffset)); 5398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(equal, &no_elements); 53993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Second chance, the object may be using the empty slow element dictionary. 5401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadRoot(kScratchRegister, Heap::kEmptySlowElementDictionaryRootIndex); 5402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(kScratchRegister, FieldOperand(rcx, JSObject::kElementsOffset)); 54033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(not_equal, call_runtime); 54043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&no_elements); 5406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rcx, FieldOperand(rbx, Map::kPrototypeOffset)); 5407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(rcx, null_value); 54083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(not_equal, &next); 54093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 54103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::TestJSArrayForAllocationMemento( 5412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register receiver_reg, 5413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch_reg, 5414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* no_memento_found) { 5415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference new_space_start = 5416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference::new_space_start(isolate()); 5417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference new_space_allocation_top = 5418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference::new_space_allocation_top_address(isolate()); 5419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(scratch_reg, Operand(receiver_reg, 5421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSArray::kSize + AllocationMemento::kSize - kHeapObjectTag)); 5422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(kScratchRegister, new_space_start); 5423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(scratch_reg, kScratchRegister); 5424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(less, no_memento_found); 5425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(scratch_reg, ExternalOperand(new_space_allocation_top)); 5426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(greater, no_memento_found); 5427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompareRoot(MemOperand(scratch_reg, -AllocationMemento::kSize), 5428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap::kAllocationMementoMapRootIndex); 5429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::JumpIfDictionaryInPrototypeChain( 5433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register object, 5434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch0, 5435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, 5436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* found) { 5437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!(scratch0.is(kScratchRegister) && scratch1.is(kScratchRegister))); 5438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!scratch1.is(scratch0)); 5439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register current = scratch0; 5440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label loop_again, end; 5441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(current, object); 5443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(current, FieldOperand(current, HeapObject::kMapOffset)); 5444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(current, FieldOperand(current, Map::kPrototypeOffset)); 5445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CompareRoot(current, Heap::kNullValueRootIndex); 5446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(equal, &end); 5447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Loop based on the map going up the prototype chain. 5449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&loop_again); 5450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(current, FieldOperand(current, HeapObject::kMapOffset)); 5451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STATIC_ASSERT(JS_PROXY_TYPE < JS_OBJECT_TYPE); 5452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STATIC_ASSERT(JS_VALUE_TYPE < JS_OBJECT_TYPE); 5453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CmpInstanceType(current, JS_OBJECT_TYPE); 5454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(below, found); 5455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch1, FieldOperand(current, Map::kBitField2Offset)); 5456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DecodeField<Map::ElementsKindBits>(scratch1); 5457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(scratch1, Immediate(DICTIONARY_ELEMENTS)); 5458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(equal, found); 5459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(current, FieldOperand(current, Map::kPrototypeOffset)); 5460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompareRoot(current, Heap::kNullValueRootIndex); 5461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(not_equal, &loop_again); 5462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 5463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(&end); 5464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::TruncatingDiv(Register dividend, int32_t divisor) { 5468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dividend.is(rax)); 5469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dividend.is(rdx)); 5470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::MagicNumbersForDivision<uint32_t> mag = 5471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::SignedDivisionByConstant(static_cast<uint32_t>(divisor)); 5472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(rax, Immediate(mag.multiplier)); 5473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch imull(dividend); 5474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool neg = (mag.multiplier & (static_cast<uint32_t>(1) << 31)) != 0; 5475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (divisor > 0 && neg) addl(rdx, dividend); 5476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (divisor < 0 && !neg && mag.multiplier > 0) subl(rdx, dividend); 5477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mag.shift > 0) sarl(rdx, Immediate(mag.shift)); 5478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(rax, dividend); 5479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shrl(rax, Immediate(31)); 5480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addl(rdx, rax); 5481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 54833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 5485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 5486f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 5487f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#endif // V8_TARGET_ARCH_X64 5488