macro-assembler-x64.cc revision bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8
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. 2183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ExternalReference store_buffer = 2193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ExternalReference::store_buffer_top(isolate()); 2203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch movp(scratch, ExternalOperand(store_buffer)); 2213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Store pointer to buffer. 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(scratch, 0), addr); 2233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Increment buffer top. 224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(scratch, Immediate(kPointerSize)); 2253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Write back new top of buffer. 2263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch movp(ExternalOperand(store_buffer), scratch); 2273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Call stub on end of buffer. 2283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label done; 2293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check for end of buffer. 2303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch testp(scratch, Immediate(StoreBuffer::kStoreBufferMask)); 2313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (and_then == kReturnAtEnd) { 2323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label buffer_overflowed; 2333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch j(equal, &buffer_overflowed, Label::kNear); 2343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ret(0); 2353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bind(&buffer_overflowed); 2363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(and_then == kFallThroughAtEnd); 2383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch j(not_equal, &done, Label::kNear); 2393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StoreBufferOverflowStub store_buffer_overflow(isolate(), save_fp); 2413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallStub(&store_buffer_overflow); 2423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (and_then == kReturnAtEnd) { 2433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ret(0); 2443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(and_then == kFallThroughAtEnd); 2463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bind(&done); 2476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 2487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 251257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::InNewSpace(Register object, 252257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register scratch, 253257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Condition cc, 254257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* branch, 2553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label::Distance distance) { 256109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch const int mask = 257109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch (1 << MemoryChunk::IN_FROM_SPACE) | (1 << MemoryChunk::IN_TO_SPACE); 258109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CheckPageFlag(object, scratch, mask, cc, branch, distance); 259257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 260257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 261257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::RecordWriteField( 2633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register object, 2643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int offset, 2653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register value, 2663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register dst, 2673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SaveFPRegsMode save_fp, 2683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RememberedSetAction remembered_set_action, 269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiCheck smi_check, 270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PointersToHereCheck pointers_to_here_check_for_value) { 2717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // First, check if a write barrier is even needed. The tests below 2723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // catch stores of Smis. 273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label done; 274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Skip barrier if writing a smi. 2763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (smi_check == INLINE_SMI_CHECK) { 2773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JumpIfSmi(value, &done); 2783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Although the object register is tagged, the offset is relative to the start 2813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // of the object, so so offset must be a multiple of kPointerSize. 282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsAligned(offset, kPointerSize)); 2833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(dst, FieldOperand(object, offset)); 2853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (emit_debug_code()) { 2863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label ok; 2873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch testb(dst, Immediate((1 << kPointerSizeLog2) - 1)); 2883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(zero, &ok, Label::kNear); 2893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int3(); 2903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bind(&ok); 2913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RecordWrite(object, dst, value, save_fp, remembered_set_action, 294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OMIT_SMI_CHECK, pointers_to_here_check_for_value); 2953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block bind(&done); 2974515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 2983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Clobber clobbered input registers when running with the debug-code flag 2993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // turned on to provoke errors. 30044f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(value, kZapValue, Assembler::RelocInfoNone()); 302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(dst, kZapValue, Assembler::RelocInfoNone()); 3034515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } 3043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 3053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 3063ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::RecordWriteArray( 308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register object, 309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register value, 310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register index, 311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SaveFPRegsMode save_fp, 312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RememberedSetAction remembered_set_action, 313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiCheck smi_check, 314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PointersToHereCheck pointers_to_here_check_for_value) { 3158defd9ff6930b4e24729971a61cf7469daf119beSteve Block // First, check if a write barrier is even needed. The tests below 3163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // catch stores of Smis. 3178defd9ff6930b4e24729971a61cf7469daf119beSteve Block Label done; 3188defd9ff6930b4e24729971a61cf7469daf119beSteve Block 3193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Skip barrier if writing a smi. 3203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (smi_check == INLINE_SMI_CHECK) { 3213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JumpIfSmi(value, &done); 3223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3238defd9ff6930b4e24729971a61cf7469daf119beSteve Block 3243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Array access: calculate the destination address. Index is not a smi. 3253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register dst = index; 326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(dst, Operand(object, index, times_pointer_size, 3273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArray::kHeaderSize - kHeapObjectTag)); 3283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RecordWrite(object, dst, value, save_fp, remembered_set_action, 330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OMIT_SMI_CHECK, pointers_to_here_check_for_value); 3318defd9ff6930b4e24729971a61cf7469daf119beSteve Block 3328defd9ff6930b4e24729971a61cf7469daf119beSteve Block bind(&done); 3338defd9ff6930b4e24729971a61cf7469daf119beSteve Block 3343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Clobber clobbered input registers when running with the debug-code flag 3358defd9ff6930b4e24729971a61cf7469daf119beSteve Block // turned on to provoke errors. 33644f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(value, kZapValue, Assembler::RelocInfoNone()); 338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(index, kZapValue, Assembler::RelocInfoNone()); 3398defd9ff6930b4e24729971a61cf7469daf119beSteve Block } 3408defd9ff6930b4e24729971a61cf7469daf119beSteve Block} 3418defd9ff6930b4e24729971a61cf7469daf119beSteve Block 3428defd9ff6930b4e24729971a61cf7469daf119beSteve Block 343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::RecordWriteForMap(Register object, 344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register map, 345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register dst, 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SaveFPRegsMode fp_mode) { 347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!object.is(kScratchRegister)); 348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!object.is(map)); 349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!object.is(dst)); 350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!map.is(dst)); 351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertNotSmi(object); 3524515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 35344f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label ok; 355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (map.is(kScratchRegister)) pushq(map); 356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompareMap(map, isolate()->factory()->meta_map()); 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (map.is(kScratchRegister)) popq(map); 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(equal, &ok, Label::kNear); 359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int3(); 360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&ok); 3614515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } 3624515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!FLAG_incremental_marking) { 364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label ok; 369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (map.is(kScratchRegister)) pushq(map); 370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(map, FieldOperand(object, HeapObject::kMapOffset)); 371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (map.is(kScratchRegister)) popq(map); 372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(equal, &ok, Label::kNear); 373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int3(); 374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&ok); 375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute the address. 378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(dst, FieldOperand(object, HeapObject::kMapOffset)); 379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // First, check if a write barrier is even needed. The tests below 381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // catch stores of smis and stores into the young generation. 382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done; 383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // A single check of the map's pages interesting flag suffices, since it is 385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // only set during incremental collection, and then it's also guaranteed that 386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the from object's page's interesting flag is also set. This optimization 387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // relies on the fact that maps can never be in new space. 388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CheckPageFlag(map, 389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map, // Used as scratch. 390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemoryChunk::kPointersToHereAreInterestingMask, 391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch zero, 392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &done, 393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::kNear); 394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RecordWriteStub stub(isolate(), object, map, dst, OMIT_REMEMBERED_SET, 396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fp_mode); 397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallStub(&stub); 398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&done); 400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Count number of write barriers in generated code. 402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->counters()->write_barriers_static()->Increment(); 403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1); 404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Clobber clobbered registers when running with the debug-code flag 406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // turned on to provoke errors. 407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(dst, kZapValue, Assembler::RelocInfoNone()); 409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(map, kZapValue, Assembler::RelocInfoNone()); 410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::RecordWrite( 415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register object, 416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register address, 417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register value, 418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SaveFPRegsMode fp_mode, 419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RememberedSetAction remembered_set_action, 420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiCheck smi_check, 421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PointersToHereCheck pointers_to_here_check_for_value) { 422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!object.is(value)); 423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!object.is(address)); 424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!value.is(address)); 425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertNotSmi(object); 426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (remembered_set_action == OMIT_REMEMBERED_SET && 4283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch !FLAG_incremental_marking) { 4293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return; 4303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 4333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label ok; 434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(value, Operand(address, 0)); 4353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(equal, &ok, Label::kNear); 4363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int3(); 4373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bind(&ok); 4383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 4403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // First, check if a write barrier is even needed. The tests below 4413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // catch stores of smis and stores into the young generation. 4423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label done; 4433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (smi_check == INLINE_SMI_CHECK) { 4453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Skip barrier if writing a smi. 4463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JumpIfSmi(value, &done); 447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (pointers_to_here_check_for_value != kPointersToHereAreAlwaysInteresting) { 450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CheckPageFlag(value, 451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value, // Used as scratch. 452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemoryChunk::kPointersToHereAreInterestingMask, 453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch zero, 454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &done, 455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::kNear); 456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CheckPageFlag(object, 4593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch value, // Used as scratch. 4603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MemoryChunk::kPointersFromHereAreInterestingMask, 4613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch zero, 4623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch &done, 4633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label::kNear); 4643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RecordWriteStub stub(isolate(), object, value, address, remembered_set_action, 466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fp_mode); 4673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallStub(&stub); 468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bind(&done); 4704515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Count number of write barriers in generated code. 472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->counters()->write_barriers_static()->Increment(); 473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1); 474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Clobber clobbered registers when running with the debug-code flag 4764515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // turned on to provoke errors. 47744f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(address, kZapValue, Assembler::RelocInfoNone()); 479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(value, kZapValue, Assembler::RelocInfoNone()); 4806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 4816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 4826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 483109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid MacroAssembler::RecordWriteCodeEntryField(Register js_function, 484109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Register code_entry, 485109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Register scratch) { 486109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch const int offset = JSFunction::kCodeEntryOffset; 487109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 488109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // The input registers are fixed to make calling the C write barrier function 489109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // easier. 490109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(js_function.is(rdi)); 491109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(code_entry.is(rcx)); 492bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(scratch.is(r15)); 493109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 494109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Since a code entry (value) is always in old space, we don't need to update 495109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // remembered set. If incremental marking is off, there is nothing for us to 496109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // do. 497109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (!FLAG_incremental_marking) return; 498109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 499109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AssertNotSmi(js_function); 500109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 501109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (emit_debug_code()) { 502109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Label ok; 503109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch leap(scratch, FieldOperand(js_function, offset)); 504109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch cmpp(code_entry, Operand(scratch, 0)); 505109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch j(equal, &ok, Label::kNear); 506109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int3(); 507109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch bind(&ok); 508109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 509109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 510109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // First, check if a write barrier is even needed. The tests below 511109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // catch stores of Smis and stores into young gen. 512109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Label done; 513109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 514109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CheckPageFlag(code_entry, scratch, 515109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch MemoryChunk::kPointersToHereAreInterestingMask, zero, &done, 516109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Label::kNear); 517109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CheckPageFlag(js_function, scratch, 518109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch MemoryChunk::kPointersFromHereAreInterestingMask, zero, &done, 519109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Label::kNear); 520109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 521109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Save input registers. 522109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Push(js_function); 523109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Push(code_entry); 524109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 525109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch const Register dst = scratch; 526109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch leap(dst, FieldOperand(js_function, offset)); 527109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 528109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Save caller-saved registers. 529109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch PushCallerSaved(kDontSaveFPRegs, js_function, code_entry); 530109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 531109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int argument_count = 3; 532109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch PrepareCallCFunction(argument_count); 533109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 534109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Load the argument registers. 535109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (arg_reg_1.is(rcx)) { 536109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Windows calling convention. 537109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(arg_reg_2.is(rdx) && arg_reg_3.is(r8)); 538109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 539109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch movp(arg_reg_1, js_function); // rcx gets rdi. 540bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch movp(arg_reg_2, dst); // rdx gets r15. 541109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 542109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // AMD64 calling convention. 543109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(arg_reg_1.is(rdi) && arg_reg_2.is(rsi) && arg_reg_3.is(rdx)); 544109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 545109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // rdi is already loaded with js_function. 546bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch movp(arg_reg_2, dst); // rsi gets r15. 547109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 548109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Move(arg_reg_3, ExternalReference::isolate_address(isolate())); 549109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 550109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch { 551109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AllowExternalCallThatCantCauseGC scope(this); 552109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CallCFunction( 553109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ExternalReference::incremental_marking_record_write_code_entry_function( 554109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch isolate()), 555109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch argument_count); 556109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 557109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 558109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Restore caller-saved registers. 559109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch PopCallerSaved(kDontSaveFPRegs, js_function, code_entry); 560109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 561109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Restore input registers. 562109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Pop(code_entry); 563109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Pop(js_function); 564109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 565109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch bind(&done); 566109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 5673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Assert(Condition cc, BailoutReason reason) { 569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) Check(cc, reason); 570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 573756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickvoid MacroAssembler::AssertFastElements(Register elements) { 57444f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 575257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label ok; 576756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CompareRoot(FieldOperand(elements, HeapObject::kMapOffset), 577756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick Heap::kFixedArrayMapRootIndex); 578257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(equal, &ok, Label::kNear); 579756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CompareRoot(FieldOperand(elements, HeapObject::kMapOffset), 5803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Heap::kFixedDoubleArrayMapRootIndex); 5813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch j(equal, &ok, Label::kNear); 5823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CompareRoot(FieldOperand(elements, HeapObject::kMapOffset), 583756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick Heap::kFixedCOWArrayMapRootIndex); 584257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(equal, &ok, Label::kNear); 585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Abort(kJSObjectWithFastElementsMapHasSlowElements); 586756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick bind(&ok); 587756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 588756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick} 589756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 590756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Check(Condition cc, BailoutReason reason) { 592257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label L; 593257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(cc, &L, Label::kNear); 594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Abort(reason); 5953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Control will not return here. 596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bind(&L); 597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6006ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid MacroAssembler::CheckStackAlignment() { 601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int frame_alignment = base::OS::ActivationFrameAlignment(); 6026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int frame_alignment_mask = frame_alignment - 1; 6036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (frame_alignment > kPointerSize) { 604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(base::bits::IsPowerOfTwo32(frame_alignment)); 605257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label alignment_as_expected; 606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(rsp, Immediate(frame_alignment_mask)); 607257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(zero, &alignment_as_expected, Label::kNear); 6086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Abort if stack is not aligned. 6096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int3(); 6106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block bind(&alignment_as_expected); 6116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 6126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 6136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 6146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::NegativeZeroTest(Register result, 616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register op, 617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label* then_label) { 618257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label ok; 619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block testl(result, result); 620257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_zero, &ok, Label::kNear); 621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block testl(op, op); 622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block j(sign, then_label); 623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bind(&ok); 624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Abort(BailoutReason reason) { 628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* msg = GetBailoutReason(reason); 630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (msg != NULL) { 631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RecordComment("Abort message: "); 632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RecordComment(msg); 633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_trap_on_abort) { 636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int3(); 637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(kScratchRegister, Smi::FromInt(static_cast<int>(reason)), 642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler::RelocInfoNone()); 643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(kScratchRegister); 6443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!has_frame_) { 6463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // We don't actually want to generate a pile of code for this, so just 6473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // claim there is a stack frame, without generating one. 6483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FrameScope scope(this, StackFrame::NONE); 649109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CallRuntime(Runtime::kAbort); 6503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 651109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CallRuntime(Runtime::kAbort); 6523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Control will not return here. 654d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block int3(); 655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::CallStub(CodeStub* stub, TypeFeedbackId ast_id) { 659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(AllowThisStubCall(stub)); // Calls are not allowed in some stubs 660257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id); 661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 664e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid MacroAssembler::TailCallStub(CodeStub* stub) { 665e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Jump(stub->GetCode(), RelocInfo::CODE_TARGET); 666e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 667e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 668e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 66985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochvoid MacroAssembler::StubReturn(int argc) { 670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(argc >= 1 && generating_stub()); 67185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch ret((argc - 1) * kPointerSize); 672592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch} 673592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 674592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 6753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool MacroAssembler::AllowThisStubCall(CodeStub* stub) { 676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return has_frame_ || !stub->SometimesSetsUpAFrame(); 677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 68080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenvoid MacroAssembler::IndexFromHash(Register hash, Register index) { 68180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // The assert checks that the constants for the maximum number of digits 68280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // for an array index cached in the hash field and the number of bits 68380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // reserved for it does not conflict. 684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(TenToThe(String::kMaxCachedArrayIndexLength) < 68580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen (1 << String::kArrayIndexValueBits)); 686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!hash.is(index)) { 687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(index, hash); 688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DecodeFieldToSmi<String::ArrayIndexValueBits>(index); 6901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 6911e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 6921e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 69344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid MacroAssembler::CallRuntime(const Runtime::Function* f, 694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int num_arguments, 695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SaveFPRegsMode save_doubles) { 696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the expected number of arguments of the runtime function is 697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // constant, we check that the actual number of arguments match the 698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // expectation. 699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(f->nargs < 0 || f->nargs == num_arguments); 700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7014515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // TODO(1236192): Most runtime routines don't need the number of 7024515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // arguments passed in because it is constant. At some point we 7034515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // should remove this need and make the runtime routine entry code 7044515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // smarter. 7058defd9ff6930b4e24729971a61cf7469daf119beSteve Block Set(rax, num_arguments); 70644f0eee88ff00398ff7f715fab053374d808c90dSteve Block LoadAddress(rbx, ExternalReference(f, isolate())); 707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CEntryStub ces(isolate(), f->result_size, save_doubles); 7084515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke CallStub(&ces); 709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 712402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuvoid MacroAssembler::CallExternalReference(const ExternalReference& ext, 713402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu int num_arguments) { 7148defd9ff6930b4e24729971a61cf7469daf119beSteve Block Set(rax, num_arguments); 71544f0eee88ff00398ff7f715fab053374d808c90dSteve Block LoadAddress(rbx, ext); 716402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CEntryStub stub(isolate(), 1); 718402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu CallStub(&stub); 719402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu} 720402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 721402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::TailCallRuntime(Runtime::FunctionId fid) { 723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ----------- S t a t e ------------- 724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // -- rsp[0] : return address 725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // -- rsp[8] : argument num_arguments - 1 726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ... 727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // -- rsp[8 * num_arguments] : argument 0 (receiver) 728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // For runtime functions with variable arguments: 730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // -- rax : number of arguments 731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ----------------------------------- 732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Runtime::Function* function = Runtime::FunctionForId(fid); 734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(1, function->result_size); 735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (function->nargs >= 0) { 736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(rax, function->nargs); 737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JumpToExternalReference(ExternalReference(fid, isolate())); 739bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch} 740bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 741bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::JumpToExternalReference(const ExternalReference& ext) { 743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set the entry point and jump to the C entry runtime stub. 74444f0eee88ff00398ff7f715fab053374d808c90dSteve Block LoadAddress(rbx, ext); 745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CEntryStub ces(isolate(), 1); 7463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block jmp(ces.GetCode(), RelocInfo::CODE_TARGET); 747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define REG(Name) \ 751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { Register::kCode_##Name } 7523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic const Register saved_regs[] = { 7543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch REG(rax), REG(rcx), REG(rdx), REG(rbx), REG(rbp), REG(rsi), REG(rdi), REG(r8), 7553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch REG(r9), REG(r10), REG(r11) 7563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 7573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#undef REG 7593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic const int kNumberOfSavedRegs = sizeof(saved_regs) / sizeof(Register); 7613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::PushCallerSaved(SaveFPRegsMode fp_mode, 7643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register exclusion1, 7653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register exclusion2, 7663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register exclusion3) { 7673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // We don't allow a GC during a store buffer overflow so there is no need to 7683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // store the registers in any particular way, but we do have to store and 7693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // restore them. 7703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < kNumberOfSavedRegs; i++) { 7713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register reg = saved_regs[i]; 7723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!reg.is(exclusion1) && !reg.is(exclusion2) && !reg.is(exclusion3)) { 773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pushq(reg); 7743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // R12 to r15 are callee save on all platforms. 7773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (fp_mode == kSaveFPRegs) { 778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(rsp, Immediate(kDoubleSize * XMMRegister::kMaxNumRegisters)); 779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { 7803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch XMMRegister reg = XMMRegister::from_code(i); 781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movsd(Operand(rsp, i * kDoubleSize), reg); 7823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 7853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::PopCallerSaved(SaveFPRegsMode fp_mode, 7883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register exclusion1, 7893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register exclusion2, 7903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register exclusion3) { 7913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (fp_mode == kSaveFPRegs) { 792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { 7933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch XMMRegister reg = XMMRegister::from_code(i); 794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movsd(reg, Operand(rsp, i * kDoubleSize)); 7953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(rsp, Immediate(kDoubleSize * XMMRegister::kMaxNumRegisters)); 7973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = kNumberOfSavedRegs - 1; i >= 0; i--) { 7993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register reg = saved_regs[i]; 8003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!reg.is(exclusion1) && !reg.is(exclusion2) && !reg.is(exclusion3)) { 801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch popq(reg); 802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtss2sd(XMMRegister dst, XMMRegister src) { 808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvtss2sd(dst, src, src); 811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvtss2sd(dst, src); 813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtss2sd(XMMRegister dst, const Operand& src) { 818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvtss2sd(dst, dst, src); 821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvtss2sd(dst, src); 823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtsd2ss(XMMRegister dst, XMMRegister src) { 828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvtsd2ss(dst, src, src); 831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvtsd2ss(dst, src); 833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtsd2ss(XMMRegister dst, const Operand& src) { 838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvtsd2ss(dst, dst, src); 841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvtsd2ss(dst, src); 843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Cvtlsi2sd(XMMRegister dst, Register src) { 848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vxorpd(dst, dst, dst); 851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvtlsi2sd(dst, dst, src); 852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch xorpd(dst, dst); 854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvtlsi2sd(dst, src); 855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Cvtlsi2sd(XMMRegister dst, const Operand& src) { 860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vxorpd(dst, dst, dst); 863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvtlsi2sd(dst, dst, src); 864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch xorpd(dst, dst); 866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvtlsi2sd(dst, src); 867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 871109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid MacroAssembler::Cvtlsi2ss(XMMRegister dst, Register src) { 872109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 873109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CpuFeatureScope scope(this, AVX); 874109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch vxorps(dst, dst, dst); 875109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch vcvtlsi2ss(dst, dst, src); 876109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 877109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch xorps(dst, dst); 878109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch cvtlsi2ss(dst, src); 879109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 880109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 881109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 882109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 883109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid MacroAssembler::Cvtlsi2ss(XMMRegister dst, const Operand& src) { 884109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 885109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CpuFeatureScope scope(this, AVX); 886109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch vxorps(dst, dst, dst); 887109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch vcvtlsi2ss(dst, dst, src); 888109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 889109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch xorps(dst, dst); 890109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch cvtlsi2ss(dst, src); 891109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 892109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 893109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 894109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtqsi2ss(XMMRegister dst, Register src) { 896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vxorps(dst, dst, dst); 899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvtqsi2ss(dst, dst, src); 900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch xorps(dst, dst); 902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvtqsi2ss(dst, src); 903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtqsi2ss(XMMRegister dst, const Operand& src) { 908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vxorps(dst, dst, dst); 911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvtqsi2ss(dst, dst, src); 912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch xorps(dst, dst); 914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvtqsi2ss(dst, src); 915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtqsi2sd(XMMRegister dst, Register src) { 920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vxorpd(dst, dst, dst); 923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvtqsi2sd(dst, dst, src); 924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch xorpd(dst, dst); 926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvtqsi2sd(dst, src); 927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtqsi2sd(XMMRegister dst, const Operand& src) { 932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vxorpd(dst, dst, dst); 935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvtqsi2sd(dst, dst, src); 936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch xorpd(dst, dst); 938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvtqsi2sd(dst, src); 939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtqui2ss(XMMRegister dst, Register src, Register tmp) { 944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label msb_set_src; 945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label jmp_return; 946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch testq(src, src); 947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(sign, &msb_set_src, Label::kNear); 948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cvtqsi2ss(dst, src); 949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jmp(&jmp_return, Label::kNear); 950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(&msb_set_src); 951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movq(tmp, src); 952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch shrq(src, Immediate(1)); 953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Recover the least significant bit to avoid rounding errors. 954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch andq(tmp, Immediate(1)); 955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch orq(src, tmp); 956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cvtqsi2ss(dst, src); 957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch addss(dst, dst); 958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(&jmp_return); 959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtqui2sd(XMMRegister dst, Register src, Register tmp) { 963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label msb_set_src; 964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label jmp_return; 965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch testq(src, src); 966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(sign, &msb_set_src, Label::kNear); 967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cvtqsi2sd(dst, src); 968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jmp(&jmp_return, Label::kNear); 969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(&msb_set_src); 970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movq(tmp, src); 971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch shrq(src, Immediate(1)); 972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch andq(tmp, Immediate(1)); 973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch orq(src, tmp); 974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cvtqsi2sd(dst, src); 975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch addsd(dst, dst); 976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(&jmp_return); 977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtsd2si(Register dst, XMMRegister src) { 981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvtsd2si(dst, src); 984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvtsd2si(dst, src); 986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 990109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid MacroAssembler::Cvttss2si(Register dst, XMMRegister src) { 991109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 992109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CpuFeatureScope scope(this, AVX); 993109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch vcvttss2si(dst, src); 994109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 995109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch cvttss2si(dst, src); 996109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 997109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 998109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 999109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1000109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid MacroAssembler::Cvttss2si(Register dst, const Operand& src) { 1001109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 1002109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CpuFeatureScope scope(this, AVX); 1003109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch vcvttss2si(dst, src); 1004109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 1005109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch cvttss2si(dst, src); 1006109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 1007109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 1008109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1009109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 1010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvttsd2si(Register dst, XMMRegister src) { 1011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 1012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 1013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvttsd2si(dst, src); 1014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvttsd2si(dst, src); 1016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvttsd2si(Register dst, const Operand& src) { 1021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 1022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 1023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvttsd2si(dst, src); 1024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvttsd2si(dst, src); 1026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvttss2siq(Register dst, XMMRegister src) { 1031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 1032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 1033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvttss2siq(dst, src); 1034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvttss2siq(dst, src); 1036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvttss2siq(Register dst, const Operand& src) { 1041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 1042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 1043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvttss2siq(dst, src); 1044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvttss2siq(dst, src); 1046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvttsd2siq(Register dst, XMMRegister src) { 1051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 1052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 1053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvttsd2siq(dst, src); 1054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvttsd2siq(dst, src); 1056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1058014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvttsd2siq(Register dst, const Operand& src) { 1061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 1062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 1063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvttsd2siq(dst, src); 1064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvttsd2siq(dst, src); 1066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Load(Register dst, const Operand& src, Representation r) { 1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!r.IsDouble()); 1072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (r.IsInteger8()) { 1073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movsxbq(dst, src); 1074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (r.IsUInteger8()) { 1075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movzxbl(dst, src); 1076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (r.IsInteger16()) { 1077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movsxwq(dst, src); 1078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (r.IsUInteger16()) { 1079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movzxwl(dst, src); 1080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (r.IsInteger32()) { 1081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(dst, src); 1082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 1084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Store(const Operand& dst, Register src, Representation r) { 1089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!r.IsDouble()); 1090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (r.IsInteger8() || r.IsUInteger8()) { 1091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movb(dst, src); 1092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (r.IsInteger16() || r.IsUInteger16()) { 1093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movw(dst, src); 1094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (r.IsInteger32()) { 1095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(dst, src); 1096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (r.IsHeapObject()) { 1098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertNotSmi(src); 1099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (r.IsSmi()) { 1100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertSmi(src); 11013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 11033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 11043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 11053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 11063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Set(Register dst, int64_t x) { 1108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (x == 0) { 11098defd9ff6930b4e24729971a61cf7469daf119beSteve Block xorl(dst, dst); 1110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (is_uint32(x)) { 1111d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block movl(dst, Immediate(static_cast<uint32_t>(x))); 11128b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } else if (is_int32(x)) { 11138b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch movq(dst, Immediate(static_cast<int32_t>(x))); 1114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movq(dst, x); 1116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Set(const Operand& dst, intptr_t x) { 1120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (kPointerSize == kInt64Size) { 1121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (is_int32(x)) { 1122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, Immediate(static_cast<int32_t>(x))); 1123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Set(kScratchRegister, x); 1125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, kScratchRegister); 1126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, Immediate(static_cast<int32_t>(x))); 1129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ---------------------------------------------------------------------------- 1134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Smi tagging, untagging and tag detection. 1135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool MacroAssembler::IsUnsafeInt(const int32_t x) { 1137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kMaxBits = 17; 1138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return !is_intn(x, kMaxBits); 1139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::SafeMove(Register dst, Smi* src) { 1143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 1144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsUnsafeInt(src->value()) && jit_cookie() != 0) { 1145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // JIT cookie can be converted to Smi. 1147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(dst, Smi::FromInt(src->value() ^ jit_cookie())); 1148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(kScratchRegister, Smi::FromInt(jit_cookie())); 1149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch xorp(dst, kScratchRegister); 1150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 1152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t value = static_cast<int32_t>(reinterpret_cast<intptr_t>(src)); 1153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, Immediate(value ^ jit_cookie())); 1154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch xorp(dst, Immediate(jit_cookie())); 1155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(dst, src); 1158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::SafePush(Smi* src) { 1163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsUnsafeInt(src->value()) && jit_cookie() != 0) { 1164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // JIT cookie can be converted to Smi. 1166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(Smi::FromInt(src->value() ^ jit_cookie())); 1167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(kScratchRegister, Smi::FromInt(jit_cookie())); 1168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch xorp(Operand(rsp, 0), kScratchRegister); 1169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 1171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t value = static_cast<int32_t>(reinterpret_cast<intptr_t>(src)); 1172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(Immediate(value ^ jit_cookie())); 1173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch xorp(Operand(rsp, 0), Immediate(jit_cookie())); 1174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(src); 1177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11818defd9ff6930b4e24729971a61cf7469daf119beSteve BlockRegister MacroAssembler::GetSmiConstant(Smi* source) { 1182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STATIC_ASSERT(kSmiTag == 0); 11838defd9ff6930b4e24729971a61cf7469daf119beSteve Block int value = source->value(); 11848defd9ff6930b4e24729971a61cf7469daf119beSteve Block if (value == 0) { 11858defd9ff6930b4e24729971a61cf7469daf119beSteve Block xorl(kScratchRegister, kScratchRegister); 11868defd9ff6930b4e24729971a61cf7469daf119beSteve Block return kScratchRegister; 11878defd9ff6930b4e24729971a61cf7469daf119beSteve Block } 11888defd9ff6930b4e24729971a61cf7469daf119beSteve Block LoadSmiConstant(kScratchRegister, source); 11898defd9ff6930b4e24729971a61cf7469daf119beSteve Block return kScratchRegister; 11908defd9ff6930b4e24729971a61cf7469daf119beSteve Block} 11918defd9ff6930b4e24729971a61cf7469daf119beSteve Block 1192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11938defd9ff6930b4e24729971a61cf7469daf119beSteve Blockvoid MacroAssembler::LoadSmiConstant(Register dst, Smi* source) { 1194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STATIC_ASSERT(kSmiTag == 0); 119544f0eee88ff00398ff7f715fab053374d808c90dSteve Block int value = source->value(); 119644f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (value == 0) { 11978defd9ff6930b4e24729971a61cf7469daf119beSteve Block xorl(dst, dst); 1198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Move(dst, source, Assembler::RelocInfoNone()); 12008defd9ff6930b4e24729971a61cf7469daf119beSteve Block } 12018defd9ff6930b4e24729971a61cf7469daf119beSteve Block} 12028defd9ff6930b4e24729971a61cf7469daf119beSteve Block 1203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 12040d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid MacroAssembler::Integer32ToSmi(Register dst, Register src) { 120569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch STATIC_ASSERT(kSmiTag == 0); 1206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!dst.is(src)) { 1207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block movl(dst, src); 1208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlp(dst, Immediate(kSmiShift)); 1210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 12139dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenvoid MacroAssembler::Integer32ToSmiField(const Operand& dst, Register src) { 121444f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 12159dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen testb(dst, Immediate(0x01)); 1216257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label ok; 1217257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(zero, &ok, Label::kNear); 1218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Abort(kInteger32ToSmiFieldWritingToNonSmiLocation); 12199dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen bind(&ok); 12209dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 1221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(kSmiShift % kBitsPerByte == 0); 1224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(Operand(dst, kSmiShift / kBitsPerByte), src); 1225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 1227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Integer32ToSmi(kScratchRegister, src); 1228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, kScratchRegister); 1229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 12309dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen} 12319dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 12329dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 12333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::Integer64PlusConstantToSmi(Register dst, 12343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Register src, 12353ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int constant) { 12363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (dst.is(src)) { 123744f0eee88ff00398ff7f715fab053374d808c90dSteve Block addl(dst, Immediate(constant)); 12383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 123944f0eee88ff00398ff7f715fab053374d808c90dSteve Block leal(dst, Operand(src, constant)); 12403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 1241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlp(dst, Immediate(kSmiShift)); 1242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiToInteger32(Register dst, Register src) { 124669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch STATIC_ASSERT(kSmiTag == 0); 1247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!dst.is(src)) { 1248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 1249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shrp(dst, Immediate(kSmiShift)); 1253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 1255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sarl(dst, Immediate(kSmiShift)); 1256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 12607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid MacroAssembler::SmiToInteger32(Register dst, const Operand& src) { 1261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(dst, Operand(src, kSmiShift / kBitsPerByte)); 1263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 1265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(dst, src); 1266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sarl(dst, Immediate(kSmiShift)); 1267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 12687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 12697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 12707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiToInteger64(Register dst, Register src) { 127269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch STATIC_ASSERT(kSmiTag == 0); 12733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (!dst.is(src)) { 1274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 1275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sarp(dst, Immediate(kSmiShift)); 1277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (kPointerSize == kInt32Size) { 1278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Sign extend to 64-bit. 1279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movsxlq(dst, dst); 1280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 12849dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenvoid MacroAssembler::SmiToInteger64(Register dst, const Operand& src) { 1285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movsxlq(dst, Operand(src, kSmiShift / kBitsPerByte)); 1287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 1289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 1290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger64(dst, dst); 1291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 12929dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen} 12939dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 12949dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 12953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::SmiTest(Register src) { 1296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertSmi(src); 1297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(src, src); 1298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 130144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid MacroAssembler::SmiCompare(Register smi1, Register smi2) { 1302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertSmi(smi1); 1303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertSmi(smi2); 1304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(smi1, smi2); 1305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 13083ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::SmiCompare(Register dst, Smi* src) { 1309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertSmi(dst); 131044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Cmp(dst, src); 131144f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 131244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 131344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 131444f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid MacroAssembler::Cmp(Register dst, Smi* src) { 1315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 13163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (src->value() == 0) { 1317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(dst, dst); 13183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 1319756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick Register constant_reg = GetSmiConstant(src); 1320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(dst, constant_reg); 1321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1325f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkevoid MacroAssembler::SmiCompare(Register dst, const Operand& src) { 1326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertSmi(dst); 1327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertSmi(src); 1328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(dst, src); 13296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 13306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 13316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 13323ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::SmiCompare(const Operand& dst, Register src) { 1333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertSmi(dst); 1334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertSmi(src); 1335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(dst, src); 1336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 13393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::SmiCompare(const Operand& dst, Smi* src) { 1340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertSmi(dst); 1341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpl(Operand(dst, kSmiShift / kBitsPerByte), Immediate(src->value())); 1343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 1345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpl(dst, Immediate(src)); 134644f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 1347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 135044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid MacroAssembler::Cmp(const Operand& dst, Smi* src) { 135144f0eee88ff00398ff7f715fab053374d808c90dSteve Block // The Operand cannot use the smi register. 135244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register smi_reg = GetSmiConstant(src); 1353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.AddressUsesRegister(smi_reg)); 1354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(dst, smi_reg); 135544f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 135644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 135744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 13589dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenvoid MacroAssembler::SmiCompareInteger32(const Operand& dst, Register src) { 1359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpl(Operand(dst, kSmiShift / kBitsPerByte), src); 1361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 1363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(kScratchRegister, dst); 1364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpl(kScratchRegister, src); 1365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 13669dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen} 13679dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 13689dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 13693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::PositiveSmiTimesPowerOfTwoToInteger64(Register dst, 13703ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Register src, 13713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int power) { 1372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(power >= 0); 1373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(power < 64); 13743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (power == 0) { 13753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block SmiToInteger64(dst, src); 13763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return; 13773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 13783ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (!dst.is(src)) { 1379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 13803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 13813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (power < kSmiShift) { 1382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sarp(dst, Immediate(kSmiShift - power)); 13833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else if (power > kSmiShift) { 1384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlp(dst, Immediate(power - kSmiShift)); 13853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 1386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 13897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid MacroAssembler::PositiveSmiDivPowerOfTwoToInteger32(Register dst, 13907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Register src, 13917f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch int power) { 1392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((0 <= power) && (power < 32)); 13937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (dst.is(src)) { 1394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shrp(dst, Immediate(power + kSmiShift)); 13957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else { 13967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch UNIMPLEMENTED(); // Not used. 13977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 13987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 13997f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 14007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1401257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SmiOrIfSmis(Register dst, Register src1, Register src2, 1402257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_smis, 1403257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1404257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (dst.is(src1) || dst.is(src2)) { 1405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(kScratchRegister)); 1406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.is(kScratchRegister)); 1407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, src1); 1408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch orp(kScratchRegister, src2); 1409257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch JumpIfNotSmi(kScratchRegister, on_not_smis, near_jump); 1410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, kScratchRegister); 1411257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 1412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src1); 1413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch orp(dst, src2); 1414257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch JumpIfNotSmi(dst, on_not_smis, near_jump); 1415257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1416257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1417257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1418257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 14193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockCondition MacroAssembler::CheckSmi(Register src) { 142069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch STATIC_ASSERT(kSmiTag == 0); 1421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block testb(src, Immediate(kSmiTagMask)); 14223ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return zero; 1423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 14261e0659c275bb392c045087af4f6b0d7565cb3d77Steve BlockCondition MacroAssembler::CheckSmi(const Operand& src) { 142769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch STATIC_ASSERT(kSmiTag == 0); 14281e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block testb(src, Immediate(kSmiTagMask)); 14291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block return zero; 14301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 14311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 14321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1433f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochCondition MacroAssembler::CheckNonNegativeSmi(Register src) { 143469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch STATIC_ASSERT(kSmiTag == 0); 1435e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Test that both bits of the mask 0x8000000000000001 are zero. 1436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, src); 1437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch rolp(kScratchRegister, Immediate(1)); 14388defd9ff6930b4e24729971a61cf7469daf119beSteve Block testb(kScratchRegister, Immediate(3)); 1439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return zero; 1440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCondition MacroAssembler::CheckBothSmi(Register first, Register second) { 1444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (first.is(second)) { 1445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return CheckSmi(first); 1446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 144769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch STATIC_ASSERT(kSmiTag == 0 && kHeapObjectTag == 1 && kHeapObjectTagMask == 3); 1448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leal(kScratchRegister, Operand(first, second, times_1, 0)); 1450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testb(kScratchRegister, Immediate(0x03)); 1451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 1453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(kScratchRegister, first); 1454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch orl(kScratchRegister, second); 1455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testb(kScratchRegister, Immediate(kSmiTagMask)); 1456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 14573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return zero; 1458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1461f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochCondition MacroAssembler::CheckBothNonNegativeSmi(Register first, 1462f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Register second) { 1463d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (first.is(second)) { 1464f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return CheckNonNegativeSmi(first); 1465d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, first); 1467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch orp(kScratchRegister, second); 1468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch rolp(kScratchRegister, Immediate(1)); 1469f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch testl(kScratchRegister, Immediate(3)); 1470d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return zero; 1471d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1472d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1473d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1474bb769b257e753aafcbd96767abb2abc645eaa20cBen MurdochCondition MacroAssembler::CheckEitherSmi(Register first, 1475bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch Register second, 1476bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch Register scratch) { 1477e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (first.is(second)) { 1478e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return CheckSmi(first); 1479e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 1480bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch if (scratch.is(second)) { 1481bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch andl(scratch, first); 1482bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } else { 1483bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch if (!scratch.is(first)) { 1484bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch movl(scratch, first); 1485bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } 1486bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch andl(scratch, second); 1487bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } 1488bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch testb(scratch, Immediate(kSmiTagMask)); 1489e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return zero; 1490e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 1491e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 1492e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 14933ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockCondition MacroAssembler::CheckInteger32ValidSmiValue(Register src) { 1494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // A 32-bit integer value can always be converted to a smi. 1496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return always; 1497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 1499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpl(src, Immediate(0xc0000000)); 1500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return positive; 1501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 15053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockCondition MacroAssembler::CheckUInteger32ValidSmiValue(Register src) { 1506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // An unsigned 32-bit integer value is valid as long as the high bit 1508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // is not set. 1509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testl(src, src); 1510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return positive; 1511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 1513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testl(src, Immediate(0xc0000000)); 1514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return zero; 1515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 15191e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::CheckSmiToIndicator(Register dst, Register src) { 15201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (dst.is(src)) { 15211e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block andl(dst, Immediate(kSmiTagMask)); 15221e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } else { 15231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block movl(dst, Immediate(kSmiTagMask)); 15241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block andl(dst, src); 15251e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 15261e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 15271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 15281e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 15291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::CheckSmiToIndicator(Register dst, const Operand& src) { 15301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (!(src.AddressUsesRegister(dst))) { 15311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block movl(dst, Immediate(kSmiTagMask)); 15321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block andl(dst, src); 15331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } else { 15341e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block movl(dst, src); 15351e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block andl(dst, Immediate(kSmiTagMask)); 15361e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 15371e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 15381e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 15391e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::JumpIfValidSmiValue(Register src, 1541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* on_valid, 1542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::Distance near_jump) { 1543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition is_valid = CheckInteger32ValidSmiValue(src); 1544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(is_valid, on_valid, near_jump); 1545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1548257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::JumpIfNotValidSmiValue(Register src, 1549257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_invalid, 1550257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1551257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Condition is_valid = CheckInteger32ValidSmiValue(src); 1552257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(NegateCondition(is_valid), on_invalid, near_jump); 1553257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1554257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1555257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::JumpIfUIntValidSmiValue(Register src, 1557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* on_valid, 1558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::Distance near_jump) { 1559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition is_valid = CheckUInteger32ValidSmiValue(src); 1560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(is_valid, on_valid, near_jump); 1561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1564257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::JumpIfUIntNotValidSmiValue(Register src, 1565257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_invalid, 1566257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1567257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Condition is_valid = CheckUInteger32ValidSmiValue(src); 1568257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(NegateCondition(is_valid), on_invalid, near_jump); 1569257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1570257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1571257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1572257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::JumpIfSmi(Register src, 1573257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_smi, 1574257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1575257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Condition smi = CheckSmi(src); 1576257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(smi, on_smi, near_jump); 1577257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1578257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1579257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1580257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::JumpIfNotSmi(Register src, 1581257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_smi, 1582257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1583257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Condition smi = CheckSmi(src); 1584257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(NegateCondition(smi), on_not_smi, near_jump); 1585257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1586257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1587257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1588257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::JumpUnlessNonNegativeSmi( 1589257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src, Label* on_not_smi_or_negative, 1590257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1591257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Condition non_negative_smi = CheckNonNegativeSmi(src); 1592257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(NegateCondition(non_negative_smi), on_not_smi_or_negative, near_jump); 1593257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1594257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1595257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1596257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::JumpIfSmiEqualsConstant(Register src, 1597257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Smi* constant, 1598257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_equals, 1599257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1600257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch SmiCompare(src, constant); 1601257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(equal, on_equals, near_jump); 1602257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1603257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1604257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1605257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::JumpIfNotBothSmi(Register src1, 1606257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src2, 1607257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_both_smi, 1608257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1609257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Condition both_smi = CheckBothSmi(src1, src2); 1610257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(NegateCondition(both_smi), on_not_both_smi, near_jump); 1611257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1612257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1613257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1614257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::JumpUnlessBothNonNegativeSmi(Register src1, 1615257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src2, 1616257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_both_smi, 1617257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1618257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Condition both_smi = CheckBothNonNegativeSmi(src1, src2); 1619257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(NegateCondition(both_smi), on_not_both_smi, near_jump); 1620257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1621257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1622257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 16233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::SmiAddConstant(Register dst, Register src, Smi* constant) { 16243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (constant->value() == 0) { 16253ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (!dst.is(src)) { 1626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 16273ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 16288defd9ff6930b4e24729971a61cf7469daf119beSteve Block return; 16293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else if (dst.is(src)) { 1630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 1631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register constant_reg = GetSmiConstant(constant); 1632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch addp(dst, constant_reg); 1633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoadSmiConstant(dst, constant); 1635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch addp(dst, src); 1636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1640f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkevoid MacroAssembler::SmiAddConstant(const Operand& dst, Smi* constant) { 1641f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke if (constant->value() != 0) { 1642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addl(Operand(dst, kSmiShift / kBitsPerByte), 1644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Immediate(constant->value())); 1645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 1647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(dst, Immediate(constant)); 1648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1649f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke } 1650f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke} 1651f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1652f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::SmiAddConstant(Register dst, Register src, Smi* constant, 1654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SmiOperationConstraints constraints, 1655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* bailout_label, 1656257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1657257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (constant->value() == 0) { 1658257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!dst.is(src)) { 1659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 1660257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1661257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else if (dst.is(src)) { 1662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 1663257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch LoadSmiConstant(kScratchRegister, constant); 1664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(dst, kScratchRegister); 1665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (constraints & SmiOperationConstraint::kBailoutOnNoOverflow) { 1666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(no_overflow, bailout_label, near_jump); 1667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(constraints & SmiOperationConstraint::kPreserveSourceRegister); 1668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(dst, kScratchRegister); 1669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (constraints & SmiOperationConstraint::kBailoutOnOverflow) { 1670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (constraints & SmiOperationConstraint::kPreserveSourceRegister) { 1671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done; 1672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(no_overflow, &done, Label::kNear); 1673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(dst, kScratchRegister); 1674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jmp(bailout_label, near_jump); 1675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&done); 1676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Bailout if overflow without reserving src. 1678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(overflow, bailout_label, near_jump); 1679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 1682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1683257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 1684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(constraints & SmiOperationConstraint::kPreserveSourceRegister); 1685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(constraints & SmiOperationConstraint::kBailoutOnOverflow); 1686257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch LoadSmiConstant(dst, constant); 1687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(dst, src); 1688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(overflow, bailout_label, near_jump); 1689257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1690257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1691257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1692257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 16933ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::SmiSubConstant(Register dst, Register src, Smi* constant) { 16943ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (constant->value() == 0) { 1695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!dst.is(src)) { 1696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 1697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 16983ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else if (dst.is(src)) { 1699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 17008defd9ff6930b4e24729971a61cf7469daf119beSteve Block Register constant_reg = GetSmiConstant(constant); 1701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(dst, constant_reg); 17023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 17033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (constant->value() == Smi::kMinValue) { 17048defd9ff6930b4e24729971a61cf7469daf119beSteve Block LoadSmiConstant(dst, constant); 17059dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen // Adding and subtracting the min-value gives the same result, it only 17069dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen // differs on the overflow bit, which we don't check here. 1707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(dst, src); 1708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 17099dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen // Subtract by adding the negation. 17108defd9ff6930b4e24729971a61cf7469daf119beSteve Block LoadSmiConstant(dst, Smi::FromInt(-constant->value())); 1711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(dst, src); 1712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::SmiSubConstant(Register dst, Register src, Smi* constant, 1718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SmiOperationConstraints constraints, 1719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* bailout_label, 1720257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1721257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (constant->value() == 0) { 1722257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!dst.is(src)) { 1723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 1724257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1725257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else if (dst.is(src)) { 1726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 1727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadSmiConstant(kScratchRegister, constant); 1728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(dst, kScratchRegister); 1729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (constraints & SmiOperationConstraint::kBailoutOnNoOverflow) { 1730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(no_overflow, bailout_label, near_jump); 1731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(constraints & SmiOperationConstraint::kPreserveSourceRegister); 1732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(dst, kScratchRegister); 1733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (constraints & SmiOperationConstraint::kBailoutOnOverflow) { 1734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (constraints & SmiOperationConstraint::kPreserveSourceRegister) { 1735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done; 1736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(no_overflow, &done, Label::kNear); 1737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(dst, kScratchRegister); 1738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jmp(bailout_label, near_jump); 1739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&done); 1740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Bailout if overflow without reserving src. 1742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(overflow, bailout_label, near_jump); 1743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1744257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 1745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 1746257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1747257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 1748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(constraints & SmiOperationConstraint::kPreserveSourceRegister); 1749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(constraints & SmiOperationConstraint::kBailoutOnOverflow); 1750257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (constant->value() == Smi::kMinValue) { 1751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 1752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 1753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadSmiConstant(kScratchRegister, constant); 1754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(dst, kScratchRegister); 1755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(overflow, bailout_label, near_jump); 1756257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 1757257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Subtract by adding the negation. 1758257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch LoadSmiConstant(dst, Smi::FromInt(-(constant->value()))); 1759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(dst, src); 1760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(overflow, bailout_label, near_jump); 1761257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1762257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1763257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1764257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1765257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1766257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SmiNeg(Register dst, 1767257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src, 1768257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_smi_result, 1769257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1770257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (dst.is(src)) { 1771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 1772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, src); 1773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch negp(dst); // Low 32 bits are retained as zero by negation. 1774257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Test if result is zero or Smi::kMinValue. 1775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(dst, kScratchRegister); 1776257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_equal, on_smi_result, near_jump); 1777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(src, kScratchRegister); 1778257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 1779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 1780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch negp(dst); 1781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(dst, src); 1782257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // If the result is zero or Smi::kMinValue, negation failed to create a smi. 1783257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_equal, on_smi_result, near_jump); 1784257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1785257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1786257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1787257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<class T> 1789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void SmiAddHelper(MacroAssembler* masm, 1790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register dst, 1791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register src1, 1792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch T src2, 1793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* on_not_smi_result, 1794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::Distance near_jump) { 1795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (dst.is(src1)) { 1796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done; 1797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->addp(dst, src2); 1798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->j(no_overflow, &done, Label::kNear); 1799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Restore src1. 1800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->subp(dst, src2); 1801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->jmp(on_not_smi_result, near_jump); 1802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->bind(&done); 1803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->movp(dst, src1); 1805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->addp(dst, src2); 1806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->j(overflow, on_not_smi_result, near_jump); 1807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1811257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SmiAdd(Register dst, 1812257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src1, 1813257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src2, 1814257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_smi_result, 1815257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NOT_NULL(on_not_smi_result); 1817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(src2)); 1818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiAddHelper<Register>(this, dst, src1, src2, on_not_smi_result, near_jump); 1819257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1820257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1821257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1822257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SmiAdd(Register dst, 1823257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src1, 1824257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch const Operand& src2, 1825257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_smi_result, 1826257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NOT_NULL(on_not_smi_result); 1828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.AddressUsesRegister(dst)); 1829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiAddHelper<Operand>(this, dst, src1, src2, on_not_smi_result, near_jump); 1830257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1831257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1832257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 18330d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid MacroAssembler::SmiAdd(Register dst, 18340d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Register src1, 18350d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Register src2) { 18360d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // No overflow checking. Use only when it's known that 18370d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // overflowing is impossible. 183844f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!dst.is(src1)) { 1839257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (emit_debug_code()) { 1840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, src1); 1841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(kScratchRegister, src2); 1842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(no_overflow, kSmiAdditionOverflow); 1843257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(dst, Operand(src1, src2, times_1, 0)); 1845257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 1846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(dst, src2); 1847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assert(no_overflow, kSmiAdditionOverflow); 1848257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1849257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1850257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1851257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<class T> 1853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void SmiSubHelper(MacroAssembler* masm, 1854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register dst, 1855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register src1, 1856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch T src2, 1857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* on_not_smi_result, 1858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::Distance near_jump) { 1859257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (dst.is(src1)) { 1860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done; 1861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->subp(dst, src2); 1862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->j(no_overflow, &done, Label::kNear); 1863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Restore src1. 1864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->addp(dst, src2); 1865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->jmp(on_not_smi_result, near_jump); 1866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->bind(&done); 1867257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 1868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->movp(dst, src1); 1869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->subp(dst, src2); 1870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->j(overflow, on_not_smi_result, near_jump); 1871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::SmiSub(Register dst, 1876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register src1, 1877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register src2, 1878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* on_not_smi_result, 1879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::Distance near_jump) { 1880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NOT_NULL(on_not_smi_result); 1881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(src2)); 1882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiSubHelper<Register>(this, dst, src1, src2, on_not_smi_result, near_jump); 1883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 18860d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid MacroAssembler::SmiSub(Register dst, 1887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register src1, 1888257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch const Operand& src2, 1889257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_smi_result, 1890257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NOT_NULL(on_not_smi_result); 1892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.AddressUsesRegister(dst)); 1893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiSubHelper<Operand>(this, dst, src1, src2, on_not_smi_result, near_jump); 1894257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1895257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1896257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<class T> 1898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void SmiSubNoOverflowHelper(MacroAssembler* masm, 1899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register dst, 1900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register src1, 1901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch T src2) { 19020d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // No overflow checking. Use only when it's known that 19030d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // overflowing is impossible (e.g., subtracting two positive smis). 190444f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!dst.is(src1)) { 1905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->movp(dst, src1); 1906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->subp(dst, src2); 1908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->Assert(no_overflow, kSmiSubtractionOverflow); 1909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::SmiSub(Register dst, Register src1, Register src2) { 1913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(src2)); 1914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiSubNoOverflowHelper<Register>(this, dst, src1, src2); 1915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::SmiSub(Register dst, 1919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register src1, 1920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& src2) { 1921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiSubNoOverflowHelper<Operand>(this, dst, src1, src2); 1922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1925257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SmiMul(Register dst, 1926257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src1, 1927257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src2, 1928257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_smi_result, 1929257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(src2)); 1931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 1932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(kScratchRegister)); 1933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.is(kScratchRegister)); 1934257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1935257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (dst.is(src1)) { 1936257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label failure, zero_correct_result; 1937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, src1); // Create backup for later testing. 1938257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch SmiToInteger64(dst, src1); 1939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch imulp(dst, src2); 1940257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(overflow, &failure, Label::kNear); 1941257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1942257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Check for negative zero result. If product is zero, and one 1943257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // argument is negative, go to slow case. 1944257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label correct_result; 1945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(dst, dst); 1946257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_zero, &correct_result, Label::kNear); 1947257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, kScratchRegister); 1949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch xorp(dst, src2); 1950257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Result was positive zero. 1951257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(positive, &zero_correct_result, Label::kNear); 1952257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1953257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&failure); // Reused failure exit, restores src1. 1954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(src1, kScratchRegister); 1955257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch jmp(on_not_smi_result, near_jump); 1956257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1957257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&zero_correct_result); 1958257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Set(dst, 0); 1959257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1960257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&correct_result); 1961257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 1962257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch SmiToInteger64(dst, src1); 1963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch imulp(dst, src2); 1964257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(overflow, on_not_smi_result, near_jump); 1965257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Check for negative zero result. If product is zero, and one 1966257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // argument is negative, go to slow case. 1967257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label correct_result; 1968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(dst, dst); 1969257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_zero, &correct_result, Label::kNear); 1970257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // One of src1 and src2 is zero, the check whether the other is 1971257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // negative. 1972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, src1); 1973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch xorp(kScratchRegister, src2); 1974257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(negative, on_not_smi_result, near_jump); 1975257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&correct_result); 1976257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1977257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1978257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1979257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1980257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SmiDiv(Register dst, 1981257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src1, 1982257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src2, 1983257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_smi_result, 1984257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(kScratchRegister)); 1986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.is(kScratchRegister)); 1987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 1988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.is(rax)); 1989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.is(rdx)); 1990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(rdx)); 1991257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1992257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Check for 0 divisor (result is +/-Infinity). 1993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(src2, src2); 1994257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(zero, on_not_smi_result, near_jump); 1995257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1996257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (src1.is(rax)) { 1997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, src1); 1998257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1999257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch SmiToInteger32(rax, src1); 2000257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // We need to rule out dividing Smi::kMinValue by -1, since that would 2001257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // overflow in idiv and raise an exception. 2002257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // We combine this with negative zero test (negative zero only happens 2003257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // when dividing zero by a negative number). 2004257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2005257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // We overshoot a little and go to slow case if we divide min-value 2006257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // by any negative value, not just -1. 2007257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label safe_div; 2008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testl(rax, Immediate(~Smi::kMinValue)); 2009257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_zero, &safe_div, Label::kNear); 2010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(src2, src2); 2011257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (src1.is(rax)) { 2012257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(positive, &safe_div, Label::kNear); 2013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(src1, kScratchRegister); 2014257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch jmp(on_not_smi_result, near_jump); 2015257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 2016257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(negative, on_not_smi_result, near_jump); 2017257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 2018257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&safe_div); 2019257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2020257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch SmiToInteger32(src2, src2); 2021257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Sign extend src1 into edx:eax. 2022257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch cdq(); 2023257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch idivl(src2); 2024257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Integer32ToSmi(src2, src2); 2025257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Check that the remainder is zero. 2026257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch testl(rdx, rdx); 2027257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (src1.is(rax)) { 2028257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label smi_result; 2029257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(zero, &smi_result, Label::kNear); 2030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(src1, kScratchRegister); 2031257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch jmp(on_not_smi_result, near_jump); 2032257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&smi_result); 2033257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 2034257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_zero, on_not_smi_result, near_jump); 2035257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 2036257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!dst.is(src1) && src1.is(rax)) { 2037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(src1, kScratchRegister); 2038257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 2039257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Integer32ToSmi(dst, rax); 2040257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 2041257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2042257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2043257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SmiMod(Register dst, 2044257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src1, 2045257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src2, 2046257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_smi_result, 2047257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 2048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 2049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(kScratchRegister)); 2050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.is(kScratchRegister)); 2051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.is(rax)); 2052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.is(rdx)); 2053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(rdx)); 2054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(src2)); 2055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(src2, src2); 2057257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(zero, on_not_smi_result, near_jump); 2058257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2059257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (src1.is(rax)) { 2060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, src1); 2061257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 2062257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch SmiToInteger32(rax, src1); 2063257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch SmiToInteger32(src2, src2); 2064257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2065257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Test for the edge case of dividing Smi::kMinValue by -1 (will overflow). 2066257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label safe_div; 2067257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch cmpl(rax, Immediate(Smi::kMinValue)); 2068257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_equal, &safe_div, Label::kNear); 2069257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch cmpl(src2, Immediate(-1)); 2070257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_equal, &safe_div, Label::kNear); 2071257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Retag inputs and go slow case. 2072257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Integer32ToSmi(src2, src2); 2073257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (src1.is(rax)) { 2074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(src1, kScratchRegister); 2075257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 2076257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch jmp(on_not_smi_result, near_jump); 2077257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&safe_div); 2078257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2079257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Sign extend eax into edx:eax. 2080257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch cdq(); 2081257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch idivl(src2); 2082257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Restore smi tags on inputs. 2083257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Integer32ToSmi(src2, src2); 2084257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (src1.is(rax)) { 2085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(src1, kScratchRegister); 2086257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 2087257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Check for a negative zero result. If the result is zero, and the 2088257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // dividend is negative, go slow to return a floating point negative zero. 2089257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label smi_result; 2090257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch testl(rdx, rdx); 2091257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_zero, &smi_result, Label::kNear); 2092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(src1, src1); 2093257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(negative, on_not_smi_result, near_jump); 2094257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&smi_result); 2095257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Integer32ToSmi(dst, rdx); 2096257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 2097257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2098257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiNot(Register dst, Register src) { 2100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 2101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src.is(kScratchRegister)); 2102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 2103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set tag and padding bits before negating, so that they are zero 2104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // afterwards. 2105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(kScratchRegister, Immediate(~0)); 2106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 2108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(kScratchRegister, Immediate(1)); 2109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (dst.is(src)) { 2111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch xorp(dst, kScratchRegister); 2112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(dst, Operand(src, kScratchRegister, times_1, 0)); 2114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch notp(dst); 2116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiAnd(Register dst, Register src1, Register src2) { 2120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(src2)); 2121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!dst.is(src1)) { 2122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src1); 2123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(dst, src2); 2125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 21283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::SmiAndConstant(Register dst, Register src, Smi* constant) { 21293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (constant->value() == 0) { 21309fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block Set(dst, 0); 21313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else if (dst.is(src)) { 2132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 21338defd9ff6930b4e24729971a61cf7469daf119beSteve Block Register constant_reg = GetSmiConstant(constant); 2134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(dst, constant_reg); 21353ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 21368defd9ff6930b4e24729971a61cf7469daf119beSteve Block LoadSmiConstant(dst, constant); 2137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(dst, src); 2138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiOr(Register dst, Register src1, Register src2) { 2143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!dst.is(src1)) { 2144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(src2)); 2145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src1); 2146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch orp(dst, src2); 2148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 21513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::SmiOrConstant(Register dst, Register src, Smi* constant) { 21523ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (dst.is(src)) { 2153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 21548defd9ff6930b4e24729971a61cf7469daf119beSteve Block Register constant_reg = GetSmiConstant(constant); 2155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch orp(dst, constant_reg); 21563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 21578defd9ff6930b4e24729971a61cf7469daf119beSteve Block LoadSmiConstant(dst, constant); 2158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch orp(dst, src); 2159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 21623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 2163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiXor(Register dst, Register src1, Register src2) { 2164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!dst.is(src1)) { 2165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(src2)); 2166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src1); 2167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch xorp(dst, src2); 2169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 21723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::SmiXorConstant(Register dst, Register src, Smi* constant) { 21733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (dst.is(src)) { 2174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 21758defd9ff6930b4e24729971a61cf7469daf119beSteve Block Register constant_reg = GetSmiConstant(constant); 2176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch xorp(dst, constant_reg); 21773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 21788defd9ff6930b4e24729971a61cf7469daf119beSteve Block LoadSmiConstant(dst, constant); 2179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch xorp(dst, src); 2180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiShiftArithmeticRightConstant(Register dst, 2185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register src, 2186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int shift_value) { 2187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_uint5(shift_value)); 2188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (shift_value > 0) { 2189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (dst.is(src)) { 2190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sarp(dst, Immediate(shift_value + kSmiShift)); 2191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlp(dst, Immediate(kSmiShift)); 2192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block UNIMPLEMENTED(); // Not used. 2194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiShiftLeftConstant(Register dst, 2200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register src, 2201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int shift_value, 2202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* on_not_smi_result, 2203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::Distance near_jump) { 2204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 2205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!dst.is(src)) { 2206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 2207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (shift_value > 0) { 2209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Shift amount specified by lower 5 bits, not six as the shl opcode. 2210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlq(dst, Immediate(shift_value & 0x1f)); 2211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 2214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (dst.is(src)) { 2215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNIMPLEMENTED(); // Not used. 2216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(dst, src); 2218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shll(dst, Immediate(shift_value)); 2219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JumpIfNotValidSmiValue(dst, on_not_smi_result, near_jump); 2220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Integer32ToSmi(dst, dst); 2221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2226257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SmiShiftLogicalRightConstant( 2227257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register dst, Register src, int shift_value, 2228257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_smi_result, Label::Distance near_jump) { 2229257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Logic right shift interprets its result as an *unsigned* number. 2230257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (dst.is(src)) { 2231257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch UNIMPLEMENTED(); // Not used. 2232257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 2233257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (shift_value == 0) { 2234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(src, src); 2235257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(negative, on_not_smi_result, near_jump); 2236257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 2237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 2238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 2239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shrp(dst, Immediate(shift_value + kSmiShift)); 2240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlp(dst, Immediate(kSmiShift)); 2241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 2243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(dst, src); 2244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shrp(dst, Immediate(shift_value)); 2245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JumpIfUIntNotValidSmiValue(dst, on_not_smi_result, near_jump); 2246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Integer32ToSmi(dst, dst); 2247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2248257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 2249257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 2250257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2251257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiShiftLeft(Register dst, 2253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register src1, 2254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register src2, 2255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* on_not_smi_result, 2256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::Distance near_jump) { 2257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 2258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(rcx)); 2259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!dst.is(src1)) { 2260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src1); 2261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Untag shift amount. 2263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(rcx, src2); 2264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Shift amount specified by lower 5 bits, not six as the shl opcode. 2265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(rcx, Immediate(0x1f)); 2266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlq_cl(dst); 2267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 2269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 2270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(kScratchRegister)); 2271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.is(kScratchRegister)); 2272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(src2)); 2273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(rcx)); 2274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (src1.is(rcx) || src2.is(rcx)) { 2276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movq(kScratchRegister, rcx); 2277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (dst.is(src1)) { 2279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNIMPLEMENTED(); // Not used. 2280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label valid_result; 2282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(dst, src1); 2283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(rcx, src2); 2284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shll_cl(dst); 2285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JumpIfValidSmiValue(dst, &valid_result, Label::kNear); 2286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // As src1 or src2 could not be dst, we do not need to restore them for 2287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // clobbering dst. 2288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (src1.is(rcx) || src2.is(rcx)) { 2289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (src1.is(rcx)) { 2290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movq(src1, kScratchRegister); 2291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movq(src2, kScratchRegister); 2293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jmp(on_not_smi_result, near_jump); 2296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&valid_result); 2297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Integer32ToSmi(dst, dst); 2298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2303257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SmiShiftLogicalRight(Register dst, 2304257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src1, 2305257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src2, 2306257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_smi_result, 2307257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 2308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 2309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(kScratchRegister)); 2310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.is(kScratchRegister)); 2311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(src2)); 2312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(rcx)); 2313257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (src1.is(rcx) || src2.is(rcx)) { 2314257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch movq(kScratchRegister, rcx); 2315257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 2316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (dst.is(src1)) { 2317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNIMPLEMENTED(); // Not used. 2318257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 2319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label valid_result; 2320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(dst, src1); 2321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(rcx, src2); 2322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shrl_cl(dst); 2323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JumpIfUIntValidSmiValue(dst, &valid_result, Label::kNear); 2324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // As src1 or src2 could not be dst, we do not need to restore them for 2325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // clobbering dst. 2326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (src1.is(rcx) || src2.is(rcx)) { 2327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (src1.is(rcx)) { 2328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movq(src1, kScratchRegister); 2329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movq(src2, kScratchRegister); 2331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jmp(on_not_smi_result, near_jump); 2334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&valid_result); 2335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Integer32ToSmi(dst, dst); 2336257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 2337257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 2338257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2339257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiShiftArithmeticRight(Register dst, 2341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register src1, 2342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register src2) { 2343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 2344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(kScratchRegister)); 2345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.is(kScratchRegister)); 2346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(rcx)); 2347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SmiToInteger32(rcx, src2); 2349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!dst.is(src1)) { 2350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src1); 23513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 2352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(dst, dst); 2353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sarl_cl(dst); 2354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Integer32ToSmi(dst, dst); 2355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2358257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SelectNonSmi(Register dst, 2359257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src1, 2360257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src2, 2361257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_smis, 2362257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 2363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 2364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(kScratchRegister)); 2365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.is(kScratchRegister)); 2366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(src1)); 2367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(src2)); 2368257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Both operands must not be smis. 2369257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#ifdef DEBUG 2370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition not_both_smis = NegateCondition(CheckBothSmi(src1, src2)); 2371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(not_both_smis, kBothRegistersWereSmisInSelectNonSmi); 2372257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#endif 237369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch STATIC_ASSERT(kSmiTag == 0); 2374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(static_cast<Smi*>(0), Smi::FromInt(0)); 2375257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch movl(kScratchRegister, Immediate(kSmiTagMask)); 2376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(kScratchRegister, src1); 2377257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch testl(kScratchRegister, src2); 2378257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // If non-zero then both are smis. 2379257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_zero, on_not_smis, near_jump); 2380257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2381257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Exactly one operand is a smi. 2382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(1, static_cast<int>(kSmiTagMask)); 2383257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // kScratchRegister still holds src1 & kSmiTag, which is either zero or one. 2384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(kScratchRegister, Immediate(1)); 2385257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // If src1 is a smi, then scratch register all 1s, else it is all 0s. 2386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src1); 2387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch xorp(dst, src2); 2388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(dst, kScratchRegister); 2389257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // If src1 is a smi, dst holds src1 ^ src2, else it is zero. 2390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch xorp(dst, src1); 2391257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // If src1 is a smi, dst is src2, else it is src1, i.e., the non-smi. 2392257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 2393257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2394257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 23953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockSmiIndex MacroAssembler::SmiToIndex(Register dst, 23963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Register src, 23973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int shift) { 2398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 2399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_uint6(shift)); 2400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // There is a possible optimization if shift is in the range 60-63, but that 2401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // will (and must) never happen. 2402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!dst.is(src)) { 2403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 2404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (shift < kSmiShift) { 2406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sarp(dst, Immediate(kSmiShift - shift)); 2407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlp(dst, Immediate(shift - kSmiShift)); 2409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return SmiIndex(dst, times_1); 24113ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 2412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 2413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(shift >= times_1 && shift <= (static_cast<int>(times_8) + 1)); 2414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!dst.is(src)) { 2415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 2416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We have to sign extend the index register to 64-bit as the SMI might 2418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // be negative. 2419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movsxlq(dst, dst); 2420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (shift == times_1) { 2421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sarq(dst, Immediate(kSmiShift)); 2422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return SmiIndex(dst, times_1); 2423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return SmiIndex(dst, static_cast<ScaleFactor>(shift - 1)); 24253ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 2426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockSmiIndex MacroAssembler::SmiToNegativeIndex(Register dst, 2430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register src, 2431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int shift) { 2432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 2433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Register src holds a positive smi. 2434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_uint6(shift)); 2435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!dst.is(src)) { 2436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 2437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch negp(dst); 2439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (shift < kSmiShift) { 2440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sarp(dst, Immediate(kSmiShift - shift)); 2441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlp(dst, Immediate(shift - kSmiShift)); 2443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return SmiIndex(dst, times_1); 24453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 2446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 2447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(shift >= times_1 && shift <= (static_cast<int>(times_8) + 1)); 2448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!dst.is(src)) { 2449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 2450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch negq(dst); 2452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (shift == times_1) { 2453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sarq(dst, Immediate(kSmiShift)); 2454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return SmiIndex(dst, times_1); 2455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return SmiIndex(dst, static_cast<ScaleFactor>(shift - 1)); 24573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 2458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 246144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid MacroAssembler::AddSmiField(Register dst, const Operand& src) { 2462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 2463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(0, kSmiShift % kBitsPerByte); 2464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addl(dst, Operand(src, kSmiShift / kBitsPerByte)); 2465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 2467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(kScratchRegister, src); 2468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addl(dst, kScratchRegister); 2469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Push(Smi* source) { 2474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch intptr_t smi = reinterpret_cast<intptr_t>(source); 2475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (is_int32(smi)) { 2476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(Immediate(static_cast<int32_t>(smi))); 2477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register constant = GetSmiConstant(source); 2479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(constant); 2480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::PushRegisterAsTwoSmis(Register src, Register scratch) { 2485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src.is(scratch)); 2486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch, src); 2487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // High bits. 2488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shrp(src, Immediate(kPointerSize * kBitsPerByte - kSmiShift)); 2489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlp(src, Immediate(kSmiShift)); 2490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(src); 2491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Low bits. 2492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlp(scratch, Immediate(kSmiShift)); 2493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(scratch); 2494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::PopRegisterAsTwoSmis(Register dst, Register scratch) { 2498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(scratch)); 2499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(scratch); 2500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Low bits. 2501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shrp(scratch, Immediate(kSmiShift)); 2502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(dst); 2503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shrp(dst, Immediate(kSmiShift)); 2504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // High bits. 2505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlp(dst, Immediate(kPointerSize * kBitsPerByte - kSmiShift)); 2506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch orp(dst, scratch); 2507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Test(const Operand& src, Smi* source) { 2511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 2512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testl(Operand(src, kIntSize), Immediate(source->value())); 2513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 2515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testl(src, Immediate(source)); 2516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ---------------------------------------------------------------------------- 2521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2523257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::JumpIfNotString(Register object, 2524257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register object_map, 2525257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* not_string, 2526257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 2527257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Condition is_smi = CheckSmi(object); 2528257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(is_smi, not_string, near_jump); 2529257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CmpObjectType(object, FIRST_NONSTRING_TYPE, object_map); 2530257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(above_equal, not_string, near_jump); 2531257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 2532257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2533257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::JumpIfNotBothSequentialOneByteStrings( 2535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register first_object, Register second_object, Register scratch1, 2536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch2, Label* on_fail, Label::Distance near_jump) { 2537257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Check that both objects are not smis. 2538257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Condition either_smi = CheckEitherSmi(first_object, second_object); 2539257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(either_smi, on_fail, near_jump); 2540257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2541257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Load instance type for both strings. 2542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch1, FieldOperand(first_object, HeapObject::kMapOffset)); 2543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch2, FieldOperand(second_object, HeapObject::kMapOffset)); 2544257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch movzxbl(scratch1, FieldOperand(scratch1, Map::kInstanceTypeOffset)); 2545257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch movzxbl(scratch2, FieldOperand(scratch2, Map::kInstanceTypeOffset)); 2546257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check that both are flat one-byte strings. 2548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(kNotStringTag != 0); 2549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int kFlatOneByteStringMask = 2550257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask; 2551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int kFlatOneByteStringTag = 2552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kStringTag | kOneByteStringTag | kSeqStringTag; 2553257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andl(scratch1, Immediate(kFlatOneByteStringMask)); 2555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andl(scratch2, Immediate(kFlatOneByteStringMask)); 2556257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Interleave the bits to check both scratch1 and scratch2 in one test. 2557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(0, kFlatOneByteStringMask & (kFlatOneByteStringMask << 3)); 2558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(scratch1, Operand(scratch1, scratch2, times_8, 0)); 2559257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch cmpl(scratch1, 2560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Immediate(kFlatOneByteStringTag + (kFlatOneByteStringTag << 3))); 2561257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_equal, on_fail, near_jump); 2562257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 2563257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2564257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::JumpIfInstanceTypeIsNotSequentialOneByte( 2566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register instance_type, Register scratch, Label* failure, 2567257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 2568257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!scratch.is(instance_type)) { 2569257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch movl(scratch, instance_type); 2570257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 2571257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int kFlatOneByteStringMask = 2573257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask; 2574257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andl(scratch, Immediate(kFlatOneByteStringMask)); 2576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpl(scratch, Immediate(kStringTag | kSeqStringTag | kOneByteStringTag)); 2577257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_equal, failure, near_jump); 2578257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 2579257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2580257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialOneByte( 2582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register first_object_instance_type, Register second_object_instance_type, 2583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, Register scratch2, Label* on_fail, 2584257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 2585257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Load instance type for both strings. 2586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch1, first_object_instance_type); 2587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch2, second_object_instance_type); 2588257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check that both are flat one-byte strings. 2590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(kNotStringTag != 0); 2591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int kFlatOneByteStringMask = 2592257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask; 2593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int kFlatOneByteStringTag = 2594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kStringTag | kOneByteStringTag | kSeqStringTag; 2595257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andl(scratch1, Immediate(kFlatOneByteStringMask)); 2597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andl(scratch2, Immediate(kFlatOneByteStringMask)); 2598257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Interleave the bits to check both scratch1 and scratch2 in one test. 2599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(0, kFlatOneByteStringMask & (kFlatOneByteStringMask << 3)); 2600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(scratch1, Operand(scratch1, scratch2, times_8, 0)); 2601257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch cmpl(scratch1, 2602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Immediate(kFlatOneByteStringTag + (kFlatOneByteStringTag << 3))); 2603257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_equal, on_fail, near_jump); 2604257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 2605257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2606257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<class T> 2608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void JumpIfNotUniqueNameHelper(MacroAssembler* masm, 2609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch T operand_or_register, 2610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* not_unique_name, 2611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::Distance distance) { 2612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0); 2613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label succeed; 2614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->testb(operand_or_register, 2615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Immediate(kIsNotStringMask | kIsNotInternalizedMask)); 2616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->j(zero, &succeed, Label::kNear); 2617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->cmpb(operand_or_register, Immediate(static_cast<uint8_t>(SYMBOL_TYPE))); 2618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->j(not_equal, not_unique_name, distance); 2619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->bind(&succeed); 2621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::JumpIfNotUniqueNameInstanceType(Operand operand, 2625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* not_unique_name, 2626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::Distance distance) { 2627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JumpIfNotUniqueNameHelper<Operand>(this, operand, not_unique_name, distance); 2628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::JumpIfNotUniqueNameInstanceType(Register reg, 2632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* not_unique_name, 2633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::Distance distance) { 2634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JumpIfNotUniqueNameHelper<Register>(this, reg, not_unique_name, distance); 2635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 263744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 26380d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid MacroAssembler::Move(Register dst, Register src) { 26390d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (!dst.is(src)) { 2640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 26416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 26426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 26436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 26446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Move(Register dst, Handle<Object> source) { 2646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllowDeferredHandleDereference smi_check; 2647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (source->IsSmi()) { 26483ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Move(dst, Smi::cast(*source)); 2649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MoveHeapObject(dst, source); 2651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Move(const Operand& dst, Handle<Object> source) { 2656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllowDeferredHandleDereference smi_check; 2657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (source->IsSmi()) { 26583ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Move(dst, Smi::cast(*source)); 2659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MoveHeapObject(kScratchRegister, source); 2661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, kScratchRegister); 2662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2666958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid MacroAssembler::Move(XMMRegister dst, uint32_t src) { 2667958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (src == 0) { 2668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Xorpd(dst, dst); 2669958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 2670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch unsigned pop = base::bits::CountPopulation32(src); 2671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_NE(0u, pop); 2672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (pop == 32) { 2673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pcmpeqd(dst, dst); 2674958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 2675958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier movl(kScratchRegister, Immediate(src)); 2676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movq(dst, kScratchRegister); 2677958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2678958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2679958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2680958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2681958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2682958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid MacroAssembler::Move(XMMRegister dst, uint64_t src) { 2683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (src == 0) { 2684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Xorpd(dst, dst); 2685958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 2686958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier unsigned nlz = base::bits::CountLeadingZeros64(src); 2687958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier unsigned ntz = base::bits::CountTrailingZeros64(src); 2688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch unsigned pop = base::bits::CountPopulation64(src); 2689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_NE(0u, pop); 2690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (pop == 64) { 2691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pcmpeqd(dst, dst); 2692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (pop + ntz == 64) { 2693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pcmpeqd(dst, dst); 2694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Psllq(dst, ntz); 2695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (pop + nlz == 64) { 2696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pcmpeqd(dst, dst); 2697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Psrlq(dst, nlz); 2698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t lower = static_cast<uint32_t>(src); 2700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t upper = static_cast<uint32_t>(src >> 32); 2701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (upper == 0) { 2702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Move(dst, lower); 2703958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 2704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movq(kScratchRegister, src); 2705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movq(dst, kScratchRegister); 2706958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2707958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2708958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2709958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2710958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2711958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movaps(XMMRegister dst, XMMRegister src) { 2713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovaps(dst, src); 27163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 2717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movaps(dst, src); 27183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 2719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movapd(XMMRegister dst, XMMRegister src) { 2723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovapd(dst, src); 2726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movapd(dst, src); 2728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movsd(XMMRegister dst, XMMRegister src) { 2733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovsd(dst, dst, src); 2736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movsd(dst, src); 2738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movsd(XMMRegister dst, const Operand& src) { 2743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovsd(dst, src); 27463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 2747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movsd(dst, src); 27483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 27493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 27503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 27513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movsd(const Operand& dst, XMMRegister src) { 2753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovsd(dst, src); 27563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 2757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movsd(dst, src); 27583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 27593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 27603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 27613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movss(XMMRegister dst, XMMRegister src) { 2763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovss(dst, dst, src); 2766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movss(dst, src); 2768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2769958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2770958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2771958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movss(XMMRegister dst, const Operand& src) { 2773014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovss(dst, src); 2776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movss(dst, src); 2778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2779958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2780958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2781958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movss(const Operand& dst, XMMRegister src) { 2783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovss(dst, src); 2786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movss(dst, src); 2788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movd(XMMRegister dst, Register src) { 2793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovd(dst, src); 2796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movd(dst, src); 2798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movd(XMMRegister dst, const Operand& src) { 2803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovd(dst, src); 28063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 2807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movd(dst, src); 28083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 28093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 28103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 28113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movd(Register dst, XMMRegister src) { 2813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovd(dst, src); 28163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 2817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movd(dst, src); 28183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 28193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 28203ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 28213ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 2822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movq(XMMRegister dst, Register src) { 2823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovq(dst, src); 2826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movq(dst, src); 2828e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 2829e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 2830e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2831e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movq(Register dst, XMMRegister src) { 2833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovq(dst, src); 2836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movq(dst, src); 2838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movmskpd(Register dst, XMMRegister src) { 2843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovmskpd(dst, src); 2846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movmskpd(dst, src); 2848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Roundss(XMMRegister dst, XMMRegister src, 2853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RoundingMode mode) { 2854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vroundss(dst, dst, src, mode); 2857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch roundss(dst, src, mode); 2859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Roundsd(XMMRegister dst, XMMRegister src, 2864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RoundingMode mode) { 2865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vroundsd(dst, dst, src, mode); 2868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch roundsd(dst, src, mode); 2870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Sqrtsd(XMMRegister dst, XMMRegister src) { 2875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsqrtsd(dst, dst, src); 2878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch sqrtsd(dst, src); 2880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Sqrtsd(XMMRegister dst, const Operand& src) { 2885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsqrtsd(dst, dst, src); 2888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch sqrtsd(dst, src); 2890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Ucomiss(XMMRegister src1, XMMRegister src2) { 2895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vucomiss(src1, src2); 2898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ucomiss(src1, src2); 2900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Ucomiss(XMMRegister src1, const Operand& src2) { 2905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vucomiss(src1, src2); 2908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ucomiss(src1, src2); 2910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Ucomisd(XMMRegister src1, XMMRegister src2) { 2915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vucomisd(src1, src2); 2918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ucomisd(src1, src2); 2920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Ucomisd(XMMRegister src1, const Operand& src2) { 2925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vucomisd(src1, src2); 2928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ucomisd(src1, src2); 2930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cmp(Register dst, Handle<Object> source) { 2935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AllowDeferredHandleDereference smi_check; 2936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (source->IsSmi()) { 2937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cmp(dst, Smi::cast(*source)); 2938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MoveHeapObject(kScratchRegister, source); 2940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cmpp(dst, kScratchRegister); 2941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cmp(const Operand& dst, Handle<Object> source) { 2946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AllowDeferredHandleDereference smi_check; 2947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (source->IsSmi()) { 2948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cmp(dst, Smi::cast(*source)); 2949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MoveHeapObject(kScratchRegister, source); 2951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cmpp(dst, kScratchRegister); 2952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Push(Handle<Object> source) { 2957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AllowDeferredHandleDereference smi_check; 2958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (source->IsSmi()) { 2959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(Smi::cast(*source)); 2960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MoveHeapObject(kScratchRegister, source); 2962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(kScratchRegister); 2963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::MoveHeapObject(Register result, 2968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> object) { 2969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AllowDeferredHandleDereference using_raw_address; 2970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(object->IsHeapObject()); 2971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (isolate()->heap()->InNewSpace(*object)) { 2972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Cell> cell = isolate()->factory()->NewCell(object); 2973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Move(result, cell, RelocInfo::CELL); 2974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(result, Operand(result, 0)); 2975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Move(result, object, RelocInfo::EMBEDDED_OBJECT); 2977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::LoadGlobalCell(Register dst, Handle<Cell> cell) { 2982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (dst.is(rax)) { 2983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AllowDeferredHandleDereference embedding_raw_address; 2984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch load_rax(cell.location(), RelocInfo::CELL); 2985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Move(dst, cell, RelocInfo::CELL); 2987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(dst, Operand(dst, 0)); 2988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::CmpWeakValue(Register value, Handle<WeakCell> cell, 2993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register scratch) { 2994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Move(scratch, cell, RelocInfo::EMBEDDED_OBJECT); 2995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cmpp(value, FieldOperand(scratch, WeakCell::kValueOffset)); 2996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::GetWeakValue(Register value, Handle<WeakCell> cell) { 3000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Move(value, cell, RelocInfo::EMBEDDED_OBJECT); 3001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(value, FieldOperand(value, WeakCell::kValueOffset)); 3002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::LoadWeakValue(Register value, Handle<WeakCell> cell, 3006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label* miss) { 3007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GetWeakValue(value, cell); 3008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JumpIfSmi(value, miss); 3009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Drop(int stack_elements) { 3013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (stack_elements > 0) { 3014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch addp(rsp, Immediate(stack_elements * kPointerSize)); 3015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::DropUnderReturnAddress(int stack_elements, 3020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register scratch) { 3021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(stack_elements > 0); 3022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize == kInt64Size && stack_elements == 1) { 3023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch popq(MemOperand(rsp, 0)); 3024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PopReturnAddressTo(scratch); 3028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Drop(stack_elements); 3029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PushReturnAddressFrom(scratch); 3030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Push(Register src) { 3034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize == kInt64Size) { 3035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pushq(src); 3036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // x32 uses 64-bit push for rbp in the prologue. 3038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(src.code() != rbp.code()); 3039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch leal(rsp, Operand(rsp, -4)); 3040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(Operand(rsp, 0), src); 3041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Push(const Operand& src) { 3046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize == kInt64Size) { 3047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pushq(src); 3048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(kScratchRegister, src); 3050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch leal(rsp, Operand(rsp, -4)); 3051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(Operand(rsp, 0), kScratchRegister); 3052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::PushQuad(const Operand& src) { 3057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize == kInt64Size) { 3058014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pushq(src); 3059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(kScratchRegister, src); 3061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pushq(kScratchRegister); 3062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Push(Immediate value) { 3067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize == kInt64Size) { 3068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pushq(value); 3069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch leal(rsp, Operand(rsp, -4)); 3071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(Operand(rsp, 0), value); 3072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::PushImm32(int32_t imm32) { 3077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize == kInt64Size) { 3078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pushq_imm32(imm32); 3079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch leal(rsp, Operand(rsp, -4)); 3081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(Operand(rsp, 0), Immediate(imm32)); 3082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Pop(Register dst) { 3087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize == kInt64Size) { 3088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch popq(dst); 3089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // x32 uses 64-bit pop for rbp in the epilogue. 3091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(dst.code() != rbp.code()); 3092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(dst, Operand(rsp, 0)); 3093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch leal(rsp, Operand(rsp, 4)); 3094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Pop(const Operand& dst) { 3099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize == kInt64Size) { 3100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch popq(dst); 3101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register scratch = dst.AddressUsesRegister(kScratchRegister) 3103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? kRootRegister : kScratchRegister; 3104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(scratch, Operand(rsp, 0)); 3105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(dst, scratch); 3106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch leal(rsp, Operand(rsp, 4)); 3107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (scratch.is(kRootRegister)) { 3108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Restore kRootRegister. 3109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InitializeRootRegister(); 3110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::PopQuad(const Operand& dst) { 3116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (kPointerSize == kInt64Size) { 3117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch popq(dst); 3118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch popq(kScratchRegister); 3120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, kScratchRegister); 3121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::LoadSharedFunctionInfoSpecialField(Register dst, 3126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register base, 3127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int offset) { 3128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(offset > SharedFunctionInfo::kLengthOffset && 3129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch offset <= SharedFunctionInfo::kSize && 3130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (((offset - SharedFunctionInfo::kLengthOffset) / kIntSize) % 2 == 1)); 3131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (kPointerSize == kInt64Size) { 3132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movsxlq(dst, FieldOperand(base, offset)); 3133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, FieldOperand(base, offset)); 3135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(dst, dst); 3136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::TestBitSharedFunctionInfoSpecialField(Register base, 3141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int offset, 3142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int bits) { 3143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(offset > SharedFunctionInfo::kLengthOffset && 3144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch offset <= SharedFunctionInfo::kSize && 3145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (((offset - SharedFunctionInfo::kLengthOffset) / kIntSize) % 2 == 1)); 3146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (kPointerSize == kInt32Size) { 3147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // On x32, this field is represented by SMI. 3148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bits += kSmiShift; 3149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 31503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int byte_offset = bits / kBitsPerByte; 31513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int bit_in_byte = bits & (kBitsPerByte - 1); 3152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testb(FieldOperand(base, offset + byte_offset), Immediate(1 << bit_in_byte)); 31533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 31543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 31553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Jump(ExternalReference ext) { 315744f0eee88ff00398ff7f715fab053374d808c90dSteve Block LoadAddress(kScratchRegister, ext); 3158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block jmp(kScratchRegister); 3159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Jump(const Operand& op) { 3163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (kPointerSize == kInt64Size) { 3164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jmp(op); 3165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, op); 3167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jmp(kScratchRegister); 3168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Jump(Address destination, RelocInfo::Mode rmode) { 3173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(kScratchRegister, destination, rmode); 3174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block jmp(kScratchRegister); 3175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Jump(Handle<Code> code_object, RelocInfo::Mode rmode) { 31793ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // TODO(X64): Inline this 31803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block jmp(code_object, rmode); 3181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 318444f0eee88ff00398ff7f715fab053374d808c90dSteve Blockint MacroAssembler::CallSize(ExternalReference ext) { 318544f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Opcode for call kScratchRegister is: Rex.B FF D4 (three bytes). 3186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return LoadAddressSize(ext) + 3187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler::kCallScratchRegisterInstructionLength; 318844f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 318944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 319044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 3191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Call(ExternalReference ext) { 319244f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG 319344f0eee88ff00398ff7f715fab053374d808c90dSteve Block int end_position = pc_offset() + CallSize(ext); 319444f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 319544f0eee88ff00398ff7f715fab053374d808c90dSteve Block LoadAddress(kScratchRegister, ext); 3196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block call(kScratchRegister); 319744f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG 319844f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(end_position, pc_offset()); 319944f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 3200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Call(const Operand& op) { 3204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize == kInt64Size && !CpuFeatures::IsSupported(ATOM)) { 3205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch call(op); 3206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, op); 3208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch call(kScratchRegister); 3209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Call(Address destination, RelocInfo::Mode rmode) { 321444f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG 3215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int end_position = pc_offset() + CallSize(destination); 321644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 3217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(kScratchRegister, destination, rmode); 3218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block call(kScratchRegister); 321944f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG 322044f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(pc_offset(), end_position); 322144f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 3222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3225257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::Call(Handle<Code> code_object, 3226257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch RelocInfo::Mode rmode, 3227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TypeFeedbackId ast_id) { 322844f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG 322944f0eee88ff00398ff7f715fab053374d808c90dSteve Block int end_position = pc_offset() + CallSize(code_object); 323044f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 3231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(RelocInfo::IsCodeTarget(rmode) || 3232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch rmode == RelocInfo::CODE_AGE_SEQUENCE); 3233257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch call(code_object, rmode, ast_id); 323444f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG 323544f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(end_position, pc_offset()); 323644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 3237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Pextrd(Register dst, XMMRegister src, int8_t imm8) { 3241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (imm8 == 0) { 3242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movd(dst, src); 3243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(1, imm8); 3246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(SSE4_1)) { 3247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope sse_scope(this, SSE4_1); 3248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pextrd(dst, src, imm8); 3249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movq(dst, src); 3252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch shrq(dst, Immediate(32)); 3253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Pinsrd(XMMRegister dst, Register src, int8_t imm8) { 3257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(SSE4_1)) { 3258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope sse_scope(this, SSE4_1); 3259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pinsrd(dst, src, imm8); 3260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movd(xmm0, src); 3263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (imm8 == 1) { 3264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch punpckldq(dst, xmm0); 3265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(0, imm8); 3267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movss(dst, xmm0); 3268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Pinsrd(XMMRegister dst, const Operand& src, int8_t imm8) { 3273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(imm8 == 0 || imm8 == 1); 3274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(SSE4_1)) { 3275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope sse_scope(this, SSE4_1); 3276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pinsrd(dst, src, imm8); 3277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movd(xmm0, src); 3280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (imm8 == 1) { 3281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch punpckldq(dst, xmm0); 3282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(0, imm8); 3284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movss(dst, xmm0); 3285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Lzcntl(Register dst, Register src) { 3290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(LZCNT)) { 3291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, LZCNT); 3292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch lzcntl(dst, src); 3293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label not_zero_src; 3296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bsrl(dst, src); 3297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(not_zero, ¬_zero_src, Label::kNear); 3298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(dst, 63); // 63^31 == 32 3299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(¬_zero_src); 3300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch xorl(dst, Immediate(31)); // for x in [0..31], 31^x == 31 - x 3301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Lzcntl(Register dst, const Operand& src) { 3305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(LZCNT)) { 3306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, LZCNT); 3307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch lzcntl(dst, src); 3308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label not_zero_src; 3311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bsrl(dst, src); 3312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(not_zero, ¬_zero_src, Label::kNear); 3313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(dst, 63); // 63^31 == 32 3314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(¬_zero_src); 3315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch xorl(dst, Immediate(31)); // for x in [0..31], 31^x == 31 - x 3316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Lzcntq(Register dst, Register src) { 3320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(LZCNT)) { 3321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, LZCNT); 3322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch lzcntq(dst, src); 3323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label not_zero_src; 3326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bsrq(dst, src); 3327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(not_zero, ¬_zero_src, Label::kNear); 3328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(dst, 127); // 127^63 == 64 3329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(¬_zero_src); 3330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch xorl(dst, Immediate(63)); // for x in [0..63], 63^x == 63 - x 3331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Lzcntq(Register dst, const Operand& src) { 3335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(LZCNT)) { 3336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, LZCNT); 3337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch lzcntq(dst, src); 3338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label not_zero_src; 3341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bsrq(dst, src); 3342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(not_zero, ¬_zero_src, Label::kNear); 3343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(dst, 127); // 127^63 == 64 3344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(¬_zero_src); 3345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch xorl(dst, Immediate(63)); // for x in [0..63], 63^x == 63 - x 3346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Tzcntq(Register dst, Register src) { 3350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(BMI1)) { 3351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, BMI1); 3352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch tzcntq(dst, src); 3353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label not_zero_src; 3356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bsfq(dst, src); 3357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(not_zero, ¬_zero_src, Label::kNear); 3358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Define the result of tzcnt(0) separately, because bsf(0) is undefined. 3359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(dst, 64); 3360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(¬_zero_src); 3361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Tzcntq(Register dst, const Operand& src) { 3365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(BMI1)) { 3366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, BMI1); 3367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch tzcntq(dst, src); 3368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label not_zero_src; 3371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bsfq(dst, src); 3372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(not_zero, ¬_zero_src, Label::kNear); 3373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Define the result of tzcnt(0) separately, because bsf(0) is undefined. 3374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(dst, 64); 3375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(¬_zero_src); 3376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Tzcntl(Register dst, Register src) { 3380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(BMI1)) { 3381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, BMI1); 3382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch tzcntl(dst, src); 3383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label not_zero_src; 3386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bsfl(dst, src); 3387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(not_zero, ¬_zero_src, Label::kNear); 3388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(dst, 32); // The result of tzcnt is 32 if src = 0. 3389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(¬_zero_src); 3390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Tzcntl(Register dst, const Operand& src) { 3394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(BMI1)) { 3395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, BMI1); 3396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch tzcntl(dst, src); 3397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label not_zero_src; 3400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bsfl(dst, src); 3401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(not_zero, ¬_zero_src, Label::kNear); 3402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(dst, 32); // The result of tzcnt is 32 if src = 0. 3403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(¬_zero_src); 3404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Popcntl(Register dst, Register src) { 3408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(POPCNT)) { 3409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, POPCNT); 3410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch popcntl(dst, src); 3411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 3414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Popcntl(Register dst, const Operand& src) { 3418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(POPCNT)) { 3419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, POPCNT); 3420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch popcntl(dst, src); 3421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 3424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Popcntq(Register dst, Register src) { 3428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(POPCNT)) { 3429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, POPCNT); 3430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch popcntq(dst, src); 3431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 3434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Popcntq(Register dst, const Operand& src) { 3438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(POPCNT)) { 3439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, POPCNT); 3440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch popcntq(dst, src); 3441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 3444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 34471e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::Pushad() { 3448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(rax); 3449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(rcx); 3450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(rdx); 3451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(rbx); 34521e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Not pushing rsp or rbp. 3453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(rsi); 3454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(rdi); 3455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(r8); 3456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(r9); 34571e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // r10 is kScratchRegister. 3458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(r11); 3459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(r12); 34601e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // r13 is kRootRegister. 3461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(r14); 3462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(r15); 3463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STATIC_ASSERT(12 == kNumSafepointSavedRegisters); 3464e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Use lea for symmetry with Popad. 3465e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int sp_delta = 3466e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch (kNumSafepointRegisters - kNumSafepointSavedRegisters) * kPointerSize; 3467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(rsp, Operand(rsp, -sp_delta)); 34681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 34691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 34701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 34711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::Popad() { 3472e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Popad must not change the flags, so use lea instead of addq. 3473e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int sp_delta = 3474e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch (kNumSafepointRegisters - kNumSafepointSavedRegisters) * kPointerSize; 3475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(rsp, Operand(rsp, sp_delta)); 3476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(r15); 3477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(r14); 3478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pop(r12); 3479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(r11); 3480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(r9); 3481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(r8); 3482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(rdi); 3483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(rsi); 3484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(rbx); 3485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(rdx); 3486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(rcx); 3487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(rax); 34881e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 34891e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 34901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 34911e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::Dropad() { 3492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(rsp, Immediate(kNumSafepointRegisters * kPointerSize)); 34931e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 34941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 34951e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 34961e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// Order general registers are pushed by Pushad: 349744f0eee88ff00398ff7f715fab053374d808c90dSteve Block// rax, rcx, rdx, rbx, rsi, rdi, r8, r9, r11, r14, r15. 34983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int 34993ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochMacroAssembler::kSafepointPushRegisterIndices[Register::kNumRegisters] = { 35001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 0, 35011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1, 35021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 2, 35031e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 3, 35041e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block -1, 35051e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block -1, 35061e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 4, 35071e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 5, 35081e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 6, 35091e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 7, 35101e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block -1, 35111e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 8, 351244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 9, 3513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch -1, 3514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 10, 3515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 11 35161e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}; 35171e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 35181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 3519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::StoreToSafepointRegisterSlot(Register dst, 3520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Immediate& imm) { 3521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(SafepointRegisterSlot(dst), imm); 3522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3525e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochvoid MacroAssembler::StoreToSafepointRegisterSlot(Register dst, Register src) { 3526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(SafepointRegisterSlot(dst), src); 3527e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 3528e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3529e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3530e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochvoid MacroAssembler::LoadFromSafepointRegisterSlot(Register dst, Register src) { 3531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, SafepointRegisterSlot(src)); 3532e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 3533e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3534e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3535e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochOperand MacroAssembler::SafepointRegisterSlot(Register reg) { 3536e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return Operand(rsp, SafepointRegisterStackIndex(reg.code()) * kPointerSize); 3537e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 3538e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3539e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::PushStackHandler() { 3541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Adjust this code if not the case. 3542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STATIC_ASSERT(StackHandlerConstants::kSize == 1 * kPointerSize); 35433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); 35443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 35453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Link the current handler as the next handler. 35463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); 3547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(ExternalOperand(handler_address)); 3548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 35493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Set this new handler as the current one. 3550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(ExternalOperand(handler_address), rsp); 3551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::PopStackHandler() { 35553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); 35563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); 3557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(ExternalOperand(handler_address)); 3558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize)); 3559e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 3560e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 3561e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 3562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Ret() { 3563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ret(0); 3564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 35671e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::Ret(int bytes_dropped, Register scratch) { 35681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (is_uint16(bytes_dropped)) { 35691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block ret(bytes_dropped); 35701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } else { 3571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PopReturnAddressTo(scratch); 3572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(rsp, Immediate(bytes_dropped)); 3573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushReturnAddressFrom(scratch); 35741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block ret(0); 35751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 35761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 35771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 35781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 3579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::FCmp() { 35803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block fucomip(); 35818defd9ff6930b4e24729971a61cf7469daf119beSteve Block fstp(0); 3582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::CmpObjectType(Register heap_object, 3586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InstanceType type, 3587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register map) { 3588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(map, FieldOperand(heap_object, HeapObject::kMapOffset)); 3589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CmpInstanceType(map, type); 3590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::CmpInstanceType(Register map, InstanceType type) { 3594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block cmpb(FieldOperand(map, Map::kInstanceTypeOffset), 3595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Immediate(static_cast<int8_t>(type))); 3596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 35993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid MacroAssembler::CheckFastElements(Register map, 36003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Label* fail, 36013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Label::Distance distance) { 3602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); 3603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); 3604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(FAST_ELEMENTS == 2); 3605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); 36063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cmpb(FieldOperand(map, Map::kBitField2Offset), 3607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Immediate(Map::kMaximumBitField2FastHoleyElementValue)); 36083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(above, fail, distance); 36093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 36103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::CheckFastObjectElements(Register map, 36133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* fail, 36143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label::Distance distance) { 3615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); 3616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); 3617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(FAST_ELEMENTS == 2); 3618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); 36193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cmpb(FieldOperand(map, Map::kBitField2Offset), 3620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Immediate(Map::kMaximumBitField2FastHoleySmiElementValue)); 36213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(below_equal, fail, distance); 3622592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch cmpb(FieldOperand(map, Map::kBitField2Offset), 3623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Immediate(Map::kMaximumBitField2FastHoleyElementValue)); 3624592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch j(above, fail, distance); 3625592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch} 3626592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 3627592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 3628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::CheckFastSmiElements(Register map, 3629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* fail, 3630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::Distance distance) { 3631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); 3632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); 36333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cmpb(FieldOperand(map, Map::kBitField2Offset), 3634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Immediate(Map::kMaximumBitField2FastHoleySmiElementValue)); 36353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(above, fail, distance); 36363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 36373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::StoreNumberToDoubleElements( 36403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register maybe_number, 36413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register elements, 36423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register index, 36433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch XMMRegister xmm_scratch, 3644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* fail, 3645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int elements_offset) { 3646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label smi_value, done; 36473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JumpIfSmi(maybe_number, &smi_value, Label::kNear); 36493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CheckMap(maybe_number, 36513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate()->factory()->heap_number_map(), 36523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch fail, 36533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DONT_DO_SMI_CHECK); 36543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Double value, turn potential sNaN into qNaN. 3656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Move(xmm_scratch, 1.0); 3657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch mulsd(xmm_scratch, FieldOperand(maybe_number, HeapNumber::kValueOffset)); 3658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jmp(&done, Label::kNear); 36593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bind(&smi_value); 36613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Value is a smi. convert to a double and store. 36623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Preserve original value. 36633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SmiToInteger32(kScratchRegister, maybe_number); 3664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Cvtlsi2sd(xmm_scratch, kScratchRegister); 3665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(&done); 3666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movsd(FieldOperand(elements, index, times_8, 3667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedDoubleArray::kHeaderSize - elements_offset), 36683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch xmm_scratch); 36693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 36703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::CompareMap(Register obj, Handle<Map> map) { 36733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Cmp(FieldOperand(obj, HeapObject::kMapOffset), map); 36743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 36753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36773100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid MacroAssembler::CheckMap(Register obj, 36783100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Handle<Map> map, 36793100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Label* fail, 3680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiCheckType smi_check_type) { 3681257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (smi_check_type == DO_SMI_CHECK) { 36823100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu JumpIfSmi(obj, fail); 36833100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 36843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompareMap(obj, map); 36863100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu j(not_equal, fail); 36873100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 36883100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 36893100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3690257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::ClampUint8(Register reg) { 3691257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label done; 3692257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch testl(reg, Immediate(0xFFFFFF00)); 3693257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(zero, &done, Label::kNear); 3694257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch setcc(negative, reg); // 1 if negative, 0 if positive. 3695257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch decb(reg); // 0 if negative, 255 if positive. 3696257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&done); 3697257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 3698257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3699257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3700257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::ClampDoubleToUint8(XMMRegister input_reg, 3701257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch XMMRegister temp_xmm_reg, 3702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register result_reg) { 3703257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label done; 3704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label conv_failure; 3705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Xorpd(temp_xmm_reg, temp_xmm_reg); 3706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cvtsd2si(result_reg, input_reg); 3707257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch testl(result_reg, Immediate(0xFFFFFF00)); 3708257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(zero, &done, Label::kNear); 3709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpl(result_reg, Immediate(1)); 3710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(overflow, &conv_failure, Label::kNear); 3711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(result_reg, Immediate(0)); 3712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch setcc(sign, result_reg); 3713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subl(result_reg, Immediate(1)); 3714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andl(result_reg, Immediate(255)); 3715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jmp(&done, Label::kNear); 3716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&conv_failure); 3717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Set(result_reg, 0); 3718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Ucomisd(input_reg, temp_xmm_reg); 3719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(below, &done, Label::kNear); 3720257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Set(result_reg, 255); 3721257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&done); 3722257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 3723257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3724257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::LoadUint32(XMMRegister dst, 3726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register src) { 3727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_debug_code) { 3728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpq(src, Immediate(0xffffffff)); 3729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assert(below_equal, kInputGPRIsExpectedToHaveUpper32Cleared); 3730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cvtqsi2sd(dst, src); 3732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::SlowTruncateToI(Register result_reg, 3736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register input_reg, 3737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int offset) { 3738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DoubleToIStub stub(isolate(), input_reg, result_reg, offset, true); 3739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch call(stub.GetCode(), RelocInfo::CODE_TARGET); 3740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::TruncateHeapNumberToI(Register result_reg, 3744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register input_reg) { 3745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done; 3746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); 3747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cvttsd2siq(result_reg, xmm0); 3748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpq(result_reg, Immediate(1)); 3749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(no_overflow, &done, Label::kNear); 3750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Slow case. 3752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (input_reg.is(result_reg)) { 3753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(rsp, Immediate(kDoubleSize)); 3754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movsd(MemOperand(rsp, 0), xmm0); 3755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SlowTruncateToI(result_reg, rsp, 0); 3756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(rsp, Immediate(kDoubleSize)); 3757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SlowTruncateToI(result_reg, input_reg); 3759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&done); 3762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Keep our invariant that the upper 32 bits are zero. 3763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(result_reg, result_reg); 3764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::TruncateDoubleToI(Register result_reg, 3768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch XMMRegister input_reg) { 3769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done; 3770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cvttsd2siq(result_reg, input_reg); 3771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpq(result_reg, Immediate(1)); 3772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(no_overflow, &done, Label::kNear); 3773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(rsp, Immediate(kDoubleSize)); 3775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movsd(MemOperand(rsp, 0), input_reg); 3776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SlowTruncateToI(result_reg, rsp, 0); 3777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(rsp, Immediate(kDoubleSize)); 3778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&done); 3780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Keep our invariant that the upper 32 bits are zero. 3781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(result_reg, result_reg); 3782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::DoubleToI(Register result_reg, XMMRegister input_reg, 3786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch XMMRegister scratch, 3787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MinusZeroMode minus_zero_mode, 3788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* lost_precision, Label* is_nan, 3789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* minus_zero, Label::Distance dst) { 3790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cvttsd2si(result_reg, input_reg); 3791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Cvtlsi2sd(xmm0, result_reg); 3792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Ucomisd(xmm0, input_reg); 3793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(not_equal, lost_precision, dst); 3794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(parity_even, is_nan, dst); // NaN. 3795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (minus_zero_mode == FAIL_ON_MINUS_ZERO) { 3796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done; 3797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The integer converted back is equal to the original. We 3798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // only have to test if we got -0 as an input. 3799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testl(result_reg, result_reg); 3800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(not_zero, &done, Label::kNear); 3801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movmskpd(result_reg, input_reg); 3802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Bit 0 contains the sign of the double in input_reg. 3803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If input was positive, we are ok and return 0, otherwise 3804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // jump to minus_zero. 3805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andl(result_reg, Immediate(1)); 3806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(not_zero, minus_zero, dst); 3807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&done); 3808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3812257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::LoadInstanceDescriptors(Register map, 3813257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register descriptors) { 3814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(descriptors, FieldOperand(map, Map::kDescriptorsOffset)); 3815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::NumberOfOwnDescriptors(Register dst, Register map) { 3819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(dst, FieldOperand(map, Map::kBitField3Offset)); 3820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DecodeField<Map::NumberOfOwnDescriptorsBits>(dst); 3821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::EnumLength(Register dst, Register map) { 3825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(Map::EnumLengthBits::kShift == 0); 3826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(dst, FieldOperand(map, Map::kBitField3Offset)); 3827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andl(dst, Immediate(Map::EnumLengthBits::kMask)); 3828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Integer32ToSmi(dst, dst); 3829257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 3830257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3831257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::LoadAccessor(Register dst, Register holder, 3833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int accessor_index, 3834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AccessorComponent accessor) { 3835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(dst, FieldOperand(holder, HeapObject::kMapOffset)); 3836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoadInstanceDescriptors(dst, dst); 3837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(dst, FieldOperand(dst, DescriptorArray::GetValueOffset(accessor_index))); 3838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int offset = accessor == ACCESSOR_GETTER ? AccessorPair::kGetterOffset 3839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : AccessorPair::kSetterOffset; 3840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(dst, FieldOperand(dst, offset)); 3841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3844958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid MacroAssembler::DispatchWeakMap(Register obj, Register scratch1, 3845958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register scratch2, Handle<WeakCell> cell, 3846958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Code> success, 3847958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SmiCheckType smi_check_type) { 3848257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label fail; 3849257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (smi_check_type == DO_SMI_CHECK) { 3850257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch JumpIfSmi(obj, &fail); 3851257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 3852958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier movq(scratch1, FieldOperand(obj, HeapObject::kMapOffset)); 3853958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CmpWeakValue(scratch1, cell, scratch2); 3854257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(equal, success, RelocInfo::CODE_TARGET); 3855257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&fail); 3856257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 3857257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3858257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertNumber(Register object) { 3860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 3861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label ok; 3862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition is_smi = CheckSmi(object); 3863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(is_smi, &ok, Label::kNear); 3864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Cmp(FieldOperand(object, HeapObject::kMapOffset), 3865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->factory()->heap_number_map()); 3866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(equal, kOperandIsNotANumber); 3867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&ok); 3868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3869402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu} 3870402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 38713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid MacroAssembler::AssertNotNumber(Register object) { 38723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (emit_debug_code()) { 38733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Condition is_smi = CheckSmi(object); 38743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Check(NegateCondition(is_smi), kOperandIsANumber); 38753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Cmp(FieldOperand(object, HeapObject::kMapOffset), 38763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch isolate()->factory()->heap_number_map()); 38773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Check(not_equal, kOperandIsANumber); 38783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 38793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 3880402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 3881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertNotSmi(Register object) { 3882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 3883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition is_smi = CheckSmi(object); 3884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(NegateCondition(is_smi), kOperandIsASmi); 3885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3886756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick} 3887756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 3888756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 3889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertSmi(Register object) { 3890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 3891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition is_smi = CheckSmi(object); 3892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(is_smi, kOperandIsNotASmi); 3893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 389444f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 389544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 389644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 3897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertSmi(const Operand& object) { 3898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 3899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition is_smi = CheckSmi(object); 3900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(is_smi, kOperandIsNotASmi); 3901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertZeroExtended(Register int32_register) { 3906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 3907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!int32_register.is(kScratchRegister)); 3908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movq(kScratchRegister, V8_INT64_C(0x0000000100000000)); 3909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpq(kScratchRegister, int32_register); 3910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(above_equal, k32BitValueInRegisterIsNotZeroExtended); 3911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertString(Register object) { 3916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 3917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testb(object, Immediate(kSmiTagMask)); 3918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(not_equal, kOperandIsASmiAndNotAString); 3919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(object); 3920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(object, FieldOperand(object, HeapObject::kMapOffset)); 3921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CmpInstanceType(object, FIRST_NONSTRING_TYPE); 3922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(object); 3923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(below, kOperandIsNotAString); 3924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 39256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 39266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 39276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertName(Register object) { 3929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 3930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testb(object, Immediate(kSmiTagMask)); 3931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(not_equal, kOperandIsASmiAndNotAName); 3932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(object); 3933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(object, FieldOperand(object, HeapObject::kMapOffset)); 3934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CmpInstanceType(object, LAST_NAME_TYPE); 3935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(object); 3936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(below_equal, kOperandIsNotAName); 3937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 39383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 39393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 39403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::AssertFunction(Register object) { 3942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (emit_debug_code()) { 3943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch testb(object, Immediate(kSmiTagMask)); 3944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Check(not_equal, kOperandIsASmiAndNotAFunction); 3945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(object); 3946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CmpObjectType(object, JS_FUNCTION_TYPE, object); 3947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pop(object); 3948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Check(equal, kOperandIsNotAFunction); 3949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::AssertBoundFunction(Register object) { 3954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (emit_debug_code()) { 3955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch testb(object, Immediate(kSmiTagMask)); 3956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Check(not_equal, kOperandIsASmiAndNotABoundFunction); 3957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(object); 3958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CmpObjectType(object, JS_BOUND_FUNCTION_TYPE, object); 3959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pop(object); 3960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Check(equal, kOperandIsNotABoundFunction); 3961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3964bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid MacroAssembler::AssertGeneratorObject(Register object) { 3965bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (emit_debug_code()) { 3966bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch testb(object, Immediate(kSmiTagMask)); 3967bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Check(not_equal, kOperandIsASmiAndNotAGeneratorObject); 3968bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Push(object); 3969bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch CmpObjectType(object, JS_GENERATOR_OBJECT_TYPE, object); 3970bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Pop(object); 3971bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Check(equal, kOperandIsNotAGeneratorObject); 3972bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 3973bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 3974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3975109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid MacroAssembler::AssertReceiver(Register object) { 3976109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (emit_debug_code()) { 3977109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch testb(object, Immediate(kSmiTagMask)); 3978109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Check(not_equal, kOperandIsASmiAndNotAReceiver); 3979109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Push(object); 3980109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE); 3981109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CmpObjectType(object, FIRST_JS_RECEIVER_TYPE, object); 3982109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Pop(object); 3983109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Check(above_equal, kOperandIsNotAReceiver); 3984109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 3985109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 3986109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 3987109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 3988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertUndefinedOrAllocationSite(Register object) { 3989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 3990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done_checking; 3991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertNotSmi(object); 3992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Cmp(object, isolate()->factory()->undefined_value()); 3993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(equal, &done_checking); 3994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Cmp(FieldOperand(object, 0), isolate()->factory()->allocation_site_map()); 3995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assert(equal, kExpectedUndefinedOrCell); 3996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&done_checking); 3997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3998e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 3999e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 4000e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 4001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertRootValue(Register src, 4002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap::RootListIndex root_value_index, 4003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutReason reason) { 4004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 4005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src.is(kScratchRegister)); 4006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadRoot(kScratchRegister, root_value_index); 4007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(src, kScratchRegister); 4008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(equal, reason); 4009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 40109dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen} 40119dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 40129dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 40139dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 4014d91b9f7d46489a9ee00f9cb415630299c76a502bLeon ClarkeCondition MacroAssembler::IsObjectStringType(Register heap_object, 4015d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Register map, 4016d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Register instance_type) { 4017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(map, FieldOperand(heap_object, HeapObject::kMapOffset)); 40184515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke movzxbl(instance_type, FieldOperand(map, Map::kInstanceTypeOffset)); 401969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch STATIC_ASSERT(kNotStringTag != 0); 4020d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke testb(instance_type, Immediate(kIsNotStringMask)); 4021d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return zero; 4022d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 4023d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 4024d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 4025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochCondition MacroAssembler::IsObjectNameType(Register heap_object, 4026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register map, 4027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register instance_type) { 4028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(map, FieldOperand(heap_object, HeapObject::kMapOffset)); 4029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movzxbl(instance_type, FieldOperand(map, Map::kInstanceTypeOffset)); 4030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpb(instance_type, Immediate(static_cast<uint8_t>(LAST_NAME_TYPE))); 4031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return below_equal; 4032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::GetMapConstructor(Register result, Register map, 4036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register temp) { 4037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label done, loop; 4038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(result, FieldOperand(map, Map::kConstructorOrBackPointerOffset)); 4039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(&loop); 4040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JumpIfSmi(result, &done, Label::kNear); 4041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CmpObjectType(result, MAP_TYPE, temp); 4042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(not_equal, &done, Label::kNear); 4043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(result, FieldOperand(result, Map::kConstructorOrBackPointerOffset)); 4044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jmp(&loop); 4045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(&done); 4046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 40473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::TryGetFunctionPrototype(Register function, Register result, 4050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label* miss) { 4051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the prototype or initial map from the function. 4052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(result, 4053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); 4054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the prototype or initial map is the hole, don't return it and 4056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // simply miss the cache instead. This will allow us to allocate a 4057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // prototype object on-demand in the runtime system. 4058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompareRoot(result, Heap::kTheHoleValueRootIndex); 4059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block j(equal, miss); 4060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the function does not have an initial map, we're done. 4062257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label done; 4063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CmpObjectType(result, MAP_TYPE, kScratchRegister); 4064257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_equal, &done, Label::kNear); 4065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the prototype from the initial map. 4067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(result, FieldOperand(result, Map::kPrototypeOffset)); 4068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // All done. 4070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bind(&done); 4071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SetCounter(StatsCounter* counter, int value) { 4075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_native_code_counters && counter->Enabled()) { 407644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Operand counter_operand = ExternalOperand(ExternalReference(counter)); 40778b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch movl(counter_operand, Immediate(value)); 4078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::IncrementCounter(StatsCounter* counter, int value) { 4083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(value > 0); 4084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_native_code_counters && counter->Enabled()) { 408544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Operand counter_operand = ExternalOperand(ExternalReference(counter)); 4086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (value == 1) { 408744f0eee88ff00398ff7f715fab053374d808c90dSteve Block incl(counter_operand); 4088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 408944f0eee88ff00398ff7f715fab053374d808c90dSteve Block addl(counter_operand, Immediate(value)); 4090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::DecrementCounter(StatsCounter* counter, int value) { 4096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(value > 0); 4097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_native_code_counters && counter->Enabled()) { 409844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Operand counter_operand = ExternalOperand(ExternalReference(counter)); 4099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (value == 1) { 410044f0eee88ff00398ff7f715fab053374d808c90dSteve Block decl(counter_operand); 4101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 410244f0eee88ff00398ff7f715fab053374d808c90dSteve Block subl(counter_operand, Immediate(value)); 4103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4108402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuvoid MacroAssembler::DebugBreak() { 41099fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block Set(rax, 0); // No arguments. 4110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoadAddress(rbx, 4111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ExternalReference(Runtime::kHandleDebuggerStatement, isolate())); 4112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CEntryStub ces(isolate(), 1); 4113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(AllowThisStubCall(&ces)); 4114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Call(ces.GetCode(), RelocInfo::DEBUGGER_STATEMENT); 4115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 4116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 41173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid MacroAssembler::PrepareForTailCall(const ParameterCount& callee_args_count, 41183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register caller_args_count_reg, 41193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register scratch0, Register scratch1, 41203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ReturnAddressState ra_state) { 41213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#if DEBUG 41223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (callee_args_count.is_reg()) { 41233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(!AreAliased(callee_args_count.reg(), caller_args_count_reg, scratch0, 41243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch scratch1)); 41253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 41263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(!AreAliased(caller_args_count_reg, scratch0, scratch1)); 41273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 41283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#endif 41293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 41303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Calculate the destination address where we will put the return address 41313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // after we drop current frame. 41323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register new_sp_reg = scratch0; 41333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (callee_args_count.is_reg()) { 41343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch subp(caller_args_count_reg, callee_args_count.reg()); 41353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch leap(new_sp_reg, Operand(rbp, caller_args_count_reg, times_pointer_size, 41363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch StandardFrameConstants::kCallerPCOffset)); 41373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 41383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch leap(new_sp_reg, Operand(rbp, caller_args_count_reg, times_pointer_size, 41393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch StandardFrameConstants::kCallerPCOffset - 41403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch callee_args_count.immediate() * kPointerSize)); 41413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 41423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 41433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (FLAG_debug_code) { 41443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cmpp(rsp, new_sp_reg); 41453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Check(below, kStackAccessBelowStackPointer); 41463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 41473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 41483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Copy return address from caller's frame to current frame's return address 41493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // to avoid its trashing and let the following loop copy it to the right 41503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // place. 41513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register tmp_reg = scratch1; 41523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (ra_state == ReturnAddressState::kOnStack) { 41533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch movp(tmp_reg, Operand(rbp, StandardFrameConstants::kCallerPCOffset)); 41543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch movp(Operand(rsp, 0), tmp_reg); 41553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 41563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(ReturnAddressState::kNotOnStack == ra_state); 41573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Push(Operand(rbp, StandardFrameConstants::kCallerPCOffset)); 41583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 41593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 41603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Restore caller's frame pointer now as it could be overwritten by 41613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // the copying loop. 41623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch movp(rbp, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); 41633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 41643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // +2 here is to copy both receiver and return address. 41653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register count_reg = caller_args_count_reg; 41663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (callee_args_count.is_reg()) { 41673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch leap(count_reg, Operand(callee_args_count.reg(), 2)); 41683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 41693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch movp(count_reg, Immediate(callee_args_count.immediate() + 2)); 41703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // TODO(ishell): Unroll copying loop for small immediate values. 41713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 41723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 41733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Now copy callee arguments to the caller frame going backwards to avoid 41743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // callee arguments corruption (source and destination areas could overlap). 41753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Label loop, entry; 41763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch jmp(&entry, Label::kNear); 41773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch bind(&loop); 41783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch decp(count_reg); 41793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch movp(tmp_reg, Operand(rsp, count_reg, times_pointer_size, 0)); 41803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch movp(Operand(new_sp_reg, count_reg, times_pointer_size, 0), tmp_reg); 41813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch bind(&entry); 41823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cmpp(count_reg, Immediate(0)); 41833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch j(not_equal, &loop, Label::kNear); 41843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 41853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Leave current frame. 41863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch movp(rsp, new_sp_reg); 41873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 4188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::InvokeFunction(Register function, 4190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register new_target, 4191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& actual, 4192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InvokeFlag flag, 4193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const CallWrapper& call_wrapper) { 4194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(rbx, FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); 4195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoadSharedFunctionInfoSpecialField( 4196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch rbx, rbx, SharedFunctionInfo::kFormalParameterCountOffset); 4197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ParameterCount expected(rbx); 4199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InvokeFunction(function, new_target, expected, actual, flag, call_wrapper); 4200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 4201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::InvokeFunction(Handle<JSFunction> function, 4204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& expected, 4205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& actual, 4206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InvokeFlag flag, 4207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const CallWrapper& call_wrapper) { 4208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Move(rdi, function); 4209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InvokeFunction(rdi, no_reg, expected, actual, flag, call_wrapper); 4210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4211257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 4212257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 4213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::InvokeFunction(Register function, 4214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register new_target, 4215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& expected, 4216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& actual, 4217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InvokeFlag flag, 4218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const CallWrapper& call_wrapper) { 4219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(function.is(rdi)); 4220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(rsi, FieldOperand(function, JSFunction::kContextOffset)); 4221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InvokeFunctionCode(rdi, new_target, expected, actual, flag, call_wrapper); 4222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 4223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::InvokeFunctionCode(Register function, Register new_target, 4226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& expected, 4227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& actual, 4228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InvokeFlag flag, 4229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const CallWrapper& call_wrapper) { 42303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // You can't call a function without a valid frame. 4231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(flag == JUMP_FUNCTION || has_frame()); 4232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(function.is(rdi)); 4233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_IMPLIES(new_target.is_valid(), new_target.is(rdx)); 4234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (call_wrapper.NeedsDebugStepCheck()) { 4236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FloodFunctionIfStepping(function, new_target, expected, actual); 4237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Clear the new.target register if not given. 4240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!new_target.is_valid()) { 4241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoadRoot(rdx, Heap::kUndefinedValueRootIndex); 4242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 42433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4244257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label done; 42453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool definitely_mismatches = false; 4246e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch InvokePrologue(expected, 4247e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch actual, 4248e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch &done, 42493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch &definitely_mismatches, 4250e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch flag, 4251257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::kNear, 4252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch call_wrapper); 42533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!definitely_mismatches) { 4254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // We call indirectly through the code field in the function to 4255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // allow recompilation to take effect without changing any of the 4256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // call sites. 4257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand code = FieldOperand(function, JSFunction::kCodeEntryOffset); 42583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (flag == CALL_FUNCTION) { 42593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch call_wrapper.BeforeCall(CallSize(code)); 42603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch call(code); 42613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch call_wrapper.AfterCall(); 42623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 4263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(flag == JUMP_FUNCTION); 42643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch jmp(code); 42653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 42663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bind(&done); 4267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4271257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::InvokePrologue(const ParameterCount& expected, 4272257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch const ParameterCount& actual, 4273257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* done, 42743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool* definitely_mismatches, 4275257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch InvokeFlag flag, 4276257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump, 4277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const CallWrapper& call_wrapper) { 4278257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bool definitely_matches = false; 42793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *definitely_mismatches = false; 4280257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label invoke; 4281257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (expected.is_immediate()) { 4282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(actual.is_immediate()); 4283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(rax, actual.immediate()); 4284257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (expected.immediate() == actual.immediate()) { 4285257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch definitely_matches = true; 4286257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 4287257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (expected.immediate() == 4288257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch SharedFunctionInfo::kDontAdaptArgumentsSentinel) { 4289257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Don't worry about adapting arguments for built-ins that 4290257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // don't want that done. Skip adaption code by making it look 4291257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // like we have a match between expected and actual number of 4292257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // arguments. 4293257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch definitely_matches = true; 4294257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 42953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *definitely_mismatches = true; 4296257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Set(rbx, expected.immediate()); 4297257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 4298257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 4299257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 4300257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (actual.is_immediate()) { 4301257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Expected is in register, actual is immediate. This is the 4302257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // case when we invoke function values without going through the 4303257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // IC mechanism. 4304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(rax, actual.immediate()); 4305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(expected.reg(), Immediate(actual.immediate())); 4306257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(equal, &invoke, Label::kNear); 4307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(expected.reg().is(rbx)); 4308257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else if (!expected.reg().is(actual.reg())) { 4309257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Both expected and actual are in (different) registers. This 4310257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // is the case when we invoke functions using call and apply. 4311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(expected.reg(), actual.reg()); 4312257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(equal, &invoke, Label::kNear); 4313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(actual.reg().is(rax)); 4314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(expected.reg().is(rbx)); 4315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 4316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Move(rax, actual.reg()); 4317257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 4318257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 4319257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 4320257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!definitely_matches) { 4321257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<Code> adaptor = isolate()->builtins()->ArgumentsAdaptorTrampoline(); 4322257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (flag == CALL_FUNCTION) { 4323257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch call_wrapper.BeforeCall(CallSize(adaptor)); 4324257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Call(adaptor, RelocInfo::CODE_TARGET); 4325257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch call_wrapper.AfterCall(); 43263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!*definitely_mismatches) { 43273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch jmp(done, near_jump); 43283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4329257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 4330257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Jump(adaptor, RelocInfo::CODE_TARGET); 4331257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 4332257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&invoke); 43331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 4334402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu} 4335402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 4336402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 4337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::FloodFunctionIfStepping(Register fun, Register new_target, 4338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& expected, 4339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& actual) { 4340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label skip_flooding; 4341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ExternalReference step_in_enabled = 4342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ExternalReference::debug_step_in_enabled_address(isolate()); 4343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand step_in_enabled_operand = ExternalOperand(step_in_enabled); 4344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cmpb(step_in_enabled_operand, Immediate(0)); 4345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(equal, &skip_flooding); 4346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { 4347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FrameScope frame(this, 4348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch has_frame() ? StackFrame::NONE : StackFrame::INTERNAL); 4349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (expected.is_reg()) { 4350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Integer32ToSmi(expected.reg(), expected.reg()); 4351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(expected.reg()); 4352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (actual.is_reg()) { 4354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Integer32ToSmi(actual.reg(), actual.reg()); 4355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(actual.reg()); 4356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (new_target.is_valid()) { 4358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(new_target); 4359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(fun); 4361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(fun); 4362109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CallRuntime(Runtime::kDebugPrepareStepInIfStepping); 4363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pop(fun); 4364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (new_target.is_valid()) { 4365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pop(new_target); 4366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (actual.is_reg()) { 4368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pop(actual.reg()); 4369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SmiToInteger64(actual.reg(), actual.reg()); 4370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (expected.is_reg()) { 4372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pop(expected.reg()); 4373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SmiToInteger64(expected.reg(), expected.reg()); 4374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(&skip_flooding); 4377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 4378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 43793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid MacroAssembler::StubPrologue(StackFrame::Type type) { 43803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch pushq(rbp); // Caller's frame pointer. 43813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch movp(rbp, rsp); 43823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Push(Smi::FromInt(type)); 4383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Prologue(bool code_pre_aging) { 4386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PredictableCodeSizeScope predictible_code_size_scope(this, 4387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kNoCodeAgeSequenceLength); 4388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (code_pre_aging) { 4389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Pre-age the code. 4390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Call(isolate()->builtins()->MarkCodeAsExecutedOnce(), 4391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfo::CODE_AGE_SEQUENCE); 4392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Nop(kNoCodeAgeSequenceLength - Assembler::kShortCallInstructionLength); 4393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pushq(rbp); // Caller's frame pointer. 4395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rbp, rsp); 4396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(rsi); // Callee's context. 4397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(rdi); // Callee's JS function. 4398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::EmitLoadTypeFeedbackVector(Register vector) { 4403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(vector, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 4404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(vector, FieldOperand(vector, JSFunction::kSharedFunctionInfoOffset)); 4405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(vector, FieldOperand(vector, SharedFunctionInfo::kFeedbackVectorOffset)); 4406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 4407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4409958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid MacroAssembler::EnterFrame(StackFrame::Type type, 4410958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool load_constant_pool_pointer_reg) { 4411958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Out-of-line constant pool not implemented on x64. 4412958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNREACHABLE(); 4413958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 4414958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 4415958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 4416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::EnterFrame(StackFrame::Type type) { 4417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pushq(rbp); 4418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rbp, rsp); 44193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Push(Smi::FromInt(type)); 44203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (type == StackFrame::INTERNAL) { 44213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Move(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); 44223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Push(kScratchRegister); 44233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 442444f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 4425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(kScratchRegister, 4426257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch isolate()->factory()->undefined_value(), 4427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfo::EMBEDDED_OBJECT); 4428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(Operand(rsp, 0), kScratchRegister); 4429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(not_equal, kCodeObjectNotProperlyPatched); 4430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::LeaveFrame(StackFrame::Type type) { 443544f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 44363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Move(kScratchRegister, Smi::FromInt(type)); 44373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cmpp(Operand(rbp, CommonFrameConstants::kContextOrFrameTypeOffset), 44383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch kScratchRegister); 4439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(equal, kStackFrameTypesMustMatch); 4440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rsp, rbp); 4442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch popq(rbp); 4443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 444680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenvoid MacroAssembler::EnterExitFramePrologue(bool save_rax) { 44473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Set up the frame structure on the stack. 4448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // All constants are relative to the frame pointer of the exit frame. 44493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_EQ(kFPOnStackSize + kPCOnStackSize, 44503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ExitFrameConstants::kCallerSPDisplacement); 44513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_EQ(kFPOnStackSize, ExitFrameConstants::kCallerPCOffset); 44523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_EQ(0 * kPointerSize, ExitFrameConstants::kCallerFPOffset); 4453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pushq(rbp); 4454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rbp, rsp); 4455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 445680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Reserve room for entry stack pointer and push the code object. 44573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Push(Smi::FromInt(StackFrame::EXIT)); 44583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_EQ(-2 * kPointerSize, ExitFrameConstants::kSPOffset); 4459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(Immediate(0)); // Saved entry sp, patched before call. 4460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); 4461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(kScratchRegister); // Accessed from EditFrame::code_slot. 4462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Save the frame pointer and the context in top. 4464bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch if (save_rax) { 4465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(r14, rax); // Backup rax in callee-save register. 4466bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } 4467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4468589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Store(ExternalReference(Isolate::kCEntryFPAddress, isolate()), rbp); 4469589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Store(ExternalReference(Isolate::kContextAddress, isolate()), rsi); 4470958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Store(ExternalReference(Isolate::kCFunctionAddress, isolate()), rbx); 4471bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch} 4472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 44738a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 44741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space, 44751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block bool save_doubles) { 4476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef _WIN64 44771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block const int kShadowSpace = 4; 44781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block arg_stack_space += kShadowSpace; 4479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 44801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Optionally save all XMM registers. 44811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (save_doubles) { 4482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int space = XMMRegister::kMaxNumRegisters * kDoubleSize + 4483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch arg_stack_space * kRegisterSize; 4484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(rsp, Immediate(space)); 44853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int offset = -ExitFrameConstants::kFixedFrameSizeFromFp; 4486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const RegisterConfiguration* config = 4487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RegisterConfiguration::ArchDefault(RegisterConfiguration::CRANKSHAFT); 4488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < config->num_allocatable_double_registers(); ++i) { 4489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister reg = 4490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister::from_code(config->GetAllocatableDoubleCode(i)); 4491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movsd(Operand(rbp, offset - ((i + 1) * kDoubleSize)), reg); 44921e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 44931e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } else if (arg_stack_space > 0) { 4494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(rsp, Immediate(arg_stack_space * kRegisterSize)); 44958a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang } 4496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the required frame alignment for the OS. 4498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int kFrameAlignment = base::OS::ActivationFrameAlignment(); 4499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (kFrameAlignment > 0) { 4500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(base::bits::IsPowerOfTwo32(kFrameAlignment)); 4501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_int8(kFrameAlignment)); 4502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(rsp, Immediate(-kFrameAlignment)); 4503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Patch the saved entry sp. 4506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(rbp, ExitFrameConstants::kSPOffset), rsp); 4507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 45101e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::EnterExitFrame(int arg_stack_space, bool save_doubles) { 451180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen EnterExitFramePrologue(true); 4512bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 45133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Set up argv in callee-saved register r15. It is reused in LeaveExitFrame, 4514bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch // so it must be retained across the C-call. 4515bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; 4516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(r15, Operand(rbp, r14, times_pointer_size, offset)); 4517bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 45181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block EnterExitFrameEpilogue(arg_stack_space, save_doubles); 4519bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch} 4520bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 4521bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 45228a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wangvoid MacroAssembler::EnterApiExitFrame(int arg_stack_space) { 452380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen EnterExitFramePrologue(false); 45241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block EnterExitFrameEpilogue(arg_stack_space, false); 4525bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch} 4526bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 4527bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 4528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::LeaveExitFrame(bool save_doubles, bool pop_arguments) { 4529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Registers: 453044f0eee88ff00398ff7f715fab053374d808c90dSteve Block // r15 : argv 45311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (save_doubles) { 45323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int offset = -ExitFrameConstants::kFixedFrameSizeFromFp; 4533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const RegisterConfiguration* config = 4534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RegisterConfiguration::ArchDefault(RegisterConfiguration::CRANKSHAFT); 4535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < config->num_allocatable_double_registers(); ++i) { 4536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister reg = 4537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister::from_code(config->GetAllocatableDoubleCode(i)); 4538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movsd(reg, Operand(rbp, offset - ((i + 1) * kDoubleSize))); 45391e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 45401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 4541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (pop_arguments) { 4543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Get the return address from the stack and restore the frame pointer. 4544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(rcx, Operand(rbp, kFPOnStackSize)); 4545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(rbp, Operand(rbp, 0 * kPointerSize)); 4546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Drop everything up to and including the arguments and the receiver 4548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // from the caller stack. 4549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch leap(rsp, Operand(r15, 1 * kPointerSize)); 4550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PushReturnAddressFrom(rcx); 4552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 4553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Otherwise just leave the exit frame. 4554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch leave(); 4555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 45568a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 4557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LeaveExitFrameEpilogue(true); 45588a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang} 45598a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 45608a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 4561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::LeaveApiExitFrame(bool restore_context) { 4562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rsp, rbp); 4563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch popq(rbp); 45648a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 4565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LeaveExitFrameEpilogue(restore_context); 45668a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang} 45678a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 45688a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 4569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::LeaveExitFrameEpilogue(bool restore_context) { 4570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Restore current context from top and clear it in debug mode. 4571589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch ExternalReference context_address(Isolate::kContextAddress, isolate()); 457244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Operand context_operand = ExternalOperand(context_address); 4573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (restore_context) { 4574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rsi, context_operand); 4575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 4577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(context_operand, Immediate(0)); 4578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 4579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear the top frame. 4581589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress, 458244f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate()); 458344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Operand c_entry_fp_operand = ExternalOperand(c_entry_fp_address); 4584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(c_entry_fp_operand, Immediate(0)); 4585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, 4589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch, 4590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label* miss) { 4591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label same_contexts; 4592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!holder_reg.is(scratch)); 4594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!scratch.is(kScratchRegister)); 45953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Load current lexical context from the active StandardFrame, which 45963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // may require crawling past STUB frames. 45973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Label load_context; 45983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Label has_context; 45993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch movp(scratch, rbp); 46003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch bind(&load_context); 46013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(SmiValuesAre32Bits()); 46023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // This is "JumpIfNotSmi" but without loading the value into a register. 46033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cmpl(MemOperand(scratch, CommonFrameConstants::kContextOrFrameTypeOffset), 46043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Immediate(0)); 46053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch j(not_equal, &has_context); 46063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch movp(scratch, MemOperand(scratch, CommonFrameConstants::kCallerFPOffset)); 46073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch jmp(&load_context); 46083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch bind(&has_context); 46093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch movp(scratch, 46103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch MemOperand(scratch, CommonFrameConstants::kContextOrFrameTypeOffset)); 4611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // When generating debug code, make sure the lexical context is set. 461344f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 4614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(scratch, Immediate(0)); 4615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(not_equal, kWeShouldNotHaveAnEmptyLexicalContext); 4616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load the native context of the current context. 4618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(scratch, ContextOperand(scratch, Context::NATIVE_CONTEXT_INDEX)); 4619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check the context is a native context. 462144f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 4622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Cmp(FieldOperand(scratch, HeapObject::kMapOffset), 4623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->factory()->native_context_map()); 4624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(equal, kJSGlobalObjectNativeContextShouldBeANativeContext); 4625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check if both contexts are the same. 4628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(scratch, FieldOperand(holder_reg, JSGlobalProxy::kNativeContextOffset)); 4629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block j(equal, &same_contexts); 4630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compare security tokens. 4632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that the security token in the calling global object is 4633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // compatible with the security token in the receiving global 4634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // object. 4635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check the context is a native context. 463744f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 4638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Preserve original value of holder_reg. 4639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(holder_reg); 4640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(holder_reg, 4641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FieldOperand(holder_reg, JSGlobalProxy::kNativeContextOffset)); 4642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompareRoot(holder_reg, Heap::kNullValueRootIndex); 4643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(not_equal, kJSGlobalProxyContextShouldNotBeNull); 4644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Read the first word and compare to native_context_map(), 4646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(holder_reg, FieldOperand(holder_reg, HeapObject::kMapOffset)); 4647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompareRoot(holder_reg, Heap::kNativeContextMapRootIndex); 4648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(equal, kJSGlobalObjectNativeContextShouldBeANativeContext); 4649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(holder_reg); 4650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, 4653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FieldOperand(holder_reg, JSGlobalProxy::kNativeContextOffset)); 46543ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int token_offset = 46553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Context::kHeaderSize + Context::SECURITY_TOKEN_INDEX * kPointerSize; 4656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch, FieldOperand(scratch, token_offset)); 4657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(scratch, FieldOperand(kScratchRegister, token_offset)); 4658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block j(not_equal, miss); 4659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bind(&same_contexts); 4661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Compute the hash code from the untagged key. This must be kept in sync with 4665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ComputeIntegerHash in utils.h and KeyedLoadGenericStub in 4666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// code-stub-hydrogen.cc 4667c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdochvoid MacroAssembler::GetNumberHash(Register r0, Register scratch) { 4668c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // First of all we assign the hash seed to scratch. 4669c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch LoadRoot(scratch, Heap::kHashSeedRootIndex); 4670c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch SmiToInteger32(scratch, scratch); 4671c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch 4672c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // Xor original key with a seed. 4673c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch xorl(r0, scratch); 4674c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch 4675c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // Compute the hash code from the untagged key. This must be kept in sync 4676c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // with ComputeIntegerHash in utils.h. 4677c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // 4678c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // hash = ~hash + (hash << 15); 4679c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch movl(scratch, r0); 4680c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch notl(r0); 4681c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch shll(scratch, Immediate(15)); 4682c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch addl(r0, scratch); 4683c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // hash = hash ^ (hash >> 12); 4684c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch movl(scratch, r0); 4685c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch shrl(scratch, Immediate(12)); 4686c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch xorl(r0, scratch); 4687c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // hash = hash + (hash << 2); 4688c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch leal(r0, Operand(r0, r0, times_4, 0)); 4689c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // hash = hash ^ (hash >> 4); 4690c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch movl(scratch, r0); 4691c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch shrl(scratch, Immediate(4)); 4692c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch xorl(r0, scratch); 4693c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // hash = hash * 2057; 4694c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch imull(r0, r0, Immediate(2057)); 4695c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // hash = hash ^ (hash >> 16); 4696c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch movl(scratch, r0); 4697c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch shrl(scratch, Immediate(16)); 4698c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch xorl(r0, scratch); 4699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch andl(r0, Immediate(0x3fffffff)); 4700c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch} 4701c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch 4702c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch 4703c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch 47043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid MacroAssembler::LoadFromNumberDictionary(Label* miss, 47053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Register elements, 47063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Register key, 47073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Register r0, 47083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Register r1, 47093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Register r2, 47103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Register result) { 47113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Register use: 47123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // 47133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // elements - holds the slow-case elements of the receiver on entry. 47143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Unchanged unless 'result' is the same register. 47153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // 47163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // key - holds the smi key on entry. 47173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Unchanged unless 'result' is the same register. 47183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // 47193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Scratch registers: 47203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // 47213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // r0 - holds the untagged key on entry and holds the hash once computed. 47223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // 47233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // r1 - used to hold the capacity mask of the dictionary 47243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // 47253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // r2 - used for the index into the dictionary. 47263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // 47273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // result - holds the result on exit if the load succeeded. 47283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Allowed to be the same as 'key' or 'result'. 47293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Unchanged on bailout so 'key' or 'result' can be used 47303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // in further computation. 47313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 47323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Label done; 47333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4734c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch GetNumberHash(r0, r1); 47353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 47363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Compute capacity mask. 4737c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch SmiToInteger32(r1, FieldOperand(elements, 4738c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch SeededNumberDictionary::kCapacityOffset)); 47393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch decl(r1); 47403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 47413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Generate an unrolled loop that performs a few probes before giving up. 4742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < kNumberDictionaryProbes; i++) { 47433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Use r2 for index calculations and keep the hash intact in r0. 4744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(r2, r0); 47453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Compute the masked index: (hash + i + i * i) & mask. 47463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (i > 0) { 4747c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch addl(r2, Immediate(SeededNumberDictionary::GetProbeOffset(i))); 47483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 4749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(r2, r1); 47503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 47513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Scale the index by multiplying by the entry size. 4752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SeededNumberDictionary::kEntrySize == 3); 4753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(r2, Operand(r2, r2, times_2, 0)); // r2 = r2 * 3 47543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 47553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Check if the key matches. 4756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(key, FieldOperand(elements, 47573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch r2, 47583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch times_pointer_size, 4759c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch SeededNumberDictionary::kElementsStartOffset)); 4760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (i != (kNumberDictionaryProbes - 1)) { 47613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch j(equal, &done); 47623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 47633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch j(not_equal, miss); 47643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 47653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 47663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 47673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bind(&done); 4768958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Check that the value is a field property. 47693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const int kDetailsOffset = 4770c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch SeededNumberDictionary::kElementsStartOffset + 2 * kPointerSize; 4771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(DATA, 0); 47723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset), 4773589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Smi::FromInt(PropertyDetails::TypeField::kMask)); 47743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch j(not_zero, miss); 47753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 47763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Get the value at the masked, scaled index. 47773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const int kValueOffset = 4778c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch SeededNumberDictionary::kElementsStartOffset + kPointerSize; 4779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(result, FieldOperand(elements, r2, times_pointer_size, kValueOffset)); 47803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 47813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 47823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::LoadAllocationTopHelper(Register result, 4784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch, 4785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AllocationFlags flags) { 4786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference allocation_top = 4787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationUtils::GetAllocationTopReference(isolate(), flags); 4788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Just return if allocation top is already known. 4790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if ((flags & RESULT_CONTAINS_TOP) != 0) { 4791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // No use of scratch if allocation top is provided. 4792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!scratch.is_valid()); 4793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 4794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Assert that result actually contains top on entry. 4795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand top_operand = ExternalOperand(allocation_top); 4796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(result, top_operand); 4797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(equal, kUnexpectedAllocationTop); 4798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 4799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 4800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 48026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Move address of new object to result. Use scratch register if available, 48036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // and keep address in scratch until call to UpdateAllocationTopHelper. 48046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (scratch.is_valid()) { 4805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadAddress(scratch, allocation_top); 4806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(result, Operand(scratch, 0)); 4807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Load(result, allocation_top); 4809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::MakeSureDoubleAlignedHelper(Register result, 4814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 4815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required, 4816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationFlags flags) { 4817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (kPointerSize == kDoubleSize) { 4818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_debug_code) { 4819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testl(result, Immediate(kDoubleAlignmentMask)); 4820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(zero, kAllocationIsNotDoubleAligned); 4821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 48226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } else { 4823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Align the next allocation. Storing the filler map without checking top 4824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // is safe in new-space because the limit of the heap is aligned there. 4825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(kPointerSize * 2 == kDoubleSize); 4826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(kPointerAlignment * 2 == kDoubleAlignment); 4827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Make sure scratch is not clobbered by this function as it might be 4828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // used in UpdateAllocationTopHelper later. 4829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!scratch.is(kScratchRegister)); 4830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label aligned; 4831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testl(result, Immediate(kDoubleAlignmentMask)); 4832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(zero, &aligned, Label::kNear); 4833bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (((flags & ALLOCATION_FOLDED) == 0) && ((flags & PRETENURE) != 0)) { 4834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference allocation_limit = 4835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationUtils::GetAllocationLimitReference(isolate(), flags); 4836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(result, ExternalOperand(allocation_limit)); 4837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(above_equal, gc_required); 4838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadRoot(kScratchRegister, Heap::kOnePointerFillerMapRootIndex); 4840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(result, 0), kScratchRegister); 4841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(result, Immediate(kDoubleSize / 2)); 4842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&aligned); 4843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::UpdateAllocationTopHelper(Register result_end, 4848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 4849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationFlags flags) { 485044f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 4851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(result_end, Immediate(kObjectAlignmentMask)); 4852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(zero, kUnalignedAllocationInNewSpace); 4853d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 4854d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 4855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference allocation_top = 4856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationUtils::GetAllocationTopReference(isolate(), flags); 4857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Update new top. 485944f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (scratch.is_valid()) { 486044f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Scratch already contains address of allocation top. 4861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(scratch, 0), result_end); 4862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 4863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Store(allocation_top, result_end); 4864a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4865a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4866a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4867a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Allocate(int object_size, 4869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register result, 4870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register result_end, 4871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 4872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required, 4873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationFlags flags) { 4874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0); 4875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(object_size <= Page::kMaxRegularHeapObjectSize); 4876bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK((flags & ALLOCATION_FOLDED) == 0); 48775913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck if (!FLAG_inline_new) { 487844f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 48795913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck // Trash the registers to simulate an allocation failure. 48805913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck movl(result, Immediate(0x7091)); 48815913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck if (result_end.is_valid()) { 48825913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck movl(result_end, Immediate(0x7191)); 48835913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } 48845913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck if (scratch.is_valid()) { 48855913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck movl(scratch, Immediate(0x7291)); 48865913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } 48875913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } 48885913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck jmp(gc_required); 48895913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck return; 48905913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } 4891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!result.is(result_end)); 4892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Load address of new object into result. 48948a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang LoadAllocationTopHelper(result, scratch, flags); 4895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((flags & DOUBLE_ALIGNMENT) != 0) { 4897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MakeSureDoubleAlignedHelper(result, scratch, gc_required, flags); 4898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Calculate new top and bail out if new space is exhausted. 4901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference allocation_limit = 4902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationUtils::GetAllocationLimitReference(isolate(), flags); 49036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 49046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Register top_reg = result_end.is_valid() ? result_end : result; 49056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 49061e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (!top_reg.is(result)) { 4907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(top_reg, result); 49086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 4909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(top_reg, Immediate(object_size)); 4910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand limit_operand = ExternalOperand(allocation_limit); 4911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(top_reg, limit_operand); 4912a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block j(above, gc_required); 4913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4914bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if ((flags & ALLOCATION_FOLDING_DOMINATOR) == 0) { 4915bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // The top pointer is not updated for allocation folding dominators. 4916bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch UpdateAllocationTopHelper(top_reg, scratch, flags); 4917bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 4918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 49196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (top_reg.is(result)) { 4920bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch subp(result, Immediate(object_size - kHeapObjectTag)); 4921bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else { 4922bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // Tag the result. 4923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(kHeapObjectTag == 1); 4924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch incp(result); 4925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Allocate(int header_size, 4930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ScaleFactor element_size, 4931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register element_count, 4932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register result, 4933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register result_end, 4934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 4935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required, 4936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationFlags flags) { 4937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((flags & SIZE_IN_WORDS) == 0); 4938bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK((flags & ALLOCATION_FOLDING_DOMINATOR) == 0); 4939bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK((flags & ALLOCATION_FOLDED) == 0); 4940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(result_end, Operand(element_count, element_size, header_size)); 4941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Allocate(result_end, result, result_end, scratch, gc_required, flags); 4942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Allocate(Register object_size, 4946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register result, 4947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register result_end, 4948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 4949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required, 4950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationFlags flags) { 4951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((flags & SIZE_IN_WORDS) == 0); 4952bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK((flags & ALLOCATION_FOLDED) == 0); 49535913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck if (!FLAG_inline_new) { 495444f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 49555913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck // Trash the registers to simulate an allocation failure. 49565913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck movl(result, Immediate(0x7091)); 49575913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck movl(result_end, Immediate(0x7191)); 49585913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck if (scratch.is_valid()) { 49595913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck movl(scratch, Immediate(0x7291)); 49605913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } 49615913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck // object_size is left unchanged by this function. 49625913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } 49635913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck jmp(gc_required); 49645913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck return; 49655913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } 4966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!result.is(result_end)); 49675913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck 4968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Load address of new object into result. 49698a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang LoadAllocationTopHelper(result, scratch, flags); 4970a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((flags & DOUBLE_ALIGNMENT) != 0) { 4972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MakeSureDoubleAlignedHelper(result, scratch, gc_required, flags); 4973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference allocation_limit = 4976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationUtils::GetAllocationLimitReference(isolate(), flags); 4977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!object_size.is(result_end)) { 4978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(result_end, object_size); 4979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(result_end, result); 4981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand limit_operand = ExternalOperand(allocation_limit); 4982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(result_end, limit_operand); 4983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block j(above, gc_required); 4984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4985bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if ((flags & ALLOCATION_FOLDING_DOMINATOR) == 0) { 4986bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // The top pointer is not updated for allocation folding dominators. 4987bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch UpdateAllocationTopHelper(result_end, scratch, flags); 4988bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 4989bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 4990bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // Tag the result. 4991bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch addp(result, Immediate(kHeapObjectTag)); 4992bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 4993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4994bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid MacroAssembler::FastAllocate(int object_size, Register result, 4995bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Register result_end, AllocationFlags flags) { 4996bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(!result.is(result_end)); 4997bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // Load address of new object into result. 4998bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch LoadAllocationTopHelper(result, no_reg, flags); 4999bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 5000bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if ((flags & DOUBLE_ALIGNMENT) != 0) { 5001bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch MakeSureDoubleAlignedHelper(result, no_reg, NULL, flags); 5002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5003bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 5004bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch leap(result_end, Operand(result, object_size)); 5005bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 5006bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch UpdateAllocationTopHelper(result_end, no_reg, flags); 5007bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 5008bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch addp(result, Immediate(kHeapObjectTag)); 5009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5011bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid MacroAssembler::FastAllocate(Register object_size, Register result, 5012bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Register result_end, AllocationFlags flags) { 5013bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(!result.is(result_end)); 5014bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // Load address of new object into result. 5015bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch LoadAllocationTopHelper(result, no_reg, flags); 5016bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 5017bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if ((flags & DOUBLE_ALIGNMENT) != 0) { 5018bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch MakeSureDoubleAlignedHelper(result, no_reg, NULL, flags); 5019bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 5020bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 5021bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch leap(result_end, Operand(result, object_size, times_1, 0)); 5022bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 5023bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch UpdateAllocationTopHelper(result_end, no_reg, flags); 5024bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 5025bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch addp(result, Immediate(kHeapObjectTag)); 5026bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 5027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 50283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::AllocateHeapNumber(Register result, 50293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Register scratch, 5030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required, 5031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MutableMode mode) { 50323ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Allocate heap number in new space. 5033bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Allocate(HeapNumber::kSize, result, scratch, no_reg, gc_required, 5034bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch NO_ALLOCATION_FLAGS); 5035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap::RootListIndex map_index = mode == MUTABLE 5037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? Heap::kMutableHeapNumberMapRootIndex 5038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : Heap::kHeapNumberMapRootIndex; 50393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 50403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Set the map. 5041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadRoot(kScratchRegister, map_index); 5042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); 50433ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 50443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 50453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 5046e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid MacroAssembler::AllocateTwoByteString(Register result, 5047e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Register length, 5048e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Register scratch1, 5049e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Register scratch2, 5050e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Register scratch3, 5051e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Label* gc_required) { 5052e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Calculate the number of bytes needed for the characters in the string while 5053e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // observing object alignment. 50546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block const int kHeaderAlignment = SeqTwoByteString::kHeaderSize & 50556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block kObjectAlignmentMask; 5056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(kShortSize == 2); 5057e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // scratch1 = length * 2 + kObjectAlignmentMask. 5058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(scratch1, Operand(length, length, times_1, kObjectAlignmentMask + 50596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block kHeaderAlignment)); 5060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(scratch1, Immediate(~kObjectAlignmentMask)); 50616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (kHeaderAlignment > 0) { 5062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(scratch1, Immediate(kHeaderAlignment)); 50636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 5064e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 5065e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Allocate two byte string in new space. 5066bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Allocate(SeqTwoByteString::kHeaderSize, times_1, scratch1, result, scratch2, 5067bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch scratch3, gc_required, NO_ALLOCATION_FLAGS); 5068e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 5069e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Set the map, length and hash field. 5070e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke LoadRoot(kScratchRegister, Heap::kStringMapRootIndex); 5071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); 50726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Integer32ToSmi(scratch1, length); 5073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(FieldOperand(result, String::kLengthOffset), scratch1); 5074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(FieldOperand(result, String::kHashFieldOffset), 5075e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Immediate(String::kEmptyHashField)); 5076e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 5077e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 5078e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 5079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AllocateOneByteString(Register result, Register length, 5080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, Register scratch2, 5081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch3, 5082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required) { 5083e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Calculate the number of bytes needed for the characters in the string while 5084e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // observing object alignment. 5085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int kHeaderAlignment = SeqOneByteString::kHeaderSize & 50866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block kObjectAlignmentMask; 5087e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke movl(scratch1, length); 5088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(kCharSize == 1); 5089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(scratch1, Immediate(kObjectAlignmentMask + kHeaderAlignment)); 5090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(scratch1, Immediate(~kObjectAlignmentMask)); 50916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (kHeaderAlignment > 0) { 5092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(scratch1, Immediate(kHeaderAlignment)); 50936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 5094e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 5095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate one-byte string in new space. 5096bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Allocate(SeqOneByteString::kHeaderSize, times_1, scratch1, result, scratch2, 5097bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch scratch3, gc_required, NO_ALLOCATION_FLAGS); 5098e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 5099e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Set the map, length and hash field. 5100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadRoot(kScratchRegister, Heap::kOneByteStringMapRootIndex); 5101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); 51026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Integer32ToSmi(scratch1, length); 5103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(FieldOperand(result, String::kLengthOffset), scratch1); 5104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(FieldOperand(result, String::kHashFieldOffset), 5105e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Immediate(String::kEmptyHashField)); 5106e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 5107e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 5108e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 5109589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochvoid MacroAssembler::AllocateTwoByteConsString(Register result, 5110e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Register scratch1, 5111e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Register scratch2, 5112e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Label* gc_required) { 5113e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Allocate heap number in new space. 5114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, 5115bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch NO_ALLOCATION_FLAGS); 5116e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 5117e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Set the map. The other fields are left uninitialized. 5118e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke LoadRoot(kScratchRegister, Heap::kConsStringMapRootIndex); 5119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); 5120e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 5121e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 5122e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 5123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AllocateOneByteConsString(Register result, 5124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, 5125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch2, 5126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required) { 5127bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, 5128bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch NO_ALLOCATION_FLAGS); 5129e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 5130e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Set the map. The other fields are left uninitialized. 5131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadRoot(kScratchRegister, Heap::kConsOneByteStringMapRootIndex); 5132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); 5133e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 5134e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 5135e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 5136589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochvoid MacroAssembler::AllocateTwoByteSlicedString(Register result, 5137589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Register scratch1, 5138589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Register scratch2, 5139589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Label* gc_required) { 5140589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Allocate heap number in new space. 5141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, 5142bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch NO_ALLOCATION_FLAGS); 5143589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 5144589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Set the map. The other fields are left uninitialized. 5145589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch LoadRoot(kScratchRegister, Heap::kSlicedStringMapRootIndex); 5146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); 5147589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch} 5148589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 5149589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 5150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AllocateOneByteSlicedString(Register result, 5151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, 5152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch2, 5153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required) { 5154589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Allocate heap number in new space. 5155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, 5156bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch NO_ALLOCATION_FLAGS); 5157589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 5158589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Set the map. The other fields are left uninitialized. 5159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadRoot(kScratchRegister, Heap::kSlicedOneByteStringMapRootIndex); 5160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); 5161589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch} 5162589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 5163589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 5164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::AllocateJSValue(Register result, Register constructor, 5165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register value, Register scratch, 5166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label* gc_required) { 5167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!result.is(constructor)); 5168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!result.is(scratch)); 5169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!result.is(value)); 5170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 5171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Allocate JSValue in new space. 5172bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Allocate(JSValue::kSize, result, scratch, no_reg, gc_required, 5173bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch NO_ALLOCATION_FLAGS); 5174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 5175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Initialize the JSValue. 5176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoadGlobalFunctionInitialMap(constructor, scratch); 5177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(FieldOperand(result, HeapObject::kMapOffset), scratch); 5178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoadRoot(scratch, Heap::kEmptyFixedArrayRootIndex); 5179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(FieldOperand(result, JSObject::kPropertiesOffset), scratch); 5180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(FieldOperand(result, JSObject::kElementsOffset), scratch); 5181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(FieldOperand(result, JSValue::kValueOffset), value); 5182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); 5183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 5184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 5185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 518644f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Copy memory, byte-by-byte, from source to destination. Not optimized for 518744f0eee88ff00398ff7f715fab053374d808c90dSteve Block// long or aligned copies. The contents of scratch and length are destroyed. 518844f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Destination is incremented by length, source, length and scratch are 518944f0eee88ff00398ff7f715fab053374d808c90dSteve Block// clobbered. 519044f0eee88ff00398ff7f715fab053374d808c90dSteve Block// A simpler loop is faster on small copies, but slower on large ones. 519144f0eee88ff00398ff7f715fab053374d808c90dSteve Block// The cld() instruction must have been emitted, to set the direction flag(), 519244f0eee88ff00398ff7f715fab053374d808c90dSteve Block// before calling this function. 519344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid MacroAssembler::CopyBytes(Register destination, 519444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register source, 519544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register length, 519644f0eee88ff00398ff7f715fab053374d808c90dSteve Block int min_length, 519744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register scratch) { 5198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(min_length >= 0); 5199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 520044f0eee88ff00398ff7f715fab053374d808c90dSteve Block cmpl(length, Immediate(min_length)); 5201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assert(greater_equal, kInvalidMinLength); 520244f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 5203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label short_loop, len8, len16, len24, done, short_string; 520444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 5205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int kLongStringLimit = 4 * kPointerSize; 520644f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (min_length <= kLongStringLimit) { 5207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpl(length, Immediate(kPointerSize)); 5208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(below, &short_string, Label::kNear); 520944f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 521044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 5211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(source.is(rsi)); 5212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(destination.is(rdi)); 5213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(length.is(rcx)); 5214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (min_length <= kLongStringLimit) { 5216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpl(length, Immediate(2 * kPointerSize)); 5217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(below_equal, &len8, Label::kNear); 5218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpl(length, Immediate(3 * kPointerSize)); 5219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(below_equal, &len16, Label::kNear); 5220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpl(length, Immediate(4 * kPointerSize)); 5221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(below_equal, &len24, Label::kNear); 5222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 522344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 522444f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Because source is 8-byte aligned in our uses of this function, 522544f0eee88ff00398ff7f715fab053374d808c90dSteve Block // we keep source aligned for the rep movs operation by copying the odd bytes 522644f0eee88ff00398ff7f715fab053374d808c90dSteve Block // at the end of the ranges. 5227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch, length); 5228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shrl(length, Immediate(kPointerSizeLog2)); 5229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch repmovsp(); 523044f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Move remaining bytes of length. 5231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andl(scratch, Immediate(kPointerSize - 1)); 5232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(length, Operand(source, scratch, times_1, -kPointerSize)); 5233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(destination, scratch, times_1, -kPointerSize), length); 5234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(destination, scratch); 523544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 523644f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (min_length <= kLongStringLimit) { 5237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jmp(&done, Label::kNear); 5238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&len24); 5239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch, Operand(source, 2 * kPointerSize)); 5240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(destination, 2 * kPointerSize), scratch); 5241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&len16); 5242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch, Operand(source, kPointerSize)); 5243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(destination, kPointerSize), scratch); 5244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&len8); 5245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch, Operand(source, 0)); 5246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(destination, 0), scratch); 5247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Move remaining bytes of length. 5248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch, Operand(source, length, times_1, -kPointerSize)); 5249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(destination, length, times_1, -kPointerSize), scratch); 5250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(destination, length); 5251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jmp(&done, Label::kNear); 525244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 525344f0eee88ff00398ff7f715fab053374d808c90dSteve Block bind(&short_string); 525444f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (min_length == 0) { 525544f0eee88ff00398ff7f715fab053374d808c90dSteve Block testl(length, length); 5256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(zero, &done, Label::kNear); 525744f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 525844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 525944f0eee88ff00398ff7f715fab053374d808c90dSteve Block bind(&short_loop); 5260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movb(scratch, Operand(source, 0)); 5261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movb(Operand(destination, 0), scratch); 5262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch incp(source); 5263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch incp(destination); 5264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch decl(length); 5265109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch j(not_zero, &short_loop, Label::kNear); 526644f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 5267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&done); 526944f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 527044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 527144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 5272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::InitializeFieldsWithFiller(Register current_address, 5273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register end_address, 52743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register filler) { 52753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label loop, entry; 5276109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch jmp(&entry, Label::kNear); 52773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bind(&loop); 5278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(Operand(current_address, 0), filler); 5279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch addp(current_address, Immediate(kPointerSize)); 52803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bind(&entry); 5281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cmpp(current_address, end_address); 5282109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch j(below, &loop, Label::kNear); 52833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 52843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 52853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5286d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockvoid MacroAssembler::LoadContext(Register dst, int context_chain_length) { 5287d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (context_chain_length > 0) { 5288d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Move up the chain of contexts to the context containing the slot. 5289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, Operand(rsi, Context::SlotOffset(Context::PREVIOUS_INDEX))); 5290d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block for (int i = 1; i < context_chain_length; i++) { 5291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, Operand(dst, Context::SlotOffset(Context::PREVIOUS_INDEX))); 5292d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 5293e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else { 5294e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Slot is in the current function context. Move it into the 5295e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // destination register in case we store into it (the write barrier 5296e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // cannot be allowed to destroy the context in rsi). 5297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, rsi); 5298e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 5299e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 53003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // We should not have found a with context by walking the context 53013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // chain (i.e., the static scope chain and runtime context chain do 53023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // not agree). A variable occurring in such a scope should have 53033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // slot type LOOKUP and not CONTEXT. 530444f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 53053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CompareRoot(FieldOperand(dst, HeapObject::kMapOffset), 53063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Heap::kWithContextMapRootIndex); 5307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(not_equal, kVariableResolvedToWithContext); 5308d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 5309d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 5310d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 53113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 53123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::LoadTransitionedArrayMapConditional( 53133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKind expected_kind, 53143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKind transitioned_kind, 53153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register map_in_out, 53163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch, 53173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* no_map_match) { 5318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsFastElementsKind(expected_kind)); 5319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsFastElementsKind(transitioned_kind)); 53203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 53213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check that the function's map is the same as the expected cached map. 5322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(scratch, NativeContextOperand()); 5323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cmpp(map_in_out, 5324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ContextOperand(scratch, Context::ArrayMapIndex(expected_kind))); 53253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(not_equal, no_map_match); 53263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 53273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Use the transitioned cached map. 5328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(map_in_out, 5329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ContextOperand(scratch, Context::ArrayMapIndex(transitioned_kind))); 53303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 53313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 53323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 533344f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef _WIN64 533444f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic const int kRegisterPassedArguments = 4; 533544f0eee88ff00398ff7f715fab053374d808c90dSteve Block#else 533644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic const int kRegisterPassedArguments = 6; 533744f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 53387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 5340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::LoadNativeContextSlot(int index, Register dst) { 5341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(dst, NativeContextOperand()); 5342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(dst, ContextOperand(dst, index)); 5343b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 5344b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 5345b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 5346b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid MacroAssembler::LoadGlobalFunctionInitialMap(Register function, 5347b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Register map) { 5348b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Load the initial map. The global functions all have initial maps. 5349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(map, FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); 535044f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 5351b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Label ok, fail; 5352257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CheckMap(map, isolate()->factory()->meta_map(), &fail, DO_SMI_CHECK); 5353b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch jmp(&ok); 5354b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bind(&fail); 5355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Abort(kGlobalFunctionsMustHaveInitialMap); 5356b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bind(&ok); 5357b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 5358b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 5359b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 5360b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 53614515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkeint MacroAssembler::ArgumentStackSlotsForCFunctionCall(int num_arguments) { 53627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // On Windows 64 stack slots are reserved by the caller for all arguments 53637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // including the ones passed in registers, and space is always allocated for 53647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // the four register arguments even if the function takes fewer than four 53657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // arguments. 53667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // On AMD64 ABI (Linux/Mac) the first six arguments are passed in registers 53677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // and the caller does not reserve stack slots for them. 5368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(num_arguments >= 0); 53694515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke#ifdef _WIN64 537044f0eee88ff00398ff7f715fab053374d808c90dSteve Block const int kMinimumStackSlots = kRegisterPassedArguments; 53717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (num_arguments < kMinimumStackSlots) return kMinimumStackSlots; 53727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch return num_arguments; 53734515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke#else 53747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (num_arguments < kRegisterPassedArguments) return 0; 53757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch return num_arguments - kRegisterPassedArguments; 53764515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke#endif 53774515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke} 53784515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 53797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::EmitSeqStringSetCharCheck(Register string, 5381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register index, 5382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register value, 5383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t encoding_mask) { 5384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label is_object; 5385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JumpIfNotSmi(string, &is_object); 5386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Abort(kNonObject); 5387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&is_object); 5388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(value); 5390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(value, FieldOperand(string, HeapObject::kMapOffset)); 5391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movzxbp(value, FieldOperand(value, Map::kInstanceTypeOffset)); 5392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andb(value, Immediate(kStringRepresentationMask | kStringEncodingMask)); 5394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(value, Immediate(encoding_mask)); 5395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(value); 5396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(equal, kUnexpectedStringType); 5397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The index is assumed to be untagged coming in, tag it to compare with the 5399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // string length without using a temp register, it is restored at the end of 5400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // this function. 5401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Integer32ToSmi(index, index); 5402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiCompare(index, FieldOperand(string, String::kLengthOffset)); 5403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(less, kIndexIsTooLarge); 5404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiCompare(index, Smi::FromInt(0)); 5406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(greater_equal, kIndexIsNegative); 5407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Restore the index 5409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(index, index); 5410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 54134515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkevoid MacroAssembler::PrepareCallCFunction(int num_arguments) { 5414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int frame_alignment = base::OS::ActivationFrameAlignment(); 5415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(frame_alignment != 0); 5416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(num_arguments >= 0); 541744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 54184515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // Make stack end at alignment and allocate space for arguments and old rsp. 5419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, rsp); 5420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(base::bits::IsPowerOfTwo32(frame_alignment)); 54214515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke int argument_slots_on_stack = 54224515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke ArgumentStackSlotsForCFunctionCall(num_arguments); 5423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(rsp, Immediate((argument_slots_on_stack + 1) * kRegisterSize)); 5424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(rsp, Immediate(-frame_alignment)); 5425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(rsp, argument_slots_on_stack * kRegisterSize), kScratchRegister); 54264515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke} 54274515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 54284515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 54294515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkevoid MacroAssembler::CallCFunction(ExternalReference function, 54304515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke int num_arguments) { 543144f0eee88ff00398ff7f715fab053374d808c90dSteve Block LoadAddress(rax, function); 54324515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke CallCFunction(rax, num_arguments); 54334515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke} 54344515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 54354515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 54364515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkevoid MacroAssembler::CallCFunction(Register function, int num_arguments) { 5437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(has_frame()); 54386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Check stack alignment. 543944f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 54406ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CheckStackAlignment(); 54416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 54426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 54434515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke call(function); 5444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(base::OS::ActivationFrameAlignment() != 0); 5445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(num_arguments >= 0); 54464515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke int argument_slots_on_stack = 54474515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke ArgumentStackSlotsForCFunctionCall(num_arguments); 5448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rsp, Operand(rsp, argument_slots_on_stack * kRegisterSize)); 54494515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke} 54504515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 5451d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 5452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 5453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool AreAliased(Register reg1, 5454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg2, 5455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg3, 5456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg4, 5457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg5, 5458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg6, 5459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg7, 5460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg8) { 5461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int n_of_valid_regs = reg1.is_valid() + reg2.is_valid() + 5462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reg3.is_valid() + reg4.is_valid() + reg5.is_valid() + reg6.is_valid() + 5463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reg7.is_valid() + reg8.is_valid(); 5464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RegList regs = 0; 5466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reg1.is_valid()) regs |= reg1.bit(); 5467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reg2.is_valid()) regs |= reg2.bit(); 5468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reg3.is_valid()) regs |= reg3.bit(); 5469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reg4.is_valid()) regs |= reg4.bit(); 5470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reg5.is_valid()) regs |= reg5.bit(); 5471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reg6.is_valid()) regs |= reg6.bit(); 5472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reg7.is_valid()) regs |= reg7.bit(); 5473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reg8.is_valid()) regs |= reg8.bit(); 5474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int n_of_non_aliasing_regs = NumRegs(regs); 5475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return n_of_valid_regs != n_of_non_aliasing_regs; 54773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 5478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 54793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 54803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochCodePatcher::CodePatcher(Isolate* isolate, byte* address, int size) 54828b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch : address_(address), 54838b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch size_(size), 5484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch masm_(isolate, address, size + Assembler::kGap, CodeObjectRequired::kNo) { 5485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a new macro assembler pointing to the address of the code to patch. 5486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The size is adjusted with kGap on order for the assembler to generate size 5487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // bytes of instructions without failing with buffer size constraints. 5488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 5489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCodePatcher::~CodePatcher() { 5493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Indicate that code has changed. 5494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Assembler::FlushICache(masm_.isolate(), address_, size_); 5495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that the code was patched as expected. 5497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(masm_.pc_ == address_ + size_); 5498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 5499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 55013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 55023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::CheckPageFlag( 55033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register object, 55043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch, 55053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int mask, 55063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Condition cc, 55073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* condition_met, 55083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label::Distance condition_met_distance) { 5509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(cc == zero || cc == not_zero); 55103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (scratch.is(object)) { 5511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(scratch, Immediate(~Page::kPageAlignmentMask)); 55123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 5513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch, Immediate(~Page::kPageAlignmentMask)); 5514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(scratch, object); 55153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 55163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (mask < (1 << kBitsPerByte)) { 55173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch testb(Operand(scratch, MemoryChunk::kFlagsOffset), 55183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Immediate(static_cast<uint8_t>(mask))); 55193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 55203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch testl(Operand(scratch, MemoryChunk::kFlagsOffset), Immediate(mask)); 55213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 55223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(cc, condition_met, condition_met_distance); 55233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 55243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 55253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 55263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::JumpIfBlack(Register object, 55273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register bitmap_scratch, 55283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register mask_scratch, 55293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* on_black, 55303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label::Distance on_black_distance) { 5531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!AreAliased(object, bitmap_scratch, mask_scratch, rcx)); 5532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 55333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GetMarkBits(object, bitmap_scratch, mask_scratch); 55343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(strcmp(Marking::kBlackBitPattern, "11") == 0); 55363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // The mask_scratch register contains a 1 at the position of the first bit 5537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // and a 1 at a position of the second bit. All other positions are zero. 5538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rcx, mask_scratch); 5539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(rcx, Operand(bitmap_scratch, MemoryChunk::kHeaderSize)); 5540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(mask_scratch, rcx); 55413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(equal, on_black, on_black_distance); 55423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 55433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 55443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 55453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::GetMarkBits(Register addr_reg, 55463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register bitmap_reg, 55473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register mask_reg) { 5548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!AreAliased(addr_reg, bitmap_reg, mask_reg, rcx)); 5549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(bitmap_reg, addr_reg); 55503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Sign extended 32 bit immediate. 5551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(bitmap_reg, Immediate(~Page::kPageAlignmentMask)); 5552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rcx, addr_reg); 55533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int shift = 55543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Bitmap::kBitsPerCellLog2 + kPointerSizeLog2 - Bitmap::kBytesPerCellLog2; 55553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch shrl(rcx, Immediate(shift)); 5556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(rcx, 55573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Immediate((Page::kPageAlignmentMask >> shift) & 55583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ~(Bitmap::kBytesPerCell - 1))); 55593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(bitmap_reg, rcx); 5561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rcx, addr_reg); 55623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch shrl(rcx, Immediate(kPointerSizeLog2)); 5563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(rcx, Immediate((1 << Bitmap::kBitsPerCellLog2) - 1)); 5564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movl(mask_reg, Immediate(3)); 5565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlp_cl(mask_reg); 55663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 55673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 55683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::JumpIfWhite(Register value, Register bitmap_scratch, 5570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register mask_scratch, Label* value_is_white, 5571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label::Distance distance) { 5572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!AreAliased(value, bitmap_scratch, mask_scratch, rcx)); 55733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GetMarkBits(value, bitmap_scratch, mask_scratch); 55743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 55753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // If the value is black or grey we don't need to do anything. 5576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(strcmp(Marking::kWhiteBitPattern, "00") == 0); 5577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(strcmp(Marking::kBlackBitPattern, "11") == 0); 5578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(strcmp(Marking::kGreyBitPattern, "10") == 0); 5579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(strcmp(Marking::kImpossibleBitPattern, "01") == 0); 55803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 55813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Since both black and grey have a 1 in the first position and white does 55823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // not have a 1 there we only need to check one bit. 5583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(Operand(bitmap_scratch, MemoryChunk::kHeaderSize), mask_scratch); 5584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(zero, value_is_white, distance); 55853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 55863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 55873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5588109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid MacroAssembler::CheckEnumCache(Label* call_runtime) { 5589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label next, start; 55903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register empty_fixed_array_value = r8; 55913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LoadRoot(empty_fixed_array_value, Heap::kEmptyFixedArrayRootIndex); 5592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rcx, rax); 5593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if the enum length field is properly initialized, indicating that 5595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // there is an enum cache. 5596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rbx, FieldOperand(rcx, HeapObject::kMapOffset)); 5597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EnumLength(rdx, rbx); 5599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Cmp(rdx, Smi::FromInt(kInvalidEnumCacheSentinel)); 5600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(equal, call_runtime); 5601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jmp(&start); 5603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 56043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bind(&next); 56053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rbx, FieldOperand(rcx, HeapObject::kMapOffset)); 5607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // For all objects but the receiver, check that the cache is empty. 5609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EnumLength(rdx, rbx); 5610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Cmp(rdx, Smi::FromInt(0)); 56113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(not_equal, call_runtime); 56123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&start); 56143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check that there are no elements. Register rcx contains the current JS 5616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // object we've reached through the prototype chain. 5617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label no_elements; 5618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(empty_fixed_array_value, 5619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FieldOperand(rcx, JSObject::kElementsOffset)); 5620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(equal, &no_elements); 56213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Second chance, the object may be using the empty slow element dictionary. 5623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadRoot(kScratchRegister, Heap::kEmptySlowElementDictionaryRootIndex); 5624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(kScratchRegister, FieldOperand(rcx, JSObject::kElementsOffset)); 56253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(not_equal, call_runtime); 56263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&no_elements); 5628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rcx, FieldOperand(rbx, Map::kPrototypeOffset)); 5629109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CompareRoot(rcx, Heap::kNullValueRootIndex); 56303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(not_equal, &next); 56313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 56323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5633109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 5634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::TestJSArrayForAllocationMemento( 5635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register receiver_reg, 5636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch_reg, 5637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* no_memento_found) { 56383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Label map_check; 56393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Label top_check; 5640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference new_space_allocation_top = 5641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference::new_space_allocation_top_address(isolate()); 56423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch const int kMementoMapOffset = JSArray::kSize - kHeapObjectTag; 56433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch const int kMementoEndOffset = kMementoMapOffset + AllocationMemento::kSize; 56443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 56453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Bail out if the object is not in new space. 56463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch JumpIfNotInNewSpace(receiver_reg, scratch_reg, no_memento_found); 56473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // If the object is in new space, we need to check whether it is on the same 56483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // page as the current top. 56493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch leap(scratch_reg, Operand(receiver_reg, kMementoEndOffset)); 56503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch xorp(scratch_reg, ExternalOperand(new_space_allocation_top)); 56513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch testp(scratch_reg, Immediate(~Page::kPageAlignmentMask)); 56523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch j(zero, &top_check); 56533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // The object is on a different page than allocation top. Bail out if the 56543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // object sits on the page boundary as no memento can follow and we cannot 56553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // touch the memory following it. 56563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch leap(scratch_reg, Operand(receiver_reg, kMementoEndOffset)); 56573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch xorp(scratch_reg, receiver_reg); 56583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch testp(scratch_reg, Immediate(~Page::kPageAlignmentMask)); 56593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch j(not_zero, no_memento_found); 56603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Continue with the actual map check. 56613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch jmp(&map_check); 56623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // If top is on the same page as the current object, we need to check whether 56633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // we are below top. 56643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch bind(&top_check); 56653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch leap(scratch_reg, Operand(receiver_reg, kMementoEndOffset)); 5666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(scratch_reg, ExternalOperand(new_space_allocation_top)); 5667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(greater, no_memento_found); 56683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Memento map check. 56693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch bind(&map_check); 56703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch CompareRoot(MemOperand(receiver_reg, kMementoMapOffset), 5671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap::kAllocationMementoMapRootIndex); 5672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::JumpIfDictionaryInPrototypeChain( 5676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register object, 5677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch0, 5678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, 5679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* found) { 5680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!(scratch0.is(kScratchRegister) && scratch1.is(kScratchRegister))); 5681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!scratch1.is(scratch0)); 5682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register current = scratch0; 5683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label loop_again, end; 5684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(current, object); 5686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(current, FieldOperand(current, HeapObject::kMapOffset)); 5687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(current, FieldOperand(current, Map::kPrototypeOffset)); 5688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CompareRoot(current, Heap::kNullValueRootIndex); 5689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(equal, &end); 5690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Loop based on the map going up the prototype chain. 5692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&loop_again); 5693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(current, FieldOperand(current, HeapObject::kMapOffset)); 5694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STATIC_ASSERT(JS_PROXY_TYPE < JS_OBJECT_TYPE); 5695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STATIC_ASSERT(JS_VALUE_TYPE < JS_OBJECT_TYPE); 5696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CmpInstanceType(current, JS_OBJECT_TYPE); 5697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(below, found); 5698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch1, FieldOperand(current, Map::kBitField2Offset)); 5699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DecodeField<Map::ElementsKindBits>(scratch1); 5700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(scratch1, Immediate(DICTIONARY_ELEMENTS)); 5701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(equal, found); 5702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(current, FieldOperand(current, Map::kPrototypeOffset)); 5703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompareRoot(current, Heap::kNullValueRootIndex); 5704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(not_equal, &loop_again); 5705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 5706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(&end); 5707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::TruncatingDiv(Register dividend, int32_t divisor) { 5711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dividend.is(rax)); 5712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dividend.is(rdx)); 5713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::MagicNumbersForDivision<uint32_t> mag = 5714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::SignedDivisionByConstant(static_cast<uint32_t>(divisor)); 5715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(rax, Immediate(mag.multiplier)); 5716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch imull(dividend); 5717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool neg = (mag.multiplier & (static_cast<uint32_t>(1) << 31)) != 0; 5718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (divisor > 0 && neg) addl(rdx, dividend); 5719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (divisor < 0 && !neg && mag.multiplier > 0) subl(rdx, dividend); 5720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mag.shift > 0) sarl(rdx, Immediate(mag.shift)); 5721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(rax, dividend); 5722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shrl(rax, Immediate(31)); 5723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addl(rdx, rax); 5724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 57263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 5728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 5729f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 5730f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#endif // V8_TARGET_ARCH_X64 5731