macro-assembler-x64.cc revision f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3
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) { 256f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch CheckPageFlag(object, scratch, MemoryChunk::kIsInNewSpaceMask, cc, branch, 257f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch distance); 258257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 259257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 260257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::RecordWriteField( 2623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register object, 2633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int offset, 2643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register value, 2653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register dst, 2663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SaveFPRegsMode save_fp, 2673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RememberedSetAction remembered_set_action, 268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiCheck smi_check, 269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PointersToHereCheck pointers_to_here_check_for_value) { 2707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // First, check if a write barrier is even needed. The tests below 2713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // catch stores of Smis. 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label done; 273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Skip barrier if writing a smi. 2753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (smi_check == INLINE_SMI_CHECK) { 2763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JumpIfSmi(value, &done); 2773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Although the object register is tagged, the offset is relative to the start 2803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // of the object, so so offset must be a multiple of kPointerSize. 281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsAligned(offset, kPointerSize)); 2823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(dst, FieldOperand(object, offset)); 2843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (emit_debug_code()) { 2853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label ok; 2863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch testb(dst, Immediate((1 << kPointerSizeLog2) - 1)); 2873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(zero, &ok, Label::kNear); 2883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int3(); 2893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bind(&ok); 2903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RecordWrite(object, dst, value, save_fp, remembered_set_action, 293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OMIT_SMI_CHECK, pointers_to_here_check_for_value); 2943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block bind(&done); 2964515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 2973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Clobber clobbered input registers when running with the debug-code flag 2983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // turned on to provoke errors. 29944f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(value, kZapValue, Assembler::RelocInfoNone()); 301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(dst, kZapValue, Assembler::RelocInfoNone()); 3024515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } 3033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 3043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 3053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::RecordWriteArray( 307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register object, 308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register value, 309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register index, 310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SaveFPRegsMode save_fp, 311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RememberedSetAction remembered_set_action, 312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiCheck smi_check, 313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PointersToHereCheck pointers_to_here_check_for_value) { 3148defd9ff6930b4e24729971a61cf7469daf119beSteve Block // First, check if a write barrier is even needed. The tests below 3153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // catch stores of Smis. 3168defd9ff6930b4e24729971a61cf7469daf119beSteve Block Label done; 3178defd9ff6930b4e24729971a61cf7469daf119beSteve Block 3183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Skip barrier if writing a smi. 3193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (smi_check == INLINE_SMI_CHECK) { 3203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JumpIfSmi(value, &done); 3213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3228defd9ff6930b4e24729971a61cf7469daf119beSteve Block 3233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Array access: calculate the destination address. Index is not a smi. 3243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register dst = index; 325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(dst, Operand(object, index, times_pointer_size, 3263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArray::kHeaderSize - kHeapObjectTag)); 3273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RecordWrite(object, dst, value, save_fp, remembered_set_action, 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OMIT_SMI_CHECK, pointers_to_here_check_for_value); 3308defd9ff6930b4e24729971a61cf7469daf119beSteve Block 3318defd9ff6930b4e24729971a61cf7469daf119beSteve Block bind(&done); 3328defd9ff6930b4e24729971a61cf7469daf119beSteve Block 3333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Clobber clobbered input registers when running with the debug-code flag 3348defd9ff6930b4e24729971a61cf7469daf119beSteve Block // turned on to provoke errors. 33544f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(value, kZapValue, Assembler::RelocInfoNone()); 337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(index, kZapValue, Assembler::RelocInfoNone()); 3388defd9ff6930b4e24729971a61cf7469daf119beSteve Block } 3398defd9ff6930b4e24729971a61cf7469daf119beSteve Block} 3408defd9ff6930b4e24729971a61cf7469daf119beSteve Block 3418defd9ff6930b4e24729971a61cf7469daf119beSteve Block 342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::RecordWriteForMap(Register object, 343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register map, 344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register dst, 345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SaveFPRegsMode fp_mode) { 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!object.is(kScratchRegister)); 347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!object.is(map)); 348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!object.is(dst)); 349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!map.is(dst)); 350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertNotSmi(object); 3514515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 35244f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label ok; 354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (map.is(kScratchRegister)) pushq(map); 355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompareMap(map, isolate()->factory()->meta_map()); 356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (map.is(kScratchRegister)) popq(map); 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(equal, &ok, Label::kNear); 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int3(); 359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&ok); 3604515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } 3614515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!FLAG_incremental_marking) { 363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label ok; 368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (map.is(kScratchRegister)) pushq(map); 369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(map, FieldOperand(object, HeapObject::kMapOffset)); 370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (map.is(kScratchRegister)) popq(map); 371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(equal, &ok, Label::kNear); 372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int3(); 373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&ok); 374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute the address. 377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(dst, FieldOperand(object, HeapObject::kMapOffset)); 378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // First, check if a write barrier is even needed. The tests below 380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // catch stores of smis and stores into the young generation. 381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done; 382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // A single check of the map's pages interesting flag suffices, since it is 384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // only set during incremental collection, and then it's also guaranteed that 385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the from object's page's interesting flag is also set. This optimization 386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // relies on the fact that maps can never be in new space. 387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CheckPageFlag(map, 388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map, // Used as scratch. 389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemoryChunk::kPointersToHereAreInterestingMask, 390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch zero, 391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &done, 392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::kNear); 393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RecordWriteStub stub(isolate(), object, map, dst, OMIT_REMEMBERED_SET, 395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fp_mode); 396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallStub(&stub); 397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&done); 399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Count number of write barriers in generated code. 401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->counters()->write_barriers_static()->Increment(); 402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1); 403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Clobber clobbered registers when running with the debug-code flag 405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // turned on to provoke errors. 406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(dst, kZapValue, Assembler::RelocInfoNone()); 408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(map, kZapValue, Assembler::RelocInfoNone()); 409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::RecordWrite( 414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register object, 415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register address, 416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register value, 417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SaveFPRegsMode fp_mode, 418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RememberedSetAction remembered_set_action, 419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiCheck smi_check, 420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PointersToHereCheck pointers_to_here_check_for_value) { 421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!object.is(value)); 422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!object.is(address)); 423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!value.is(address)); 424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertNotSmi(object); 425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (remembered_set_action == OMIT_REMEMBERED_SET && 4273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch !FLAG_incremental_marking) { 4283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return; 4293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 4323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label ok; 433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(value, Operand(address, 0)); 4343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(equal, &ok, Label::kNear); 4353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int3(); 4363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bind(&ok); 4373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 4393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // First, check if a write barrier is even needed. The tests below 4403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // catch stores of smis and stores into the young generation. 4413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label done; 4423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (smi_check == INLINE_SMI_CHECK) { 4443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Skip barrier if writing a smi. 4453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JumpIfSmi(value, &done); 446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (pointers_to_here_check_for_value != kPointersToHereAreAlwaysInteresting) { 449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CheckPageFlag(value, 450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value, // Used as scratch. 451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemoryChunk::kPointersToHereAreInterestingMask, 452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch zero, 453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &done, 454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::kNear); 455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CheckPageFlag(object, 4583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch value, // Used as scratch. 4593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MemoryChunk::kPointersFromHereAreInterestingMask, 4603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch zero, 4613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch &done, 4623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label::kNear); 4633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RecordWriteStub stub(isolate(), object, value, address, remembered_set_action, 465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fp_mode); 4663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallStub(&stub); 467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bind(&done); 4694515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Count number of write barriers in generated code. 471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->counters()->write_barriers_static()->Increment(); 472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1); 473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Clobber clobbered registers when running with the debug-code flag 4754515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // turned on to provoke errors. 47644f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(address, kZapValue, Assembler::RelocInfoNone()); 478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(value, kZapValue, Assembler::RelocInfoNone()); 4796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 4806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 4816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 482109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid MacroAssembler::RecordWriteCodeEntryField(Register js_function, 483109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Register code_entry, 484109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Register scratch) { 485109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch const int offset = JSFunction::kCodeEntryOffset; 486109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 487109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // The input registers are fixed to make calling the C write barrier function 488109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // easier. 489109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(js_function.is(rdi)); 490109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(code_entry.is(rcx)); 491bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(scratch.is(r15)); 492109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 493109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Since a code entry (value) is always in old space, we don't need to update 494109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // remembered set. If incremental marking is off, there is nothing for us to 495109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // do. 496109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (!FLAG_incremental_marking) return; 497109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 498109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AssertNotSmi(js_function); 499109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 500109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (emit_debug_code()) { 501109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Label ok; 502109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch leap(scratch, FieldOperand(js_function, offset)); 503109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch cmpp(code_entry, Operand(scratch, 0)); 504109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch j(equal, &ok, Label::kNear); 505109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int3(); 506109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch bind(&ok); 507109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 508109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 509109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // First, check if a write barrier is even needed. The tests below 510109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // catch stores of Smis and stores into young gen. 511109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Label done; 512109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 513109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CheckPageFlag(code_entry, scratch, 514109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch MemoryChunk::kPointersToHereAreInterestingMask, zero, &done, 515109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Label::kNear); 516109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CheckPageFlag(js_function, scratch, 517109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch MemoryChunk::kPointersFromHereAreInterestingMask, zero, &done, 518109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Label::kNear); 519109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 520109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Save input registers. 521109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Push(js_function); 522109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Push(code_entry); 523109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 524109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch const Register dst = scratch; 525109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch leap(dst, FieldOperand(js_function, offset)); 526109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 527109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Save caller-saved registers. 528109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch PushCallerSaved(kDontSaveFPRegs, js_function, code_entry); 529109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 530109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int argument_count = 3; 531109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch PrepareCallCFunction(argument_count); 532109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 533109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Load the argument registers. 534109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (arg_reg_1.is(rcx)) { 535109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Windows calling convention. 536109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(arg_reg_2.is(rdx) && arg_reg_3.is(r8)); 537109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 538109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch movp(arg_reg_1, js_function); // rcx gets rdi. 539bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch movp(arg_reg_2, dst); // rdx gets r15. 540109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 541109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // AMD64 calling convention. 542109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(arg_reg_1.is(rdi) && arg_reg_2.is(rsi) && arg_reg_3.is(rdx)); 543109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 544109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // rdi is already loaded with js_function. 545bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch movp(arg_reg_2, dst); // rsi gets r15. 546109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 547109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Move(arg_reg_3, ExternalReference::isolate_address(isolate())); 548109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 549109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch { 550109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AllowExternalCallThatCantCauseGC scope(this); 551109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CallCFunction( 552109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ExternalReference::incremental_marking_record_write_code_entry_function( 553109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch isolate()), 554109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch argument_count); 555109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 556109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 557109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Restore caller-saved registers. 558109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch PopCallerSaved(kDontSaveFPRegs, js_function, code_entry); 559109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 560109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Restore input registers. 561109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Pop(code_entry); 562109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Pop(js_function); 563109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 564109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch bind(&done); 565109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 5663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Assert(Condition cc, BailoutReason reason) { 568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) Check(cc, reason); 569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 572756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickvoid MacroAssembler::AssertFastElements(Register elements) { 57344f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 574257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label ok; 575756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CompareRoot(FieldOperand(elements, HeapObject::kMapOffset), 576756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick Heap::kFixedArrayMapRootIndex); 577257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(equal, &ok, Label::kNear); 578756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CompareRoot(FieldOperand(elements, HeapObject::kMapOffset), 5793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Heap::kFixedDoubleArrayMapRootIndex); 5803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch j(equal, &ok, Label::kNear); 5813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CompareRoot(FieldOperand(elements, HeapObject::kMapOffset), 582756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick Heap::kFixedCOWArrayMapRootIndex); 583257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(equal, &ok, Label::kNear); 584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Abort(kJSObjectWithFastElementsMapHasSlowElements); 585756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick bind(&ok); 586756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 587756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick} 588756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 589756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Check(Condition cc, BailoutReason reason) { 591257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label L; 592257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(cc, &L, Label::kNear); 593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Abort(reason); 5943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Control will not return here. 595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bind(&L); 596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5996ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid MacroAssembler::CheckStackAlignment() { 600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int frame_alignment = base::OS::ActivationFrameAlignment(); 6016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int frame_alignment_mask = frame_alignment - 1; 6026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (frame_alignment > kPointerSize) { 603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(base::bits::IsPowerOfTwo32(frame_alignment)); 604257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label alignment_as_expected; 605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(rsp, Immediate(frame_alignment_mask)); 606257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(zero, &alignment_as_expected, Label::kNear); 6076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Abort if stack is not aligned. 6086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int3(); 6096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block bind(&alignment_as_expected); 6106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 6116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 6126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 6136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::NegativeZeroTest(Register result, 615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register op, 616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label* then_label) { 617257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label ok; 618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block testl(result, result); 619257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_zero, &ok, Label::kNear); 620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block testl(op, op); 621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block j(sign, then_label); 622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bind(&ok); 623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Abort(BailoutReason reason) { 627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* msg = GetBailoutReason(reason); 629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (msg != NULL) { 630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RecordComment("Abort message: "); 631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RecordComment(msg); 632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_trap_on_abort) { 635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int3(); 636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 640f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Check if Abort() has already been initialized. 641f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(isolate()->builtins()->Abort()->IsHeapObject()); 642f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 643f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Move(rdx, Smi::FromInt(static_cast<int>(reason))); 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); 649f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Call(isolate()->builtins()->Abort(), RelocInfo::CODE_TARGET); 6503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 651f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Call(isolate()->builtins()->Abort(), RelocInfo::CODE_TARGET); 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 741f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::JumpToExternalReference(const ExternalReference& ext, 742f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch bool builtin_exit_frame) { 743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set the entry point and jump to the C entry runtime stub. 74444f0eee88ff00398ff7f715fab053374d808c90dSteve Block LoadAddress(rbx, ext); 745f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CEntryStub ces(isolate(), 1, kDontSaveFPRegs, kArgvOnStack, 746f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch builtin_exit_frame); 7473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block jmp(ces.GetCode(), RelocInfo::CODE_TARGET); 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 2721f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::Movups(XMMRegister dst, XMMRegister src) { 2722f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (CpuFeatures::IsSupported(AVX)) { 2723f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CpuFeatureScope scope(this, AVX); 2724f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch vmovups(dst, src); 2725f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 2726f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch movups(dst, src); 2727f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2728f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 2729f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2730f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::Movups(XMMRegister dst, const Operand& src) { 2731f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (CpuFeatures::IsSupported(AVX)) { 2732f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CpuFeatureScope scope(this, AVX); 2733f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch vmovups(dst, src); 2734f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 2735f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch movups(dst, src); 2736f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2737f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 2738f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2739f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::Movups(const Operand& dst, XMMRegister src) { 2740f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (CpuFeatures::IsSupported(AVX)) { 2741f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CpuFeatureScope scope(this, AVX); 2742f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch vmovups(dst, src); 2743f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 2744f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch movups(dst, src); 2745f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2746f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 2747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movapd(XMMRegister dst, XMMRegister src) { 2749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovapd(dst, src); 2752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movapd(dst, src); 2754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2757f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::Movupd(XMMRegister dst, const Operand& src) { 2758f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (CpuFeatures::IsSupported(AVX)) { 2759f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CpuFeatureScope scope(this, AVX); 2760f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch vmovupd(dst, src); 2761f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 2762f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch movupd(dst, src); 2763f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2764f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 2765f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2766f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::Movupd(const Operand& dst, XMMRegister src) { 2767f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (CpuFeatures::IsSupported(AVX)) { 2768f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CpuFeatureScope scope(this, AVX); 2769f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch vmovupd(dst, src); 2770f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 2771f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch movupd(dst, src); 2772f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2773f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 2774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movsd(XMMRegister dst, XMMRegister src) { 2776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovsd(dst, dst, src); 2779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movsd(dst, src); 2781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movsd(XMMRegister dst, const Operand& src) { 2786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovsd(dst, src); 27893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 2790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movsd(dst, src); 27913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 27923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 27933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 27943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movsd(const Operand& dst, XMMRegister src) { 2796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovsd(dst, src); 27993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 2800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movsd(dst, src); 28013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 28023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 28033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 28043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movss(XMMRegister dst, XMMRegister src) { 2806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovss(dst, dst, src); 2809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movss(dst, src); 2811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2812958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2813958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2814958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movss(XMMRegister dst, const Operand& src) { 2816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovss(dst, src); 2819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movss(dst, src); 2821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2822958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2823958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2824958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movss(const Operand& dst, XMMRegister src) { 2826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovss(dst, src); 2829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movss(dst, src); 2831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movd(XMMRegister dst, Register src) { 2836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovd(dst, src); 2839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movd(dst, src); 2841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movd(XMMRegister dst, const Operand& src) { 2846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovd(dst, src); 28493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 2850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movd(dst, src); 28513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 28523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 28533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 28543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movd(Register dst, XMMRegister src) { 2856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovd(dst, src); 28593ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 2860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movd(dst, src); 28613ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 28623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 28633ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 28643ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 2865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movq(XMMRegister dst, Register src) { 2866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovq(dst, src); 2869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movq(dst, src); 2871e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 2872e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 2873e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2874e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movq(Register dst, XMMRegister src) { 2876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovq(dst, src); 2879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movq(dst, src); 2881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2884f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::Movmskps(Register dst, XMMRegister src) { 2885f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (CpuFeatures::IsSupported(AVX)) { 2886f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CpuFeatureScope scope(this, AVX); 2887f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch vmovmskps(dst, src); 2888f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 2889f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch movmskps(dst, src); 2890f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2891f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 2892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movmskpd(Register dst, XMMRegister src) { 2894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovmskpd(dst, src); 2897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movmskpd(dst, src); 2899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2902f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::Xorps(XMMRegister dst, XMMRegister src) { 2903f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (CpuFeatures::IsSupported(AVX)) { 2904f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CpuFeatureScope scope(this, AVX); 2905f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch vxorps(dst, dst, src); 2906f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 2907f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch xorps(dst, src); 2908f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2909f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 2910f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2911f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::Xorps(XMMRegister dst, const Operand& src) { 2912f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (CpuFeatures::IsSupported(AVX)) { 2913f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CpuFeatureScope scope(this, AVX); 2914f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch vxorps(dst, dst, src); 2915f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 2916f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch xorps(dst, src); 2917f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2918f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 2919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Roundss(XMMRegister dst, XMMRegister src, 2921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RoundingMode mode) { 2922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vroundss(dst, dst, src, mode); 2925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch roundss(dst, src, mode); 2927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Roundsd(XMMRegister dst, XMMRegister src, 2932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RoundingMode mode) { 2933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vroundsd(dst, dst, src, mode); 2936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch roundsd(dst, src, mode); 2938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Sqrtsd(XMMRegister dst, XMMRegister src) { 2943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsqrtsd(dst, dst, src); 2946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch sqrtsd(dst, src); 2948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Sqrtsd(XMMRegister dst, const Operand& src) { 2953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsqrtsd(dst, dst, src); 2956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch sqrtsd(dst, src); 2958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Ucomiss(XMMRegister src1, XMMRegister src2) { 2963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vucomiss(src1, src2); 2966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ucomiss(src1, src2); 2968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Ucomiss(XMMRegister src1, const Operand& src2) { 2973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vucomiss(src1, src2); 2976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ucomiss(src1, src2); 2978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Ucomisd(XMMRegister src1, XMMRegister src2) { 2983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vucomisd(src1, src2); 2986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ucomisd(src1, src2); 2988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Ucomisd(XMMRegister src1, const Operand& src2) { 2993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vucomisd(src1, src2); 2996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ucomisd(src1, src2); 2998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3001f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ---------------------------------------------------------------------------- 3002f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 3003f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::Absps(XMMRegister dst) { 3004f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Andps(dst, 3005f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ExternalOperand(ExternalReference::address_of_float_abs_constant())); 3006f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 3007f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 3008f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::Negps(XMMRegister dst) { 3009f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Xorps(dst, 3010f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ExternalOperand(ExternalReference::address_of_float_neg_constant())); 3011f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 3012f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 3013f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::Abspd(XMMRegister dst) { 3014f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Andps(dst, 3015f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ExternalOperand(ExternalReference::address_of_double_abs_constant())); 3016f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 3017f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 3018f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::Negpd(XMMRegister dst) { 3019f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Xorps(dst, 3020f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ExternalOperand(ExternalReference::address_of_double_neg_constant())); 3021f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 3022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cmp(Register dst, Handle<Object> source) { 3024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AllowDeferredHandleDereference smi_check; 3025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (source->IsSmi()) { 3026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cmp(dst, Smi::cast(*source)); 3027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MoveHeapObject(kScratchRegister, source); 3029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cmpp(dst, kScratchRegister); 3030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cmp(const Operand& dst, Handle<Object> source) { 3035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AllowDeferredHandleDereference smi_check; 3036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (source->IsSmi()) { 3037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cmp(dst, Smi::cast(*source)); 3038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MoveHeapObject(kScratchRegister, source); 3040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cmpp(dst, kScratchRegister); 3041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Push(Handle<Object> source) { 3046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AllowDeferredHandleDereference smi_check; 3047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (source->IsSmi()) { 3048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(Smi::cast(*source)); 3049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MoveHeapObject(kScratchRegister, source); 3051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(kScratchRegister); 3052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::MoveHeapObject(Register result, 3057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> object) { 3058014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(object->IsHeapObject()); 3059f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Move(result, object, RelocInfo::EMBEDDED_OBJECT); 3060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::LoadGlobalCell(Register dst, Handle<Cell> cell) { 3064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (dst.is(rax)) { 3065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AllowDeferredHandleDereference embedding_raw_address; 3066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch load_rax(cell.location(), RelocInfo::CELL); 3067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Move(dst, cell, RelocInfo::CELL); 3069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(dst, Operand(dst, 0)); 3070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::CmpWeakValue(Register value, Handle<WeakCell> cell, 3075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register scratch) { 3076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Move(scratch, cell, RelocInfo::EMBEDDED_OBJECT); 3077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cmpp(value, FieldOperand(scratch, WeakCell::kValueOffset)); 3078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::GetWeakValue(Register value, Handle<WeakCell> cell) { 3082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Move(value, cell, RelocInfo::EMBEDDED_OBJECT); 3083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(value, FieldOperand(value, WeakCell::kValueOffset)); 3084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::LoadWeakValue(Register value, Handle<WeakCell> cell, 3088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label* miss) { 3089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GetWeakValue(value, cell); 3090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JumpIfSmi(value, miss); 3091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Drop(int stack_elements) { 3095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (stack_elements > 0) { 3096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch addp(rsp, Immediate(stack_elements * kPointerSize)); 3097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::DropUnderReturnAddress(int stack_elements, 3102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register scratch) { 3103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(stack_elements > 0); 3104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize == kInt64Size && stack_elements == 1) { 3105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch popq(MemOperand(rsp, 0)); 3106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PopReturnAddressTo(scratch); 3110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Drop(stack_elements); 3111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PushReturnAddressFrom(scratch); 3112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Push(Register src) { 3116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize == kInt64Size) { 3117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pushq(src); 3118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // x32 uses 64-bit push for rbp in the prologue. 3120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(src.code() != rbp.code()); 3121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch leal(rsp, Operand(rsp, -4)); 3122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(Operand(rsp, 0), src); 3123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Push(const Operand& src) { 3128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize == kInt64Size) { 3129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pushq(src); 3130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(kScratchRegister, src); 3132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch leal(rsp, Operand(rsp, -4)); 3133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(Operand(rsp, 0), kScratchRegister); 3134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::PushQuad(const Operand& src) { 3139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize == kInt64Size) { 3140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pushq(src); 3141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(kScratchRegister, src); 3143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pushq(kScratchRegister); 3144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Push(Immediate value) { 3149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize == kInt64Size) { 3150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pushq(value); 3151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch leal(rsp, Operand(rsp, -4)); 3153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(Operand(rsp, 0), value); 3154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::PushImm32(int32_t imm32) { 3159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize == kInt64Size) { 3160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pushq_imm32(imm32); 3161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch leal(rsp, Operand(rsp, -4)); 3163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(Operand(rsp, 0), Immediate(imm32)); 3164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Pop(Register dst) { 3169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize == kInt64Size) { 3170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch popq(dst); 3171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // x32 uses 64-bit pop for rbp in the epilogue. 3173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(dst.code() != rbp.code()); 3174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(dst, Operand(rsp, 0)); 3175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch leal(rsp, Operand(rsp, 4)); 3176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Pop(const Operand& dst) { 3181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize == kInt64Size) { 3182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch popq(dst); 3183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register scratch = dst.AddressUsesRegister(kScratchRegister) 3185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? kRootRegister : kScratchRegister; 3186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(scratch, Operand(rsp, 0)); 3187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(dst, scratch); 3188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch leal(rsp, Operand(rsp, 4)); 3189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (scratch.is(kRootRegister)) { 3190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Restore kRootRegister. 3191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InitializeRootRegister(); 3192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::PopQuad(const Operand& dst) { 3198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (kPointerSize == kInt64Size) { 3199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch popq(dst); 3200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch popq(kScratchRegister); 3202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, kScratchRegister); 3203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::LoadSharedFunctionInfoSpecialField(Register dst, 3208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register base, 3209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int offset) { 3210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(offset > SharedFunctionInfo::kLengthOffset && 3211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch offset <= SharedFunctionInfo::kSize && 3212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (((offset - SharedFunctionInfo::kLengthOffset) / kIntSize) % 2 == 1)); 3213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (kPointerSize == kInt64Size) { 3214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movsxlq(dst, FieldOperand(base, offset)); 3215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, FieldOperand(base, offset)); 3217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(dst, dst); 3218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::TestBitSharedFunctionInfoSpecialField(Register base, 3223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int offset, 3224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int bits) { 3225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(offset > SharedFunctionInfo::kLengthOffset && 3226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch offset <= SharedFunctionInfo::kSize && 3227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (((offset - SharedFunctionInfo::kLengthOffset) / kIntSize) % 2 == 1)); 3228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (kPointerSize == kInt32Size) { 3229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // On x32, this field is represented by SMI. 3230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bits += kSmiShift; 3231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 32323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int byte_offset = bits / kBitsPerByte; 32333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int bit_in_byte = bits & (kBitsPerByte - 1); 3234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testb(FieldOperand(base, offset + byte_offset), Immediate(1 << bit_in_byte)); 32353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 32363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 32373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Jump(ExternalReference ext) { 323944f0eee88ff00398ff7f715fab053374d808c90dSteve Block LoadAddress(kScratchRegister, ext); 3240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block jmp(kScratchRegister); 3241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Jump(const Operand& op) { 3245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (kPointerSize == kInt64Size) { 3246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jmp(op); 3247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, op); 3249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jmp(kScratchRegister); 3250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Jump(Address destination, RelocInfo::Mode rmode) { 3255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(kScratchRegister, destination, rmode); 3256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block jmp(kScratchRegister); 3257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Jump(Handle<Code> code_object, RelocInfo::Mode rmode) { 32613ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // TODO(X64): Inline this 32623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block jmp(code_object, rmode); 3263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 326644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockint MacroAssembler::CallSize(ExternalReference ext) { 326744f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Opcode for call kScratchRegister is: Rex.B FF D4 (three bytes). 3268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return LoadAddressSize(ext) + 3269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler::kCallScratchRegisterInstructionLength; 327044f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 327144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 327244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 3273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Call(ExternalReference ext) { 327444f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG 327544f0eee88ff00398ff7f715fab053374d808c90dSteve Block int end_position = pc_offset() + CallSize(ext); 327644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 327744f0eee88ff00398ff7f715fab053374d808c90dSteve Block LoadAddress(kScratchRegister, ext); 3278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block call(kScratchRegister); 327944f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG 328044f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(end_position, pc_offset()); 328144f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 3282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Call(const Operand& op) { 3286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize == kInt64Size && !CpuFeatures::IsSupported(ATOM)) { 3287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch call(op); 3288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, op); 3290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch call(kScratchRegister); 3291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Call(Address destination, RelocInfo::Mode rmode) { 329644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG 3297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int end_position = pc_offset() + CallSize(destination); 329844f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 3299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(kScratchRegister, destination, rmode); 3300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block call(kScratchRegister); 330144f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG 330244f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(pc_offset(), end_position); 330344f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 3304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3307257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::Call(Handle<Code> code_object, 3308257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch RelocInfo::Mode rmode, 3309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TypeFeedbackId ast_id) { 331044f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG 331144f0eee88ff00398ff7f715fab053374d808c90dSteve Block int end_position = pc_offset() + CallSize(code_object); 331244f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 3313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(RelocInfo::IsCodeTarget(rmode) || 3314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch rmode == RelocInfo::CODE_AGE_SEQUENCE); 3315257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch call(code_object, rmode, ast_id); 331644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG 331744f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(end_position, pc_offset()); 331844f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 3319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Pextrd(Register dst, XMMRegister src, int8_t imm8) { 3323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (imm8 == 0) { 3324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movd(dst, src); 3325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(SSE4_1)) { 3328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope sse_scope(this, SSE4_1); 3329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pextrd(dst, src, imm8); 3330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3332f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK_EQ(1, imm8); 3333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movq(dst, src); 3334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch shrq(dst, Immediate(32)); 3335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Pinsrd(XMMRegister dst, Register src, int8_t imm8) { 3339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(SSE4_1)) { 3340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope sse_scope(this, SSE4_1); 3341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pinsrd(dst, src, imm8); 3342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 334413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Movd(kScratchDoubleReg, src); 3345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (imm8 == 1) { 334613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch punpckldq(dst, kScratchDoubleReg); 3347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(0, imm8); 334913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Movss(dst, kScratchDoubleReg); 3350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Pinsrd(XMMRegister dst, const Operand& src, int8_t imm8) { 3355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(imm8 == 0 || imm8 == 1); 3356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(SSE4_1)) { 3357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope sse_scope(this, SSE4_1); 3358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pinsrd(dst, src, imm8); 3359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 336113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Movd(kScratchDoubleReg, src); 3362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (imm8 == 1) { 336313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch punpckldq(dst, kScratchDoubleReg); 3364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(0, imm8); 336613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Movss(dst, kScratchDoubleReg); 3367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Lzcntl(Register dst, Register src) { 3372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(LZCNT)) { 3373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, LZCNT); 3374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch lzcntl(dst, src); 3375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label not_zero_src; 3378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bsrl(dst, src); 3379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(not_zero, ¬_zero_src, Label::kNear); 3380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(dst, 63); // 63^31 == 32 3381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(¬_zero_src); 3382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch xorl(dst, Immediate(31)); // for x in [0..31], 31^x == 31 - x 3383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Lzcntl(Register dst, const Operand& src) { 3387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(LZCNT)) { 3388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, LZCNT); 3389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch lzcntl(dst, src); 3390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label not_zero_src; 3393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bsrl(dst, src); 3394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(not_zero, ¬_zero_src, Label::kNear); 3395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(dst, 63); // 63^31 == 32 3396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(¬_zero_src); 3397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch xorl(dst, Immediate(31)); // for x in [0..31], 31^x == 31 - x 3398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Lzcntq(Register dst, Register src) { 3402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(LZCNT)) { 3403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, LZCNT); 3404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch lzcntq(dst, src); 3405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label not_zero_src; 3408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bsrq(dst, src); 3409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(not_zero, ¬_zero_src, Label::kNear); 3410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(dst, 127); // 127^63 == 64 3411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(¬_zero_src); 3412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch xorl(dst, Immediate(63)); // for x in [0..63], 63^x == 63 - x 3413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Lzcntq(Register dst, const Operand& src) { 3417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(LZCNT)) { 3418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, LZCNT); 3419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch lzcntq(dst, src); 3420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label not_zero_src; 3423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bsrq(dst, src); 3424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(not_zero, ¬_zero_src, Label::kNear); 3425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(dst, 127); // 127^63 == 64 3426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(¬_zero_src); 3427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch xorl(dst, Immediate(63)); // for x in [0..63], 63^x == 63 - x 3428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Tzcntq(Register dst, Register src) { 3432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(BMI1)) { 3433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, BMI1); 3434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch tzcntq(dst, src); 3435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label not_zero_src; 3438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bsfq(dst, src); 3439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(not_zero, ¬_zero_src, Label::kNear); 3440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Define the result of tzcnt(0) separately, because bsf(0) is undefined. 3441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(dst, 64); 3442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(¬_zero_src); 3443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Tzcntq(Register dst, const Operand& src) { 3447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(BMI1)) { 3448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, BMI1); 3449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch tzcntq(dst, src); 3450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label not_zero_src; 3453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bsfq(dst, src); 3454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(not_zero, ¬_zero_src, Label::kNear); 3455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Define the result of tzcnt(0) separately, because bsf(0) is undefined. 3456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(dst, 64); 3457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(¬_zero_src); 3458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Tzcntl(Register dst, Register src) { 3462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(BMI1)) { 3463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, BMI1); 3464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch tzcntl(dst, src); 3465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label not_zero_src; 3468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bsfl(dst, src); 3469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(not_zero, ¬_zero_src, Label::kNear); 3470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(dst, 32); // The result of tzcnt is 32 if src = 0. 3471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(¬_zero_src); 3472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Tzcntl(Register dst, const Operand& src) { 3476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(BMI1)) { 3477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, BMI1); 3478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch tzcntl(dst, src); 3479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label not_zero_src; 3482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bsfl(dst, src); 3483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(not_zero, ¬_zero_src, Label::kNear); 3484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(dst, 32); // The result of tzcnt is 32 if src = 0. 3485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(¬_zero_src); 3486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Popcntl(Register dst, Register src) { 3490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(POPCNT)) { 3491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, POPCNT); 3492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch popcntl(dst, src); 3493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 3496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Popcntl(Register dst, const Operand& src) { 3500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(POPCNT)) { 3501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, POPCNT); 3502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch popcntl(dst, src); 3503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 3506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Popcntq(Register dst, Register src) { 3510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(POPCNT)) { 3511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, POPCNT); 3512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch popcntq(dst, src); 3513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 3516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Popcntq(Register dst, const Operand& src) { 3520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(POPCNT)) { 3521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, POPCNT); 3522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch popcntq(dst, src); 3523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 3526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 35291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::Pushad() { 3530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(rax); 3531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(rcx); 3532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(rdx); 3533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(rbx); 35341e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Not pushing rsp or rbp. 3535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(rsi); 3536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(rdi); 3537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(r8); 3538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(r9); 35391e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // r10 is kScratchRegister. 3540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(r11); 3541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(r12); 35421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // r13 is kRootRegister. 3543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(r14); 3544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(r15); 3545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STATIC_ASSERT(12 == kNumSafepointSavedRegisters); 3546e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Use lea for symmetry with Popad. 3547e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int sp_delta = 3548e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch (kNumSafepointRegisters - kNumSafepointSavedRegisters) * kPointerSize; 3549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(rsp, Operand(rsp, -sp_delta)); 35501e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 35511e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 35521e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 35531e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::Popad() { 3554e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Popad must not change the flags, so use lea instead of addq. 3555e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int sp_delta = 3556e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch (kNumSafepointRegisters - kNumSafepointSavedRegisters) * kPointerSize; 3557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(rsp, Operand(rsp, sp_delta)); 3558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(r15); 3559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(r14); 3560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pop(r12); 3561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(r11); 3562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(r9); 3563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(r8); 3564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(rdi); 3565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(rsi); 3566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(rbx); 3567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(rdx); 3568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(rcx); 3569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(rax); 35701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 35711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 35721e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 35731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::Dropad() { 3574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(rsp, Immediate(kNumSafepointRegisters * kPointerSize)); 35751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 35761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 35771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 35781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// Order general registers are pushed by Pushad: 357944f0eee88ff00398ff7f715fab053374d808c90dSteve Block// rax, rcx, rdx, rbx, rsi, rdi, r8, r9, r11, r14, r15. 35803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int 35813ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochMacroAssembler::kSafepointPushRegisterIndices[Register::kNumRegisters] = { 35821e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 0, 35831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1, 35841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 2, 35851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 3, 35861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block -1, 35871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block -1, 35881e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 4, 35891e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 5, 35901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 6, 35911e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 7, 35921e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block -1, 35931e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 8, 359444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 9, 3595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch -1, 3596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 10, 3597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 11 35981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}; 35991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 36001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 3601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::StoreToSafepointRegisterSlot(Register dst, 3602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Immediate& imm) { 3603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(SafepointRegisterSlot(dst), imm); 3604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3607e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochvoid MacroAssembler::StoreToSafepointRegisterSlot(Register dst, Register src) { 3608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(SafepointRegisterSlot(dst), src); 3609e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 3610e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3611e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3612e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochvoid MacroAssembler::LoadFromSafepointRegisterSlot(Register dst, Register src) { 3613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, SafepointRegisterSlot(src)); 3614e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 3615e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3616e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3617e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochOperand MacroAssembler::SafepointRegisterSlot(Register reg) { 3618e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return Operand(rsp, SafepointRegisterStackIndex(reg.code()) * kPointerSize); 3619e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 3620e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3621e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::PushStackHandler() { 3623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Adjust this code if not the case. 3624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STATIC_ASSERT(StackHandlerConstants::kSize == 1 * kPointerSize); 36253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); 36263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Link the current handler as the next handler. 36283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); 3629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(ExternalOperand(handler_address)); 3630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 36313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Set this new handler as the current one. 3632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(ExternalOperand(handler_address), rsp); 3633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::PopStackHandler() { 36373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); 36383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); 3639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(ExternalOperand(handler_address)); 3640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize)); 3641e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 3642e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 3643e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 3644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Ret() { 3645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ret(0); 3646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 36491e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::Ret(int bytes_dropped, Register scratch) { 36501e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (is_uint16(bytes_dropped)) { 36511e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block ret(bytes_dropped); 36521e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } else { 3653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PopReturnAddressTo(scratch); 3654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(rsp, Immediate(bytes_dropped)); 3655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushReturnAddressFrom(scratch); 36561e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block ret(0); 36571e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 36581e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 36591e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 36601e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 3661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::FCmp() { 36623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block fucomip(); 36638defd9ff6930b4e24729971a61cf7469daf119beSteve Block fstp(0); 3664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::CmpObjectType(Register heap_object, 3668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InstanceType type, 3669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register map) { 3670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(map, FieldOperand(heap_object, HeapObject::kMapOffset)); 3671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CmpInstanceType(map, type); 3672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::CmpInstanceType(Register map, InstanceType type) { 3676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block cmpb(FieldOperand(map, Map::kInstanceTypeOffset), 3677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Immediate(static_cast<int8_t>(type))); 3678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 36813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid MacroAssembler::CheckFastElements(Register map, 36823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Label* fail, 36833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Label::Distance distance) { 3684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); 3685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); 3686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(FAST_ELEMENTS == 2); 3687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); 36883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cmpb(FieldOperand(map, Map::kBitField2Offset), 3689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Immediate(Map::kMaximumBitField2FastHoleyElementValue)); 36903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(above, fail, distance); 36913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 36923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::CheckFastObjectElements(Register map, 36953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* fail, 36963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label::Distance distance) { 3697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); 3698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); 3699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(FAST_ELEMENTS == 2); 3700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); 37013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cmpb(FieldOperand(map, Map::kBitField2Offset), 3702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Immediate(Map::kMaximumBitField2FastHoleySmiElementValue)); 37033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(below_equal, fail, distance); 3704592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch cmpb(FieldOperand(map, Map::kBitField2Offset), 3705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Immediate(Map::kMaximumBitField2FastHoleyElementValue)); 3706592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch j(above, fail, distance); 3707592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch} 3708592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 3709592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 3710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::CheckFastSmiElements(Register map, 3711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* fail, 3712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::Distance distance) { 3713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); 3714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); 37153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cmpb(FieldOperand(map, Map::kBitField2Offset), 3716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Immediate(Map::kMaximumBitField2FastHoleySmiElementValue)); 37173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(above, fail, distance); 37183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 37193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 37203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 37213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::StoreNumberToDoubleElements( 37223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register maybe_number, 37233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register elements, 37243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register index, 37253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch XMMRegister xmm_scratch, 3726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* fail, 3727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int elements_offset) { 3728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label smi_value, done; 37293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 37303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JumpIfSmi(maybe_number, &smi_value, Label::kNear); 37313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 37323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CheckMap(maybe_number, 37333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate()->factory()->heap_number_map(), 37343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch fail, 37353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DONT_DO_SMI_CHECK); 37363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Double value, turn potential sNaN into qNaN. 3738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Move(xmm_scratch, 1.0); 3739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch mulsd(xmm_scratch, FieldOperand(maybe_number, HeapNumber::kValueOffset)); 3740014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jmp(&done, Label::kNear); 37413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 37423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bind(&smi_value); 37433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Value is a smi. convert to a double and store. 37443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Preserve original value. 37453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SmiToInteger32(kScratchRegister, maybe_number); 3746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Cvtlsi2sd(xmm_scratch, kScratchRegister); 3747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(&done); 3748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movsd(FieldOperand(elements, index, times_8, 3749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FixedDoubleArray::kHeaderSize - elements_offset), 37503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch xmm_scratch); 37513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 37523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 37533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::CompareMap(Register obj, Handle<Map> map) { 37553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Cmp(FieldOperand(obj, HeapObject::kMapOffset), map); 37563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 37573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 37583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 37593100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid MacroAssembler::CheckMap(Register obj, 37603100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Handle<Map> map, 37613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Label* fail, 3762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiCheckType smi_check_type) { 3763257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (smi_check_type == DO_SMI_CHECK) { 37643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu JumpIfSmi(obj, fail); 37653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 37663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompareMap(obj, map); 37683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu j(not_equal, fail); 37693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 37703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 37713100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3772257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::ClampUint8(Register reg) { 3773257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label done; 3774257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch testl(reg, Immediate(0xFFFFFF00)); 3775257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(zero, &done, Label::kNear); 3776257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch setcc(negative, reg); // 1 if negative, 0 if positive. 3777257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch decb(reg); // 0 if negative, 255 if positive. 3778257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&done); 3779257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 3780257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3781257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3782257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::ClampDoubleToUint8(XMMRegister input_reg, 3783257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch XMMRegister temp_xmm_reg, 3784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register result_reg) { 3785257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label done; 3786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label conv_failure; 3787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Xorpd(temp_xmm_reg, temp_xmm_reg); 3788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cvtsd2si(result_reg, input_reg); 3789257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch testl(result_reg, Immediate(0xFFFFFF00)); 3790257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(zero, &done, Label::kNear); 3791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpl(result_reg, Immediate(1)); 3792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(overflow, &conv_failure, Label::kNear); 3793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(result_reg, Immediate(0)); 3794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch setcc(sign, result_reg); 3795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subl(result_reg, Immediate(1)); 3796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andl(result_reg, Immediate(255)); 3797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jmp(&done, Label::kNear); 3798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&conv_failure); 3799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Set(result_reg, 0); 3800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Ucomisd(input_reg, temp_xmm_reg); 3801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(below, &done, Label::kNear); 3802257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Set(result_reg, 255); 3803257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&done); 3804257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 3805257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3806257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::LoadUint32(XMMRegister dst, 3808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register src) { 3809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_debug_code) { 3810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpq(src, Immediate(0xffffffff)); 3811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assert(below_equal, kInputGPRIsExpectedToHaveUpper32Cleared); 3812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cvtqsi2sd(dst, src); 3814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::SlowTruncateToI(Register result_reg, 3818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register input_reg, 3819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int offset) { 3820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DoubleToIStub stub(isolate(), input_reg, result_reg, offset, true); 3821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch call(stub.GetCode(), RelocInfo::CODE_TARGET); 3822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::TruncateHeapNumberToI(Register result_reg, 3826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register input_reg) { 3827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done; 382813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Movsd(kScratchDoubleReg, FieldOperand(input_reg, HeapNumber::kValueOffset)); 382913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Cvttsd2siq(result_reg, kScratchDoubleReg); 3830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpq(result_reg, Immediate(1)); 3831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(no_overflow, &done, Label::kNear); 3832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Slow case. 3834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (input_reg.is(result_reg)) { 3835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(rsp, Immediate(kDoubleSize)); 383613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Movsd(MemOperand(rsp, 0), kScratchDoubleReg); 3837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SlowTruncateToI(result_reg, rsp, 0); 3838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(rsp, Immediate(kDoubleSize)); 3839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SlowTruncateToI(result_reg, input_reg); 3841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&done); 3844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Keep our invariant that the upper 32 bits are zero. 3845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(result_reg, result_reg); 3846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::TruncateDoubleToI(Register result_reg, 3850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch XMMRegister input_reg) { 3851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done; 3852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cvttsd2siq(result_reg, input_reg); 3853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpq(result_reg, Immediate(1)); 3854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(no_overflow, &done, Label::kNear); 3855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(rsp, Immediate(kDoubleSize)); 3857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movsd(MemOperand(rsp, 0), input_reg); 3858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SlowTruncateToI(result_reg, rsp, 0); 3859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(rsp, Immediate(kDoubleSize)); 3860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&done); 3862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Keep our invariant that the upper 32 bits are zero. 3863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(result_reg, result_reg); 3864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::DoubleToI(Register result_reg, XMMRegister input_reg, 3868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch XMMRegister scratch, 3869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MinusZeroMode minus_zero_mode, 3870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* lost_precision, Label* is_nan, 3871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* minus_zero, Label::Distance dst) { 3872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cvttsd2si(result_reg, input_reg); 387313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Cvtlsi2sd(kScratchDoubleReg, result_reg); 387413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Ucomisd(kScratchDoubleReg, input_reg); 3875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(not_equal, lost_precision, dst); 3876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(parity_even, is_nan, dst); // NaN. 3877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (minus_zero_mode == FAIL_ON_MINUS_ZERO) { 3878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done; 3879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The integer converted back is equal to the original. We 3880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // only have to test if we got -0 as an input. 3881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testl(result_reg, result_reg); 3882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(not_zero, &done, Label::kNear); 3883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movmskpd(result_reg, input_reg); 3884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Bit 0 contains the sign of the double in input_reg. 3885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If input was positive, we are ok and return 0, otherwise 3886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // jump to minus_zero. 3887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andl(result_reg, Immediate(1)); 3888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(not_zero, minus_zero, dst); 3889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&done); 3890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3894257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::LoadInstanceDescriptors(Register map, 3895257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register descriptors) { 3896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(descriptors, FieldOperand(map, Map::kDescriptorsOffset)); 3897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::NumberOfOwnDescriptors(Register dst, Register map) { 3901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(dst, FieldOperand(map, Map::kBitField3Offset)); 3902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DecodeField<Map::NumberOfOwnDescriptorsBits>(dst); 3903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::EnumLength(Register dst, Register map) { 3907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(Map::EnumLengthBits::kShift == 0); 3908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(dst, FieldOperand(map, Map::kBitField3Offset)); 3909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andl(dst, Immediate(Map::EnumLengthBits::kMask)); 3910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Integer32ToSmi(dst, dst); 3911257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 3912257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3913257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::LoadAccessor(Register dst, Register holder, 3915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int accessor_index, 3916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AccessorComponent accessor) { 3917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(dst, FieldOperand(holder, HeapObject::kMapOffset)); 3918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoadInstanceDescriptors(dst, dst); 3919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(dst, FieldOperand(dst, DescriptorArray::GetValueOffset(accessor_index))); 3920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int offset = accessor == ACCESSOR_GETTER ? AccessorPair::kGetterOffset 3921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : AccessorPair::kSetterOffset; 3922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(dst, FieldOperand(dst, offset)); 3923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3926958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid MacroAssembler::DispatchWeakMap(Register obj, Register scratch1, 3927958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register scratch2, Handle<WeakCell> cell, 3928958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Code> success, 3929958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SmiCheckType smi_check_type) { 3930257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label fail; 3931257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (smi_check_type == DO_SMI_CHECK) { 3932257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch JumpIfSmi(obj, &fail); 3933257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 3934958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier movq(scratch1, FieldOperand(obj, HeapObject::kMapOffset)); 3935958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CmpWeakValue(scratch1, cell, scratch2); 3936257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(equal, success, RelocInfo::CODE_TARGET); 3937257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&fail); 3938257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 3939257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3940257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertNumber(Register object) { 3942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 3943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label ok; 3944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition is_smi = CheckSmi(object); 3945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(is_smi, &ok, Label::kNear); 3946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Cmp(FieldOperand(object, HeapObject::kMapOffset), 3947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->factory()->heap_number_map()); 3948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(equal, kOperandIsNotANumber); 3949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&ok); 3950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3951402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu} 3952402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 39533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid MacroAssembler::AssertNotNumber(Register object) { 39543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (emit_debug_code()) { 39553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Condition is_smi = CheckSmi(object); 39563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Check(NegateCondition(is_smi), kOperandIsANumber); 39573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Cmp(FieldOperand(object, HeapObject::kMapOffset), 39583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch isolate()->factory()->heap_number_map()); 39593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Check(not_equal, kOperandIsANumber); 39603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 39613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 3962402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 3963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertNotSmi(Register object) { 3964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 3965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition is_smi = CheckSmi(object); 3966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(NegateCondition(is_smi), kOperandIsASmi); 3967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3968756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick} 3969756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 3970756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 3971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertSmi(Register object) { 3972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 3973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition is_smi = CheckSmi(object); 3974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(is_smi, kOperandIsNotASmi); 3975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 397644f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 397744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 397844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 3979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertSmi(const Operand& object) { 3980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 3981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition is_smi = CheckSmi(object); 3982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(is_smi, kOperandIsNotASmi); 3983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertZeroExtended(Register int32_register) { 3988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 3989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!int32_register.is(kScratchRegister)); 3990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movq(kScratchRegister, V8_INT64_C(0x0000000100000000)); 3991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpq(kScratchRegister, int32_register); 3992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(above_equal, k32BitValueInRegisterIsNotZeroExtended); 3993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertString(Register object) { 3998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 3999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testb(object, Immediate(kSmiTagMask)); 4000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(not_equal, kOperandIsASmiAndNotAString); 4001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(object); 4002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(object, FieldOperand(object, HeapObject::kMapOffset)); 4003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CmpInstanceType(object, FIRST_NONSTRING_TYPE); 4004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(object); 4005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(below, kOperandIsNotAString); 4006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 40076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 40086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 40096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 4010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertName(Register object) { 4011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 4012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testb(object, Immediate(kSmiTagMask)); 4013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(not_equal, kOperandIsASmiAndNotAName); 4014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(object); 4015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(object, FieldOperand(object, HeapObject::kMapOffset)); 4016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CmpInstanceType(object, LAST_NAME_TYPE); 4017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(object); 4018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(below_equal, kOperandIsNotAName); 4019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 40203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 40213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 40223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::AssertFunction(Register object) { 4024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (emit_debug_code()) { 4025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch testb(object, Immediate(kSmiTagMask)); 4026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Check(not_equal, kOperandIsASmiAndNotAFunction); 4027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(object); 4028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CmpObjectType(object, JS_FUNCTION_TYPE, object); 4029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pop(object); 4030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Check(equal, kOperandIsNotAFunction); 4031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 4033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::AssertBoundFunction(Register object) { 4036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (emit_debug_code()) { 4037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch testb(object, Immediate(kSmiTagMask)); 4038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Check(not_equal, kOperandIsASmiAndNotABoundFunction); 4039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(object); 4040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CmpObjectType(object, JS_BOUND_FUNCTION_TYPE, object); 4041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pop(object); 4042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Check(equal, kOperandIsNotABoundFunction); 4043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 4045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4046bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid MacroAssembler::AssertGeneratorObject(Register object) { 4047bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (emit_debug_code()) { 4048bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch testb(object, Immediate(kSmiTagMask)); 4049bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Check(not_equal, kOperandIsASmiAndNotAGeneratorObject); 4050bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Push(object); 4051bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch CmpObjectType(object, JS_GENERATOR_OBJECT_TYPE, object); 4052bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Pop(object); 4053bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Check(equal, kOperandIsNotAGeneratorObject); 4054bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 4055bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 4056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4057109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid MacroAssembler::AssertReceiver(Register object) { 4058109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (emit_debug_code()) { 4059109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch testb(object, Immediate(kSmiTagMask)); 4060109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Check(not_equal, kOperandIsASmiAndNotAReceiver); 4061109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Push(object); 4062109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE); 4063109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CmpObjectType(object, FIRST_JS_RECEIVER_TYPE, object); 4064109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Pop(object); 4065109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Check(above_equal, kOperandIsNotAReceiver); 4066109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 4067109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 4068109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 4069109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 4070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertUndefinedOrAllocationSite(Register object) { 4071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 4072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done_checking; 4073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertNotSmi(object); 4074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Cmp(object, isolate()->factory()->undefined_value()); 4075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(equal, &done_checking); 4076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Cmp(FieldOperand(object, 0), isolate()->factory()->allocation_site_map()); 4077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assert(equal, kExpectedUndefinedOrCell); 4078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&done_checking); 4079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4080e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 4081e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 4082e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 4083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertRootValue(Register src, 4084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap::RootListIndex root_value_index, 4085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutReason reason) { 4086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 4087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src.is(kScratchRegister)); 4088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadRoot(kScratchRegister, root_value_index); 4089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(src, kScratchRegister); 4090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(equal, reason); 4091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 40929dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen} 40939dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 40949dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 40959dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 4096d91b9f7d46489a9ee00f9cb415630299c76a502bLeon ClarkeCondition MacroAssembler::IsObjectStringType(Register heap_object, 4097d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Register map, 4098d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Register instance_type) { 4099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(map, FieldOperand(heap_object, HeapObject::kMapOffset)); 41004515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke movzxbl(instance_type, FieldOperand(map, Map::kInstanceTypeOffset)); 410169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch STATIC_ASSERT(kNotStringTag != 0); 4102d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke testb(instance_type, Immediate(kIsNotStringMask)); 4103d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return zero; 4104d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 4105d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 4106d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 4107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochCondition MacroAssembler::IsObjectNameType(Register heap_object, 4108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register map, 4109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register instance_type) { 4110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(map, FieldOperand(heap_object, HeapObject::kMapOffset)); 4111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movzxbl(instance_type, FieldOperand(map, Map::kInstanceTypeOffset)); 4112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpb(instance_type, Immediate(static_cast<uint8_t>(LAST_NAME_TYPE))); 4113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return below_equal; 4114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::GetMapConstructor(Register result, Register map, 4118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register temp) { 4119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label done, loop; 4120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(result, FieldOperand(map, Map::kConstructorOrBackPointerOffset)); 4121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(&loop); 4122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JumpIfSmi(result, &done, Label::kNear); 4123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CmpObjectType(result, MAP_TYPE, temp); 4124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(not_equal, &done, Label::kNear); 4125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(result, FieldOperand(result, Map::kConstructorOrBackPointerOffset)); 4126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jmp(&loop); 4127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(&done); 4128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 41293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::TryGetFunctionPrototype(Register function, Register result, 4132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label* miss) { 4133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the prototype or initial map from the function. 4134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(result, 4135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); 4136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the prototype or initial map is the hole, don't return it and 4138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // simply miss the cache instead. This will allow us to allocate a 4139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // prototype object on-demand in the runtime system. 4140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompareRoot(result, Heap::kTheHoleValueRootIndex); 4141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block j(equal, miss); 4142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the function does not have an initial map, we're done. 4144257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label done; 4145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CmpObjectType(result, MAP_TYPE, kScratchRegister); 4146257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_equal, &done, Label::kNear); 4147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the prototype from the initial map. 4149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(result, FieldOperand(result, Map::kPrototypeOffset)); 4150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // All done. 4152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bind(&done); 4153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SetCounter(StatsCounter* counter, int value) { 4157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_native_code_counters && counter->Enabled()) { 415844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Operand counter_operand = ExternalOperand(ExternalReference(counter)); 41598b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch movl(counter_operand, Immediate(value)); 4160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::IncrementCounter(StatsCounter* counter, int value) { 4165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(value > 0); 4166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_native_code_counters && counter->Enabled()) { 416744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Operand counter_operand = ExternalOperand(ExternalReference(counter)); 4168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (value == 1) { 416944f0eee88ff00398ff7f715fab053374d808c90dSteve Block incl(counter_operand); 4170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 417144f0eee88ff00398ff7f715fab053374d808c90dSteve Block addl(counter_operand, Immediate(value)); 4172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::DecrementCounter(StatsCounter* counter, int value) { 4178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(value > 0); 4179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_native_code_counters && counter->Enabled()) { 418044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Operand counter_operand = ExternalOperand(ExternalReference(counter)); 4181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (value == 1) { 418244f0eee88ff00398ff7f715fab053374d808c90dSteve Block decl(counter_operand); 4183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 418444f0eee88ff00398ff7f715fab053374d808c90dSteve Block subl(counter_operand, Immediate(value)); 4185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4190402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuvoid MacroAssembler::DebugBreak() { 41919fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block Set(rax, 0); // No arguments. 4192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoadAddress(rbx, 4193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ExternalReference(Runtime::kHandleDebuggerStatement, isolate())); 4194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CEntryStub ces(isolate(), 1); 4195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(AllowThisStubCall(&ces)); 4196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Call(ces.GetCode(), RelocInfo::DEBUGGER_STATEMENT); 4197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 4198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 41993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid MacroAssembler::PrepareForTailCall(const ParameterCount& callee_args_count, 42003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register caller_args_count_reg, 42013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register scratch0, Register scratch1, 42023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ReturnAddressState ra_state) { 42033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#if DEBUG 42043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (callee_args_count.is_reg()) { 42053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(!AreAliased(callee_args_count.reg(), caller_args_count_reg, scratch0, 42063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch scratch1)); 42073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 42083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(!AreAliased(caller_args_count_reg, scratch0, scratch1)); 42093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 42103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#endif 42113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 42123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Calculate the destination address where we will put the return address 42133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // after we drop current frame. 42143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register new_sp_reg = scratch0; 42153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (callee_args_count.is_reg()) { 42163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch subp(caller_args_count_reg, callee_args_count.reg()); 42173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch leap(new_sp_reg, Operand(rbp, caller_args_count_reg, times_pointer_size, 42183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch StandardFrameConstants::kCallerPCOffset)); 42193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 42203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch leap(new_sp_reg, Operand(rbp, caller_args_count_reg, times_pointer_size, 42213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch StandardFrameConstants::kCallerPCOffset - 42223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch callee_args_count.immediate() * kPointerSize)); 42233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 42243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 42253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (FLAG_debug_code) { 42263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cmpp(rsp, new_sp_reg); 42273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Check(below, kStackAccessBelowStackPointer); 42283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 42293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 42303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Copy return address from caller's frame to current frame's return address 42313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // to avoid its trashing and let the following loop copy it to the right 42323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // place. 42333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register tmp_reg = scratch1; 42343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (ra_state == ReturnAddressState::kOnStack) { 42353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch movp(tmp_reg, Operand(rbp, StandardFrameConstants::kCallerPCOffset)); 42363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch movp(Operand(rsp, 0), tmp_reg); 42373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 42383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(ReturnAddressState::kNotOnStack == ra_state); 42393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Push(Operand(rbp, StandardFrameConstants::kCallerPCOffset)); 42403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 42413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 42423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Restore caller's frame pointer now as it could be overwritten by 42433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // the copying loop. 42443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch movp(rbp, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); 42453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 42463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // +2 here is to copy both receiver and return address. 42473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register count_reg = caller_args_count_reg; 42483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (callee_args_count.is_reg()) { 42493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch leap(count_reg, Operand(callee_args_count.reg(), 2)); 42503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 42513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch movp(count_reg, Immediate(callee_args_count.immediate() + 2)); 42523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // TODO(ishell): Unroll copying loop for small immediate values. 42533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 42543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 42553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Now copy callee arguments to the caller frame going backwards to avoid 42563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // callee arguments corruption (source and destination areas could overlap). 42573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Label loop, entry; 42583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch jmp(&entry, Label::kNear); 42593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch bind(&loop); 42603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch decp(count_reg); 42613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch movp(tmp_reg, Operand(rsp, count_reg, times_pointer_size, 0)); 42623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch movp(Operand(new_sp_reg, count_reg, times_pointer_size, 0), tmp_reg); 42633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch bind(&entry); 42643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cmpp(count_reg, Immediate(0)); 42653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch j(not_equal, &loop, Label::kNear); 42663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 42673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Leave current frame. 42683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch movp(rsp, new_sp_reg); 42693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 4270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::InvokeFunction(Register function, 4272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register new_target, 4273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& actual, 4274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InvokeFlag flag, 4275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const CallWrapper& call_wrapper) { 4276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(rbx, FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); 4277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoadSharedFunctionInfoSpecialField( 4278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch rbx, rbx, SharedFunctionInfo::kFormalParameterCountOffset); 4279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ParameterCount expected(rbx); 4281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InvokeFunction(function, new_target, expected, actual, flag, call_wrapper); 4282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 4283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::InvokeFunction(Handle<JSFunction> function, 4286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& expected, 4287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& actual, 4288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InvokeFlag flag, 4289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const CallWrapper& call_wrapper) { 4290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Move(rdi, function); 4291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InvokeFunction(rdi, no_reg, expected, actual, flag, call_wrapper); 4292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4293257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 4294257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 4295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::InvokeFunction(Register function, 4296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register new_target, 4297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& expected, 4298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& actual, 4299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InvokeFlag flag, 4300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const CallWrapper& call_wrapper) { 4301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(function.is(rdi)); 4302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(rsi, FieldOperand(function, JSFunction::kContextOffset)); 4303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InvokeFunctionCode(rdi, new_target, expected, actual, flag, call_wrapper); 4304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 4305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::InvokeFunctionCode(Register function, Register new_target, 4308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& expected, 4309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& actual, 4310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InvokeFlag flag, 4311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const CallWrapper& call_wrapper) { 43123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // You can't call a function without a valid frame. 4313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(flag == JUMP_FUNCTION || has_frame()); 4314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(function.is(rdi)); 4315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_IMPLIES(new_target.is_valid(), new_target.is(rdx)); 4316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (call_wrapper.NeedsDebugStepCheck()) { 4318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FloodFunctionIfStepping(function, new_target, expected, actual); 4319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Clear the new.target register if not given. 4322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!new_target.is_valid()) { 4323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoadRoot(rdx, Heap::kUndefinedValueRootIndex); 4324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 43253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4326257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label done; 43273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool definitely_mismatches = false; 4328e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch InvokePrologue(expected, 4329e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch actual, 4330e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch &done, 43313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch &definitely_mismatches, 4332e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch flag, 4333257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::kNear, 4334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch call_wrapper); 43353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!definitely_mismatches) { 4336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // We call indirectly through the code field in the function to 4337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // allow recompilation to take effect without changing any of the 4338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // call sites. 4339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand code = FieldOperand(function, JSFunction::kCodeEntryOffset); 43403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (flag == CALL_FUNCTION) { 43413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch call_wrapper.BeforeCall(CallSize(code)); 43423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch call(code); 43433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch call_wrapper.AfterCall(); 43443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 4345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(flag == JUMP_FUNCTION); 43463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch jmp(code); 43473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 43483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bind(&done); 4349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4353257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::InvokePrologue(const ParameterCount& expected, 4354257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch const ParameterCount& actual, 4355257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* done, 43563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool* definitely_mismatches, 4357257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch InvokeFlag flag, 4358257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump, 4359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const CallWrapper& call_wrapper) { 4360257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bool definitely_matches = false; 43613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *definitely_mismatches = false; 4362257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label invoke; 4363257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (expected.is_immediate()) { 4364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(actual.is_immediate()); 4365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(rax, actual.immediate()); 4366257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (expected.immediate() == actual.immediate()) { 4367257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch definitely_matches = true; 4368257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 4369257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (expected.immediate() == 4370257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch SharedFunctionInfo::kDontAdaptArgumentsSentinel) { 4371257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Don't worry about adapting arguments for built-ins that 4372257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // don't want that done. Skip adaption code by making it look 4373257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // like we have a match between expected and actual number of 4374257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // arguments. 4375257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch definitely_matches = true; 4376257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 43773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *definitely_mismatches = true; 4378257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Set(rbx, expected.immediate()); 4379257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 4380257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 4381257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 4382257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (actual.is_immediate()) { 4383257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Expected is in register, actual is immediate. This is the 4384257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // case when we invoke function values without going through the 4385257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // IC mechanism. 4386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(rax, actual.immediate()); 4387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(expected.reg(), Immediate(actual.immediate())); 4388257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(equal, &invoke, Label::kNear); 4389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(expected.reg().is(rbx)); 4390257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else if (!expected.reg().is(actual.reg())) { 4391257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Both expected and actual are in (different) registers. This 4392257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // is the case when we invoke functions using call and apply. 4393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(expected.reg(), actual.reg()); 4394257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(equal, &invoke, Label::kNear); 4395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(actual.reg().is(rax)); 4396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(expected.reg().is(rbx)); 4397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 4398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Move(rax, actual.reg()); 4399257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 4400257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 4401257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 4402257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!definitely_matches) { 4403257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<Code> adaptor = isolate()->builtins()->ArgumentsAdaptorTrampoline(); 4404257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (flag == CALL_FUNCTION) { 4405257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch call_wrapper.BeforeCall(CallSize(adaptor)); 4406257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Call(adaptor, RelocInfo::CODE_TARGET); 4407257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch call_wrapper.AfterCall(); 44083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!*definitely_mismatches) { 44093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch jmp(done, near_jump); 44103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4411257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 4412257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Jump(adaptor, RelocInfo::CODE_TARGET); 4413257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 4414257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&invoke); 44151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 4416402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu} 4417402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 4418402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 4419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::FloodFunctionIfStepping(Register fun, Register new_target, 4420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& expected, 4421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& actual) { 4422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label skip_flooding; 442313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ExternalReference last_step_action = 442413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch ExternalReference::debug_last_step_action_address(isolate()); 442513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Operand last_step_action_operand = ExternalOperand(last_step_action); 442613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch STATIC_ASSERT(StepFrame > StepIn); 442713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch cmpb(last_step_action_operand, Immediate(StepIn)); 442813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch j(less, &skip_flooding); 4429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { 4430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FrameScope frame(this, 4431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch has_frame() ? StackFrame::NONE : StackFrame::INTERNAL); 4432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (expected.is_reg()) { 4433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Integer32ToSmi(expected.reg(), expected.reg()); 4434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(expected.reg()); 4435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (actual.is_reg()) { 4437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Integer32ToSmi(actual.reg(), actual.reg()); 4438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(actual.reg()); 4439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (new_target.is_valid()) { 4441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(new_target); 4442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(fun); 4444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(fun); 4445109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CallRuntime(Runtime::kDebugPrepareStepInIfStepping); 4446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pop(fun); 4447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (new_target.is_valid()) { 4448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pop(new_target); 4449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (actual.is_reg()) { 4451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pop(actual.reg()); 4452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SmiToInteger64(actual.reg(), actual.reg()); 4453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (expected.is_reg()) { 4455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pop(expected.reg()); 4456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SmiToInteger64(expected.reg(), expected.reg()); 4457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(&skip_flooding); 4460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 4461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 44623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid MacroAssembler::StubPrologue(StackFrame::Type type) { 44633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch pushq(rbp); // Caller's frame pointer. 44643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch movp(rbp, rsp); 44653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Push(Smi::FromInt(type)); 4466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Prologue(bool code_pre_aging) { 4469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PredictableCodeSizeScope predictible_code_size_scope(this, 4470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kNoCodeAgeSequenceLength); 4471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (code_pre_aging) { 4472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Pre-age the code. 4473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Call(isolate()->builtins()->MarkCodeAsExecutedOnce(), 4474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfo::CODE_AGE_SEQUENCE); 4475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Nop(kNoCodeAgeSequenceLength - Assembler::kShortCallInstructionLength); 4476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pushq(rbp); // Caller's frame pointer. 4478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rbp, rsp); 4479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(rsi); // Callee's context. 4480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(rdi); // Callee's JS function. 4481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::EmitLoadTypeFeedbackVector(Register vector) { 4486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(vector, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 448713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch movp(vector, FieldOperand(vector, JSFunction::kLiteralsOffset)); 448813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch movp(vector, FieldOperand(vector, LiteralsArray::kFeedbackVectorOffset)); 4489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 4490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4492958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid MacroAssembler::EnterFrame(StackFrame::Type type, 4493958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool load_constant_pool_pointer_reg) { 4494958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Out-of-line constant pool not implemented on x64. 4495958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNREACHABLE(); 4496958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 4497958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 4498958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 4499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::EnterFrame(StackFrame::Type type) { 4500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pushq(rbp); 4501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rbp, rsp); 45023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Push(Smi::FromInt(type)); 45033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (type == StackFrame::INTERNAL) { 45043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Move(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); 45053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Push(kScratchRegister); 45063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 450744f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 4508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(kScratchRegister, 4509257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch isolate()->factory()->undefined_value(), 4510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfo::EMBEDDED_OBJECT); 4511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(Operand(rsp, 0), kScratchRegister); 4512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(not_equal, kCodeObjectNotProperlyPatched); 4513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::LeaveFrame(StackFrame::Type type) { 451844f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 45193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Move(kScratchRegister, Smi::FromInt(type)); 45203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cmpp(Operand(rbp, CommonFrameConstants::kContextOrFrameTypeOffset), 45213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch kScratchRegister); 4522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(equal, kStackFrameTypesMustMatch); 4523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rsp, rbp); 4525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch popq(rbp); 4526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4528f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::EnterBuiltinFrame(Register context, Register target, 4529f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Register argc) { 4530f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Push(rbp); 4531f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Move(rbp, rsp); 4532f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Push(context); 4533f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Push(target); 4534f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Push(argc); 4535f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 4536f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 4537f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::LeaveBuiltinFrame(Register context, Register target, 4538f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Register argc) { 4539f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Pop(argc); 4540f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Pop(target); 4541f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Pop(context); 4542f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch leave(); 4543f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 4544f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 4545f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::EnterExitFramePrologue(bool save_rax, 4546f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch StackFrame::Type frame_type) { 4547f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(frame_type == StackFrame::EXIT || 4548f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch frame_type == StackFrame::BUILTIN_EXIT); 4549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 45503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Set up the frame structure on the stack. 4551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // All constants are relative to the frame pointer of the exit frame. 45523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_EQ(kFPOnStackSize + kPCOnStackSize, 45533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ExitFrameConstants::kCallerSPDisplacement); 45543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_EQ(kFPOnStackSize, ExitFrameConstants::kCallerPCOffset); 45553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_EQ(0 * kPointerSize, ExitFrameConstants::kCallerFPOffset); 4556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pushq(rbp); 4557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rbp, rsp); 4558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 455980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Reserve room for entry stack pointer and push the code object. 4560f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Push(Smi::FromInt(frame_type)); 45613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_EQ(-2 * kPointerSize, ExitFrameConstants::kSPOffset); 4562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(Immediate(0)); // Saved entry sp, patched before call. 4563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); 4564f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Push(kScratchRegister); // Accessed from ExitFrame::code_slot. 4565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Save the frame pointer and the context in top. 4567bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch if (save_rax) { 4568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(r14, rax); // Backup rax in callee-save register. 4569bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } 4570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4571589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Store(ExternalReference(Isolate::kCEntryFPAddress, isolate()), rbp); 4572589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Store(ExternalReference(Isolate::kContextAddress, isolate()), rsi); 4573958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Store(ExternalReference(Isolate::kCFunctionAddress, isolate()), rbx); 4574bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch} 4575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 45768a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 45771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space, 45781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block bool save_doubles) { 4579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef _WIN64 45801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block const int kShadowSpace = 4; 45811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block arg_stack_space += kShadowSpace; 4582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 45831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Optionally save all XMM registers. 45841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (save_doubles) { 4585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int space = XMMRegister::kMaxNumRegisters * kDoubleSize + 4586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch arg_stack_space * kRegisterSize; 4587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(rsp, Immediate(space)); 45883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int offset = -ExitFrameConstants::kFixedFrameSizeFromFp; 458913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch const RegisterConfiguration* config = RegisterConfiguration::Crankshaft(); 4590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < config->num_allocatable_double_registers(); ++i) { 4591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister reg = 4592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister::from_code(config->GetAllocatableDoubleCode(i)); 4593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movsd(Operand(rbp, offset - ((i + 1) * kDoubleSize)), reg); 45941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 45951e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } else if (arg_stack_space > 0) { 4596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(rsp, Immediate(arg_stack_space * kRegisterSize)); 45978a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang } 4598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the required frame alignment for the OS. 4600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int kFrameAlignment = base::OS::ActivationFrameAlignment(); 4601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (kFrameAlignment > 0) { 4602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(base::bits::IsPowerOfTwo32(kFrameAlignment)); 4603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_int8(kFrameAlignment)); 4604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(rsp, Immediate(-kFrameAlignment)); 4605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Patch the saved entry sp. 4608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(rbp, ExitFrameConstants::kSPOffset), rsp); 4609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4611f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::EnterExitFrame(int arg_stack_space, bool save_doubles, 4612f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch StackFrame::Type frame_type) { 4613f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch EnterExitFramePrologue(true, frame_type); 4614bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 46153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Set up argv in callee-saved register r15. It is reused in LeaveExitFrame, 4616bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch // so it must be retained across the C-call. 4617bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; 4618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(r15, Operand(rbp, r14, times_pointer_size, offset)); 4619bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 46201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block EnterExitFrameEpilogue(arg_stack_space, save_doubles); 4621bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch} 4622bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 4623bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 46248a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wangvoid MacroAssembler::EnterApiExitFrame(int arg_stack_space) { 4625f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch EnterExitFramePrologue(false, StackFrame::EXIT); 46261e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block EnterExitFrameEpilogue(arg_stack_space, false); 4627bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch} 4628bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 4629bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 4630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::LeaveExitFrame(bool save_doubles, bool pop_arguments) { 4631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Registers: 463244f0eee88ff00398ff7f715fab053374d808c90dSteve Block // r15 : argv 46331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (save_doubles) { 46343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int offset = -ExitFrameConstants::kFixedFrameSizeFromFp; 463513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch const RegisterConfiguration* config = RegisterConfiguration::Crankshaft(); 4636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < config->num_allocatable_double_registers(); ++i) { 4637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister reg = 4638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister::from_code(config->GetAllocatableDoubleCode(i)); 4639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movsd(reg, Operand(rbp, offset - ((i + 1) * kDoubleSize))); 46401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 46411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 4642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (pop_arguments) { 4644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Get the return address from the stack and restore the frame pointer. 4645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(rcx, Operand(rbp, kFPOnStackSize)); 4646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(rbp, Operand(rbp, 0 * kPointerSize)); 4647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Drop everything up to and including the arguments and the receiver 4649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // from the caller stack. 4650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch leap(rsp, Operand(r15, 1 * kPointerSize)); 4651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PushReturnAddressFrom(rcx); 4653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 4654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Otherwise just leave the exit frame. 4655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch leave(); 4656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 46578a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 4658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LeaveExitFrameEpilogue(true); 46598a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang} 46608a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 46618a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 4662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::LeaveApiExitFrame(bool restore_context) { 4663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rsp, rbp); 4664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch popq(rbp); 46658a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 4666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LeaveExitFrameEpilogue(restore_context); 46678a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang} 46688a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 46698a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 4670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::LeaveExitFrameEpilogue(bool restore_context) { 4671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Restore current context from top and clear it in debug mode. 4672589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch ExternalReference context_address(Isolate::kContextAddress, isolate()); 467344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Operand context_operand = ExternalOperand(context_address); 4674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (restore_context) { 4675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rsi, context_operand); 4676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 4678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(context_operand, Immediate(0)); 4679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 4680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear the top frame. 4682589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress, 468344f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate()); 468444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Operand c_entry_fp_operand = ExternalOperand(c_entry_fp_address); 4685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(c_entry_fp_operand, Immediate(0)); 4686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, 4690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch, 4691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label* miss) { 4692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label same_contexts; 4693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!holder_reg.is(scratch)); 4695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!scratch.is(kScratchRegister)); 46963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Load current lexical context from the active StandardFrame, which 46973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // may require crawling past STUB frames. 46983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Label load_context; 46993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Label has_context; 47003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch movp(scratch, rbp); 47013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch bind(&load_context); 47023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(SmiValuesAre32Bits()); 47033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // This is "JumpIfNotSmi" but without loading the value into a register. 47043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cmpl(MemOperand(scratch, CommonFrameConstants::kContextOrFrameTypeOffset), 47053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Immediate(0)); 47063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch j(not_equal, &has_context); 47073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch movp(scratch, MemOperand(scratch, CommonFrameConstants::kCallerFPOffset)); 47083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch jmp(&load_context); 47093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch bind(&has_context); 47103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch movp(scratch, 47113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch MemOperand(scratch, CommonFrameConstants::kContextOrFrameTypeOffset)); 4712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // When generating debug code, make sure the lexical context is set. 471444f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 4715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(scratch, Immediate(0)); 4716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(not_equal, kWeShouldNotHaveAnEmptyLexicalContext); 4717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load the native context of the current context. 4719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(scratch, ContextOperand(scratch, Context::NATIVE_CONTEXT_INDEX)); 4720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check the context is a native context. 472244f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 4723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Cmp(FieldOperand(scratch, HeapObject::kMapOffset), 4724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->factory()->native_context_map()); 4725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(equal, kJSGlobalObjectNativeContextShouldBeANativeContext); 4726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check if both contexts are the same. 4729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(scratch, FieldOperand(holder_reg, JSGlobalProxy::kNativeContextOffset)); 4730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block j(equal, &same_contexts); 4731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compare security tokens. 4733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that the security token in the calling global object is 4734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // compatible with the security token in the receiving global 4735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // object. 4736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check the context is a native context. 473844f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 4739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Preserve original value of holder_reg. 4740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(holder_reg); 4741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(holder_reg, 4742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FieldOperand(holder_reg, JSGlobalProxy::kNativeContextOffset)); 4743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CompareRoot(holder_reg, Heap::kNullValueRootIndex); 4744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(not_equal, kJSGlobalProxyContextShouldNotBeNull); 4745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Read the first word and compare to native_context_map(), 4747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(holder_reg, FieldOperand(holder_reg, HeapObject::kMapOffset)); 4748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompareRoot(holder_reg, Heap::kNativeContextMapRootIndex); 4749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(equal, kJSGlobalObjectNativeContextShouldBeANativeContext); 4750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(holder_reg); 4751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, 4754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FieldOperand(holder_reg, JSGlobalProxy::kNativeContextOffset)); 47553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int token_offset = 47563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Context::kHeaderSize + Context::SECURITY_TOKEN_INDEX * kPointerSize; 4757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch, FieldOperand(scratch, token_offset)); 4758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(scratch, FieldOperand(kScratchRegister, token_offset)); 4759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block j(not_equal, miss); 4760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bind(&same_contexts); 4762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Compute the hash code from the untagged key. This must be kept in sync with 4766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ComputeIntegerHash in utils.h and KeyedLoadGenericStub in 4767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// code-stub-hydrogen.cc 4768c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdochvoid MacroAssembler::GetNumberHash(Register r0, Register scratch) { 4769c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // First of all we assign the hash seed to scratch. 4770c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch LoadRoot(scratch, Heap::kHashSeedRootIndex); 4771c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch SmiToInteger32(scratch, scratch); 4772c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch 4773c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // Xor original key with a seed. 4774c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch xorl(r0, scratch); 4775c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch 4776c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // Compute the hash code from the untagged key. This must be kept in sync 4777c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // with ComputeIntegerHash in utils.h. 4778c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // 4779c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // hash = ~hash + (hash << 15); 4780c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch movl(scratch, r0); 4781c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch notl(r0); 4782c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch shll(scratch, Immediate(15)); 4783c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch addl(r0, scratch); 4784c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // hash = hash ^ (hash >> 12); 4785c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch movl(scratch, r0); 4786c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch shrl(scratch, Immediate(12)); 4787c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch xorl(r0, scratch); 4788c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // hash = hash + (hash << 2); 4789c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch leal(r0, Operand(r0, r0, times_4, 0)); 4790c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // hash = hash ^ (hash >> 4); 4791c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch movl(scratch, r0); 4792c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch shrl(scratch, Immediate(4)); 4793c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch xorl(r0, scratch); 4794c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // hash = hash * 2057; 4795c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch imull(r0, r0, Immediate(2057)); 4796c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // hash = hash ^ (hash >> 16); 4797c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch movl(scratch, r0); 4798c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch shrl(scratch, Immediate(16)); 4799c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch xorl(r0, scratch); 4800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch andl(r0, Immediate(0x3fffffff)); 4801c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch} 4802c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch 4803c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch 4804c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch 48053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid MacroAssembler::LoadFromNumberDictionary(Label* miss, 48063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Register elements, 48073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Register key, 48083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Register r0, 48093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Register r1, 48103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Register r2, 48113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Register result) { 48123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Register use: 48133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // 48143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // elements - holds the slow-case elements of the receiver on entry. 48153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Unchanged unless 'result' is the same register. 48163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // 48173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // key - holds the smi key on entry. 48183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Unchanged unless 'result' is the same register. 48193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // 48203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Scratch registers: 48213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // 48223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // r0 - holds the untagged key on entry and holds the hash once computed. 48233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // 48243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // r1 - used to hold the capacity mask of the dictionary 48253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // 48263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // r2 - used for the index into the dictionary. 48273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // 48283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // result - holds the result on exit if the load succeeded. 48293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Allowed to be the same as 'key' or 'result'. 48303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Unchanged on bailout so 'key' or 'result' can be used 48313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // in further computation. 48323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 48333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Label done; 48343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4835c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch GetNumberHash(r0, r1); 48363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 48373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Compute capacity mask. 4838c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch SmiToInteger32(r1, FieldOperand(elements, 4839c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch SeededNumberDictionary::kCapacityOffset)); 48403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch decl(r1); 48413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 48423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Generate an unrolled loop that performs a few probes before giving up. 4843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < kNumberDictionaryProbes; i++) { 48443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Use r2 for index calculations and keep the hash intact in r0. 4845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(r2, r0); 48463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Compute the masked index: (hash + i + i * i) & mask. 48473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (i > 0) { 4848c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch addl(r2, Immediate(SeededNumberDictionary::GetProbeOffset(i))); 48493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 4850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(r2, r1); 48513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 48523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Scale the index by multiplying by the entry size. 4853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SeededNumberDictionary::kEntrySize == 3); 4854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(r2, Operand(r2, r2, times_2, 0)); // r2 = r2 * 3 48553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 48563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Check if the key matches. 4857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(key, FieldOperand(elements, 48583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch r2, 48593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch times_pointer_size, 4860c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch SeededNumberDictionary::kElementsStartOffset)); 4861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (i != (kNumberDictionaryProbes - 1)) { 48623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch j(equal, &done); 48633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } else { 48643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch j(not_equal, miss); 48653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 48663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 48673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 48683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch bind(&done); 4869958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Check that the value is a field property. 48703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const int kDetailsOffset = 4871c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch SeededNumberDictionary::kElementsStartOffset + 2 * kPointerSize; 4872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(DATA, 0); 48733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset), 4874589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Smi::FromInt(PropertyDetails::TypeField::kMask)); 48753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch j(not_zero, miss); 48763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 48773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Get the value at the masked, scaled index. 48783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch const int kValueOffset = 4879c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch SeededNumberDictionary::kElementsStartOffset + kPointerSize; 4880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(result, FieldOperand(elements, r2, times_pointer_size, kValueOffset)); 48813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 48823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 48833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 4884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::LoadAllocationTopHelper(Register result, 4885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch, 4886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AllocationFlags flags) { 4887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference allocation_top = 4888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationUtils::GetAllocationTopReference(isolate(), flags); 4889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Just return if allocation top is already known. 4891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if ((flags & RESULT_CONTAINS_TOP) != 0) { 4892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // No use of scratch if allocation top is provided. 4893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!scratch.is_valid()); 4894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 4895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Assert that result actually contains top on entry. 4896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand top_operand = ExternalOperand(allocation_top); 4897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(result, top_operand); 4898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(equal, kUnexpectedAllocationTop); 4899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 4900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 4901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 49036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Move address of new object to result. Use scratch register if available, 49046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // and keep address in scratch until call to UpdateAllocationTopHelper. 49056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (scratch.is_valid()) { 4906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadAddress(scratch, allocation_top); 4907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(result, Operand(scratch, 0)); 4908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Load(result, allocation_top); 4910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::MakeSureDoubleAlignedHelper(Register result, 4915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 4916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required, 4917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationFlags flags) { 4918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (kPointerSize == kDoubleSize) { 4919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_debug_code) { 4920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testl(result, Immediate(kDoubleAlignmentMask)); 4921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(zero, kAllocationIsNotDoubleAligned); 4922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 49236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } else { 4924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Align the next allocation. Storing the filler map without checking top 4925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // is safe in new-space because the limit of the heap is aligned there. 4926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(kPointerSize * 2 == kDoubleSize); 4927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(kPointerAlignment * 2 == kDoubleAlignment); 4928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Make sure scratch is not clobbered by this function as it might be 4929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // used in UpdateAllocationTopHelper later. 4930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!scratch.is(kScratchRegister)); 4931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label aligned; 4932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testl(result, Immediate(kDoubleAlignmentMask)); 4933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(zero, &aligned, Label::kNear); 4934bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (((flags & ALLOCATION_FOLDED) == 0) && ((flags & PRETENURE) != 0)) { 4935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference allocation_limit = 4936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationUtils::GetAllocationLimitReference(isolate(), flags); 4937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(result, ExternalOperand(allocation_limit)); 4938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(above_equal, gc_required); 4939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadRoot(kScratchRegister, Heap::kOnePointerFillerMapRootIndex); 4941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(result, 0), kScratchRegister); 4942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(result, Immediate(kDoubleSize / 2)); 4943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&aligned); 4944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::UpdateAllocationTopHelper(Register result_end, 4949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 4950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationFlags flags) { 495144f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 4952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(result_end, Immediate(kObjectAlignmentMask)); 4953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(zero, kUnalignedAllocationInNewSpace); 4954d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 4955d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 4956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference allocation_top = 4957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationUtils::GetAllocationTopReference(isolate(), flags); 4958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Update new top. 496044f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (scratch.is_valid()) { 496144f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Scratch already contains address of allocation top. 4962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(scratch, 0), result_end); 4963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 4964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Store(allocation_top, result_end); 4965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Allocate(int object_size, 4970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register result, 4971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register result_end, 4972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 4973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required, 4974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationFlags flags) { 4975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0); 4976f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(object_size <= kMaxRegularHeapObjectSize); 4977bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK((flags & ALLOCATION_FOLDED) == 0); 49785913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck if (!FLAG_inline_new) { 497944f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 49805913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck // Trash the registers to simulate an allocation failure. 49815913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck movl(result, Immediate(0x7091)); 49825913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck if (result_end.is_valid()) { 49835913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck movl(result_end, Immediate(0x7191)); 49845913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } 49855913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck if (scratch.is_valid()) { 49865913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck movl(scratch, Immediate(0x7291)); 49875913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } 49885913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } 49895913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck jmp(gc_required); 49905913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck return; 49915913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } 4992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!result.is(result_end)); 4993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Load address of new object into result. 49958a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang LoadAllocationTopHelper(result, scratch, flags); 4996a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((flags & DOUBLE_ALIGNMENT) != 0) { 4998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MakeSureDoubleAlignedHelper(result, scratch, gc_required, flags); 4999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5001a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Calculate new top and bail out if new space is exhausted. 5002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference allocation_limit = 5003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationUtils::GetAllocationLimitReference(isolate(), flags); 50046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 50056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Register top_reg = result_end.is_valid() ? result_end : result; 50066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 50071e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (!top_reg.is(result)) { 5008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(top_reg, result); 50096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 5010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(top_reg, Immediate(object_size)); 5011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand limit_operand = ExternalOperand(allocation_limit); 5012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(top_reg, limit_operand); 5013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block j(above, gc_required); 5014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5015bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if ((flags & ALLOCATION_FOLDING_DOMINATOR) == 0) { 5016bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // The top pointer is not updated for allocation folding dominators. 5017bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch UpdateAllocationTopHelper(top_reg, scratch, flags); 5018bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 5019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 50206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (top_reg.is(result)) { 5021bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch subp(result, Immediate(object_size - kHeapObjectTag)); 5022bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else { 5023bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // Tag the result. 5024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(kHeapObjectTag == 1); 5025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch incp(result); 5026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Allocate(int header_size, 5031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ScaleFactor element_size, 5032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register element_count, 5033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register result, 5034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register result_end, 5035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 5036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required, 5037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationFlags flags) { 5038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((flags & SIZE_IN_WORDS) == 0); 5039bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK((flags & ALLOCATION_FOLDING_DOMINATOR) == 0); 5040bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK((flags & ALLOCATION_FOLDED) == 0); 5041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(result_end, Operand(element_count, element_size, header_size)); 5042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Allocate(result_end, result, result_end, scratch, gc_required, flags); 5043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Allocate(Register object_size, 5047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register result, 5048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register result_end, 5049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 5050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required, 5051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationFlags flags) { 5052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((flags & SIZE_IN_WORDS) == 0); 5053bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK((flags & ALLOCATION_FOLDED) == 0); 50545913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck if (!FLAG_inline_new) { 505544f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 50565913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck // Trash the registers to simulate an allocation failure. 50575913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck movl(result, Immediate(0x7091)); 50585913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck movl(result_end, Immediate(0x7191)); 50595913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck if (scratch.is_valid()) { 50605913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck movl(scratch, Immediate(0x7291)); 50615913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } 50625913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck // object_size is left unchanged by this function. 50635913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } 50645913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck jmp(gc_required); 50655913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck return; 50665913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } 5067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!result.is(result_end)); 50685913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck 5069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Load address of new object into result. 50708a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang LoadAllocationTopHelper(result, scratch, flags); 5071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((flags & DOUBLE_ALIGNMENT) != 0) { 5073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MakeSureDoubleAlignedHelper(result, scratch, gc_required, flags); 5074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference allocation_limit = 5077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationUtils::GetAllocationLimitReference(isolate(), flags); 5078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!object_size.is(result_end)) { 5079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(result_end, object_size); 5080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(result_end, result); 5082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand limit_operand = ExternalOperand(allocation_limit); 5083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(result_end, limit_operand); 5084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block j(above, gc_required); 5085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5086bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if ((flags & ALLOCATION_FOLDING_DOMINATOR) == 0) { 5087bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // The top pointer is not updated for allocation folding dominators. 5088bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch UpdateAllocationTopHelper(result_end, scratch, flags); 5089bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 5090bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 5091bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // Tag the result. 5092bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch addp(result, Immediate(kHeapObjectTag)); 5093bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 5094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5095bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid MacroAssembler::FastAllocate(int object_size, Register result, 5096bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Register result_end, AllocationFlags flags) { 5097bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(!result.is(result_end)); 5098bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // Load address of new object into result. 5099bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch LoadAllocationTopHelper(result, no_reg, flags); 5100bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 5101bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if ((flags & DOUBLE_ALIGNMENT) != 0) { 5102bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch MakeSureDoubleAlignedHelper(result, no_reg, NULL, flags); 5103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 5104bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 5105bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch leap(result_end, Operand(result, object_size)); 5106bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 5107bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch UpdateAllocationTopHelper(result_end, no_reg, flags); 5108bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 5109bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch addp(result, Immediate(kHeapObjectTag)); 5110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5112bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid MacroAssembler::FastAllocate(Register object_size, Register result, 5113bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Register result_end, AllocationFlags flags) { 5114bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(!result.is(result_end)); 5115bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // Load address of new object into result. 5116bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch LoadAllocationTopHelper(result, no_reg, flags); 5117bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 5118bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if ((flags & DOUBLE_ALIGNMENT) != 0) { 5119bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch MakeSureDoubleAlignedHelper(result, no_reg, NULL, flags); 5120bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 5121bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 5122bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch leap(result_end, Operand(result, object_size, times_1, 0)); 5123bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 5124bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch UpdateAllocationTopHelper(result_end, no_reg, flags); 5125bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 5126bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch addp(result, Immediate(kHeapObjectTag)); 5127bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 5128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 51293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::AllocateHeapNumber(Register result, 51303ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Register scratch, 5131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required, 5132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MutableMode mode) { 51333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Allocate heap number in new space. 5134bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Allocate(HeapNumber::kSize, result, scratch, no_reg, gc_required, 5135bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch NO_ALLOCATION_FLAGS); 5136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap::RootListIndex map_index = mode == MUTABLE 5138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? Heap::kMutableHeapNumberMapRootIndex 5139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : Heap::kHeapNumberMapRootIndex; 51403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 51413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Set the map. 5142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadRoot(kScratchRegister, map_index); 5143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); 51443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 51453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 51463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 5147e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid MacroAssembler::AllocateTwoByteString(Register result, 5148e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Register length, 5149e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Register scratch1, 5150e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Register scratch2, 5151e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Register scratch3, 5152e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Label* gc_required) { 5153e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Calculate the number of bytes needed for the characters in the string while 5154e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // observing object alignment. 51556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block const int kHeaderAlignment = SeqTwoByteString::kHeaderSize & 51566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block kObjectAlignmentMask; 5157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(kShortSize == 2); 5158e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // scratch1 = length * 2 + kObjectAlignmentMask. 5159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(scratch1, Operand(length, length, times_1, kObjectAlignmentMask + 51606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block kHeaderAlignment)); 5161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(scratch1, Immediate(~kObjectAlignmentMask)); 51626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (kHeaderAlignment > 0) { 5163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(scratch1, Immediate(kHeaderAlignment)); 51646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 5165e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 5166e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Allocate two byte string in new space. 5167bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Allocate(SeqTwoByteString::kHeaderSize, times_1, scratch1, result, scratch2, 5168bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch scratch3, gc_required, NO_ALLOCATION_FLAGS); 5169e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 5170e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Set the map, length and hash field. 5171e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke LoadRoot(kScratchRegister, Heap::kStringMapRootIndex); 5172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); 51736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Integer32ToSmi(scratch1, length); 5174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(FieldOperand(result, String::kLengthOffset), scratch1); 5175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(FieldOperand(result, String::kHashFieldOffset), 5176e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Immediate(String::kEmptyHashField)); 5177e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 5178e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 5179e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 5180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AllocateOneByteString(Register result, Register length, 5181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, Register scratch2, 5182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch3, 5183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required) { 5184e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Calculate the number of bytes needed for the characters in the string while 5185e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // observing object alignment. 5186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int kHeaderAlignment = SeqOneByteString::kHeaderSize & 51876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block kObjectAlignmentMask; 5188e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke movl(scratch1, length); 5189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(kCharSize == 1); 5190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(scratch1, Immediate(kObjectAlignmentMask + kHeaderAlignment)); 5191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(scratch1, Immediate(~kObjectAlignmentMask)); 51926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (kHeaderAlignment > 0) { 5193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(scratch1, Immediate(kHeaderAlignment)); 51946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 5195e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 5196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Allocate one-byte string in new space. 5197bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Allocate(SeqOneByteString::kHeaderSize, times_1, scratch1, result, scratch2, 5198bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch scratch3, gc_required, NO_ALLOCATION_FLAGS); 5199e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 5200e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Set the map, length and hash field. 5201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadRoot(kScratchRegister, Heap::kOneByteStringMapRootIndex); 5202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); 52036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Integer32ToSmi(scratch1, length); 5204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(FieldOperand(result, String::kLengthOffset), scratch1); 5205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(FieldOperand(result, String::kHashFieldOffset), 5206e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Immediate(String::kEmptyHashField)); 5207e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 5208e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 5209e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 5210589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochvoid MacroAssembler::AllocateTwoByteConsString(Register result, 5211e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Register scratch1, 5212e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Register scratch2, 5213e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Label* gc_required) { 5214e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Allocate heap number in new space. 5215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, 5216bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch NO_ALLOCATION_FLAGS); 5217e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 5218e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Set the map. The other fields are left uninitialized. 5219e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke LoadRoot(kScratchRegister, Heap::kConsStringMapRootIndex); 5220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); 5221e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 5222e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 5223e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 5224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AllocateOneByteConsString(Register result, 5225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, 5226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch2, 5227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required) { 5228bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required, 5229bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch NO_ALLOCATION_FLAGS); 5230e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 5231e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Set the map. The other fields are left uninitialized. 5232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadRoot(kScratchRegister, Heap::kConsOneByteStringMapRootIndex); 5233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); 5234e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 5235e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 5236e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 5237589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochvoid MacroAssembler::AllocateTwoByteSlicedString(Register result, 5238589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Register scratch1, 5239589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Register scratch2, 5240589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Label* gc_required) { 5241589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Allocate heap number in new space. 5242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, 5243bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch NO_ALLOCATION_FLAGS); 5244589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 5245589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Set the map. The other fields are left uninitialized. 5246589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch LoadRoot(kScratchRegister, Heap::kSlicedStringMapRootIndex); 5247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); 5248589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch} 5249589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 5250589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 5251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AllocateOneByteSlicedString(Register result, 5252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, 5253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch2, 5254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required) { 5255589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Allocate heap number in new space. 5256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required, 5257bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch NO_ALLOCATION_FLAGS); 5258589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 5259589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // Set the map. The other fields are left uninitialized. 5260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadRoot(kScratchRegister, Heap::kSlicedOneByteStringMapRootIndex); 5261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); 5262589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch} 5263589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 5264589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch 5265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::AllocateJSValue(Register result, Register constructor, 5266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register value, Register scratch, 5267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label* gc_required) { 5268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!result.is(constructor)); 5269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!result.is(scratch)); 5270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!result.is(value)); 5271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 5272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Allocate JSValue in new space. 5273bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Allocate(JSValue::kSize, result, scratch, no_reg, gc_required, 5274bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch NO_ALLOCATION_FLAGS); 5275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 5276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Initialize the JSValue. 5277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoadGlobalFunctionInitialMap(constructor, scratch); 5278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(FieldOperand(result, HeapObject::kMapOffset), scratch); 5279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoadRoot(scratch, Heap::kEmptyFixedArrayRootIndex); 5280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(FieldOperand(result, JSObject::kPropertiesOffset), scratch); 5281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(FieldOperand(result, JSObject::kElementsOffset), scratch); 5282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(FieldOperand(result, JSValue::kValueOffset), value); 5283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); 5284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 5285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 5286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 528744f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Copy memory, byte-by-byte, from source to destination. Not optimized for 528844f0eee88ff00398ff7f715fab053374d808c90dSteve Block// long or aligned copies. The contents of scratch and length are destroyed. 528944f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Destination is incremented by length, source, length and scratch are 529044f0eee88ff00398ff7f715fab053374d808c90dSteve Block// clobbered. 529144f0eee88ff00398ff7f715fab053374d808c90dSteve Block// A simpler loop is faster on small copies, but slower on large ones. 529244f0eee88ff00398ff7f715fab053374d808c90dSteve Block// The cld() instruction must have been emitted, to set the direction flag(), 529344f0eee88ff00398ff7f715fab053374d808c90dSteve Block// before calling this function. 529444f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid MacroAssembler::CopyBytes(Register destination, 529544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register source, 529644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register length, 529744f0eee88ff00398ff7f715fab053374d808c90dSteve Block int min_length, 529844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register scratch) { 5299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(min_length >= 0); 5300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 530144f0eee88ff00398ff7f715fab053374d808c90dSteve Block cmpl(length, Immediate(min_length)); 5302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assert(greater_equal, kInvalidMinLength); 530344f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 5304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label short_loop, len8, len16, len24, done, short_string; 530544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 5306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int kLongStringLimit = 4 * kPointerSize; 530744f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (min_length <= kLongStringLimit) { 5308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpl(length, Immediate(kPointerSize)); 5309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(below, &short_string, Label::kNear); 531044f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 531144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 5312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(source.is(rsi)); 5313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(destination.is(rdi)); 5314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(length.is(rcx)); 5315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (min_length <= kLongStringLimit) { 5317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpl(length, Immediate(2 * kPointerSize)); 5318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(below_equal, &len8, Label::kNear); 5319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpl(length, Immediate(3 * kPointerSize)); 5320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(below_equal, &len16, Label::kNear); 5321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpl(length, Immediate(4 * kPointerSize)); 5322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(below_equal, &len24, Label::kNear); 5323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 532444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 532544f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Because source is 8-byte aligned in our uses of this function, 532644f0eee88ff00398ff7f715fab053374d808c90dSteve Block // we keep source aligned for the rep movs operation by copying the odd bytes 532744f0eee88ff00398ff7f715fab053374d808c90dSteve Block // at the end of the ranges. 5328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch, length); 5329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shrl(length, Immediate(kPointerSizeLog2)); 5330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch repmovsp(); 533144f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Move remaining bytes of length. 5332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andl(scratch, Immediate(kPointerSize - 1)); 5333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(length, Operand(source, scratch, times_1, -kPointerSize)); 5334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(destination, scratch, times_1, -kPointerSize), length); 5335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(destination, scratch); 533644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 533744f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (min_length <= kLongStringLimit) { 5338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jmp(&done, Label::kNear); 5339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&len24); 5340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch, Operand(source, 2 * kPointerSize)); 5341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(destination, 2 * kPointerSize), scratch); 5342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&len16); 5343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch, Operand(source, kPointerSize)); 5344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(destination, kPointerSize), scratch); 5345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&len8); 5346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch, Operand(source, 0)); 5347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(destination, 0), scratch); 5348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Move remaining bytes of length. 5349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch, Operand(source, length, times_1, -kPointerSize)); 5350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(destination, length, times_1, -kPointerSize), scratch); 5351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(destination, length); 5352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jmp(&done, Label::kNear); 535344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 535444f0eee88ff00398ff7f715fab053374d808c90dSteve Block bind(&short_string); 535544f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (min_length == 0) { 535644f0eee88ff00398ff7f715fab053374d808c90dSteve Block testl(length, length); 5357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(zero, &done, Label::kNear); 535844f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 535944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 536044f0eee88ff00398ff7f715fab053374d808c90dSteve Block bind(&short_loop); 5361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movb(scratch, Operand(source, 0)); 5362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movb(Operand(destination, 0), scratch); 5363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch incp(source); 5364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch incp(destination); 5365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch decl(length); 5366109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch j(not_zero, &short_loop, Label::kNear); 536744f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 5368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&done); 537044f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 537144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 537244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 5373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::InitializeFieldsWithFiller(Register current_address, 5374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register end_address, 53753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register filler) { 53763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label loop, entry; 5377109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch jmp(&entry, Label::kNear); 53783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bind(&loop); 5379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(Operand(current_address, 0), filler); 5380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch addp(current_address, Immediate(kPointerSize)); 53813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bind(&entry); 5382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cmpp(current_address, end_address); 5383109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch j(below, &loop, Label::kNear); 53843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 53853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 53863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5387d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockvoid MacroAssembler::LoadContext(Register dst, int context_chain_length) { 5388d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (context_chain_length > 0) { 5389d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Move up the chain of contexts to the context containing the slot. 5390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, Operand(rsi, Context::SlotOffset(Context::PREVIOUS_INDEX))); 5391d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block for (int i = 1; i < context_chain_length; i++) { 5392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, Operand(dst, Context::SlotOffset(Context::PREVIOUS_INDEX))); 5393d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 5394e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else { 5395e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Slot is in the current function context. Move it into the 5396e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // destination register in case we store into it (the write barrier 5397e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // cannot be allowed to destroy the context in rsi). 5398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, rsi); 5399e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 5400e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 54013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // We should not have found a with context by walking the context 54023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // chain (i.e., the static scope chain and runtime context chain do 54033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // not agree). A variable occurring in such a scope should have 54043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // slot type LOOKUP and not CONTEXT. 540544f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 54063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CompareRoot(FieldOperand(dst, HeapObject::kMapOffset), 54073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Heap::kWithContextMapRootIndex); 5408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(not_equal, kVariableResolvedToWithContext); 5409d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 5410d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 5411d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 54123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 54133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::LoadTransitionedArrayMapConditional( 54143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKind expected_kind, 54153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ElementsKind transitioned_kind, 54163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register map_in_out, 54173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch, 54183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* no_map_match) { 5419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsFastElementsKind(expected_kind)); 5420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsFastElementsKind(transitioned_kind)); 54213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 54223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check that the function's map is the same as the expected cached map. 5423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(scratch, NativeContextOperand()); 5424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cmpp(map_in_out, 5425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ContextOperand(scratch, Context::ArrayMapIndex(expected_kind))); 54263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(not_equal, no_map_match); 54273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 54283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Use the transitioned cached map. 5429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(map_in_out, 5430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ContextOperand(scratch, Context::ArrayMapIndex(transitioned_kind))); 54313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 54323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 54333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 543444f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef _WIN64 543544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic const int kRegisterPassedArguments = 4; 543644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#else 543744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic const int kRegisterPassedArguments = 6; 543844f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 54397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 5441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::LoadNativeContextSlot(int index, Register dst) { 5442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(dst, NativeContextOperand()); 5443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(dst, ContextOperand(dst, index)); 5444b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 5445b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 5446b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 5447b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid MacroAssembler::LoadGlobalFunctionInitialMap(Register function, 5448b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Register map) { 5449b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Load the initial map. The global functions all have initial maps. 5450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(map, FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); 545144f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 5452b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Label ok, fail; 5453257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CheckMap(map, isolate()->factory()->meta_map(), &fail, DO_SMI_CHECK); 5454b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch jmp(&ok); 5455b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bind(&fail); 5456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Abort(kGlobalFunctionsMustHaveInitialMap); 5457b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bind(&ok); 5458b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 5459b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 5460b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 5461b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 54624515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkeint MacroAssembler::ArgumentStackSlotsForCFunctionCall(int num_arguments) { 54637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // On Windows 64 stack slots are reserved by the caller for all arguments 54647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // including the ones passed in registers, and space is always allocated for 54657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // the four register arguments even if the function takes fewer than four 54667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // arguments. 54677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // On AMD64 ABI (Linux/Mac) the first six arguments are passed in registers 54687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // and the caller does not reserve stack slots for them. 5469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(num_arguments >= 0); 54704515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke#ifdef _WIN64 547144f0eee88ff00398ff7f715fab053374d808c90dSteve Block const int kMinimumStackSlots = kRegisterPassedArguments; 54727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (num_arguments < kMinimumStackSlots) return kMinimumStackSlots; 54737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch return num_arguments; 54744515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke#else 54757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (num_arguments < kRegisterPassedArguments) return 0; 54767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch return num_arguments - kRegisterPassedArguments; 54774515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke#endif 54784515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke} 54794515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 54807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 5481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::EmitSeqStringSetCharCheck(Register string, 5482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register index, 5483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register value, 5484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t encoding_mask) { 5485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label is_object; 5486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JumpIfNotSmi(string, &is_object); 5487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Abort(kNonObject); 5488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&is_object); 5489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(value); 5491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(value, FieldOperand(string, HeapObject::kMapOffset)); 5492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movzxbp(value, FieldOperand(value, Map::kInstanceTypeOffset)); 5493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andb(value, Immediate(kStringRepresentationMask | kStringEncodingMask)); 5495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(value, Immediate(encoding_mask)); 5496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(value); 5497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(equal, kUnexpectedStringType); 5498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The index is assumed to be untagged coming in, tag it to compare with the 5500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // string length without using a temp register, it is restored at the end of 5501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // this function. 5502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Integer32ToSmi(index, index); 5503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiCompare(index, FieldOperand(string, String::kLengthOffset)); 5504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(less, kIndexIsTooLarge); 5505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiCompare(index, Smi::FromInt(0)); 5507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(greater_equal, kIndexIsNegative); 5508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Restore the index 5510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(index, index); 5511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 55144515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkevoid MacroAssembler::PrepareCallCFunction(int num_arguments) { 5515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int frame_alignment = base::OS::ActivationFrameAlignment(); 5516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(frame_alignment != 0); 5517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(num_arguments >= 0); 551844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 55194515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // Make stack end at alignment and allocate space for arguments and old rsp. 5520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, rsp); 5521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(base::bits::IsPowerOfTwo32(frame_alignment)); 55224515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke int argument_slots_on_stack = 55234515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke ArgumentStackSlotsForCFunctionCall(num_arguments); 5524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(rsp, Immediate((argument_slots_on_stack + 1) * kRegisterSize)); 5525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(rsp, Immediate(-frame_alignment)); 5526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(rsp, argument_slots_on_stack * kRegisterSize), kScratchRegister); 55274515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke} 55284515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 55294515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 55304515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkevoid MacroAssembler::CallCFunction(ExternalReference function, 55314515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke int num_arguments) { 553244f0eee88ff00398ff7f715fab053374d808c90dSteve Block LoadAddress(rax, function); 55334515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke CallCFunction(rax, num_arguments); 55344515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke} 55354515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 55364515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 55374515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkevoid MacroAssembler::CallCFunction(Register function, int num_arguments) { 5538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(has_frame()); 55396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Check stack alignment. 554044f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 55416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CheckStackAlignment(); 55426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 55436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 55444515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke call(function); 5545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(base::OS::ActivationFrameAlignment() != 0); 5546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(num_arguments >= 0); 55474515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke int argument_slots_on_stack = 55484515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke ArgumentStackSlotsForCFunctionCall(num_arguments); 5549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rsp, Operand(rsp, argument_slots_on_stack * kRegisterSize)); 55504515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke} 55514515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 5552d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 5553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 5554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool AreAliased(Register reg1, 5555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg2, 5556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg3, 5557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg4, 5558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg5, 5559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg6, 5560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg7, 5561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg8) { 5562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int n_of_valid_regs = reg1.is_valid() + reg2.is_valid() + 5563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reg3.is_valid() + reg4.is_valid() + reg5.is_valid() + reg6.is_valid() + 5564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reg7.is_valid() + reg8.is_valid(); 5565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RegList regs = 0; 5567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reg1.is_valid()) regs |= reg1.bit(); 5568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reg2.is_valid()) regs |= reg2.bit(); 5569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reg3.is_valid()) regs |= reg3.bit(); 5570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reg4.is_valid()) regs |= reg4.bit(); 5571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reg5.is_valid()) regs |= reg5.bit(); 5572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reg6.is_valid()) regs |= reg6.bit(); 5573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reg7.is_valid()) regs |= reg7.bit(); 5574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reg8.is_valid()) regs |= reg8.bit(); 5575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int n_of_non_aliasing_regs = NumRegs(regs); 5576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return n_of_valid_regs != n_of_non_aliasing_regs; 55783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 5579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 55803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 55813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochCodePatcher::CodePatcher(Isolate* isolate, byte* address, int size) 55838b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch : address_(address), 55848b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch size_(size), 5585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch masm_(isolate, address, size + Assembler::kGap, CodeObjectRequired::kNo) { 5586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a new macro assembler pointing to the address of the code to patch. 5587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The size is adjusted with kGap on order for the assembler to generate size 5588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // bytes of instructions without failing with buffer size constraints. 5589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 5590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCodePatcher::~CodePatcher() { 5594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Indicate that code has changed. 5595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Assembler::FlushICache(masm_.isolate(), address_, size_); 5596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that the code was patched as expected. 5598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(masm_.pc_ == address_ + size_); 5599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 5600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 56023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 56033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::CheckPageFlag( 56043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register object, 56053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch, 56063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int mask, 56073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Condition cc, 56083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* condition_met, 56093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label::Distance condition_met_distance) { 5610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(cc == zero || cc == not_zero); 56113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (scratch.is(object)) { 5612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(scratch, Immediate(~Page::kPageAlignmentMask)); 56133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 5614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch, Immediate(~Page::kPageAlignmentMask)); 5615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(scratch, object); 56163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 56173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (mask < (1 << kBitsPerByte)) { 56183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch testb(Operand(scratch, MemoryChunk::kFlagsOffset), 56193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Immediate(static_cast<uint8_t>(mask))); 56203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 56213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch testl(Operand(scratch, MemoryChunk::kFlagsOffset), Immediate(mask)); 56223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 56233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(cc, condition_met, condition_met_distance); 56243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 56253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 56263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 56273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::JumpIfBlack(Register object, 56283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register bitmap_scratch, 56293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register mask_scratch, 56303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* on_black, 56313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label::Distance on_black_distance) { 5632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!AreAliased(object, bitmap_scratch, mask_scratch, rcx)); 5633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 56343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GetMarkBits(object, bitmap_scratch, mask_scratch); 56353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(strcmp(Marking::kBlackBitPattern, "11") == 0); 56373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // The mask_scratch register contains a 1 at the position of the first bit 5638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // and a 1 at a position of the second bit. All other positions are zero. 5639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rcx, mask_scratch); 5640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(rcx, Operand(bitmap_scratch, MemoryChunk::kHeaderSize)); 5641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(mask_scratch, rcx); 56423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(equal, on_black, on_black_distance); 56433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 56443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 56453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 56463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::GetMarkBits(Register addr_reg, 56473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register bitmap_reg, 56483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register mask_reg) { 5649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!AreAliased(addr_reg, bitmap_reg, mask_reg, rcx)); 5650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(bitmap_reg, addr_reg); 56513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Sign extended 32 bit immediate. 5652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(bitmap_reg, Immediate(~Page::kPageAlignmentMask)); 5653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rcx, addr_reg); 56543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int shift = 56553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Bitmap::kBitsPerCellLog2 + kPointerSizeLog2 - Bitmap::kBytesPerCellLog2; 56563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch shrl(rcx, Immediate(shift)); 5657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(rcx, 56583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Immediate((Page::kPageAlignmentMask >> shift) & 56593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ~(Bitmap::kBytesPerCell - 1))); 56603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(bitmap_reg, rcx); 5662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rcx, addr_reg); 56633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch shrl(rcx, Immediate(kPointerSizeLog2)); 5664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(rcx, Immediate((1 << Bitmap::kBitsPerCellLog2) - 1)); 5665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movl(mask_reg, Immediate(3)); 5666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlp_cl(mask_reg); 56673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 56683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 56693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::JumpIfWhite(Register value, Register bitmap_scratch, 5671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register mask_scratch, Label* value_is_white, 5672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label::Distance distance) { 5673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!AreAliased(value, bitmap_scratch, mask_scratch, rcx)); 56743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GetMarkBits(value, bitmap_scratch, mask_scratch); 56753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 56763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // If the value is black or grey we don't need to do anything. 5677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(strcmp(Marking::kWhiteBitPattern, "00") == 0); 5678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(strcmp(Marking::kBlackBitPattern, "11") == 0); 5679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(strcmp(Marking::kGreyBitPattern, "10") == 0); 5680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(strcmp(Marking::kImpossibleBitPattern, "01") == 0); 56813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 56823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Since both black and grey have a 1 in the first position and white does 56833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // not have a 1 there we only need to check one bit. 5684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(Operand(bitmap_scratch, MemoryChunk::kHeaderSize), mask_scratch); 5685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(zero, value_is_white, distance); 56863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 56873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 56883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5689109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid MacroAssembler::CheckEnumCache(Label* call_runtime) { 5690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label next, start; 56913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register empty_fixed_array_value = r8; 56923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LoadRoot(empty_fixed_array_value, Heap::kEmptyFixedArrayRootIndex); 5693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rcx, rax); 5694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if the enum length field is properly initialized, indicating that 5696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // there is an enum cache. 5697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rbx, FieldOperand(rcx, HeapObject::kMapOffset)); 5698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EnumLength(rdx, rbx); 5700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Cmp(rdx, Smi::FromInt(kInvalidEnumCacheSentinel)); 5701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(equal, call_runtime); 5702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jmp(&start); 5704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 57053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bind(&next); 57063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rbx, FieldOperand(rcx, HeapObject::kMapOffset)); 5708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // For all objects but the receiver, check that the cache is empty. 5710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EnumLength(rdx, rbx); 5711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Cmp(rdx, Smi::FromInt(0)); 57123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(not_equal, call_runtime); 57133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&start); 57153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check that there are no elements. Register rcx contains the current JS 5717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // object we've reached through the prototype chain. 5718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label no_elements; 5719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(empty_fixed_array_value, 5720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FieldOperand(rcx, JSObject::kElementsOffset)); 5721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(equal, &no_elements); 57223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Second chance, the object may be using the empty slow element dictionary. 5724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadRoot(kScratchRegister, Heap::kEmptySlowElementDictionaryRootIndex); 5725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(kScratchRegister, FieldOperand(rcx, JSObject::kElementsOffset)); 57263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(not_equal, call_runtime); 57273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&no_elements); 5729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rcx, FieldOperand(rbx, Map::kPrototypeOffset)); 5730109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CompareRoot(rcx, Heap::kNullValueRootIndex); 57313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(not_equal, &next); 57323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 57333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5734109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 5735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::TestJSArrayForAllocationMemento( 5736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register receiver_reg, 5737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch_reg, 5738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* no_memento_found) { 57393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Label map_check; 57403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Label top_check; 5741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference new_space_allocation_top = 5742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference::new_space_allocation_top_address(isolate()); 57433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch const int kMementoMapOffset = JSArray::kSize - kHeapObjectTag; 57443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch const int kMementoEndOffset = kMementoMapOffset + AllocationMemento::kSize; 57453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 57463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Bail out if the object is not in new space. 57473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch JumpIfNotInNewSpace(receiver_reg, scratch_reg, no_memento_found); 57483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // If the object is in new space, we need to check whether it is on the same 57493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // page as the current top. 57503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch leap(scratch_reg, Operand(receiver_reg, kMementoEndOffset)); 57513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch xorp(scratch_reg, ExternalOperand(new_space_allocation_top)); 57523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch testp(scratch_reg, Immediate(~Page::kPageAlignmentMask)); 57533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch j(zero, &top_check); 57543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // The object is on a different page than allocation top. Bail out if the 57553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // object sits on the page boundary as no memento can follow and we cannot 57563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // touch the memory following it. 57573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch leap(scratch_reg, Operand(receiver_reg, kMementoEndOffset)); 57583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch xorp(scratch_reg, receiver_reg); 57593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch testp(scratch_reg, Immediate(~Page::kPageAlignmentMask)); 57603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch j(not_zero, no_memento_found); 57613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Continue with the actual map check. 57623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch jmp(&map_check); 57633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // If top is on the same page as the current object, we need to check whether 57643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // we are below top. 57653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch bind(&top_check); 57663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch leap(scratch_reg, Operand(receiver_reg, kMementoEndOffset)); 5767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(scratch_reg, ExternalOperand(new_space_allocation_top)); 5768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(greater, no_memento_found); 57693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Memento map check. 57703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch bind(&map_check); 57713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch CompareRoot(MemOperand(receiver_reg, kMementoMapOffset), 5772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap::kAllocationMementoMapRootIndex); 5773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::JumpIfDictionaryInPrototypeChain( 5777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register object, 5778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch0, 5779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, 5780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* found) { 5781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!(scratch0.is(kScratchRegister) && scratch1.is(kScratchRegister))); 5782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!scratch1.is(scratch0)); 5783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register current = scratch0; 5784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label loop_again, end; 5785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(current, object); 5787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(current, FieldOperand(current, HeapObject::kMapOffset)); 5788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(current, FieldOperand(current, Map::kPrototypeOffset)); 5789014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CompareRoot(current, Heap::kNullValueRootIndex); 5790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(equal, &end); 5791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Loop based on the map going up the prototype chain. 5793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&loop_again); 5794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(current, FieldOperand(current, HeapObject::kMapOffset)); 5795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STATIC_ASSERT(JS_PROXY_TYPE < JS_OBJECT_TYPE); 5796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STATIC_ASSERT(JS_VALUE_TYPE < JS_OBJECT_TYPE); 5797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CmpInstanceType(current, JS_OBJECT_TYPE); 5798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(below, found); 5799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch1, FieldOperand(current, Map::kBitField2Offset)); 5800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DecodeField<Map::ElementsKindBits>(scratch1); 5801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(scratch1, Immediate(DICTIONARY_ELEMENTS)); 5802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(equal, found); 5803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(current, FieldOperand(current, Map::kPrototypeOffset)); 5804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompareRoot(current, Heap::kNullValueRootIndex); 5805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(not_equal, &loop_again); 5806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 5807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(&end); 5808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::TruncatingDiv(Register dividend, int32_t divisor) { 5812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dividend.is(rax)); 5813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dividend.is(rdx)); 5814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::MagicNumbersForDivision<uint32_t> mag = 5815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::SignedDivisionByConstant(static_cast<uint32_t>(divisor)); 5816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(rax, Immediate(mag.multiplier)); 5817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch imull(dividend); 5818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool neg = (mag.multiplier & (static_cast<uint32_t>(1) << 31)) != 0; 5819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (divisor > 0 && neg) addl(rdx, dividend); 5820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (divisor < 0 && !neg && mag.multiplier > 0) subl(rdx, dividend); 5821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mag.shift > 0) sarl(rdx, Immediate(mag.shift)); 5822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(rax, dividend); 5823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shrl(rax, Immediate(31)); 5824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addl(rdx, rax); 5825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 58273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 5829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 5830f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 5831f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#endif // V8_TARGET_ARCH_X64 5832