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" 1162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/counters.h" 12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/debug/debug.h" 1362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/heap/heap-inl.h" 1462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/objects-inl.h" 15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/register-configuration.h" 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/x64/assembler-x64.h" 1762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 1862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/x64/macro-assembler-x64.h" // Cannot be the first include. 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochMacroAssembler::MacroAssembler(Isolate* arg_isolate, void* buffer, int size, 24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CodeObjectRequired create_code_object) 258b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch : Assembler(arg_isolate, buffer, size), 263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block generating_stub_(false), 273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch has_frame_(false), 288b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch root_array_available_(true) { 29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (create_code_object == CodeObjectRequired::kYes) { 30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch code_object_ = 31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object>::New(isolate()->heap()->undefined_value(), isolate()); 328b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 3344f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 3444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 3544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const int64_t kInvalidRootRegisterDelta = -1; 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint64_t MacroAssembler::RootRegisterDelta(ExternalReference other) { 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (predictable_code_size() && 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (other.address() < reinterpret_cast<Address>(isolate()) || 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch other.address() >= reinterpret_cast<Address>(isolate() + 1))) { 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return kInvalidRootRegisterDelta; 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Address roots_register_value = kRootRegisterBias + 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<Address>(isolate()->heap()->roots_array_start()); 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int64_t delta = kInvalidRootRegisterDelta; // Bogus initialization. 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (kPointerSize == kInt64Size) { 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delta = other.address() - roots_register_value; 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // For x32, zero extend the address to 64-bit and calculate the delta. 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint64_t o = static_cast<uint32_t>( 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<intptr_t>(other.address())); 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint64_t r = static_cast<uint32_t>( 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<intptr_t>(roots_register_value)); 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch delta = o - r; 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5944f0eee88ff00398ff7f715fab053374d808c90dSteve Block return delta; 6044f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 6144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 6244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 6344f0eee88ff00398ff7f715fab053374d808c90dSteve BlockOperand MacroAssembler::ExternalOperand(ExternalReference target, 6444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register scratch) { 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (root_array_available_ && !serializer_enabled()) { 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int64_t delta = RootRegisterDelta(target); 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (delta != kInvalidRootRegisterDelta && is_int32(delta)) { 6844f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Operand(kRootRegister, static_cast<int32_t>(delta)); 6944f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 7044f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(scratch, target); 7244f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Operand(scratch, 0); 7344f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 7444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 7544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 7644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid MacroAssembler::Load(Register destination, ExternalReference source) { 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (root_array_available_ && !serializer_enabled()) { 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int64_t delta = RootRegisterDelta(source); 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (delta != kInvalidRootRegisterDelta && is_int32(delta)) { 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(destination, Operand(kRootRegister, static_cast<int32_t>(delta))); 8144f0eee88ff00398ff7f715fab053374d808c90dSteve Block return; 8244f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 8344f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 8444f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Safe code. 8544f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (destination.is(rax)) { 8644f0eee88ff00398ff7f715fab053374d808c90dSteve Block load_rax(source); 8744f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else { 88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(kScratchRegister, source); 89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(destination, Operand(kScratchRegister, 0)); 9044f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 9144f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 9244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 9344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 9444f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid MacroAssembler::Store(ExternalReference destination, Register source) { 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (root_array_available_ && !serializer_enabled()) { 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int64_t delta = RootRegisterDelta(destination); 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (delta != kInvalidRootRegisterDelta && is_int32(delta)) { 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(kRootRegister, static_cast<int32_t>(delta)), source); 9944f0eee88ff00398ff7f715fab053374d808c90dSteve Block return; 10044f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 10144f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 10244f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Safe code. 10344f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (source.is(rax)) { 10444f0eee88ff00398ff7f715fab053374d808c90dSteve Block store_rax(destination); 10544f0eee88ff00398ff7f715fab053374d808c90dSteve Block } else { 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(kScratchRegister, destination); 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(kScratchRegister, 0), source); 10844f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 10944f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 11044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 11144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 11244f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid MacroAssembler::LoadAddress(Register destination, 11344f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExternalReference source) { 114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (root_array_available_ && !serializer_enabled()) { 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int64_t delta = RootRegisterDelta(source); 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (delta != kInvalidRootRegisterDelta && is_int32(delta)) { 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(destination, Operand(kRootRegister, static_cast<int32_t>(delta))); 11844f0eee88ff00398ff7f715fab053374d808c90dSteve Block return; 11944f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 12044f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 12144f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Safe code. 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(destination, source); 12344f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 12444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 12544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 12644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockint MacroAssembler::LoadAddressSize(ExternalReference source) { 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (root_array_available_ && !serializer_enabled()) { 12844f0eee88ff00398ff7f715fab053374d808c90dSteve Block // This calculation depends on the internals of LoadAddress. 12944f0eee88ff00398ff7f715fab053374d808c90dSteve Block // It's correctness is ensured by the asserts in the Call 13044f0eee88ff00398ff7f715fab053374d808c90dSteve Block // instruction below. 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int64_t delta = RootRegisterDelta(source); 132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (delta != kInvalidRootRegisterDelta && is_int32(delta)) { 133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Operand is leap(scratch, Operand(kRootRegister, delta)); 13444f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Opcodes : REX.W 8D ModRM Disp8/Disp32 - 4 or 7. 13544f0eee88ff00398ff7f715fab053374d808c90dSteve Block int size = 4; 13644f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!is_int8(static_cast<int32_t>(delta))) { 13744f0eee88ff00398ff7f715fab053374d808c90dSteve Block size += 3; // Need full four-byte displacement in lea. 13844f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 13944f0eee88ff00398ff7f715fab053374d808c90dSteve Block return size; 14044f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 14144f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Size of movp(destination, src); 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Assembler::kMoveAddressIntoScratchRegisterInstructionLength; 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::PushAddress(ExternalReference source) { 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int64_t address = reinterpret_cast<int64_t>(source.address()); 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (is_int32(address) && !serializer_enabled()) { 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(kScratchRegister, kZapValue, Assembler::RelocInfoNone()); 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(Immediate(static_cast<int32_t>(address))); 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadAddress(kScratchRegister, source); 157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(kScratchRegister); 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1613ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::LoadRoot(Register destination, Heap::RootListIndex index) { 162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(root_array_available_); 163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(destination, Operand(kRootRegister, 164e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch (index << kPointerSizeLog2) - kRootRegisterBias)); 165e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 166e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 167e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 168e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochvoid MacroAssembler::LoadRootIndexed(Register destination, 169e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Register variable_offset, 170e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int fixed_offset) { 171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(root_array_available_); 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(destination, 173e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Operand(kRootRegister, 174e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch variable_offset, times_pointer_size, 175e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch (fixed_offset << kPointerSizeLog2) - kRootRegisterBias)); 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 17925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsenvoid MacroAssembler::StoreRoot(Register source, Heap::RootListIndex index) { 180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(Heap::RootCanBeWrittenAfterInitialization(index)); 181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(root_array_available_); 182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(kRootRegister, (index << kPointerSizeLog2) - kRootRegisterBias), 183e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch source); 18425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen} 18525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 18625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::PushRoot(Heap::RootListIndex index) { 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(root_array_available_); 189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(Operand(kRootRegister, (index << kPointerSizeLog2) - kRootRegisterBias)); 190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1933ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::CompareRoot(Register with, Heap::RootListIndex index) { 194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(root_array_available_); 195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(with, Operand(kRootRegister, 196e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch (index << kPointerSizeLog2) - kRootRegisterBias)); 197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::CompareRoot(const Operand& with, 2011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Heap::RootListIndex index) { 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(root_array_available_); 203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!with.AddressUsesRegister(kScratchRegister)); 204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block LoadRoot(kScratchRegister, index); 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(with, kScratchRegister); 206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::RememberedSetHelper(Register object, // For debug tests. 2103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register addr, 2113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch, 2123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SaveFPRegsMode save_fp, 2133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RememberedSetFinalAction and_then) { 214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 2153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label ok; 2163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JumpIfNotInNewSpace(object, scratch, &ok, Label::kNear); 2173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int3(); 2183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bind(&ok); 2193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Load store buffer top. 2213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ExternalReference store_buffer = 2223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ExternalReference::store_buffer_top(isolate()); 2233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch movp(scratch, ExternalOperand(store_buffer)); 2243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Store pointer to buffer. 225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(scratch, 0), addr); 2263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Increment buffer top. 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(scratch, Immediate(kPointerSize)); 2283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Write back new top of buffer. 2293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch movp(ExternalOperand(store_buffer), scratch); 2303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Call stub on end of buffer. 2313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label done; 2323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check for end of buffer. 2333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch testp(scratch, Immediate(StoreBuffer::kStoreBufferMask)); 2343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (and_then == kReturnAtEnd) { 2353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label buffer_overflowed; 2363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch j(equal, &buffer_overflowed, Label::kNear); 2373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ret(0); 2383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bind(&buffer_overflowed); 2393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(and_then == kFallThroughAtEnd); 2413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch j(not_equal, &done, Label::kNear); 2423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StoreBufferOverflowStub store_buffer_overflow(isolate(), save_fp); 2443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallStub(&store_buffer_overflow); 2453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (and_then == kReturnAtEnd) { 2463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ret(0); 2473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(and_then == kFallThroughAtEnd); 2493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bind(&done); 2506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 2517f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2527f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2537f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 254257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::InNewSpace(Register object, 255257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register scratch, 256257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Condition cc, 257257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* branch, 2583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label::Distance distance) { 259f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch CheckPageFlag(object, scratch, MemoryChunk::kIsInNewSpaceMask, cc, branch, 260f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch distance); 261257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 262257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 263257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::RecordWriteField( 2653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register object, 2663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int offset, 2673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register value, 2683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register dst, 2693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SaveFPRegsMode save_fp, 2703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RememberedSetAction remembered_set_action, 271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiCheck smi_check, 272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PointersToHereCheck pointers_to_here_check_for_value) { 2737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // First, check if a write barrier is even needed. The tests below 2743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // catch stores of Smis. 275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label done; 276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Skip barrier if writing a smi. 2783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (smi_check == INLINE_SMI_CHECK) { 2793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JumpIfSmi(value, &done); 2803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Although the object register is tagged, the offset is relative to the start 2833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // of the object, so so offset must be a multiple of kPointerSize. 284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsAligned(offset, kPointerSize)); 2853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(dst, FieldOperand(object, offset)); 2873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (emit_debug_code()) { 2883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label ok; 2893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch testb(dst, Immediate((1 << kPointerSizeLog2) - 1)); 2903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(zero, &ok, Label::kNear); 2913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int3(); 2923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bind(&ok); 2933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RecordWrite(object, dst, value, save_fp, remembered_set_action, 296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OMIT_SMI_CHECK, pointers_to_here_check_for_value); 2973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2983ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block bind(&done); 2994515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 3003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Clobber clobbered input registers when running with the debug-code flag 3013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // turned on to provoke errors. 30244f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(value, kZapValue, Assembler::RelocInfoNone()); 304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(dst, kZapValue, Assembler::RelocInfoNone()); 3054515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } 3063ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 3073ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 3083ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::RecordWriteArray( 310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register object, 311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register value, 312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register index, 313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SaveFPRegsMode save_fp, 314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RememberedSetAction remembered_set_action, 315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiCheck smi_check, 316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PointersToHereCheck pointers_to_here_check_for_value) { 3178defd9ff6930b4e24729971a61cf7469daf119beSteve Block // First, check if a write barrier is even needed. The tests below 3183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // catch stores of Smis. 3198defd9ff6930b4e24729971a61cf7469daf119beSteve Block Label done; 3208defd9ff6930b4e24729971a61cf7469daf119beSteve Block 3213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Skip barrier if writing a smi. 3223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (smi_check == INLINE_SMI_CHECK) { 3233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JumpIfSmi(value, &done); 3243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3258defd9ff6930b4e24729971a61cf7469daf119beSteve Block 3263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Array access: calculate the destination address. Index is not a smi. 3273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register dst = index; 328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(dst, Operand(object, index, times_pointer_size, 3293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FixedArray::kHeaderSize - kHeapObjectTag)); 3303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RecordWrite(object, dst, value, save_fp, remembered_set_action, 332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch OMIT_SMI_CHECK, pointers_to_here_check_for_value); 3338defd9ff6930b4e24729971a61cf7469daf119beSteve Block 3348defd9ff6930b4e24729971a61cf7469daf119beSteve Block bind(&done); 3358defd9ff6930b4e24729971a61cf7469daf119beSteve Block 3363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Clobber clobbered input registers when running with the debug-code flag 3378defd9ff6930b4e24729971a61cf7469daf119beSteve Block // turned on to provoke errors. 33844f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(value, kZapValue, Assembler::RelocInfoNone()); 340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(index, kZapValue, Assembler::RelocInfoNone()); 3418defd9ff6930b4e24729971a61cf7469daf119beSteve Block } 3428defd9ff6930b4e24729971a61cf7469daf119beSteve Block} 3438defd9ff6930b4e24729971a61cf7469daf119beSteve Block 3448defd9ff6930b4e24729971a61cf7469daf119beSteve Block 345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::RecordWriteForMap(Register object, 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register map, 347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register dst, 348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SaveFPRegsMode fp_mode) { 349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!object.is(kScratchRegister)); 350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!object.is(map)); 351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!object.is(dst)); 352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!map.is(dst)); 353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertNotSmi(object); 3544515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 35544f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label ok; 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (map.is(kScratchRegister)) pushq(map); 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompareMap(map, isolate()->factory()->meta_map()); 359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (map.is(kScratchRegister)) popq(map); 360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(equal, &ok, Label::kNear); 361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int3(); 362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&ok); 3634515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke } 3644515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!FLAG_incremental_marking) { 366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label ok; 371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (map.is(kScratchRegister)) pushq(map); 372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(map, FieldOperand(object, HeapObject::kMapOffset)); 373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (map.is(kScratchRegister)) popq(map); 374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(equal, &ok, Label::kNear); 375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int3(); 376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&ok); 377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute the address. 380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(dst, FieldOperand(object, HeapObject::kMapOffset)); 381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // First, check if a write barrier is even needed. The tests below 383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // catch stores of smis and stores into the young generation. 384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done; 385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // A single check of the map's pages interesting flag suffices, since it is 387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // only set during incremental collection, and then it's also guaranteed that 388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the from object's page's interesting flag is also set. This optimization 389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // relies on the fact that maps can never be in new space. 390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CheckPageFlag(map, 391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map, // Used as scratch. 392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemoryChunk::kPointersToHereAreInterestingMask, 393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch zero, 394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &done, 395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::kNear); 396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RecordWriteStub stub(isolate(), object, map, dst, OMIT_REMEMBERED_SET, 398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fp_mode); 399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallStub(&stub); 400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&done); 402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Count number of write barriers in generated code. 404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->counters()->write_barriers_static()->Increment(); 405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1); 406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Clobber clobbered registers when running with the debug-code flag 408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // turned on to provoke errors. 409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(dst, kZapValue, Assembler::RelocInfoNone()); 411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(map, kZapValue, Assembler::RelocInfoNone()); 412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::RecordWrite( 417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register object, 418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register address, 419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register value, 420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SaveFPRegsMode fp_mode, 421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RememberedSetAction remembered_set_action, 422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiCheck smi_check, 423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PointersToHereCheck pointers_to_here_check_for_value) { 424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!object.is(value)); 425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!object.is(address)); 426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!value.is(address)); 427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertNotSmi(object); 428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (remembered_set_action == OMIT_REMEMBERED_SET && 4303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch !FLAG_incremental_marking) { 4313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return; 4323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 4353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label ok; 436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(value, Operand(address, 0)); 4373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(equal, &ok, Label::kNear); 4383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int3(); 4393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bind(&ok); 4403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 4423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // First, check if a write barrier is even needed. The tests below 4433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // catch stores of smis and stores into the young generation. 4443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label done; 4453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (smi_check == INLINE_SMI_CHECK) { 4473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Skip barrier if writing a smi. 4483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JumpIfSmi(value, &done); 449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (pointers_to_here_check_for_value != kPointersToHereAreAlwaysInteresting) { 452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CheckPageFlag(value, 453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value, // Used as scratch. 454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MemoryChunk::kPointersToHereAreInterestingMask, 455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch zero, 456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &done, 457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::kNear); 458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CheckPageFlag(object, 4613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch value, // Used as scratch. 4623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MemoryChunk::kPointersFromHereAreInterestingMask, 4633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch zero, 4643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch &done, 4653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label::kNear); 4663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RecordWriteStub stub(isolate(), object, value, address, remembered_set_action, 468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch fp_mode); 4693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallStub(&stub); 470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bind(&done); 4724515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Count number of write barriers in generated code. 474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->counters()->write_barriers_static()->Increment(); 475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1); 476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Clobber clobbered registers when running with the debug-code flag 4784515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // turned on to provoke errors. 47944f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(address, kZapValue, Assembler::RelocInfoNone()); 481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(value, kZapValue, Assembler::RelocInfoNone()); 4826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 4836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 4846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 485109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid MacroAssembler::RecordWriteCodeEntryField(Register js_function, 486109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Register code_entry, 487109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Register scratch) { 488109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch const int offset = JSFunction::kCodeEntryOffset; 489109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 490109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // The input registers are fixed to make calling the C write barrier function 491109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // easier. 492109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(js_function.is(rdi)); 493109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(code_entry.is(rcx)); 494bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(scratch.is(r15)); 495109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 496109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Since a code entry (value) is always in old space, we don't need to update 497109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // remembered set. If incremental marking is off, there is nothing for us to 498109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // do. 499109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (!FLAG_incremental_marking) return; 500109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 501109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AssertNotSmi(js_function); 502109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 503109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (emit_debug_code()) { 504109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Label ok; 505109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch leap(scratch, FieldOperand(js_function, offset)); 506109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch cmpp(code_entry, Operand(scratch, 0)); 507109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch j(equal, &ok, Label::kNear); 508109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int3(); 509109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch bind(&ok); 510109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 511109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 512109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // First, check if a write barrier is even needed. The tests below 513109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // catch stores of Smis and stores into young gen. 514109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Label done; 515109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 516109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CheckPageFlag(code_entry, scratch, 517109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch MemoryChunk::kPointersToHereAreInterestingMask, zero, &done, 518109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Label::kNear); 519109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CheckPageFlag(js_function, scratch, 520109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch MemoryChunk::kPointersFromHereAreInterestingMask, zero, &done, 521109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Label::kNear); 522109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 523109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Save input registers. 524109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Push(js_function); 525109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Push(code_entry); 526109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 527109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch const Register dst = scratch; 528109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch leap(dst, FieldOperand(js_function, offset)); 529109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 530109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Save caller-saved registers. 531109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch PushCallerSaved(kDontSaveFPRegs, js_function, code_entry); 532109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 533109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch int argument_count = 3; 534109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch PrepareCallCFunction(argument_count); 535109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 536109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Load the argument registers. 537109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (arg_reg_1.is(rcx)) { 538109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Windows calling convention. 539109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(arg_reg_2.is(rdx) && arg_reg_3.is(r8)); 540109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 541109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch movp(arg_reg_1, js_function); // rcx gets rdi. 542bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch movp(arg_reg_2, dst); // rdx gets r15. 543109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 544109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // AMD64 calling convention. 545109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch DCHECK(arg_reg_1.is(rdi) && arg_reg_2.is(rsi) && arg_reg_3.is(rdx)); 546109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 547109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // rdi is already loaded with js_function. 548bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch movp(arg_reg_2, dst); // rsi gets r15. 549109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 550109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Move(arg_reg_3, ExternalReference::isolate_address(isolate())); 551109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 552109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch { 553109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AllowExternalCallThatCantCauseGC scope(this); 554109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CallCFunction( 555109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch ExternalReference::incremental_marking_record_write_code_entry_function( 556109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch isolate()), 557109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch argument_count); 558109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 559109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 560109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Restore caller-saved registers. 561109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch PopCallerSaved(kDontSaveFPRegs, js_function, code_entry); 562109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 563109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // Restore input registers. 564109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Pop(code_entry); 565109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Pop(js_function); 566109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 567109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch bind(&done); 568109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 5693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Assert(Condition cc, BailoutReason reason) { 571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) Check(cc, reason); 572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 575756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickvoid MacroAssembler::AssertFastElements(Register elements) { 57644f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 577257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label ok; 578756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CompareRoot(FieldOperand(elements, HeapObject::kMapOffset), 579756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick Heap::kFixedArrayMapRootIndex); 580257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(equal, &ok, Label::kNear); 581756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick CompareRoot(FieldOperand(elements, HeapObject::kMapOffset), 5823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Heap::kFixedDoubleArrayMapRootIndex); 5833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch j(equal, &ok, Label::kNear); 5843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CompareRoot(FieldOperand(elements, HeapObject::kMapOffset), 585756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick Heap::kFixedCOWArrayMapRootIndex); 586257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(equal, &ok, Label::kNear); 587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Abort(kJSObjectWithFastElementsMapHasSlowElements); 588756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick bind(&ok); 589756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick } 590756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick} 591756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 592756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Check(Condition cc, BailoutReason reason) { 594257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label L; 595257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(cc, &L, Label::kNear); 596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Abort(reason); 5973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Control will not return here. 598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bind(&L); 599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6026ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid MacroAssembler::CheckStackAlignment() { 603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int frame_alignment = base::OS::ActivationFrameAlignment(); 6046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int frame_alignment_mask = frame_alignment - 1; 6056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (frame_alignment > kPointerSize) { 606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(base::bits::IsPowerOfTwo32(frame_alignment)); 607257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label alignment_as_expected; 608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(rsp, Immediate(frame_alignment_mask)); 609257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(zero, &alignment_as_expected, Label::kNear); 6106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Abort if stack is not aligned. 6116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int3(); 6126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block bind(&alignment_as_expected); 6136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 6146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 6156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 6166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::NegativeZeroTest(Register result, 618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register op, 619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Label* then_label) { 620257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label ok; 621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block testl(result, result); 622257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_zero, &ok, Label::kNear); 623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block testl(op, op); 624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block j(sign, then_label); 625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bind(&ok); 626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Abort(BailoutReason reason) { 630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const char* msg = GetBailoutReason(reason); 632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (msg != NULL) { 633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RecordComment("Abort message: "); 634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RecordComment(msg); 635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_trap_on_abort) { 638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int3(); 639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 643f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Check if Abort() has already been initialized. 644f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(isolate()->builtins()->Abort()->IsHeapObject()); 645f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 646f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Move(rdx, Smi::FromInt(static_cast<int>(reason))); 6473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!has_frame_) { 6493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // We don't actually want to generate a pile of code for this, so just 6503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // claim there is a stack frame, without generating one. 6513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FrameScope scope(this, StackFrame::NONE); 652f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Call(isolate()->builtins()->Abort(), RelocInfo::CODE_TARGET); 6533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 654f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Call(isolate()->builtins()->Abort(), RelocInfo::CODE_TARGET); 6553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Control will not return here. 657d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block int3(); 658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::CallStub(CodeStub* stub, TypeFeedbackId ast_id) { 662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(AllowThisStubCall(stub)); // Calls are not allowed in some stubs 663257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id); 664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 667e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid MacroAssembler::TailCallStub(CodeStub* stub) { 668e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke Jump(stub->GetCode(), RelocInfo::CODE_TARGET); 669e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 670e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 671e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 67285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochvoid MacroAssembler::StubReturn(int argc) { 673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(argc >= 1 && generating_stub()); 67485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch ret((argc - 1) * kPointerSize); 675592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch} 676592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 677592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 6783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool MacroAssembler::AllowThisStubCall(CodeStub* stub) { 679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return has_frame_ || !stub->SometimesSetsUpAFrame(); 680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 68244f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid MacroAssembler::CallRuntime(const Runtime::Function* f, 683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int num_arguments, 684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SaveFPRegsMode save_doubles) { 685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the expected number of arguments of the runtime function is 686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // constant, we check that the actual number of arguments match the 687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // expectation. 688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(f->nargs < 0 || f->nargs == num_arguments); 689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6904515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // TODO(1236192): Most runtime routines don't need the number of 6914515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // arguments passed in because it is constant. At some point we 6924515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // should remove this need and make the runtime routine entry code 6934515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // smarter. 6948defd9ff6930b4e24729971a61cf7469daf119beSteve Block Set(rax, num_arguments); 69544f0eee88ff00398ff7f715fab053374d808c90dSteve Block LoadAddress(rbx, ExternalReference(f, isolate())); 696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CEntryStub ces(isolate(), f->result_size, save_doubles); 6974515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke CallStub(&ces); 698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 701402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuvoid MacroAssembler::CallExternalReference(const ExternalReference& ext, 702402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu int num_arguments) { 7038defd9ff6930b4e24729971a61cf7469daf119beSteve Block Set(rax, num_arguments); 70444f0eee88ff00398ff7f715fab053374d808c90dSteve Block LoadAddress(rbx, ext); 705402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CEntryStub stub(isolate(), 1); 707402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu CallStub(&stub); 708402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu} 709402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 710402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::TailCallRuntime(Runtime::FunctionId fid) { 712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ----------- S t a t e ------------- 713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // -- rsp[0] : return address 714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // -- rsp[8] : argument num_arguments - 1 715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ... 716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // -- rsp[8 * num_arguments] : argument 0 (receiver) 717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // For runtime functions with variable arguments: 719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // -- rax : number of arguments 720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ----------------------------------- 721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Runtime::Function* function = Runtime::FunctionForId(fid); 723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(1, function->result_size); 724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (function->nargs >= 0) { 725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(rax, function->nargs); 726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JumpToExternalReference(ExternalReference(fid, isolate())); 728bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch} 729bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 730f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::JumpToExternalReference(const ExternalReference& ext, 731f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch bool builtin_exit_frame) { 732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Set the entry point and jump to the C entry runtime stub. 73344f0eee88ff00398ff7f715fab053374d808c90dSteve Block LoadAddress(rbx, ext); 734f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CEntryStub ces(isolate(), 1, kDontSaveFPRegs, kArgvOnStack, 735f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch builtin_exit_frame); 7363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block jmp(ces.GetCode(), RelocInfo::CODE_TARGET); 737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define REG(Name) \ 740014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { Register::kCode_##Name } 7413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic const Register saved_regs[] = { 7433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch REG(rax), REG(rcx), REG(rdx), REG(rbx), REG(rbp), REG(rsi), REG(rdi), REG(r8), 7443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch REG(r9), REG(r10), REG(r11) 7453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}; 7463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#undef REG 7483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic const int kNumberOfSavedRegs = sizeof(saved_regs) / sizeof(Register); 7503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::PushCallerSaved(SaveFPRegsMode fp_mode, 7533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register exclusion1, 7543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register exclusion2, 7553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register exclusion3) { 7563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // We don't allow a GC during a store buffer overflow so there is no need to 7573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // store the registers in any particular way, but we do have to store and 7583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // restore them. 7593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < kNumberOfSavedRegs; i++) { 7603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register reg = saved_regs[i]; 7613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!reg.is(exclusion1) && !reg.is(exclusion2) && !reg.is(exclusion3)) { 762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pushq(reg); 7633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // R12 to r15 are callee save on all platforms. 7663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (fp_mode == kSaveFPRegs) { 767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(rsp, Immediate(kDoubleSize * XMMRegister::kMaxNumRegisters)); 768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { 7693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch XMMRegister reg = XMMRegister::from_code(i); 770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movsd(Operand(rsp, i * kDoubleSize), reg); 7713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 7743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::PopCallerSaved(SaveFPRegsMode fp_mode, 7773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register exclusion1, 7783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register exclusion2, 7793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register exclusion3) { 7803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (fp_mode == kSaveFPRegs) { 781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { 7823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch XMMRegister reg = XMMRegister::from_code(i); 783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movsd(reg, Operand(rsp, i * kDoubleSize)); 7843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(rsp, Immediate(kDoubleSize * XMMRegister::kMaxNumRegisters)); 7863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = kNumberOfSavedRegs - 1; i >= 0; i--) { 7883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register reg = saved_regs[i]; 7893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!reg.is(exclusion1) && !reg.is(exclusion2) && !reg.is(exclusion3)) { 790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch popq(reg); 791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtss2sd(XMMRegister dst, XMMRegister src) { 797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvtss2sd(dst, src, src); 800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvtss2sd(dst, src); 802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtss2sd(XMMRegister dst, const Operand& src) { 807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvtss2sd(dst, dst, src); 810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvtss2sd(dst, src); 812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtsd2ss(XMMRegister dst, XMMRegister src) { 817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvtsd2ss(dst, src, src); 820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvtsd2ss(dst, src); 822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtsd2ss(XMMRegister dst, const Operand& src) { 827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvtsd2ss(dst, dst, src); 830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvtsd2ss(dst, src); 832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Cvtlsi2sd(XMMRegister dst, Register src) { 837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vxorpd(dst, dst, dst); 840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvtlsi2sd(dst, dst, src); 841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch xorpd(dst, dst); 843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvtlsi2sd(dst, src); 844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Cvtlsi2sd(XMMRegister dst, const Operand& src) { 849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vxorpd(dst, dst, dst); 852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvtlsi2sd(dst, dst, src); 853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch xorpd(dst, dst); 855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvtlsi2sd(dst, src); 856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 860109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid MacroAssembler::Cvtlsi2ss(XMMRegister dst, Register src) { 861109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 862109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CpuFeatureScope scope(this, AVX); 863109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch vxorps(dst, dst, dst); 864109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch vcvtlsi2ss(dst, dst, src); 865109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 866109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch xorps(dst, dst); 867109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch cvtlsi2ss(dst, src); 868109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 869109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 870109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 871109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 872109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid MacroAssembler::Cvtlsi2ss(XMMRegister dst, const Operand& src) { 873109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 874109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CpuFeatureScope scope(this, AVX); 875109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch vxorps(dst, dst, dst); 876109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch vcvtlsi2ss(dst, dst, src); 877109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 878109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch xorps(dst, dst); 879109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch cvtlsi2ss(dst, src); 880109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 881109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 882109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 883109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtqsi2ss(XMMRegister dst, Register src) { 885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vxorps(dst, dst, dst); 888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvtqsi2ss(dst, dst, src); 889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch xorps(dst, dst); 891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvtqsi2ss(dst, src); 892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtqsi2ss(XMMRegister dst, const Operand& src) { 897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vxorps(dst, dst, dst); 900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvtqsi2ss(dst, dst, src); 901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch xorps(dst, dst); 903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvtqsi2ss(dst, src); 904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtqsi2sd(XMMRegister dst, Register src) { 909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vxorpd(dst, dst, dst); 912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvtqsi2sd(dst, dst, src); 913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch xorpd(dst, dst); 915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvtqsi2sd(dst, src); 916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtqsi2sd(XMMRegister dst, const Operand& src) { 921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vxorpd(dst, dst, dst); 924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvtqsi2sd(dst, dst, src); 925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch xorpd(dst, dst); 927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvtqsi2sd(dst, src); 928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtqui2ss(XMMRegister dst, Register src, Register tmp) { 933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label msb_set_src; 934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label jmp_return; 935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch testq(src, src); 936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(sign, &msb_set_src, Label::kNear); 937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cvtqsi2ss(dst, src); 938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jmp(&jmp_return, Label::kNear); 939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(&msb_set_src); 940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movq(tmp, src); 941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch shrq(src, Immediate(1)); 942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Recover the least significant bit to avoid rounding errors. 943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch andq(tmp, Immediate(1)); 944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch orq(src, tmp); 945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cvtqsi2ss(dst, src); 946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch addss(dst, dst); 947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(&jmp_return); 948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtqui2sd(XMMRegister dst, Register src, Register tmp) { 952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label msb_set_src; 953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label jmp_return; 954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch testq(src, src); 955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(sign, &msb_set_src, Label::kNear); 956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cvtqsi2sd(dst, src); 957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jmp(&jmp_return, Label::kNear); 958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(&msb_set_src); 959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movq(tmp, src); 960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch shrq(src, Immediate(1)); 961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch andq(tmp, Immediate(1)); 962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch orq(src, tmp); 963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cvtqsi2sd(dst, src); 964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch addsd(dst, dst); 965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(&jmp_return); 966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtsd2si(Register dst, XMMRegister src) { 970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvtsd2si(dst, src); 973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvtsd2si(dst, src); 975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 979109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid MacroAssembler::Cvttss2si(Register dst, XMMRegister src) { 980109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 981109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CpuFeatureScope scope(this, AVX); 982109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch vcvttss2si(dst, src); 983109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 984109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch cvttss2si(dst, src); 985109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 986109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 987109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 988109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 989109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid MacroAssembler::Cvttss2si(Register dst, const Operand& src) { 990109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 991109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CpuFeatureScope scope(this, AVX); 992109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch vcvttss2si(dst, src); 993109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 994109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch cvttss2si(dst, src); 995109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 996109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 997109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 998109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvttsd2si(Register dst, XMMRegister src) { 1000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 1001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 1002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvttsd2si(dst, src); 1003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvttsd2si(dst, src); 1005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvttsd2si(Register dst, const Operand& src) { 1010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 1011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 1012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvttsd2si(dst, src); 1013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvttsd2si(dst, src); 1015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvttss2siq(Register dst, XMMRegister src) { 1020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 1021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 1022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvttss2siq(dst, src); 1023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvttss2siq(dst, src); 1025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvttss2siq(Register dst, const Operand& src) { 1030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 1031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 1032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvttss2siq(dst, src); 1033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvttss2siq(dst, src); 1035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvttsd2siq(Register dst, XMMRegister src) { 1040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 1041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 1042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvttsd2siq(dst, src); 1043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvttsd2siq(dst, src); 1045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 1047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 1049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvttsd2siq(Register dst, const Operand& src) { 1050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 1051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 1052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vcvttsd2siq(dst, src); 1053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cvttsd2siq(dst, src); 1055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 1056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Load(Register dst, const Operand& src, Representation r) { 1060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!r.IsDouble()); 1061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (r.IsInteger8()) { 1062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movsxbq(dst, src); 1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (r.IsUInteger8()) { 1064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movzxbl(dst, src); 1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (r.IsInteger16()) { 1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movsxwq(dst, src); 1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (r.IsUInteger16()) { 1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movzxwl(dst, src); 1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (r.IsInteger32()) { 1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(dst, src); 1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 1073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Store(const Operand& dst, Register src, Representation r) { 1078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!r.IsDouble()); 1079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (r.IsInteger8() || r.IsUInteger8()) { 1080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movb(dst, src); 1081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (r.IsInteger16() || r.IsUInteger16()) { 1082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movw(dst, src); 1083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (r.IsInteger32()) { 1084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(dst, src); 1085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (r.IsHeapObject()) { 1087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertNotSmi(src); 1088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (r.IsSmi()) { 1089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertSmi(src); 10903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 10923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 10933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 10943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 10953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Set(Register dst, int64_t x) { 1097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (x == 0) { 10988defd9ff6930b4e24729971a61cf7469daf119beSteve Block xorl(dst, dst); 1099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (is_uint32(x)) { 1100d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block movl(dst, Immediate(static_cast<uint32_t>(x))); 11018b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } else if (is_int32(x)) { 11028b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch movq(dst, Immediate(static_cast<int32_t>(x))); 1103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movq(dst, x); 1105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Set(const Operand& dst, intptr_t x) { 1109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (kPointerSize == kInt64Size) { 1110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (is_int32(x)) { 1111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, Immediate(static_cast<int32_t>(x))); 1112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Set(kScratchRegister, x); 1114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, kScratchRegister); 1115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, Immediate(static_cast<int32_t>(x))); 1118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ---------------------------------------------------------------------------- 1123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Smi tagging, untagging and tag detection. 1124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool MacroAssembler::IsUnsafeInt(const int32_t x) { 1126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static const int kMaxBits = 17; 1127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return !is_intn(x, kMaxBits); 1128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::SafeMove(Register dst, Smi* src) { 1132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 1133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsUnsafeInt(src->value()) && jit_cookie() != 0) { 1134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // JIT cookie can be converted to Smi. 1136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(dst, Smi::FromInt(src->value() ^ jit_cookie())); 1137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(kScratchRegister, Smi::FromInt(jit_cookie())); 1138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch xorp(dst, kScratchRegister); 1139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 1141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t value = static_cast<int32_t>(reinterpret_cast<intptr_t>(src)); 1142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, Immediate(value ^ jit_cookie())); 1143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch xorp(dst, Immediate(jit_cookie())); 1144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(dst, src); 1147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::SafePush(Smi* src) { 1152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsUnsafeInt(src->value()) && jit_cookie() != 0) { 1153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // JIT cookie can be converted to Smi. 1155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(Smi::FromInt(src->value() ^ jit_cookie())); 1156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(kScratchRegister, Smi::FromInt(jit_cookie())); 1157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch xorp(Operand(rsp, 0), kScratchRegister); 1158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 1160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t value = static_cast<int32_t>(reinterpret_cast<intptr_t>(src)); 1161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(Immediate(value ^ jit_cookie())); 1162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch xorp(Operand(rsp, 0), Immediate(jit_cookie())); 1163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(src); 1166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11708defd9ff6930b4e24729971a61cf7469daf119beSteve BlockRegister MacroAssembler::GetSmiConstant(Smi* source) { 1171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STATIC_ASSERT(kSmiTag == 0); 11728defd9ff6930b4e24729971a61cf7469daf119beSteve Block int value = source->value(); 11738defd9ff6930b4e24729971a61cf7469daf119beSteve Block if (value == 0) { 11748defd9ff6930b4e24729971a61cf7469daf119beSteve Block xorl(kScratchRegister, kScratchRegister); 11758defd9ff6930b4e24729971a61cf7469daf119beSteve Block return kScratchRegister; 11768defd9ff6930b4e24729971a61cf7469daf119beSteve Block } 11778defd9ff6930b4e24729971a61cf7469daf119beSteve Block LoadSmiConstant(kScratchRegister, source); 11788defd9ff6930b4e24729971a61cf7469daf119beSteve Block return kScratchRegister; 11798defd9ff6930b4e24729971a61cf7469daf119beSteve Block} 11808defd9ff6930b4e24729971a61cf7469daf119beSteve Block 1181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11828defd9ff6930b4e24729971a61cf7469daf119beSteve Blockvoid MacroAssembler::LoadSmiConstant(Register dst, Smi* source) { 1183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STATIC_ASSERT(kSmiTag == 0); 118444f0eee88ff00398ff7f715fab053374d808c90dSteve Block int value = source->value(); 118544f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (value == 0) { 11868defd9ff6930b4e24729971a61cf7469daf119beSteve Block xorl(dst, dst); 1187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 1188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Move(dst, source, Assembler::RelocInfoNone()); 11898defd9ff6930b4e24729971a61cf7469daf119beSteve Block } 11908defd9ff6930b4e24729971a61cf7469daf119beSteve Block} 11918defd9ff6930b4e24729971a61cf7469daf119beSteve Block 1192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 11930d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid MacroAssembler::Integer32ToSmi(Register dst, Register src) { 119469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch STATIC_ASSERT(kSmiTag == 0); 1195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!dst.is(src)) { 1196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block movl(dst, src); 1197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlp(dst, Immediate(kSmiShift)); 1199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 12029dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenvoid MacroAssembler::Integer32ToSmiField(const Operand& dst, Register src) { 120344f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 12049dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen testb(dst, Immediate(0x01)); 1205257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label ok; 1206257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(zero, &ok, Label::kNear); 1207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Abort(kInteger32ToSmiFieldWritingToNonSmiLocation); 12089dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen bind(&ok); 12099dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 1210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(kSmiShift % kBitsPerByte == 0); 1213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(Operand(dst, kSmiShift / kBitsPerByte), src); 1214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 1216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Integer32ToSmi(kScratchRegister, src); 1217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, kScratchRegister); 1218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 12199dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen} 12209dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 12219dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 12223ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::Integer64PlusConstantToSmi(Register dst, 12233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Register src, 12243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int constant) { 12253ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (dst.is(src)) { 122644f0eee88ff00398ff7f715fab053374d808c90dSteve Block addl(dst, Immediate(constant)); 12273ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 122844f0eee88ff00398ff7f715fab053374d808c90dSteve Block leal(dst, Operand(src, constant)); 12293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 1230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlp(dst, Immediate(kSmiShift)); 1231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiToInteger32(Register dst, Register src) { 123569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch STATIC_ASSERT(kSmiTag == 0); 1236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!dst.is(src)) { 1237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 1238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shrp(dst, Immediate(kSmiShift)); 1242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 1244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sarl(dst, Immediate(kSmiShift)); 1245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 12497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid MacroAssembler::SmiToInteger32(Register dst, const Operand& src) { 1250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(dst, Operand(src, kSmiShift / kBitsPerByte)); 1252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 1254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(dst, src); 1255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sarl(dst, Immediate(kSmiShift)); 1256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 12577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 12587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 12597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiToInteger64(Register dst, Register src) { 126169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch STATIC_ASSERT(kSmiTag == 0); 12623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (!dst.is(src)) { 1263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 1264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sarp(dst, Immediate(kSmiShift)); 1266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (kPointerSize == kInt32Size) { 1267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Sign extend to 64-bit. 1268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movsxlq(dst, dst); 1269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 12739dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenvoid MacroAssembler::SmiToInteger64(Register dst, const Operand& src) { 1274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movsxlq(dst, Operand(src, kSmiShift / kBitsPerByte)); 1276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 1278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 1279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger64(dst, dst); 1280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 12819dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen} 12829dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 12839dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 12843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::SmiTest(Register src) { 1285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertSmi(src); 1286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(src, src); 1287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 129044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid MacroAssembler::SmiCompare(Register smi1, Register smi2) { 1291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertSmi(smi1); 1292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertSmi(smi2); 1293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(smi1, smi2); 1294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 12973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::SmiCompare(Register dst, Smi* src) { 1298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertSmi(dst); 129944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Cmp(dst, src); 130044f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 130144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 130244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 130344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid MacroAssembler::Cmp(Register dst, Smi* src) { 1304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 13053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (src->value() == 0) { 1306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(dst, dst); 13073ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 1308756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick Register constant_reg = GetSmiConstant(src); 1309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(dst, constant_reg); 1310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1314f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkevoid MacroAssembler::SmiCompare(Register dst, const Operand& src) { 1315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertSmi(dst); 1316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertSmi(src); 1317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(dst, src); 13186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 13196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 13206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 13213ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::SmiCompare(const Operand& dst, Register src) { 1322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertSmi(dst); 1323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertSmi(src); 1324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(dst, src); 1325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 13283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::SmiCompare(const Operand& dst, Smi* src) { 1329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertSmi(dst); 1330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpl(Operand(dst, kSmiShift / kBitsPerByte), Immediate(src->value())); 1332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 1334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpl(dst, Immediate(src)); 133544f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 1336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 133944f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid MacroAssembler::Cmp(const Operand& dst, Smi* src) { 134044f0eee88ff00398ff7f715fab053374d808c90dSteve Block // The Operand cannot use the smi register. 134144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Register smi_reg = GetSmiConstant(src); 1342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.AddressUsesRegister(smi_reg)); 1343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(dst, smi_reg); 134444f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 134544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 134644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 13479dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenvoid MacroAssembler::SmiCompareInteger32(const Operand& dst, Register src) { 1348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpl(Operand(dst, kSmiShift / kBitsPerByte), src); 1350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 1352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(kScratchRegister, dst); 1353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpl(kScratchRegister, src); 1354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 13559dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen} 13569dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 13579dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 13583ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::PositiveSmiTimesPowerOfTwoToInteger64(Register dst, 13593ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Register src, 13603ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int power) { 1361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(power >= 0); 1362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(power < 64); 13633ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (power == 0) { 13643ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block SmiToInteger64(dst, src); 13653ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return; 13663ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 13673ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (!dst.is(src)) { 1368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 13693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 13703ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (power < kSmiShift) { 1371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sarp(dst, Immediate(kSmiShift - power)); 13723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else if (power > kSmiShift) { 1373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlp(dst, Immediate(power - kSmiShift)); 13743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 1375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 13787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid MacroAssembler::PositiveSmiDivPowerOfTwoToInteger32(Register dst, 13797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Register src, 13807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch int power) { 1381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((0 <= power) && (power < 32)); 13827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (dst.is(src)) { 1383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shrp(dst, Immediate(power + kSmiShift)); 13847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else { 13857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch UNIMPLEMENTED(); // Not used. 13867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 13877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 13887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 13897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 1390257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SmiOrIfSmis(Register dst, Register src1, Register src2, 1391257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_smis, 1392257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1393257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (dst.is(src1) || dst.is(src2)) { 1394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(kScratchRegister)); 1395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.is(kScratchRegister)); 1396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, src1); 1397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch orp(kScratchRegister, src2); 1398257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch JumpIfNotSmi(kScratchRegister, on_not_smis, near_jump); 1399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, kScratchRegister); 1400257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 1401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src1); 1402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch orp(dst, src2); 1403257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch JumpIfNotSmi(dst, on_not_smis, near_jump); 1404257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1405257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1406257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1407257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 14083ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockCondition MacroAssembler::CheckSmi(Register src) { 140969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch STATIC_ASSERT(kSmiTag == 0); 1410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block testb(src, Immediate(kSmiTagMask)); 14113ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return zero; 1412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 14151e0659c275bb392c045087af4f6b0d7565cb3d77Steve BlockCondition MacroAssembler::CheckSmi(const Operand& src) { 141669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch STATIC_ASSERT(kSmiTag == 0); 14171e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block testb(src, Immediate(kSmiTagMask)); 14181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block return zero; 14191e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 14201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 14211e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1422f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochCondition MacroAssembler::CheckNonNegativeSmi(Register src) { 142369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch STATIC_ASSERT(kSmiTag == 0); 1424e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Test that both bits of the mask 0x8000000000000001 are zero. 1425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, src); 1426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch rolp(kScratchRegister, Immediate(1)); 14278defd9ff6930b4e24729971a61cf7469daf119beSteve Block testb(kScratchRegister, Immediate(3)); 1428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return zero; 1429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCondition MacroAssembler::CheckBothSmi(Register first, Register second) { 1433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (first.is(second)) { 1434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return CheckSmi(first); 1435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 143669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch STATIC_ASSERT(kSmiTag == 0 && kHeapObjectTag == 1 && kHeapObjectTagMask == 3); 1437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leal(kScratchRegister, Operand(first, second, times_1, 0)); 1439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testb(kScratchRegister, Immediate(0x03)); 1440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 1442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(kScratchRegister, first); 1443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch orl(kScratchRegister, second); 1444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testb(kScratchRegister, Immediate(kSmiTagMask)); 1445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 14463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return zero; 1447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1450f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochCondition MacroAssembler::CheckBothNonNegativeSmi(Register first, 1451f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Register second) { 1452d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke if (first.is(second)) { 1453f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return CheckNonNegativeSmi(first); 1454d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 1455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, first); 1456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch orp(kScratchRegister, second); 1457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch rolp(kScratchRegister, Immediate(1)); 1458f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch testl(kScratchRegister, Immediate(3)); 1459d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return zero; 1460d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 1461d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1462d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 1463bb769b257e753aafcbd96767abb2abc645eaa20cBen MurdochCondition MacroAssembler::CheckEitherSmi(Register first, 1464bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch Register second, 1465bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch Register scratch) { 1466e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (first.is(second)) { 1467e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return CheckSmi(first); 1468e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 1469bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch if (scratch.is(second)) { 1470bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch andl(scratch, first); 1471bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } else { 1472bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch if (!scratch.is(first)) { 1473bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch movl(scratch, first); 1474bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } 1475bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch andl(scratch, second); 1476bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } 1477bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch testb(scratch, Immediate(kSmiTagMask)); 1478e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return zero; 1479e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 1480e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 1481e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 14823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockCondition MacroAssembler::CheckInteger32ValidSmiValue(Register src) { 1483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // A 32-bit integer value can always be converted to a smi. 1485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return always; 1486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 1488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpl(src, Immediate(0xc0000000)); 1489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return positive; 1490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 14943ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockCondition MacroAssembler::CheckUInteger32ValidSmiValue(Register src) { 1495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // An unsigned 32-bit integer value is valid as long as the high bit 1497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // is not set. 1498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testl(src, src); 1499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return positive; 1500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 1502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testl(src, Immediate(0xc0000000)); 1503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return zero; 1504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 15081e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::CheckSmiToIndicator(Register dst, Register src) { 15091e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (dst.is(src)) { 15101e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block andl(dst, Immediate(kSmiTagMask)); 15111e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } else { 15121e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block movl(dst, Immediate(kSmiTagMask)); 15131e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block andl(dst, src); 15141e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 15151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 15161e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 15171e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 15181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::CheckSmiToIndicator(Register dst, const Operand& src) { 15191e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (!(src.AddressUsesRegister(dst))) { 15201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block movl(dst, Immediate(kSmiTagMask)); 15211e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block andl(dst, src); 15221e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } else { 15231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block movl(dst, src); 15241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block andl(dst, Immediate(kSmiTagMask)); 15251e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 15261e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 15271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 15281e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::JumpIfValidSmiValue(Register src, 1530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* on_valid, 1531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::Distance near_jump) { 1532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition is_valid = CheckInteger32ValidSmiValue(src); 1533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(is_valid, on_valid, near_jump); 1534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1537257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::JumpIfNotValidSmiValue(Register src, 1538257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_invalid, 1539257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1540257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Condition is_valid = CheckInteger32ValidSmiValue(src); 1541257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(NegateCondition(is_valid), on_invalid, near_jump); 1542257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1543257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1544257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::JumpIfUIntValidSmiValue(Register src, 1546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* on_valid, 1547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::Distance near_jump) { 1548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition is_valid = CheckUInteger32ValidSmiValue(src); 1549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(is_valid, on_valid, near_jump); 1550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1553257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::JumpIfUIntNotValidSmiValue(Register src, 1554257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_invalid, 1555257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1556257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Condition is_valid = CheckUInteger32ValidSmiValue(src); 1557257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(NegateCondition(is_valid), on_invalid, near_jump); 1558257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1559257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1560257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1561257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::JumpIfSmi(Register src, 1562257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_smi, 1563257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1564257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Condition smi = CheckSmi(src); 1565257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(smi, on_smi, near_jump); 1566257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1567257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1568257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1569257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::JumpIfNotSmi(Register src, 1570257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_smi, 1571257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1572257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Condition smi = CheckSmi(src); 1573257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(NegateCondition(smi), on_not_smi, near_jump); 1574257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1575257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 157662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid MacroAssembler::JumpIfNotSmi(Operand src, Label* on_not_smi, 157762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Label::Distance near_jump) { 157862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Condition smi = CheckSmi(src); 157962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch j(NegateCondition(smi), on_not_smi, near_jump); 158062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 1581257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1582257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::JumpUnlessNonNegativeSmi( 1583257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src, Label* on_not_smi_or_negative, 1584257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1585257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Condition non_negative_smi = CheckNonNegativeSmi(src); 1586257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(NegateCondition(non_negative_smi), on_not_smi_or_negative, near_jump); 1587257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1588257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1589257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1590257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::JumpIfSmiEqualsConstant(Register src, 1591257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Smi* constant, 1592257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_equals, 1593257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1594257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch SmiCompare(src, constant); 1595257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(equal, on_equals, near_jump); 1596257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1597257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1598257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1599257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::JumpIfNotBothSmi(Register src1, 1600257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src2, 1601257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_both_smi, 1602257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1603257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Condition both_smi = CheckBothSmi(src1, src2); 1604257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(NegateCondition(both_smi), on_not_both_smi, near_jump); 1605257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1606257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1607257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1608257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::JumpUnlessBothNonNegativeSmi(Register src1, 1609257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src2, 1610257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_both_smi, 1611257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1612257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Condition both_smi = CheckBothNonNegativeSmi(src1, src2); 1613257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(NegateCondition(both_smi), on_not_both_smi, near_jump); 1614257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1615257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1616257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 16173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::SmiAddConstant(Register dst, Register src, Smi* constant) { 16183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (constant->value() == 0) { 16193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (!dst.is(src)) { 1620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 16213ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 16228defd9ff6930b4e24729971a61cf7469daf119beSteve Block return; 16233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else if (dst.is(src)) { 1624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 1625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register constant_reg = GetSmiConstant(constant); 1626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch addp(dst, constant_reg); 1627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 1628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoadSmiConstant(dst, constant); 1629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch addp(dst, src); 1630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1634f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkevoid MacroAssembler::SmiAddConstant(const Operand& dst, Smi* constant) { 1635f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke if (constant->value() != 0) { 1636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 1637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addl(Operand(dst, kSmiShift / kBitsPerByte), 1638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Immediate(constant->value())); 1639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 1641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(dst, Immediate(constant)); 1642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1643f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke } 1644f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke} 1645f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1646f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 1647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::SmiAddConstant(Register dst, Register src, Smi* constant, 1648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SmiOperationConstraints constraints, 1649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* bailout_label, 1650257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1651257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (constant->value() == 0) { 1652257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!dst.is(src)) { 1653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 1654257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1655257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else if (dst.is(src)) { 1656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 1657257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch LoadSmiConstant(kScratchRegister, constant); 1658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(dst, kScratchRegister); 1659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (constraints & SmiOperationConstraint::kBailoutOnNoOverflow) { 1660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(no_overflow, bailout_label, near_jump); 1661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(constraints & SmiOperationConstraint::kPreserveSourceRegister); 1662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(dst, kScratchRegister); 1663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (constraints & SmiOperationConstraint::kBailoutOnOverflow) { 1664014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (constraints & SmiOperationConstraint::kPreserveSourceRegister) { 1665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done; 1666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(no_overflow, &done, Label::kNear); 1667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(dst, kScratchRegister); 1668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jmp(bailout_label, near_jump); 1669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&done); 1670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Bailout if overflow without reserving src. 1672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(overflow, bailout_label, near_jump); 1673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 1676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1677257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 1678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(constraints & SmiOperationConstraint::kPreserveSourceRegister); 1679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(constraints & SmiOperationConstraint::kBailoutOnOverflow); 1680257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch LoadSmiConstant(dst, constant); 1681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(dst, src); 1682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(overflow, bailout_label, near_jump); 1683257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1684257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1685257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1686257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 16873ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::SmiSubConstant(Register dst, Register src, Smi* constant) { 16883ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (constant->value() == 0) { 1689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!dst.is(src)) { 1690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 1691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 16923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else if (dst.is(src)) { 1693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 16948defd9ff6930b4e24729971a61cf7469daf119beSteve Block Register constant_reg = GetSmiConstant(constant); 1695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(dst, constant_reg); 16963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 16973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (constant->value() == Smi::kMinValue) { 16988defd9ff6930b4e24729971a61cf7469daf119beSteve Block LoadSmiConstant(dst, constant); 16999dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen // Adding and subtracting the min-value gives the same result, it only 17009dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen // differs on the overflow bit, which we don't check here. 1701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(dst, src); 1702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 17039dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen // Subtract by adding the negation. 17048defd9ff6930b4e24729971a61cf7469daf119beSteve Block LoadSmiConstant(dst, Smi::FromInt(-constant->value())); 1705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(dst, src); 1706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::SmiSubConstant(Register dst, Register src, Smi* constant, 1712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SmiOperationConstraints constraints, 1713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* bailout_label, 1714257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1715257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (constant->value() == 0) { 1716257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!dst.is(src)) { 1717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 1718257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1719257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else if (dst.is(src)) { 1720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 1721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadSmiConstant(kScratchRegister, constant); 1722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(dst, kScratchRegister); 1723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (constraints & SmiOperationConstraint::kBailoutOnNoOverflow) { 1724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(no_overflow, bailout_label, near_jump); 1725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(constraints & SmiOperationConstraint::kPreserveSourceRegister); 1726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(dst, kScratchRegister); 1727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (constraints & SmiOperationConstraint::kBailoutOnOverflow) { 1728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (constraints & SmiOperationConstraint::kPreserveSourceRegister) { 1729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done; 1730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(no_overflow, &done, Label::kNear); 1731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(dst, kScratchRegister); 1732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jmp(bailout_label, near_jump); 1733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&done); 1734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Bailout if overflow without reserving src. 1736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(overflow, bailout_label, near_jump); 1737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1738257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 1739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 1740257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1741257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 1742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(constraints & SmiOperationConstraint::kPreserveSourceRegister); 1743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(constraints & SmiOperationConstraint::kBailoutOnOverflow); 1744257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (constant->value() == Smi::kMinValue) { 1745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 1746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 1747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadSmiConstant(kScratchRegister, constant); 1748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(dst, kScratchRegister); 1749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(overflow, bailout_label, near_jump); 1750257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 1751257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Subtract by adding the negation. 1752257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch LoadSmiConstant(dst, Smi::FromInt(-(constant->value()))); 1753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(dst, src); 1754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(overflow, bailout_label, near_jump); 1755257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1756257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1757257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1758257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1759257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1760257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SmiNeg(Register dst, 1761257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src, 1762257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_smi_result, 1763257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1764257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (dst.is(src)) { 1765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 1766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, src); 1767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch negp(dst); // Low 32 bits are retained as zero by negation. 1768257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Test if result is zero or Smi::kMinValue. 1769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(dst, kScratchRegister); 1770257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_equal, on_smi_result, near_jump); 1771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(src, kScratchRegister); 1772257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 1773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 1774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch negp(dst); 1775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(dst, src); 1776257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // If the result is zero or Smi::kMinValue, negation failed to create a smi. 1777257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_equal, on_smi_result, near_jump); 1778257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1779257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1780257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1781257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<class T> 1783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void SmiAddHelper(MacroAssembler* masm, 1784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register dst, 1785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register src1, 1786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch T src2, 1787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* on_not_smi_result, 1788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::Distance near_jump) { 1789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (dst.is(src1)) { 1790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done; 1791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->addp(dst, src2); 1792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->j(no_overflow, &done, Label::kNear); 1793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Restore src1. 1794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->subp(dst, src2); 1795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->jmp(on_not_smi_result, near_jump); 1796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->bind(&done); 1797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->movp(dst, src1); 1799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->addp(dst, src2); 1800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->j(overflow, on_not_smi_result, near_jump); 1801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1805257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SmiAdd(Register dst, 1806257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src1, 1807257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src2, 1808257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_smi_result, 1809257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NOT_NULL(on_not_smi_result); 1811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(src2)); 1812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiAddHelper<Register>(this, dst, src1, src2, on_not_smi_result, near_jump); 1813257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1814257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1815257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1816257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SmiAdd(Register dst, 1817257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src1, 1818257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch const Operand& src2, 1819257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_smi_result, 1820257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NOT_NULL(on_not_smi_result); 1822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.AddressUsesRegister(dst)); 1823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiAddHelper<Operand>(this, dst, src1, src2, on_not_smi_result, near_jump); 1824257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1825257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1826257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 18270d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid MacroAssembler::SmiAdd(Register dst, 18280d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Register src1, 18290d5e116f6aee03185f237311a943491bb079a768Kristian Monsen Register src2) { 18300d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // No overflow checking. Use only when it's known that 18310d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // overflowing is impossible. 183244f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!dst.is(src1)) { 1833257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (emit_debug_code()) { 1834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, src1); 1835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(kScratchRegister, src2); 1836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(no_overflow, kSmiAdditionOverflow); 1837257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(dst, Operand(src1, src2, times_1, 0)); 1839257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 1840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(dst, src2); 1841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assert(no_overflow, kSmiAdditionOverflow); 1842257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1843257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1844257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1845257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<class T> 1847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void SmiSubHelper(MacroAssembler* masm, 1848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register dst, 1849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register src1, 1850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch T src2, 1851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* on_not_smi_result, 1852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::Distance near_jump) { 1853257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (dst.is(src1)) { 1854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done; 1855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->subp(dst, src2); 1856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->j(no_overflow, &done, Label::kNear); 1857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Restore src1. 1858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->addp(dst, src2); 1859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->jmp(on_not_smi_result, near_jump); 1860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->bind(&done); 1861257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 1862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->movp(dst, src1); 1863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->subp(dst, src2); 1864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->j(overflow, on_not_smi_result, near_jump); 1865a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1866a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1867a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::SmiSub(Register dst, 1870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register src1, 1871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register src2, 1872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* on_not_smi_result, 1873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::Distance near_jump) { 1874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NOT_NULL(on_not_smi_result); 1875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(src2)); 1876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiSubHelper<Register>(this, dst, src1, src2, on_not_smi_result, near_jump); 1877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 18800d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid MacroAssembler::SmiSub(Register dst, 1881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register src1, 1882257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch const Operand& src2, 1883257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_smi_result, 1884257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NOT_NULL(on_not_smi_result); 1886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.AddressUsesRegister(dst)); 1887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiSubHelper<Operand>(this, dst, src1, src2, on_not_smi_result, near_jump); 1888257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1889257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1890257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<class T> 1892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void SmiSubNoOverflowHelper(MacroAssembler* masm, 1893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register dst, 1894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register src1, 1895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch T src2) { 18960d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // No overflow checking. Use only when it's known that 18970d5e116f6aee03185f237311a943491bb079a768Kristian Monsen // overflowing is impossible (e.g., subtracting two positive smis). 189844f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!dst.is(src1)) { 1899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->movp(dst, src1); 1900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->subp(dst, src2); 1902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->Assert(no_overflow, kSmiSubtractionOverflow); 1903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::SmiSub(Register dst, Register src1, Register src2) { 1907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(src2)); 1908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiSubNoOverflowHelper<Register>(this, dst, src1, src2); 1909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::SmiSub(Register dst, 1913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register src1, 1914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Operand& src2) { 1915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiSubNoOverflowHelper<Operand>(this, dst, src1, src2); 1916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1919257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SmiMul(Register dst, 1920257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src1, 1921257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src2, 1922257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_smi_result, 1923257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(src2)); 1925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 1926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(kScratchRegister)); 1927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.is(kScratchRegister)); 1928257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1929257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (dst.is(src1)) { 1930257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label failure, zero_correct_result; 1931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, src1); // Create backup for later testing. 1932257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch SmiToInteger64(dst, src1); 1933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch imulp(dst, src2); 1934257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(overflow, &failure, Label::kNear); 1935257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1936257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Check for negative zero result. If product is zero, and one 1937257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // argument is negative, go to slow case. 1938257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label correct_result; 1939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(dst, dst); 1940257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_zero, &correct_result, Label::kNear); 1941257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, kScratchRegister); 1943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch xorp(dst, src2); 1944257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Result was positive zero. 1945257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(positive, &zero_correct_result, Label::kNear); 1946257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1947257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&failure); // Reused failure exit, restores src1. 1948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(src1, kScratchRegister); 1949257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch jmp(on_not_smi_result, near_jump); 1950257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1951257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&zero_correct_result); 1952257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Set(dst, 0); 1953257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1954257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&correct_result); 1955257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 1956257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch SmiToInteger64(dst, src1); 1957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch imulp(dst, src2); 1958257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(overflow, on_not_smi_result, near_jump); 1959257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Check for negative zero result. If product is zero, and one 1960257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // argument is negative, go to slow case. 1961257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label correct_result; 1962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(dst, dst); 1963257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_zero, &correct_result, Label::kNear); 1964257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // One of src1 and src2 is zero, the check whether the other is 1965257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // negative. 1966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, src1); 1967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch xorp(kScratchRegister, src2); 1968257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(negative, on_not_smi_result, near_jump); 1969257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&correct_result); 1970257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1971257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 1972257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1973257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1974257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SmiDiv(Register dst, 1975257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src1, 1976257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src2, 1977257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_smi_result, 1978257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 1979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(kScratchRegister)); 1980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.is(kScratchRegister)); 1981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 1982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.is(rax)); 1983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.is(rdx)); 1984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(rdx)); 1985257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1986257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Check for 0 divisor (result is +/-Infinity). 1987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(src2, src2); 1988257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(zero, on_not_smi_result, near_jump); 1989257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1990257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (src1.is(rax)) { 1991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, src1); 1992257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 1993257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch SmiToInteger32(rax, src1); 1994257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // We need to rule out dividing Smi::kMinValue by -1, since that would 1995257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // overflow in idiv and raise an exception. 1996257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // We combine this with negative zero test (negative zero only happens 1997257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // when dividing zero by a negative number). 1998257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 1999257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // We overshoot a little and go to slow case if we divide min-value 2000257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // by any negative value, not just -1. 2001257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label safe_div; 2002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testl(rax, Immediate(~Smi::kMinValue)); 2003257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_zero, &safe_div, Label::kNear); 2004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(src2, src2); 2005257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (src1.is(rax)) { 2006257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(positive, &safe_div, Label::kNear); 2007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(src1, kScratchRegister); 2008257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch jmp(on_not_smi_result, near_jump); 2009257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 2010257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(negative, on_not_smi_result, near_jump); 2011257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 2012257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&safe_div); 2013257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2014257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch SmiToInteger32(src2, src2); 2015257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Sign extend src1 into edx:eax. 2016257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch cdq(); 2017257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch idivl(src2); 2018257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Integer32ToSmi(src2, src2); 2019257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Check that the remainder is zero. 2020257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch testl(rdx, rdx); 2021257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (src1.is(rax)) { 2022257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label smi_result; 2023257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(zero, &smi_result, Label::kNear); 2024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(src1, kScratchRegister); 2025257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch jmp(on_not_smi_result, near_jump); 2026257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&smi_result); 2027257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 2028257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_zero, on_not_smi_result, near_jump); 2029257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 2030257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!dst.is(src1) && src1.is(rax)) { 2031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(src1, kScratchRegister); 2032257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 2033257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Integer32ToSmi(dst, rax); 2034257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 2035257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2036257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2037257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SmiMod(Register dst, 2038257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src1, 2039257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src2, 2040257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_smi_result, 2041257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 2042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 2043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(kScratchRegister)); 2044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.is(kScratchRegister)); 2045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.is(rax)); 2046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.is(rdx)); 2047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(rdx)); 2048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(src2)); 2049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(src2, src2); 2051257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(zero, on_not_smi_result, near_jump); 2052257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2053257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (src1.is(rax)) { 2054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, src1); 2055257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 2056257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch SmiToInteger32(rax, src1); 2057257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch SmiToInteger32(src2, src2); 2058257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2059257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Test for the edge case of dividing Smi::kMinValue by -1 (will overflow). 2060257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label safe_div; 2061257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch cmpl(rax, Immediate(Smi::kMinValue)); 2062257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_equal, &safe_div, Label::kNear); 2063257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch cmpl(src2, Immediate(-1)); 2064257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_equal, &safe_div, Label::kNear); 2065257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Retag inputs and go slow case. 2066257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Integer32ToSmi(src2, src2); 2067257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (src1.is(rax)) { 2068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(src1, kScratchRegister); 2069257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 2070257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch jmp(on_not_smi_result, near_jump); 2071257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&safe_div); 2072257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2073257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Sign extend eax into edx:eax. 2074257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch cdq(); 2075257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch idivl(src2); 2076257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Restore smi tags on inputs. 2077257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Integer32ToSmi(src2, src2); 2078257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (src1.is(rax)) { 2079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(src1, kScratchRegister); 2080257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 2081257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Check for a negative zero result. If the result is zero, and the 2082257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // dividend is negative, go slow to return a floating point negative zero. 2083257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label smi_result; 2084257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch testl(rdx, rdx); 2085257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_zero, &smi_result, Label::kNear); 2086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(src1, src1); 2087257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(negative, on_not_smi_result, near_jump); 2088257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&smi_result); 2089257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Integer32ToSmi(dst, rdx); 2090257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 2091257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2092257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiNot(Register dst, Register src) { 2094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 2095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src.is(kScratchRegister)); 2096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 2097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Set tag and padding bits before negating, so that they are zero 2098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // afterwards. 2099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(kScratchRegister, Immediate(~0)); 2100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 2102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(kScratchRegister, Immediate(1)); 2103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (dst.is(src)) { 2105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch xorp(dst, kScratchRegister); 2106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(dst, Operand(src, kScratchRegister, times_1, 0)); 2108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch notp(dst); 2110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiAnd(Register dst, Register src1, Register src2) { 2114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(src2)); 2115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!dst.is(src1)) { 2116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src1); 2117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(dst, src2); 2119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 21223ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::SmiAndConstant(Register dst, Register src, Smi* constant) { 21233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (constant->value() == 0) { 21249fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block Set(dst, 0); 21253ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else if (dst.is(src)) { 2126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 21278defd9ff6930b4e24729971a61cf7469daf119beSteve Block Register constant_reg = GetSmiConstant(constant); 2128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(dst, constant_reg); 21293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 21308defd9ff6930b4e24729971a61cf7469daf119beSteve Block LoadSmiConstant(dst, constant); 2131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(dst, src); 2132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiOr(Register dst, Register src1, Register src2) { 2137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!dst.is(src1)) { 2138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(src2)); 2139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src1); 2140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch orp(dst, src2); 2142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 21453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::SmiOrConstant(Register dst, Register src, Smi* constant) { 21463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (dst.is(src)) { 2147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 21488defd9ff6930b4e24729971a61cf7469daf119beSteve Block Register constant_reg = GetSmiConstant(constant); 2149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch orp(dst, constant_reg); 21503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 21518defd9ff6930b4e24729971a61cf7469daf119beSteve Block LoadSmiConstant(dst, constant); 2152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch orp(dst, src); 2153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 21563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 2157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiXor(Register dst, Register src1, Register src2) { 2158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!dst.is(src1)) { 2159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(src2)); 2160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src1); 2161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch xorp(dst, src2); 2163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 21663ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::SmiXorConstant(Register dst, Register src, Smi* constant) { 21673ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block if (dst.is(src)) { 2168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 21698defd9ff6930b4e24729971a61cf7469daf119beSteve Block Register constant_reg = GetSmiConstant(constant); 2170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch xorp(dst, constant_reg); 21713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 21728defd9ff6930b4e24729971a61cf7469daf119beSteve Block LoadSmiConstant(dst, constant); 2173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch xorp(dst, src); 2174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiShiftArithmeticRightConstant(Register dst, 2179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register src, 2180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int shift_value) { 2181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_uint5(shift_value)); 2182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (shift_value > 0) { 2183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (dst.is(src)) { 2184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sarp(dst, Immediate(shift_value + kSmiShift)); 2185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlp(dst, Immediate(kSmiShift)); 2186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block UNIMPLEMENTED(); // Not used. 2188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiShiftLeftConstant(Register dst, 2194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register src, 2195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int shift_value, 2196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* on_not_smi_result, 2197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::Distance near_jump) { 2198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 2199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!dst.is(src)) { 2200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 2201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (shift_value > 0) { 2203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Shift amount specified by lower 5 bits, not six as the shl opcode. 2204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlq(dst, Immediate(shift_value & 0x1f)); 2205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 2208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (dst.is(src)) { 2209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNIMPLEMENTED(); // Not used. 2210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(dst, src); 2212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shll(dst, Immediate(shift_value)); 2213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JumpIfNotValidSmiValue(dst, on_not_smi_result, near_jump); 2214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Integer32ToSmi(dst, dst); 2215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2220257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SmiShiftLogicalRightConstant( 2221257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register dst, Register src, int shift_value, 2222257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_smi_result, Label::Distance near_jump) { 2223257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Logic right shift interprets its result as an *unsigned* number. 2224257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (dst.is(src)) { 2225257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch UNIMPLEMENTED(); // Not used. 2226257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 2227257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (shift_value == 0) { 2228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(src, src); 2229257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(negative, on_not_smi_result, near_jump); 2230257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 2231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 2232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 2233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shrp(dst, Immediate(shift_value + kSmiShift)); 2234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlp(dst, Immediate(kSmiShift)); 2235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 2237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(dst, src); 2238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shrp(dst, Immediate(shift_value)); 2239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JumpIfUIntNotValidSmiValue(dst, on_not_smi_result, near_jump); 2240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Integer32ToSmi(dst, dst); 2241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2242257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 2243257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 2244257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2245257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiShiftLeft(Register dst, 2247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register src1, 2248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register src2, 2249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* on_not_smi_result, 2250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::Distance near_jump) { 2251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 2252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(rcx)); 2253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!dst.is(src1)) { 2254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src1); 2255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Untag shift amount. 2257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(rcx, src2); 2258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Shift amount specified by lower 5 bits, not six as the shl opcode. 2259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(rcx, Immediate(0x1f)); 2260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlq_cl(dst); 2261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 2263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 2264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(kScratchRegister)); 2265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.is(kScratchRegister)); 2266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(src2)); 2267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(rcx)); 2268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (src1.is(rcx) || src2.is(rcx)) { 2270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movq(kScratchRegister, rcx); 2271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (dst.is(src1)) { 2273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNIMPLEMENTED(); // Not used. 2274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label valid_result; 2276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(dst, src1); 2277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(rcx, src2); 2278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shll_cl(dst); 2279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JumpIfValidSmiValue(dst, &valid_result, Label::kNear); 2280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // As src1 or src2 could not be dst, we do not need to restore them for 2281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // clobbering dst. 2282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (src1.is(rcx) || src2.is(rcx)) { 2283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (src1.is(rcx)) { 2284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movq(src1, kScratchRegister); 2285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movq(src2, kScratchRegister); 2287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jmp(on_not_smi_result, near_jump); 2290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&valid_result); 2291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Integer32ToSmi(dst, dst); 2292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2297257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SmiShiftLogicalRight(Register dst, 2298257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src1, 2299257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src2, 2300257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_smi_result, 2301257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 2302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 2303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(kScratchRegister)); 2304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.is(kScratchRegister)); 2305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(src2)); 2306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(rcx)); 2307257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (src1.is(rcx) || src2.is(rcx)) { 2308257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch movq(kScratchRegister, rcx); 2309257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 2310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (dst.is(src1)) { 2311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNIMPLEMENTED(); // Not used. 2312257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 2313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label valid_result; 2314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(dst, src1); 2315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(rcx, src2); 2316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shrl_cl(dst); 2317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JumpIfUIntValidSmiValue(dst, &valid_result, Label::kNear); 2318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // As src1 or src2 could not be dst, we do not need to restore them for 2319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // clobbering dst. 2320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (src1.is(rcx) || src2.is(rcx)) { 2321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (src1.is(rcx)) { 2322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movq(src1, kScratchRegister); 2323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movq(src2, kScratchRegister); 2325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jmp(on_not_smi_result, near_jump); 2328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&valid_result); 2329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Integer32ToSmi(dst, dst); 2330257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 2331257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 2332257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2333257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiShiftArithmeticRight(Register dst, 2335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register src1, 2336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register src2) { 2337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 2338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(kScratchRegister)); 2339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.is(kScratchRegister)); 2340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(rcx)); 2341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SmiToInteger32(rcx, src2); 2343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!dst.is(src1)) { 2344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src1); 23453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 2346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(dst, dst); 2347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sarl_cl(dst); 2348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Integer32ToSmi(dst, dst); 2349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2352257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SelectNonSmi(Register dst, 2353257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src1, 2354257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register src2, 2355257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* on_not_smis, 2356257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 2357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(kScratchRegister)); 2358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src1.is(kScratchRegister)); 2359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src2.is(kScratchRegister)); 2360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(src1)); 2361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(src2)); 2362257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Both operands must not be smis. 2363257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#ifdef DEBUG 2364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition not_both_smis = NegateCondition(CheckBothSmi(src1, src2)); 2365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(not_both_smis, kBothRegistersWereSmisInSelectNonSmi); 2366257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#endif 236769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch STATIC_ASSERT(kSmiTag == 0); 2368c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DCHECK_EQ(static_cast<Smi*>(0), Smi::kZero); 2369257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch movl(kScratchRegister, Immediate(kSmiTagMask)); 2370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(kScratchRegister, src1); 2371257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch testl(kScratchRegister, src2); 2372257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // If non-zero then both are smis. 2373257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_zero, on_not_smis, near_jump); 2374257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2375257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Exactly one operand is a smi. 2376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(1, static_cast<int>(kSmiTagMask)); 2377257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // kScratchRegister still holds src1 & kSmiTag, which is either zero or one. 2378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(kScratchRegister, Immediate(1)); 2379257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // If src1 is a smi, then scratch register all 1s, else it is all 0s. 2380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src1); 2381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch xorp(dst, src2); 2382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(dst, kScratchRegister); 2383257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // If src1 is a smi, dst holds src1 ^ src2, else it is zero. 2384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch xorp(dst, src1); 2385257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // If src1 is a smi, dst is src2, else it is src1, i.e., the non-smi. 2386257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 2387257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2388257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 23893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockSmiIndex MacroAssembler::SmiToIndex(Register dst, 23903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Register src, 23913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block int shift) { 2392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 2393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_uint6(shift)); 2394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // There is a possible optimization if shift is in the range 60-63, but that 2395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // will (and must) never happen. 2396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!dst.is(src)) { 2397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 2398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (shift < kSmiShift) { 2400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sarp(dst, Immediate(kSmiShift - shift)); 2401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlp(dst, Immediate(shift - kSmiShift)); 2403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return SmiIndex(dst, times_1); 24053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 2406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 2407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(shift >= times_1 && shift <= (static_cast<int>(times_8) + 1)); 2408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!dst.is(src)) { 2409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 2410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We have to sign extend the index register to 64-bit as the SMI might 2412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // be negative. 2413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movsxlq(dst, dst); 2414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (shift == times_1) { 2415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sarq(dst, Immediate(kSmiShift)); 2416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return SmiIndex(dst, times_1); 2417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return SmiIndex(dst, static_cast<ScaleFactor>(shift - 1)); 24193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 2420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockSmiIndex MacroAssembler::SmiToNegativeIndex(Register dst, 2424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register src, 2425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int shift) { 2426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 2427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Register src holds a positive smi. 2428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_uint6(shift)); 2429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!dst.is(src)) { 2430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 2431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch negp(dst); 2433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (shift < kSmiShift) { 2434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sarp(dst, Immediate(kSmiShift - shift)); 2435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlp(dst, Immediate(shift - kSmiShift)); 2437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return SmiIndex(dst, times_1); 24393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 2440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 2441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(shift >= times_1 && shift <= (static_cast<int>(times_8) + 1)); 2442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!dst.is(src)) { 2443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 2444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch negq(dst); 2446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (shift == times_1) { 2447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sarq(dst, Immediate(kSmiShift)); 2448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return SmiIndex(dst, times_1); 2449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return SmiIndex(dst, static_cast<ScaleFactor>(shift - 1)); 24513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 2452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 245544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid MacroAssembler::AddSmiField(Register dst, const Operand& src) { 2456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 2457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(0, kSmiShift % kBitsPerByte); 2458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addl(dst, Operand(src, kSmiShift / kBitsPerByte)); 2459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 2461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(kScratchRegister, src); 2462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addl(dst, kScratchRegister); 2463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Push(Smi* source) { 2468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch intptr_t smi = reinterpret_cast<intptr_t>(source); 2469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (is_int32(smi)) { 2470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(Immediate(static_cast<int32_t>(smi))); 247162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return; 2472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 247362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int first_byte_set = base::bits::CountTrailingZeros64(smi) / 8; 247462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int last_byte_set = (63 - base::bits::CountLeadingZeros64(smi)) / 8; 247562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (first_byte_set == last_byte_set && kPointerSize == kInt64Size) { 247662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // This sequence has only 7 bytes, compared to the 12 bytes below. 247762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Push(Immediate(0)); 247862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch movb(Operand(rsp, first_byte_set), 247962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Immediate(static_cast<int8_t>(smi >> (8 * first_byte_set)))); 248062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return; 248162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 248262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Register constant = GetSmiConstant(source); 248362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Push(constant); 2484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::PushRegisterAsTwoSmis(Register src, Register scratch) { 2488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src.is(scratch)); 2489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch, src); 2490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // High bits. 2491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shrp(src, Immediate(kPointerSize * kBitsPerByte - kSmiShift)); 2492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlp(src, Immediate(kSmiShift)); 2493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(src); 2494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Low bits. 2495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlp(scratch, Immediate(kSmiShift)); 2496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(scratch); 2497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::PopRegisterAsTwoSmis(Register dst, Register scratch) { 2501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dst.is(scratch)); 2502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(scratch); 2503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Low bits. 2504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shrp(scratch, Immediate(kSmiShift)); 2505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(dst); 2506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shrp(dst, Immediate(kSmiShift)); 2507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // High bits. 2508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlp(dst, Immediate(kPointerSize * kBitsPerByte - kSmiShift)); 2509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch orp(dst, scratch); 2510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Test(const Operand& src, Smi* source) { 2514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (SmiValuesAre32Bits()) { 2515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testl(Operand(src, kIntSize), Immediate(source->value())); 2516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SmiValuesAre31Bits()); 2518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testl(src, Immediate(source)); 2519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ---------------------------------------------------------------------------- 2524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2526257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::JumpIfNotString(Register object, 2527257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register object_map, 2528257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* not_string, 2529257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 2530257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Condition is_smi = CheckSmi(object); 2531257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(is_smi, not_string, near_jump); 2532257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CmpObjectType(object, FIRST_NONSTRING_TYPE, object_map); 2533257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(above_equal, not_string, near_jump); 2534257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 2535257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2536257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::JumpIfNotBothSequentialOneByteStrings( 2538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register first_object, Register second_object, Register scratch1, 2539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch2, Label* on_fail, Label::Distance near_jump) { 2540257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Check that both objects are not smis. 2541257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Condition either_smi = CheckEitherSmi(first_object, second_object); 2542257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(either_smi, on_fail, near_jump); 2543257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2544257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Load instance type for both strings. 2545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch1, FieldOperand(first_object, HeapObject::kMapOffset)); 2546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch2, FieldOperand(second_object, HeapObject::kMapOffset)); 2547257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch movzxbl(scratch1, FieldOperand(scratch1, Map::kInstanceTypeOffset)); 2548257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch movzxbl(scratch2, FieldOperand(scratch2, Map::kInstanceTypeOffset)); 2549257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check that both are flat one-byte strings. 2551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(kNotStringTag != 0); 2552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int kFlatOneByteStringMask = 2553257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask; 2554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int kFlatOneByteStringTag = 2555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kStringTag | kOneByteStringTag | kSeqStringTag; 2556257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andl(scratch1, Immediate(kFlatOneByteStringMask)); 2558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andl(scratch2, Immediate(kFlatOneByteStringMask)); 2559257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Interleave the bits to check both scratch1 and scratch2 in one test. 256062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch const int kShift = 8; 256162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_EQ(0, kFlatOneByteStringMask & (kFlatOneByteStringMask << kShift)); 256262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch shlp(scratch2, Immediate(kShift)); 256362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch orp(scratch1, scratch2); 2564257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch cmpl(scratch1, 256562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Immediate(kFlatOneByteStringTag + (kFlatOneByteStringTag << kShift))); 2566257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_equal, on_fail, near_jump); 2567257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 2568257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialOneByte( 2570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register first_object_instance_type, Register second_object_instance_type, 2571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, Register scratch2, Label* on_fail, 2572257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump) { 2573257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Load instance type for both strings. 2574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch1, first_object_instance_type); 2575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch2, second_object_instance_type); 2576257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check that both are flat one-byte strings. 2578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(kNotStringTag != 0); 2579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int kFlatOneByteStringMask = 2580257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask; 2581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int kFlatOneByteStringTag = 2582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kStringTag | kOneByteStringTag | kSeqStringTag; 2583257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andl(scratch1, Immediate(kFlatOneByteStringMask)); 2585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andl(scratch2, Immediate(kFlatOneByteStringMask)); 2586257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Interleave the bits to check both scratch1 and scratch2 in one test. 2587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(0, kFlatOneByteStringMask & (kFlatOneByteStringMask << 3)); 2588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(scratch1, Operand(scratch1, scratch2, times_8, 0)); 2589257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch cmpl(scratch1, 2590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Immediate(kFlatOneByteStringTag + (kFlatOneByteStringTag << 3))); 2591257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(not_equal, on_fail, near_jump); 2592257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 2593257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2594257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 2595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<class T> 2596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void JumpIfNotUniqueNameHelper(MacroAssembler* masm, 2597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch T operand_or_register, 2598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* not_unique_name, 2599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::Distance distance) { 2600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0); 2601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label succeed; 2602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->testb(operand_or_register, 2603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Immediate(kIsNotStringMask | kIsNotInternalizedMask)); 2604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->j(zero, &succeed, Label::kNear); 2605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->cmpb(operand_or_register, Immediate(static_cast<uint8_t>(SYMBOL_TYPE))); 2606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->j(not_equal, not_unique_name, distance); 2607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->bind(&succeed); 2609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::JumpIfNotUniqueNameInstanceType(Operand operand, 2613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* not_unique_name, 2614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::Distance distance) { 2615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JumpIfNotUniqueNameHelper<Operand>(this, operand, not_unique_name, distance); 2616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::JumpIfNotUniqueNameInstanceType(Register reg, 2620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* not_unique_name, 2621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label::Distance distance) { 2622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JumpIfNotUniqueNameHelper<Register>(this, reg, not_unique_name, distance); 2623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 262544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 26260d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid MacroAssembler::Move(Register dst, Register src) { 26270d5e116f6aee03185f237311a943491bb079a768Kristian Monsen if (!dst.is(src)) { 2628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, src); 26296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 26306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 26316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 26326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Move(Register dst, Handle<Object> source) { 2634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllowDeferredHandleDereference smi_check; 2635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (source->IsSmi()) { 26363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Move(dst, Smi::cast(*source)); 2637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MoveHeapObject(dst, source); 2639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Move(const Operand& dst, Handle<Object> source) { 2644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllowDeferredHandleDereference smi_check; 2645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (source->IsSmi()) { 26463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Move(dst, Smi::cast(*source)); 2647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MoveHeapObject(kScratchRegister, source); 2649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, kScratchRegister); 2650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2654958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid MacroAssembler::Move(XMMRegister dst, uint32_t src) { 2655958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (src == 0) { 2656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Xorpd(dst, dst); 2657958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 2658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch unsigned pop = base::bits::CountPopulation32(src); 2659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_NE(0u, pop); 2660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (pop == 32) { 2661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pcmpeqd(dst, dst); 2662958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 2663958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier movl(kScratchRegister, Immediate(src)); 2664014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movq(dst, kScratchRegister); 2665958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2666958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2667958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2668958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2669958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2670958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid MacroAssembler::Move(XMMRegister dst, uint64_t src) { 2671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (src == 0) { 2672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Xorpd(dst, dst); 2673958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 2674958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier unsigned nlz = base::bits::CountLeadingZeros64(src); 2675958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier unsigned ntz = base::bits::CountTrailingZeros64(src); 2676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch unsigned pop = base::bits::CountPopulation64(src); 2677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_NE(0u, pop); 2678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (pop == 64) { 2679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pcmpeqd(dst, dst); 2680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (pop + ntz == 64) { 2681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pcmpeqd(dst, dst); 2682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Psllq(dst, ntz); 2683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (pop + nlz == 64) { 2684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pcmpeqd(dst, dst); 2685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Psrlq(dst, nlz); 2686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t lower = static_cast<uint32_t>(src); 2688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t upper = static_cast<uint32_t>(src >> 32); 2689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (upper == 0) { 2690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Move(dst, lower); 2691958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 2692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movq(kScratchRegister, src); 2693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movq(dst, kScratchRegister); 2694958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2695958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2696958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 2697958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2698958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2699958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movaps(XMMRegister dst, XMMRegister src) { 2701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovaps(dst, src); 27043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 2705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movaps(dst, src); 27063ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 2707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2709f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::Movups(XMMRegister dst, XMMRegister src) { 2710f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (CpuFeatures::IsSupported(AVX)) { 2711f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CpuFeatureScope scope(this, AVX); 2712f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch vmovups(dst, src); 2713f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 2714f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch movups(dst, src); 2715f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2716f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 2717f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2718f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::Movups(XMMRegister dst, const Operand& src) { 2719f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (CpuFeatures::IsSupported(AVX)) { 2720f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CpuFeatureScope scope(this, AVX); 2721f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch vmovups(dst, src); 2722f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 2723f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch movups(dst, src); 2724f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2725f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 2726f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2727f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::Movups(const Operand& dst, XMMRegister src) { 2728f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (CpuFeatures::IsSupported(AVX)) { 2729f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CpuFeatureScope scope(this, AVX); 2730f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch vmovups(dst, src); 2731f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 2732f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch movups(dst, src); 2733f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2734f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 2735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movapd(XMMRegister dst, XMMRegister src) { 2737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovapd(dst, src); 2740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2741014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movapd(dst, src); 2742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2745f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::Movupd(XMMRegister dst, const Operand& src) { 2746f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (CpuFeatures::IsSupported(AVX)) { 2747f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CpuFeatureScope scope(this, AVX); 2748f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch vmovupd(dst, src); 2749f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 2750f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch movupd(dst, src); 2751f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2752f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 2753f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2754f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::Movupd(const Operand& dst, XMMRegister src) { 2755f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (CpuFeatures::IsSupported(AVX)) { 2756f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CpuFeatureScope scope(this, AVX); 2757f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch vmovupd(dst, src); 2758f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 2759f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch movupd(dst, src); 2760f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2761f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 2762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movsd(XMMRegister dst, XMMRegister src) { 2764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovsd(dst, dst, src); 2767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 2768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movsd(dst, src); 2769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 2770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2773014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movsd(XMMRegister dst, const Operand& src) { 2774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovsd(dst, src); 27773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 2778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movsd(dst, src); 27793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 27803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 27813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 27823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movsd(const Operand& dst, XMMRegister src) { 2784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovsd(dst, src); 27873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 2788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movsd(dst, src); 27893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 27903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 27913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 27923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movss(XMMRegister dst, XMMRegister src) { 2794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovss(dst, dst, src); 2797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movss(dst, src); 2799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2800958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2801958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2802958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movss(XMMRegister dst, const Operand& src) { 2804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovss(dst, src); 2807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movss(dst, src); 2809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2810958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2811958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2812958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movss(const Operand& dst, XMMRegister src) { 2814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovss(dst, src); 2817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movss(dst, src); 2819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movd(XMMRegister dst, Register src) { 2824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovd(dst, src); 2827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movd(dst, src); 2829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movd(XMMRegister dst, const Operand& src) { 2834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovd(dst, src); 28373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 2838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movd(dst, src); 28393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 28403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 28413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 28423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movd(Register dst, XMMRegister src) { 2844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovd(dst, src); 28473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } else { 2848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movd(dst, src); 28493ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block } 28503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 28513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 28523ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 2853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movq(XMMRegister dst, Register src) { 2854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovq(dst, src); 2857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movq(dst, src); 2859e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 2860e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 2861e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2862e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 2863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movq(Register dst, XMMRegister src) { 2864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovq(dst, src); 2867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movq(dst, src); 2869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2872f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::Movmskps(Register dst, XMMRegister src) { 2873f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (CpuFeatures::IsSupported(AVX)) { 2874f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CpuFeatureScope scope(this, AVX); 2875f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch vmovmskps(dst, src); 2876f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 2877f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch movmskps(dst, src); 2878f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2879f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 2880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movmskpd(Register dst, XMMRegister src) { 2882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vmovmskpd(dst, src); 2885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movmskpd(dst, src); 2887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2890f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::Xorps(XMMRegister dst, XMMRegister src) { 2891f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (CpuFeatures::IsSupported(AVX)) { 2892f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CpuFeatureScope scope(this, AVX); 2893f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch vxorps(dst, dst, src); 2894f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 2895f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch xorps(dst, src); 2896f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2897f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 2898f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2899f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::Xorps(XMMRegister dst, const Operand& src) { 2900f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (CpuFeatures::IsSupported(AVX)) { 2901f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch CpuFeatureScope scope(this, AVX); 2902f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch vxorps(dst, dst, src); 2903f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 2904f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch xorps(dst, src); 2905f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 2906f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 2907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Roundss(XMMRegister dst, XMMRegister src, 2909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RoundingMode mode) { 2910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vroundss(dst, dst, src, mode); 2913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch roundss(dst, src, mode); 2915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 2917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Roundsd(XMMRegister dst, XMMRegister src, 2920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RoundingMode mode) { 2921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vroundsd(dst, dst, src, mode); 2924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch roundsd(dst, src, mode); 2926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Sqrtsd(XMMRegister dst, XMMRegister src) { 2931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsqrtsd(dst, dst, src); 2934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch sqrtsd(dst, src); 2936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Sqrtsd(XMMRegister dst, const Operand& src) { 2941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vsqrtsd(dst, dst, src); 2944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch sqrtsd(dst, src); 2946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Ucomiss(XMMRegister src1, XMMRegister src2) { 2951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vucomiss(src1, src2); 2954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ucomiss(src1, src2); 2956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Ucomiss(XMMRegister src1, const Operand& src2) { 2961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vucomiss(src1, src2); 2964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ucomiss(src1, src2); 2966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Ucomisd(XMMRegister src1, XMMRegister src2) { 2971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vucomisd(src1, src2); 2974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ucomisd(src1, src2); 2976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Ucomisd(XMMRegister src1, const Operand& src2) { 2981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(AVX)) { 2982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, AVX); 2983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vucomisd(src1, src2); 2984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 2985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ucomisd(src1, src2); 2986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 2987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 2988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 2989f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ---------------------------------------------------------------------------- 2990f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2991f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::Absps(XMMRegister dst) { 2992f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Andps(dst, 2993f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ExternalOperand(ExternalReference::address_of_float_abs_constant())); 2994f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 2995f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 2996f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::Negps(XMMRegister dst) { 2997f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Xorps(dst, 2998f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ExternalOperand(ExternalReference::address_of_float_neg_constant())); 2999f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 3000f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 3001f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::Abspd(XMMRegister dst) { 3002f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Andps(dst, 3003f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ExternalOperand(ExternalReference::address_of_double_abs_constant())); 3004f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 3005f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 3006f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::Negpd(XMMRegister dst) { 3007f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Xorps(dst, 3008f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ExternalOperand(ExternalReference::address_of_double_neg_constant())); 3009f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 3010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cmp(Register dst, Handle<Object> source) { 3012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AllowDeferredHandleDereference smi_check; 3013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (source->IsSmi()) { 3014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cmp(dst, Smi::cast(*source)); 3015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MoveHeapObject(kScratchRegister, source); 3017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cmpp(dst, kScratchRegister); 3018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cmp(const Operand& dst, Handle<Object> source) { 3023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AllowDeferredHandleDereference smi_check; 3024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (source->IsSmi()) { 3025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cmp(dst, Smi::cast(*source)); 3026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MoveHeapObject(kScratchRegister, source); 3028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cmpp(dst, kScratchRegister); 3029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Push(Handle<Object> source) { 3034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AllowDeferredHandleDereference smi_check; 3035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (source->IsSmi()) { 3036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(Smi::cast(*source)); 3037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MoveHeapObject(kScratchRegister, source); 3039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(kScratchRegister); 3040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::MoveHeapObject(Register result, 3045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> object) { 3046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(object->IsHeapObject()); 3047f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Move(result, object, RelocInfo::EMBEDDED_OBJECT); 3048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::LoadGlobalCell(Register dst, Handle<Cell> cell) { 3052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (dst.is(rax)) { 3053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AllowDeferredHandleDereference embedding_raw_address; 3054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch load_rax(cell.location(), RelocInfo::CELL); 3055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Move(dst, cell, RelocInfo::CELL); 3057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(dst, Operand(dst, 0)); 3058014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::CmpWeakValue(Register value, Handle<WeakCell> cell, 3063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register scratch) { 3064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Move(scratch, cell, RelocInfo::EMBEDDED_OBJECT); 3065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cmpp(value, FieldOperand(scratch, WeakCell::kValueOffset)); 3066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::GetWeakValue(Register value, Handle<WeakCell> cell) { 3070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Move(value, cell, RelocInfo::EMBEDDED_OBJECT); 3071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(value, FieldOperand(value, WeakCell::kValueOffset)); 3072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::LoadWeakValue(Register value, Handle<WeakCell> cell, 3076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label* miss) { 3077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GetWeakValue(value, cell); 3078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JumpIfSmi(value, miss); 3079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Drop(int stack_elements) { 3083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (stack_elements > 0) { 3084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch addp(rsp, Immediate(stack_elements * kPointerSize)); 3085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::DropUnderReturnAddress(int stack_elements, 3090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register scratch) { 3091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(stack_elements > 0); 3092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize == kInt64Size && stack_elements == 1) { 3093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch popq(MemOperand(rsp, 0)); 3094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PopReturnAddressTo(scratch); 3098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Drop(stack_elements); 3099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PushReturnAddressFrom(scratch); 3100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Push(Register src) { 3104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize == kInt64Size) { 3105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pushq(src); 3106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // x32 uses 64-bit push for rbp in the prologue. 3108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(src.code() != rbp.code()); 3109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch leal(rsp, Operand(rsp, -4)); 3110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(Operand(rsp, 0), src); 3111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Push(const Operand& src) { 3116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize == kInt64Size) { 3117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pushq(src); 3118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(kScratchRegister, src); 3120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch leal(rsp, Operand(rsp, -4)); 3121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(Operand(rsp, 0), kScratchRegister); 3122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::PushQuad(const Operand& src) { 3127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize == kInt64Size) { 3128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pushq(src); 3129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(kScratchRegister, src); 3131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pushq(kScratchRegister); 3132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Push(Immediate value) { 3137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize == kInt64Size) { 3138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pushq(value); 3139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch leal(rsp, Operand(rsp, -4)); 3141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(Operand(rsp, 0), value); 3142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::PushImm32(int32_t imm32) { 3147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize == kInt64Size) { 3148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pushq_imm32(imm32); 3149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch leal(rsp, Operand(rsp, -4)); 3151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(Operand(rsp, 0), Immediate(imm32)); 3152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Pop(Register dst) { 3157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize == kInt64Size) { 3158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch popq(dst); 3159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // x32 uses 64-bit pop for rbp in the epilogue. 3161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(dst.code() != rbp.code()); 3162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(dst, Operand(rsp, 0)); 3163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch leal(rsp, Operand(rsp, 4)); 3164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Pop(const Operand& dst) { 3169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize == kInt64Size) { 3170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch popq(dst); 3171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register scratch = dst.AddressUsesRegister(kScratchRegister) 3173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? kRootRegister : kScratchRegister; 3174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(scratch, Operand(rsp, 0)); 3175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(dst, scratch); 3176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch leal(rsp, Operand(rsp, 4)); 3177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (scratch.is(kRootRegister)) { 3178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Restore kRootRegister. 3179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InitializeRootRegister(); 3180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::PopQuad(const Operand& dst) { 3186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (kPointerSize == kInt64Size) { 3187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch popq(dst); 3188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch popq(kScratchRegister); 3190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, kScratchRegister); 3191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::LoadSharedFunctionInfoSpecialField(Register dst, 3196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register base, 3197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int offset) { 3198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(offset > SharedFunctionInfo::kLengthOffset && 3199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch offset <= SharedFunctionInfo::kSize && 3200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (((offset - SharedFunctionInfo::kLengthOffset) / kIntSize) % 2 == 1)); 3201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (kPointerSize == kInt64Size) { 3202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movsxlq(dst, FieldOperand(base, offset)); 3203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, FieldOperand(base, offset)); 3205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(dst, dst); 3206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::TestBitSharedFunctionInfoSpecialField(Register base, 3211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int offset, 3212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int bits) { 3213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(offset > SharedFunctionInfo::kLengthOffset && 3214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch offset <= SharedFunctionInfo::kSize && 3215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (((offset - SharedFunctionInfo::kLengthOffset) / kIntSize) % 2 == 1)); 3216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (kPointerSize == kInt32Size) { 3217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // On x32, this field is represented by SMI. 3218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bits += kSmiShift; 3219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 32203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int byte_offset = bits / kBitsPerByte; 32213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int bit_in_byte = bits & (kBitsPerByte - 1); 3222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testb(FieldOperand(base, offset + byte_offset), Immediate(1 << bit_in_byte)); 32233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 32243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 32253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Jump(ExternalReference ext) { 322744f0eee88ff00398ff7f715fab053374d808c90dSteve Block LoadAddress(kScratchRegister, ext); 3228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block jmp(kScratchRegister); 3229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Jump(const Operand& op) { 3233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (kPointerSize == kInt64Size) { 3234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jmp(op); 3235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, op); 3237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jmp(kScratchRegister); 3238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Jump(Address destination, RelocInfo::Mode rmode) { 3243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(kScratchRegister, destination, rmode); 3244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block jmp(kScratchRegister); 3245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Jump(Handle<Code> code_object, RelocInfo::Mode rmode) { 32493ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // TODO(X64): Inline this 32503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block jmp(code_object, rmode); 3251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 325444f0eee88ff00398ff7f715fab053374d808c90dSteve Blockint MacroAssembler::CallSize(ExternalReference ext) { 325544f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Opcode for call kScratchRegister is: Rex.B FF D4 (three bytes). 3256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return LoadAddressSize(ext) + 3257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assembler::kCallScratchRegisterInstructionLength; 325844f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 325944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 326044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 3261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Call(ExternalReference ext) { 326244f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG 326344f0eee88ff00398ff7f715fab053374d808c90dSteve Block int end_position = pc_offset() + CallSize(ext); 326444f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 326544f0eee88ff00398ff7f715fab053374d808c90dSteve Block LoadAddress(kScratchRegister, ext); 3266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block call(kScratchRegister); 326744f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG 326844f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(end_position, pc_offset()); 326944f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 3270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Call(const Operand& op) { 3274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (kPointerSize == kInt64Size && !CpuFeatures::IsSupported(ATOM)) { 3275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch call(op); 3276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, op); 3278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch call(kScratchRegister); 3279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Call(Address destination, RelocInfo::Mode rmode) { 328444f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG 3285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int end_position = pc_offset() + CallSize(destination); 328644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 3287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(kScratchRegister, destination, rmode); 3288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block call(kScratchRegister); 328944f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG 329044f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(pc_offset(), end_position); 329144f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 3292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3295257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::Call(Handle<Code> code_object, 3296257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch RelocInfo::Mode rmode, 3297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TypeFeedbackId ast_id) { 329844f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG 329944f0eee88ff00398ff7f715fab053374d808c90dSteve Block int end_position = pc_offset() + CallSize(code_object); 330044f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 3301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(RelocInfo::IsCodeTarget(rmode) || 3302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch rmode == RelocInfo::CODE_AGE_SEQUENCE); 3303257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch call(code_object, rmode, ast_id); 330444f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG 330544f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(end_position, pc_offset()); 330644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 3307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Pextrd(Register dst, XMMRegister src, int8_t imm8) { 3311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (imm8 == 0) { 3312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movd(dst, src); 3313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(SSE4_1)) { 3316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope sse_scope(this, SSE4_1); 3317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pextrd(dst, src, imm8); 3318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3320f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK_EQ(1, imm8); 3321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movq(dst, src); 3322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch shrq(dst, Immediate(32)); 3323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Pinsrd(XMMRegister dst, Register src, int8_t imm8) { 3327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(SSE4_1)) { 3328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope sse_scope(this, SSE4_1); 3329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pinsrd(dst, src, imm8); 3330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 333213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Movd(kScratchDoubleReg, src); 3333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (imm8 == 1) { 333413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch punpckldq(dst, kScratchDoubleReg); 3335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(0, imm8); 333713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Movss(dst, kScratchDoubleReg); 3338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Pinsrd(XMMRegister dst, const Operand& src, int8_t imm8) { 3343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(imm8 == 0 || imm8 == 1); 3344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(SSE4_1)) { 3345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope sse_scope(this, SSE4_1); 3346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch pinsrd(dst, src, imm8); 3347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 334913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Movd(kScratchDoubleReg, src); 3350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (imm8 == 1) { 335113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch punpckldq(dst, kScratchDoubleReg); 3352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 3353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(0, imm8); 335413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Movss(dst, kScratchDoubleReg); 3355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Lzcntl(Register dst, Register src) { 3360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(LZCNT)) { 3361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, LZCNT); 3362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch lzcntl(dst, src); 3363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label not_zero_src; 3366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bsrl(dst, src); 3367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(not_zero, ¬_zero_src, Label::kNear); 3368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(dst, 63); // 63^31 == 32 3369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(¬_zero_src); 3370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch xorl(dst, Immediate(31)); // for x in [0..31], 31^x == 31 - x 3371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Lzcntl(Register dst, const Operand& src) { 3375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(LZCNT)) { 3376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, LZCNT); 3377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch lzcntl(dst, src); 3378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label not_zero_src; 3381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bsrl(dst, src); 3382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(not_zero, ¬_zero_src, Label::kNear); 3383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(dst, 63); // 63^31 == 32 3384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(¬_zero_src); 3385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch xorl(dst, Immediate(31)); // for x in [0..31], 31^x == 31 - x 3386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Lzcntq(Register dst, Register src) { 3390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(LZCNT)) { 3391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, LZCNT); 3392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch lzcntq(dst, src); 3393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label not_zero_src; 3396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bsrq(dst, src); 3397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(not_zero, ¬_zero_src, Label::kNear); 3398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(dst, 127); // 127^63 == 64 3399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(¬_zero_src); 3400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch xorl(dst, Immediate(63)); // for x in [0..63], 63^x == 63 - x 3401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Lzcntq(Register dst, const Operand& src) { 3405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(LZCNT)) { 3406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, LZCNT); 3407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch lzcntq(dst, src); 3408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label not_zero_src; 3411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bsrq(dst, src); 3412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(not_zero, ¬_zero_src, Label::kNear); 3413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(dst, 127); // 127^63 == 64 3414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(¬_zero_src); 3415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch xorl(dst, Immediate(63)); // for x in [0..63], 63^x == 63 - x 3416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Tzcntq(Register dst, Register src) { 3420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(BMI1)) { 3421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, BMI1); 3422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch tzcntq(dst, src); 3423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label not_zero_src; 3426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bsfq(dst, src); 3427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(not_zero, ¬_zero_src, Label::kNear); 3428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Define the result of tzcnt(0) separately, because bsf(0) is undefined. 3429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(dst, 64); 3430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(¬_zero_src); 3431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Tzcntq(Register dst, const Operand& src) { 3435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(BMI1)) { 3436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, BMI1); 3437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch tzcntq(dst, src); 3438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label not_zero_src; 3441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bsfq(dst, src); 3442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(not_zero, ¬_zero_src, Label::kNear); 3443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Define the result of tzcnt(0) separately, because bsf(0) is undefined. 3444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(dst, 64); 3445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(¬_zero_src); 3446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Tzcntl(Register dst, Register src) { 3450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(BMI1)) { 3451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, BMI1); 3452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch tzcntl(dst, src); 3453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label not_zero_src; 3456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bsfl(dst, src); 3457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(not_zero, ¬_zero_src, Label::kNear); 3458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(dst, 32); // The result of tzcnt is 32 if src = 0. 3459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(¬_zero_src); 3460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Tzcntl(Register dst, const Operand& src) { 3464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(BMI1)) { 3465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, BMI1); 3466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch tzcntl(dst, src); 3467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label not_zero_src; 3470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bsfl(dst, src); 3471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(not_zero, ¬_zero_src, Label::kNear); 3472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(dst, 32); // The result of tzcnt is 32 if src = 0. 3473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(¬_zero_src); 3474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Popcntl(Register dst, Register src) { 3478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(POPCNT)) { 3479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, POPCNT); 3480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch popcntl(dst, src); 3481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 3484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Popcntl(Register dst, const Operand& src) { 3488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(POPCNT)) { 3489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, POPCNT); 3490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch popcntl(dst, src); 3491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 3494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Popcntq(Register dst, Register src) { 3498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(POPCNT)) { 3499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, POPCNT); 3500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch popcntq(dst, src); 3501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 3504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Popcntq(Register dst, const Operand& src) { 3508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (CpuFeatures::IsSupported(POPCNT)) { 3509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CpuFeatureScope scope(this, POPCNT); 3510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch popcntq(dst, src); 3511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 3512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 3514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 35171e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::Pushad() { 3518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(rax); 3519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(rcx); 3520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(rdx); 3521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(rbx); 35221e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Not pushing rsp or rbp. 3523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(rsi); 3524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(rdi); 3525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(r8); 3526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(r9); 35271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // r10 is kScratchRegister. 3528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(r11); 3529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(r12); 35301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // r13 is kRootRegister. 3531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(r14); 3532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(r15); 3533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STATIC_ASSERT(12 == kNumSafepointSavedRegisters); 3534e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Use lea for symmetry with Popad. 3535e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int sp_delta = 3536e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch (kNumSafepointRegisters - kNumSafepointSavedRegisters) * kPointerSize; 3537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(rsp, Operand(rsp, -sp_delta)); 35381e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 35391e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 35401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 35411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::Popad() { 3542e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Popad must not change the flags, so use lea instead of addq. 3543e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch int sp_delta = 3544e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch (kNumSafepointRegisters - kNumSafepointSavedRegisters) * kPointerSize; 3545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(rsp, Operand(rsp, sp_delta)); 3546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(r15); 3547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(r14); 3548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pop(r12); 3549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(r11); 3550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(r9); 3551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(r8); 3552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(rdi); 3553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(rsi); 3554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(rbx); 3555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(rdx); 3556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(rcx); 3557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(rax); 35581e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 35591e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 35601e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 35611e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::Dropad() { 3562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(rsp, Immediate(kNumSafepointRegisters * kPointerSize)); 35631e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 35641e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 35651e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 35661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// Order general registers are pushed by Pushad: 356744f0eee88ff00398ff7f715fab053374d808c90dSteve Block// rax, rcx, rdx, rbx, rsi, rdi, r8, r9, r11, r14, r15. 35683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int 35693ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochMacroAssembler::kSafepointPushRegisterIndices[Register::kNumRegisters] = { 35701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 0, 35711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 1, 35721e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 2, 35731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 3, 35741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block -1, 35751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block -1, 35761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 4, 35771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 5, 35781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 6, 35791e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 7, 35801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block -1, 35811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 8, 358244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 9, 3583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch -1, 3584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 10, 3585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 11 35861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}; 35871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 35881e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 3589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::StoreToSafepointRegisterSlot(Register dst, 3590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Immediate& imm) { 3591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(SafepointRegisterSlot(dst), imm); 3592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3595e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochvoid MacroAssembler::StoreToSafepointRegisterSlot(Register dst, Register src) { 3596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(SafepointRegisterSlot(dst), src); 3597e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 3598e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3599e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3600e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochvoid MacroAssembler::LoadFromSafepointRegisterSlot(Register dst, Register src) { 3601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, SafepointRegisterSlot(src)); 3602e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 3603e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3604e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3605e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochOperand MacroAssembler::SafepointRegisterSlot(Register reg) { 3606e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return Operand(rsp, SafepointRegisterStackIndex(reg.code()) * kPointerSize); 3607e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 3608e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3609e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::PushStackHandler() { 3611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Adjust this code if not the case. 3612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STATIC_ASSERT(StackHandlerConstants::kSize == 1 * kPointerSize); 36133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); 36143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Link the current handler as the next handler. 36163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); 3617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(ExternalOperand(handler_address)); 3618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 36193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Set this new handler as the current one. 3620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(ExternalOperand(handler_address), rsp); 3621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::PopStackHandler() { 36253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); 36263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ExternalReference handler_address(Isolate::kHandlerAddress, isolate()); 3627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(ExternalOperand(handler_address)); 3628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize)); 3629e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 3630e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 3631e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 3632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Ret() { 3633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ret(0); 3634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 36371e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::Ret(int bytes_dropped, Register scratch) { 36381e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (is_uint16(bytes_dropped)) { 36391e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block ret(bytes_dropped); 36401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } else { 3641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PopReturnAddressTo(scratch); 3642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(rsp, Immediate(bytes_dropped)); 3643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushReturnAddressFrom(scratch); 36441e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block ret(0); 36451e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 36461e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 36471e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 36481e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 3649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::FCmp() { 36503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block fucomip(); 36518defd9ff6930b4e24729971a61cf7469daf119beSteve Block fstp(0); 3652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::CmpObjectType(Register heap_object, 3656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InstanceType type, 3657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register map) { 3658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(map, FieldOperand(heap_object, HeapObject::kMapOffset)); 3659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CmpInstanceType(map, type); 3660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::CmpInstanceType(Register map, InstanceType type) { 3664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block cmpb(FieldOperand(map, Map::kInstanceTypeOffset), 3665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Immediate(static_cast<int8_t>(type))); 3666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 3667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::CompareMap(Register obj, Handle<Map> map) { 36693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Cmp(FieldOperand(obj, HeapObject::kMapOffset), map); 36703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 36713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 36733100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid MacroAssembler::CheckMap(Register obj, 36743100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Handle<Map> map, 36753100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu Label* fail, 3676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiCheckType smi_check_type) { 3677257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (smi_check_type == DO_SMI_CHECK) { 36783100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu JumpIfSmi(obj, fail); 36793100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu } 36803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompareMap(obj, map); 36823100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu j(not_equal, fail); 36833100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu} 36843100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 36853100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu 3686257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::ClampUint8(Register reg) { 3687257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label done; 3688257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch testl(reg, Immediate(0xFFFFFF00)); 3689257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(zero, &done, Label::kNear); 3690257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch setcc(negative, reg); // 1 if negative, 0 if positive. 3691257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch decb(reg); // 0 if negative, 255 if positive. 3692257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&done); 3693257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 3694257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3695257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3696257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::ClampDoubleToUint8(XMMRegister input_reg, 3697257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch XMMRegister temp_xmm_reg, 3698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register result_reg) { 3699257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label done; 3700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label conv_failure; 3701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Xorpd(temp_xmm_reg, temp_xmm_reg); 3702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cvtsd2si(result_reg, input_reg); 3703257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch testl(result_reg, Immediate(0xFFFFFF00)); 3704257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(zero, &done, Label::kNear); 3705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpl(result_reg, Immediate(1)); 3706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(overflow, &conv_failure, Label::kNear); 3707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(result_reg, Immediate(0)); 3708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch setcc(sign, result_reg); 3709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subl(result_reg, Immediate(1)); 3710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andl(result_reg, Immediate(255)); 3711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jmp(&done, Label::kNear); 3712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&conv_failure); 3713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Set(result_reg, 0); 3714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Ucomisd(input_reg, temp_xmm_reg); 3715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(below, &done, Label::kNear); 3716257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Set(result_reg, 255); 3717257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&done); 3718257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 3719257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3720257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::LoadUint32(XMMRegister dst, 3722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register src) { 3723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_debug_code) { 3724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpq(src, Immediate(0xffffffff)); 3725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assert(below_equal, kInputGPRIsExpectedToHaveUpper32Cleared); 3726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cvtqsi2sd(dst, src); 3728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::SlowTruncateToI(Register result_reg, 3732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register input_reg, 3733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int offset) { 3734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DoubleToIStub stub(isolate(), input_reg, result_reg, offset, true); 3735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch call(stub.GetCode(), RelocInfo::CODE_TARGET); 3736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::TruncateHeapNumberToI(Register result_reg, 3740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register input_reg) { 3741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done; 374213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Movsd(kScratchDoubleReg, FieldOperand(input_reg, HeapNumber::kValueOffset)); 374313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Cvttsd2siq(result_reg, kScratchDoubleReg); 3744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpq(result_reg, Immediate(1)); 3745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(no_overflow, &done, Label::kNear); 3746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Slow case. 3748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (input_reg.is(result_reg)) { 3749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(rsp, Immediate(kDoubleSize)); 375013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Movsd(MemOperand(rsp, 0), kScratchDoubleReg); 3751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SlowTruncateToI(result_reg, rsp, 0); 3752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(rsp, Immediate(kDoubleSize)); 3753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 3754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SlowTruncateToI(result_reg, input_reg); 3755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&done); 3758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Keep our invariant that the upper 32 bits are zero. 3759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(result_reg, result_reg); 3760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::TruncateDoubleToI(Register result_reg, 3764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch XMMRegister input_reg) { 3765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done; 3766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cvttsd2siq(result_reg, input_reg); 3767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpq(result_reg, Immediate(1)); 3768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(no_overflow, &done, Label::kNear); 3769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(rsp, Immediate(kDoubleSize)); 3771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movsd(MemOperand(rsp, 0), input_reg); 3772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SlowTruncateToI(result_reg, rsp, 0); 3773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(rsp, Immediate(kDoubleSize)); 3774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&done); 3776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Keep our invariant that the upper 32 bits are zero. 3777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(result_reg, result_reg); 3778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::DoubleToI(Register result_reg, XMMRegister input_reg, 3782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch XMMRegister scratch, 3783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MinusZeroMode minus_zero_mode, 3784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* lost_precision, Label* is_nan, 3785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* minus_zero, Label::Distance dst) { 3786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Cvttsd2si(result_reg, input_reg); 378713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Cvtlsi2sd(kScratchDoubleReg, result_reg); 378813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Ucomisd(kScratchDoubleReg, input_reg); 3789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(not_equal, lost_precision, dst); 3790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(parity_even, is_nan, dst); // NaN. 3791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (minus_zero_mode == FAIL_ON_MINUS_ZERO) { 3792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done; 3793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The integer converted back is equal to the original. We 3794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // only have to test if we got -0 as an input. 3795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testl(result_reg, result_reg); 3796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(not_zero, &done, Label::kNear); 3797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movmskpd(result_reg, input_reg); 3798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Bit 0 contains the sign of the double in input_reg. 3799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If input was positive, we are ok and return 0, otherwise 3800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // jump to minus_zero. 3801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andl(result_reg, Immediate(1)); 3802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(not_zero, minus_zero, dst); 3803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&done); 3804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3808257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::LoadInstanceDescriptors(Register map, 3809257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Register descriptors) { 3810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(descriptors, FieldOperand(map, Map::kDescriptorsOffset)); 3811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::NumberOfOwnDescriptors(Register dst, Register map) { 3815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(dst, FieldOperand(map, Map::kBitField3Offset)); 3816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DecodeField<Map::NumberOfOwnDescriptorsBits>(dst); 3817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::EnumLength(Register dst, Register map) { 3821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(Map::EnumLengthBits::kShift == 0); 3822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(dst, FieldOperand(map, Map::kBitField3Offset)); 3823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andl(dst, Immediate(Map::EnumLengthBits::kMask)); 3824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Integer32ToSmi(dst, dst); 3825257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 3826257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3827257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::LoadAccessor(Register dst, Register holder, 3829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int accessor_index, 3830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AccessorComponent accessor) { 3831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(dst, FieldOperand(holder, HeapObject::kMapOffset)); 3832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoadInstanceDescriptors(dst, dst); 3833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(dst, FieldOperand(dst, DescriptorArray::GetValueOffset(accessor_index))); 3834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int offset = accessor == ACCESSOR_GETTER ? AccessorPair::kGetterOffset 3835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : AccessorPair::kSetterOffset; 3836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(dst, FieldOperand(dst, offset)); 3837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3840958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid MacroAssembler::DispatchWeakMap(Register obj, Register scratch1, 3841958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register scratch2, Handle<WeakCell> cell, 3842958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Code> success, 3843958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SmiCheckType smi_check_type) { 3844257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label fail; 3845257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (smi_check_type == DO_SMI_CHECK) { 3846257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch JumpIfSmi(obj, &fail); 3847257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 3848958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier movq(scratch1, FieldOperand(obj, HeapObject::kMapOffset)); 3849958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CmpWeakValue(scratch1, cell, scratch2); 3850257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(equal, success, RelocInfo::CODE_TARGET); 3851257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&fail); 3852257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 3853257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3854257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertNumber(Register object) { 3856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 3857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label ok; 3858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition is_smi = CheckSmi(object); 3859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(is_smi, &ok, Label::kNear); 3860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Cmp(FieldOperand(object, HeapObject::kMapOffset), 3861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch isolate()->factory()->heap_number_map()); 3862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(equal, kOperandIsNotANumber); 3863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&ok); 3864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3865402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu} 3866402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 38673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid MacroAssembler::AssertNotNumber(Register object) { 38683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (emit_debug_code()) { 38693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Condition is_smi = CheckSmi(object); 38703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Check(NegateCondition(is_smi), kOperandIsANumber); 38713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Cmp(FieldOperand(object, HeapObject::kMapOffset), 38723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch isolate()->factory()->heap_number_map()); 38733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Check(not_equal, kOperandIsANumber); 38743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 38753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 3876402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 3877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertNotSmi(Register object) { 3878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 3879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition is_smi = CheckSmi(object); 3880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(NegateCondition(is_smi), kOperandIsASmi); 3881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3882756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick} 3883756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 3884756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 3885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertSmi(Register object) { 3886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 3887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition is_smi = CheckSmi(object); 3888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(is_smi, kOperandIsNotASmi); 3889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 389044f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 389144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 389244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 3893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertSmi(const Operand& object) { 3894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 3895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition is_smi = CheckSmi(object); 3896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(is_smi, kOperandIsNotASmi); 3897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertZeroExtended(Register int32_register) { 3902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 3903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!int32_register.is(kScratchRegister)); 3904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movq(kScratchRegister, V8_INT64_C(0x0000000100000000)); 3905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpq(kScratchRegister, int32_register); 3906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(above_equal, k32BitValueInRegisterIsNotZeroExtended); 3907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertString(Register object) { 3912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 3913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testb(object, Immediate(kSmiTagMask)); 3914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(not_equal, kOperandIsASmiAndNotAString); 3915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(object); 3916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(object, FieldOperand(object, HeapObject::kMapOffset)); 3917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CmpInstanceType(object, FIRST_NONSTRING_TYPE); 3918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(object); 3919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(below, kOperandIsNotAString); 3920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 39216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 39226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 39236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertName(Register object) { 3925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 3926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testb(object, Immediate(kSmiTagMask)); 3927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(not_equal, kOperandIsASmiAndNotAName); 3928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(object); 3929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(object, FieldOperand(object, HeapObject::kMapOffset)); 3930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CmpInstanceType(object, LAST_NAME_TYPE); 3931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(object); 3932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(below_equal, kOperandIsNotAName); 3933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 39343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 39353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 39363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::AssertFunction(Register object) { 3938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (emit_debug_code()) { 3939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch testb(object, Immediate(kSmiTagMask)); 3940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Check(not_equal, kOperandIsASmiAndNotAFunction); 3941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(object); 3942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CmpObjectType(object, JS_FUNCTION_TYPE, object); 3943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pop(object); 3944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Check(equal, kOperandIsNotAFunction); 3945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::AssertBoundFunction(Register object) { 3950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (emit_debug_code()) { 3951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch testb(object, Immediate(kSmiTagMask)); 3952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Check(not_equal, kOperandIsASmiAndNotABoundFunction); 3953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(object); 3954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CmpObjectType(object, JS_BOUND_FUNCTION_TYPE, object); 3955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pop(object); 3956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Check(equal, kOperandIsNotABoundFunction); 3957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 3958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 3959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3960bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid MacroAssembler::AssertGeneratorObject(Register object) { 3961bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (emit_debug_code()) { 3962bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch testb(object, Immediate(kSmiTagMask)); 3963bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Check(not_equal, kOperandIsASmiAndNotAGeneratorObject); 3964bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Push(object); 3965bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch CmpObjectType(object, JS_GENERATOR_OBJECT_TYPE, object); 3966bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Pop(object); 3967bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Check(equal, kOperandIsNotAGeneratorObject); 3968bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 3969bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 3970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 3971109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid MacroAssembler::AssertReceiver(Register object) { 3972109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (emit_debug_code()) { 3973109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch testb(object, Immediate(kSmiTagMask)); 3974109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Check(not_equal, kOperandIsASmiAndNotAReceiver); 3975109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Push(object); 3976109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE); 3977109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CmpObjectType(object, FIRST_JS_RECEIVER_TYPE, object); 3978109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Pop(object); 3979109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Check(above_equal, kOperandIsNotAReceiver); 3980109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 3981109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch} 3982109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 3983109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 3984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertUndefinedOrAllocationSite(Register object) { 3985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 3986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done_checking; 3987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AssertNotSmi(object); 3988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Cmp(object, isolate()->factory()->undefined_value()); 3989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(equal, &done_checking); 3990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Cmp(FieldOperand(object, 0), isolate()->factory()->allocation_site_map()); 3991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Assert(equal, kExpectedUndefinedOrCell); 3992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&done_checking); 3993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 3994e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 3995e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3996e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 3997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertRootValue(Register src, 3998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap::RootListIndex root_value_index, 3999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BailoutReason reason) { 4000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (emit_debug_code()) { 4001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!src.is(kScratchRegister)); 4002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadRoot(kScratchRegister, root_value_index); 4003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(src, kScratchRegister); 4004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(equal, reason); 4005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 40069dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen} 40079dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 40089dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 40099dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 4010d91b9f7d46489a9ee00f9cb415630299c76a502bLeon ClarkeCondition MacroAssembler::IsObjectStringType(Register heap_object, 4011d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Register map, 4012d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Register instance_type) { 4013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(map, FieldOperand(heap_object, HeapObject::kMapOffset)); 40144515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke movzxbl(instance_type, FieldOperand(map, Map::kInstanceTypeOffset)); 401569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch STATIC_ASSERT(kNotStringTag != 0); 4016d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke testb(instance_type, Immediate(kIsNotStringMask)); 4017d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke return zero; 4018d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 4019d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 4020d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 4021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochCondition MacroAssembler::IsObjectNameType(Register heap_object, 4022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register map, 4023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register instance_type) { 4024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(map, FieldOperand(heap_object, HeapObject::kMapOffset)); 4025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movzxbl(instance_type, FieldOperand(map, Map::kInstanceTypeOffset)); 4026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpb(instance_type, Immediate(static_cast<uint8_t>(LAST_NAME_TYPE))); 4027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return below_equal; 4028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::GetMapConstructor(Register result, Register map, 4032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register temp) { 4033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label done, loop; 4034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(result, FieldOperand(map, Map::kConstructorOrBackPointerOffset)); 4035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(&loop); 4036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JumpIfSmi(result, &done, Label::kNear); 4037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CmpObjectType(result, MAP_TYPE, temp); 4038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(not_equal, &done, Label::kNear); 4039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(result, FieldOperand(result, Map::kConstructorOrBackPointerOffset)); 4040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch jmp(&loop); 4041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bind(&done); 4042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 40433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SetCounter(StatsCounter* counter, int value) { 4045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_native_code_counters && counter->Enabled()) { 404644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Operand counter_operand = ExternalOperand(ExternalReference(counter)); 40478b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch movl(counter_operand, Immediate(value)); 4048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::IncrementCounter(StatsCounter* counter, int value) { 4053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(value > 0); 4054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_native_code_counters && counter->Enabled()) { 405544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Operand counter_operand = ExternalOperand(ExternalReference(counter)); 4056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (value == 1) { 405744f0eee88ff00398ff7f715fab053374d808c90dSteve Block incl(counter_operand); 4058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 405944f0eee88ff00398ff7f715fab053374d808c90dSteve Block addl(counter_operand, Immediate(value)); 4060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::DecrementCounter(StatsCounter* counter, int value) { 4066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(value > 0); 4067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_native_code_counters && counter->Enabled()) { 406844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Operand counter_operand = ExternalOperand(ExternalReference(counter)); 4069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (value == 1) { 407044f0eee88ff00398ff7f715fab053374d808c90dSteve Block decl(counter_operand); 4071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 407244f0eee88ff00398ff7f715fab053374d808c90dSteve Block subl(counter_operand, Immediate(value)); 4073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 407762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid MacroAssembler::MaybeDropFrames() { 407862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Check whether we need to drop frames to restart a function on the stack. 407962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ExternalReference restart_fp = 408062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ExternalReference::debug_restart_fp_address(isolate()); 408162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Load(rbx, restart_fp); 408262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch testp(rbx, rbx); 408362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch j(not_zero, isolate()->builtins()->FrameDropperTrampoline(), 408462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch RelocInfo::CODE_TARGET); 4085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 4086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 40873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid MacroAssembler::PrepareForTailCall(const ParameterCount& callee_args_count, 40883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register caller_args_count_reg, 40893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register scratch0, Register scratch1, 40903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ReturnAddressState ra_state) { 40913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#if DEBUG 40923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (callee_args_count.is_reg()) { 40933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(!AreAliased(callee_args_count.reg(), caller_args_count_reg, scratch0, 40943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch scratch1)); 40953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 40963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(!AreAliased(caller_args_count_reg, scratch0, scratch1)); 40973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 40983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#endif 40993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 41003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Calculate the destination address where we will put the return address 41013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // after we drop current frame. 41023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register new_sp_reg = scratch0; 41033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (callee_args_count.is_reg()) { 41043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch subp(caller_args_count_reg, callee_args_count.reg()); 41053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch leap(new_sp_reg, Operand(rbp, caller_args_count_reg, times_pointer_size, 41063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch StandardFrameConstants::kCallerPCOffset)); 41073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 41083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch leap(new_sp_reg, Operand(rbp, caller_args_count_reg, times_pointer_size, 41093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch StandardFrameConstants::kCallerPCOffset - 41103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch callee_args_count.immediate() * kPointerSize)); 41113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 41123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 41133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (FLAG_debug_code) { 41143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cmpp(rsp, new_sp_reg); 41153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Check(below, kStackAccessBelowStackPointer); 41163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 41173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 41183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Copy return address from caller's frame to current frame's return address 41193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // to avoid its trashing and let the following loop copy it to the right 41203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // place. 41213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register tmp_reg = scratch1; 41223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (ra_state == ReturnAddressState::kOnStack) { 41233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch movp(tmp_reg, Operand(rbp, StandardFrameConstants::kCallerPCOffset)); 41243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch movp(Operand(rsp, 0), tmp_reg); 41253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 41263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(ReturnAddressState::kNotOnStack == ra_state); 41273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Push(Operand(rbp, StandardFrameConstants::kCallerPCOffset)); 41283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 41293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 41303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Restore caller's frame pointer now as it could be overwritten by 41313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // the copying loop. 41323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch movp(rbp, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); 41333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 41343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // +2 here is to copy both receiver and return address. 41353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Register count_reg = caller_args_count_reg; 41363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (callee_args_count.is_reg()) { 41373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch leap(count_reg, Operand(callee_args_count.reg(), 2)); 41383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } else { 41393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch movp(count_reg, Immediate(callee_args_count.immediate() + 2)); 41403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // TODO(ishell): Unroll copying loop for small immediate values. 41413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 41423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 41433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Now copy callee arguments to the caller frame going backwards to avoid 41443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // callee arguments corruption (source and destination areas could overlap). 41453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Label loop, entry; 41463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch jmp(&entry, Label::kNear); 41473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch bind(&loop); 41483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch decp(count_reg); 41493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch movp(tmp_reg, Operand(rsp, count_reg, times_pointer_size, 0)); 41503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch movp(Operand(new_sp_reg, count_reg, times_pointer_size, 0), tmp_reg); 41513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch bind(&entry); 41523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cmpp(count_reg, Immediate(0)); 41533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch j(not_equal, &loop, Label::kNear); 41543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 41553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Leave current frame. 41563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch movp(rsp, new_sp_reg); 41573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch} 4158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::InvokeFunction(Register function, 4160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register new_target, 4161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& actual, 4162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InvokeFlag flag, 4163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const CallWrapper& call_wrapper) { 4164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(rbx, FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); 4165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoadSharedFunctionInfoSpecialField( 4166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch rbx, rbx, SharedFunctionInfo::kFormalParameterCountOffset); 4167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ParameterCount expected(rbx); 4169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InvokeFunction(function, new_target, expected, actual, flag, call_wrapper); 4170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 4171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::InvokeFunction(Handle<JSFunction> function, 4174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& expected, 4175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& actual, 4176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InvokeFlag flag, 4177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const CallWrapper& call_wrapper) { 4178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Move(rdi, function); 4179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InvokeFunction(rdi, no_reg, expected, actual, flag, call_wrapper); 4180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4181257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 4182257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 4183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::InvokeFunction(Register function, 4184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register new_target, 4185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& expected, 4186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& actual, 4187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InvokeFlag flag, 4188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const CallWrapper& call_wrapper) { 4189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(function.is(rdi)); 4190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(rsi, FieldOperand(function, JSFunction::kContextOffset)); 4191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InvokeFunctionCode(rdi, new_target, expected, actual, flag, call_wrapper); 4192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 4193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::InvokeFunctionCode(Register function, Register new_target, 4196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& expected, 4197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const ParameterCount& actual, 4198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InvokeFlag flag, 4199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const CallWrapper& call_wrapper) { 42003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // You can't call a function without a valid frame. 4201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(flag == JUMP_FUNCTION || has_frame()); 4202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(function.is(rdi)); 4203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_IMPLIES(new_target.is_valid(), new_target.is(rdx)); 4204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 420562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (call_wrapper.NeedsDebugHookCheck()) { 420662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CheckDebugHook(function, new_target, expected, actual); 4207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Clear the new.target register if not given. 4210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!new_target.is_valid()) { 4211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoadRoot(rdx, Heap::kUndefinedValueRootIndex); 4212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 42133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4214257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label done; 42153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool definitely_mismatches = false; 4216e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch InvokePrologue(expected, 4217e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch actual, 4218e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch &done, 42193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch &definitely_mismatches, 4220e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch flag, 4221257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::kNear, 4222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch call_wrapper); 42233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!definitely_mismatches) { 4224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // We call indirectly through the code field in the function to 4225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // allow recompilation to take effect without changing any of the 4226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // call sites. 4227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Operand code = FieldOperand(function, JSFunction::kCodeEntryOffset); 42283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (flag == CALL_FUNCTION) { 42293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch call_wrapper.BeforeCall(CallSize(code)); 42303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch call(code); 42313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch call_wrapper.AfterCall(); 42323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 4233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(flag == JUMP_FUNCTION); 42343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch jmp(code); 42353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 42363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bind(&done); 4237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4241257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::InvokePrologue(const ParameterCount& expected, 4242257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch const ParameterCount& actual, 4243257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label* done, 42443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool* definitely_mismatches, 4245257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch InvokeFlag flag, 4246257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label::Distance near_jump, 4247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const CallWrapper& call_wrapper) { 4248257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bool definitely_matches = false; 42493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *definitely_mismatches = false; 4250257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Label invoke; 4251257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (expected.is_immediate()) { 4252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(actual.is_immediate()); 4253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(rax, actual.immediate()); 4254257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (expected.immediate() == actual.immediate()) { 4255257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch definitely_matches = true; 4256257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 4257257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (expected.immediate() == 4258257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch SharedFunctionInfo::kDontAdaptArgumentsSentinel) { 4259257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Don't worry about adapting arguments for built-ins that 4260257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // don't want that done. Skip adaption code by making it look 4261257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // like we have a match between expected and actual number of 4262257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // arguments. 4263257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch definitely_matches = true; 4264257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 42653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *definitely_mismatches = true; 4266257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Set(rbx, expected.immediate()); 4267257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 4268257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 4269257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 4270257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (actual.is_immediate()) { 4271257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Expected is in register, actual is immediate. This is the 4272257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // case when we invoke function values without going through the 4273257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // IC mechanism. 4274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(rax, actual.immediate()); 4275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(expected.reg(), Immediate(actual.immediate())); 4276257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(equal, &invoke, Label::kNear); 4277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(expected.reg().is(rbx)); 4278257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else if (!expected.reg().is(actual.reg())) { 4279257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Both expected and actual are in (different) registers. This 4280257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // is the case when we invoke functions using call and apply. 4281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(expected.reg(), actual.reg()); 4282257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch j(equal, &invoke, Label::kNear); 4283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(actual.reg().is(rax)); 4284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(expected.reg().is(rbx)); 4285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 428662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch definitely_matches = true; 4287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Move(rax, actual.reg()); 4288257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 4289257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 4290257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 4291257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!definitely_matches) { 4292257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<Code> adaptor = isolate()->builtins()->ArgumentsAdaptorTrampoline(); 4293257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (flag == CALL_FUNCTION) { 4294257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch call_wrapper.BeforeCall(CallSize(adaptor)); 4295257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Call(adaptor, RelocInfo::CODE_TARGET); 4296257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch call_wrapper.AfterCall(); 42973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!*definitely_mismatches) { 42983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch jmp(done, near_jump); 42993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4300257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 4301257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Jump(adaptor, RelocInfo::CODE_TARGET); 4302257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 4303257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bind(&invoke); 43041e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 4305402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu} 4306402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 430762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid MacroAssembler::CheckDebugHook(Register fun, Register new_target, 430862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch const ParameterCount& expected, 430962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch const ParameterCount& actual) { 431062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Label skip_hook; 431162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ExternalReference debug_hook_active = 431262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ExternalReference::debug_hook_on_function_call_address(isolate()); 431362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Operand debug_hook_active_operand = ExternalOperand(debug_hook_active); 431462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch cmpb(debug_hook_active_operand, Immediate(0)); 431562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch j(equal, &skip_hook); 4316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch { 4317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FrameScope frame(this, 4318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch has_frame() ? StackFrame::NONE : StackFrame::INTERNAL); 4319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (expected.is_reg()) { 4320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Integer32ToSmi(expected.reg(), expected.reg()); 4321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(expected.reg()); 4322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (actual.is_reg()) { 4324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Integer32ToSmi(actual.reg(), actual.reg()); 4325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(actual.reg()); 4326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (new_target.is_valid()) { 4328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(new_target); 4329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(fun); 4331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Push(fun); 433262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CallRuntime(Runtime::kDebugOnFunctionCall); 4333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pop(fun); 4334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (new_target.is_valid()) { 4335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pop(new_target); 4336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (actual.is_reg()) { 4338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pop(actual.reg()); 4339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SmiToInteger64(actual.reg(), actual.reg()); 4340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (expected.is_reg()) { 4342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Pop(expected.reg()); 4343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SmiToInteger64(expected.reg(), expected.reg()); 4344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 4345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 434662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bind(&skip_hook); 4347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 4348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 43493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid MacroAssembler::StubPrologue(StackFrame::Type type) { 43503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch pushq(rbp); // Caller's frame pointer. 43513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch movp(rbp, rsp); 435262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Push(Immediate(StackFrame::TypeToMarker(type))); 4353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Prologue(bool code_pre_aging) { 4356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PredictableCodeSizeScope predictible_code_size_scope(this, 4357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kNoCodeAgeSequenceLength); 4358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (code_pre_aging) { 4359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Pre-age the code. 4360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Call(isolate()->builtins()->MarkCodeAsExecutedOnce(), 4361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfo::CODE_AGE_SEQUENCE); 4362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Nop(kNoCodeAgeSequenceLength - Assembler::kShortCallInstructionLength); 4363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pushq(rbp); // Caller's frame pointer. 4365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rbp, rsp); 4366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(rsi); // Callee's context. 4367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(rdi); // Callee's JS function. 4368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 437162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid MacroAssembler::EmitLoadFeedbackVector(Register vector) { 4372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(vector, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 437362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch movp(vector, FieldOperand(vector, JSFunction::kFeedbackVectorOffset)); 437462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch movp(vector, FieldOperand(vector, Cell::kValueOffset)); 4375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 4376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4378958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid MacroAssembler::EnterFrame(StackFrame::Type type, 4379958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool load_constant_pool_pointer_reg) { 4380958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Out-of-line constant pool not implemented on x64. 4381958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNREACHABLE(); 4382958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 4383958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 4384958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 4385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::EnterFrame(StackFrame::Type type) { 4386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pushq(rbp); 4387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rbp, rsp); 438862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Push(Immediate(StackFrame::TypeToMarker(type))); 43893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (type == StackFrame::INTERNAL) { 43903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Move(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); 43913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Push(kScratchRegister); 43923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 439344f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 4394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(kScratchRegister, 4395257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch isolate()->factory()->undefined_value(), 4396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RelocInfo::EMBEDDED_OBJECT); 4397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(Operand(rsp, 0), kScratchRegister); 4398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(not_equal, kCodeObjectNotProperlyPatched); 4399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::LeaveFrame(StackFrame::Type type) { 440444f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 44053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch cmpp(Operand(rbp, CommonFrameConstants::kContextOrFrameTypeOffset), 440662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Immediate(StackFrame::TypeToMarker(type))); 4407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(equal, kStackFrameTypesMustMatch); 4408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rsp, rbp); 4410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch popq(rbp); 4411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4413f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::EnterBuiltinFrame(Register context, Register target, 4414f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Register argc) { 4415f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Push(rbp); 4416f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Move(rbp, rsp); 4417f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Push(context); 4418f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Push(target); 4419f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Push(argc); 4420f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 4421f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 4422f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::LeaveBuiltinFrame(Register context, Register target, 4423f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Register argc) { 4424f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Pop(argc); 4425f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Pop(target); 4426f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Pop(context); 4427f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch leave(); 4428f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 4429f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 4430f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::EnterExitFramePrologue(bool save_rax, 4431f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch StackFrame::Type frame_type) { 4432f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(frame_type == StackFrame::EXIT || 4433f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch frame_type == StackFrame::BUILTIN_EXIT); 4434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 44353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Set up the frame structure on the stack. 4436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // All constants are relative to the frame pointer of the exit frame. 44373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_EQ(kFPOnStackSize + kPCOnStackSize, 44383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ExitFrameConstants::kCallerSPDisplacement); 44393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_EQ(kFPOnStackSize, ExitFrameConstants::kCallerPCOffset); 44403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_EQ(0 * kPointerSize, ExitFrameConstants::kCallerFPOffset); 4441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pushq(rbp); 4442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rbp, rsp); 4443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 444480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen // Reserve room for entry stack pointer and push the code object. 444562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Push(Immediate(StackFrame::TypeToMarker(frame_type))); 44463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK_EQ(-2 * kPointerSize, ExitFrameConstants::kSPOffset); 4447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(Immediate(0)); // Saved entry sp, patched before call. 4448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Move(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); 4449f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Push(kScratchRegister); // Accessed from ExitFrame::code_slot. 4450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Save the frame pointer and the context in top. 4452bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch if (save_rax) { 4453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(r14, rax); // Backup rax in callee-save register. 4454bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch } 4455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4456589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Store(ExternalReference(Isolate::kCEntryFPAddress, isolate()), rbp); 4457589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Store(ExternalReference(Isolate::kContextAddress, isolate()), rsi); 4458958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Store(ExternalReference(Isolate::kCFunctionAddress, isolate()), rbx); 4459bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch} 4460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 44618a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 44621e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space, 44631e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block bool save_doubles) { 4464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef _WIN64 44651e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block const int kShadowSpace = 4; 44661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block arg_stack_space += kShadowSpace; 4467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 44681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block // Optionally save all XMM registers. 44691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (save_doubles) { 4470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int space = XMMRegister::kMaxNumRegisters * kDoubleSize + 4471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch arg_stack_space * kRegisterSize; 4472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(rsp, Immediate(space)); 44733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int offset = -ExitFrameConstants::kFixedFrameSizeFromFp; 447413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch const RegisterConfiguration* config = RegisterConfiguration::Crankshaft(); 4475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < config->num_allocatable_double_registers(); ++i) { 4476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister reg = 4477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister::from_code(config->GetAllocatableDoubleCode(i)); 4478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movsd(Operand(rbp, offset - ((i + 1) * kDoubleSize)), reg); 44791e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 44801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } else if (arg_stack_space > 0) { 4481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(rsp, Immediate(arg_stack_space * kRegisterSize)); 44828a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang } 4483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the required frame alignment for the OS. 4485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int kFrameAlignment = base::OS::ActivationFrameAlignment(); 4486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (kFrameAlignment > 0) { 4487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(base::bits::IsPowerOfTwo32(kFrameAlignment)); 4488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_int8(kFrameAlignment)); 4489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(rsp, Immediate(-kFrameAlignment)); 4490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Patch the saved entry sp. 4493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(rbp, ExitFrameConstants::kSPOffset), rsp); 4494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4496f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::EnterExitFrame(int arg_stack_space, bool save_doubles, 4497f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch StackFrame::Type frame_type) { 4498f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch EnterExitFramePrologue(true, frame_type); 4499bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 45003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Set up argv in callee-saved register r15. It is reused in LeaveExitFrame, 4501bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch // so it must be retained across the C-call. 4502bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; 4503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(r15, Operand(rbp, r14, times_pointer_size, offset)); 4504bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 45051e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block EnterExitFrameEpilogue(arg_stack_space, save_doubles); 4506bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch} 4507bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 4508bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 45098a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wangvoid MacroAssembler::EnterApiExitFrame(int arg_stack_space) { 4510f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch EnterExitFramePrologue(false, StackFrame::EXIT); 45111e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block EnterExitFrameEpilogue(arg_stack_space, false); 4512bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch} 4513bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 4514bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch 4515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::LeaveExitFrame(bool save_doubles, bool pop_arguments) { 4516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Registers: 451744f0eee88ff00398ff7f715fab053374d808c90dSteve Block // r15 : argv 45181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (save_doubles) { 45193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch int offset = -ExitFrameConstants::kFixedFrameSizeFromFp; 452013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch const RegisterConfiguration* config = RegisterConfiguration::Crankshaft(); 4521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < config->num_allocatable_double_registers(); ++i) { 4522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister reg = 4523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DoubleRegister::from_code(config->GetAllocatableDoubleCode(i)); 4524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Movsd(reg, Operand(rbp, offset - ((i + 1) * kDoubleSize))); 45251e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 45261e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 4527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (pop_arguments) { 4529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Get the return address from the stack and restore the frame pointer. 4530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(rcx, Operand(rbp, kFPOnStackSize)); 4531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(rbp, Operand(rbp, 0 * kPointerSize)); 4532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Drop everything up to and including the arguments and the receiver 4534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // from the caller stack. 4535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch leap(rsp, Operand(r15, 1 * kPointerSize)); 4536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PushReturnAddressFrom(rcx); 4538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 4539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Otherwise just leave the exit frame. 4540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch leave(); 4541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 45428a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 4543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LeaveExitFrameEpilogue(true); 45448a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang} 45458a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 45468a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 4547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::LeaveApiExitFrame(bool restore_context) { 4548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rsp, rbp); 4549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch popq(rbp); 45508a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 4551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LeaveExitFrameEpilogue(restore_context); 45528a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang} 45538a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 45548a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 4555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::LeaveExitFrameEpilogue(bool restore_context) { 4556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Restore current context from top and clear it in debug mode. 4557589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch ExternalReference context_address(Isolate::kContextAddress, isolate()); 455844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Operand context_operand = ExternalOperand(context_address); 4559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (restore_context) { 4560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rsi, context_operand); 4561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 4563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(context_operand, Immediate(0)); 4564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 4565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear the top frame. 4567589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress, 456844f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate()); 456944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Operand c_entry_fp_operand = ExternalOperand(c_entry_fp_address); 4570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(c_entry_fp_operand, Immediate(0)); 4571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Compute the hash code from the untagged key. This must be kept in sync with 4575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ComputeIntegerHash in utils.h and KeyedLoadGenericStub in 4576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// code-stub-hydrogen.cc 4577c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdochvoid MacroAssembler::GetNumberHash(Register r0, Register scratch) { 4578c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // First of all we assign the hash seed to scratch. 4579c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch LoadRoot(scratch, Heap::kHashSeedRootIndex); 4580c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch SmiToInteger32(scratch, scratch); 4581c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch 4582c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // Xor original key with a seed. 4583c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch xorl(r0, scratch); 4584c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch 4585c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // Compute the hash code from the untagged key. This must be kept in sync 4586c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // with ComputeIntegerHash in utils.h. 4587c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // 4588c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // hash = ~hash + (hash << 15); 4589c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch movl(scratch, r0); 4590c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch notl(r0); 4591c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch shll(scratch, Immediate(15)); 4592c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch addl(r0, scratch); 4593c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // hash = hash ^ (hash >> 12); 4594c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch movl(scratch, r0); 4595c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch shrl(scratch, Immediate(12)); 4596c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch xorl(r0, scratch); 4597c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // hash = hash + (hash << 2); 4598c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch leal(r0, Operand(r0, r0, times_4, 0)); 4599c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // hash = hash ^ (hash >> 4); 4600c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch movl(scratch, r0); 4601c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch shrl(scratch, Immediate(4)); 4602c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch xorl(r0, scratch); 4603c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // hash = hash * 2057; 4604c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch imull(r0, r0, Immediate(2057)); 4605c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch // hash = hash ^ (hash >> 16); 4606c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch movl(scratch, r0); 4607c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch shrl(scratch, Immediate(16)); 4608c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch xorl(r0, scratch); 4609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch andl(r0, Immediate(0x3fffffff)); 4610c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch} 4611c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch 4612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::LoadAllocationTopHelper(Register result, 4613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Register scratch, 4614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AllocationFlags flags) { 4615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference allocation_top = 4616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationUtils::GetAllocationTopReference(isolate(), flags); 4617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Just return if allocation top is already known. 4619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if ((flags & RESULT_CONTAINS_TOP) != 0) { 4620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // No use of scratch if allocation top is provided. 4621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!scratch.is_valid()); 4622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 4623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Assert that result actually contains top on entry. 4624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand top_operand = ExternalOperand(allocation_top); 4625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(result, top_operand); 4626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(equal, kUnexpectedAllocationTop); 4627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 4628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 4629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 46316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Move address of new object to result. Use scratch register if available, 46326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // and keep address in scratch until call to UpdateAllocationTopHelper. 46336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (scratch.is_valid()) { 4634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadAddress(scratch, allocation_top); 4635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(result, Operand(scratch, 0)); 4636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 4637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Load(result, allocation_top); 4638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 4640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::MakeSureDoubleAlignedHelper(Register result, 4643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 4644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required, 4645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationFlags flags) { 4646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (kPointerSize == kDoubleSize) { 4647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_debug_code) { 4648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testl(result, Immediate(kDoubleAlignmentMask)); 4649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(zero, kAllocationIsNotDoubleAligned); 4650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 46516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } else { 4652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Align the next allocation. Storing the filler map without checking top 4653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // is safe in new-space because the limit of the heap is aligned there. 4654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(kPointerSize * 2 == kDoubleSize); 4655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(kPointerAlignment * 2 == kDoubleAlignment); 4656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Make sure scratch is not clobbered by this function as it might be 4657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // used in UpdateAllocationTopHelper later. 4658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!scratch.is(kScratchRegister)); 4659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label aligned; 4660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testl(result, Immediate(kDoubleAlignmentMask)); 4661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(zero, &aligned, Label::kNear); 4662bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (((flags & ALLOCATION_FOLDED) == 0) && ((flags & PRETENURE) != 0)) { 4663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference allocation_limit = 4664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationUtils::GetAllocationLimitReference(isolate(), flags); 4665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(result, ExternalOperand(allocation_limit)); 4666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(above_equal, gc_required); 4667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadRoot(kScratchRegister, Heap::kOnePointerFillerMapRootIndex); 4669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(result, 0), kScratchRegister); 4670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(result, Immediate(kDoubleSize / 2)); 4671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&aligned); 4672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::UpdateAllocationTopHelper(Register result_end, 4677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 4678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationFlags flags) { 467944f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 4680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(result_end, Immediate(kObjectAlignmentMask)); 4681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(zero, kUnalignedAllocationInNewSpace); 4682d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 4683d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 4684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference allocation_top = 4685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationUtils::GetAllocationTopReference(isolate(), flags); 4686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Update new top. 468844f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (scratch.is_valid()) { 468944f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Scratch already contains address of allocation top. 4690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(scratch, 0), result_end); 4691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 4692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Store(allocation_top, result_end); 4693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Allocate(int object_size, 4698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register result, 4699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register result_end, 4700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 4701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required, 4702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationFlags flags) { 4703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0); 4704f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(object_size <= kMaxRegularHeapObjectSize); 4705bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK((flags & ALLOCATION_FOLDED) == 0); 47065913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck if (!FLAG_inline_new) { 470744f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 47085913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck // Trash the registers to simulate an allocation failure. 47095913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck movl(result, Immediate(0x7091)); 47105913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck if (result_end.is_valid()) { 47115913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck movl(result_end, Immediate(0x7191)); 47125913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } 47135913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck if (scratch.is_valid()) { 47145913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck movl(scratch, Immediate(0x7291)); 47155913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } 47165913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } 47175913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck jmp(gc_required); 47185913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck return; 47195913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } 4720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!result.is(result_end)); 4721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Load address of new object into result. 47238a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang LoadAllocationTopHelper(result, scratch, flags); 4724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((flags & DOUBLE_ALIGNMENT) != 0) { 4726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MakeSureDoubleAlignedHelper(result, scratch, gc_required, flags); 4727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Calculate new top and bail out if new space is exhausted. 4730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference allocation_limit = 4731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationUtils::GetAllocationLimitReference(isolate(), flags); 47326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 47336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Register top_reg = result_end.is_valid() ? result_end : result; 47346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 47351e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block if (!top_reg.is(result)) { 4736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(top_reg, result); 47376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 4738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(top_reg, Immediate(object_size)); 4739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand limit_operand = ExternalOperand(allocation_limit); 4740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(top_reg, limit_operand); 4741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block j(above, gc_required); 4742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4743bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if ((flags & ALLOCATION_FOLDING_DOMINATOR) == 0) { 4744bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // The top pointer is not updated for allocation folding dominators. 4745bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch UpdateAllocationTopHelper(top_reg, scratch, flags); 4746bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 4747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 47486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (top_reg.is(result)) { 4749bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch subp(result, Immediate(object_size - kHeapObjectTag)); 4750bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } else { 4751bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // Tag the result. 4752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(kHeapObjectTag == 1); 4753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch incp(result); 4754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Allocate(int header_size, 4759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ScaleFactor element_size, 4760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register element_count, 4761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register result, 4762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register result_end, 4763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 4764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required, 4765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationFlags flags) { 4766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((flags & SIZE_IN_WORDS) == 0); 4767bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK((flags & ALLOCATION_FOLDING_DOMINATOR) == 0); 4768bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK((flags & ALLOCATION_FOLDED) == 0); 4769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch leap(result_end, Operand(element_count, element_size, header_size)); 4770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Allocate(result_end, result, result_end, scratch, gc_required, flags); 4771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Allocate(Register object_size, 4775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register result, 4776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register result_end, 4777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, 4778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required, 4779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationFlags flags) { 4780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((flags & SIZE_IN_WORDS) == 0); 4781bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK((flags & ALLOCATION_FOLDED) == 0); 47825913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck if (!FLAG_inline_new) { 478344f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 47845913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck // Trash the registers to simulate an allocation failure. 47855913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck movl(result, Immediate(0x7091)); 47865913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck movl(result_end, Immediate(0x7191)); 47875913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck if (scratch.is_valid()) { 47885913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck movl(scratch, Immediate(0x7291)); 47895913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } 47905913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck // object_size is left unchanged by this function. 47915913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } 47925913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck jmp(gc_required); 47935913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck return; 47945913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } 4795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!result.is(result_end)); 47965913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck 4797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Load address of new object into result. 47988a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang LoadAllocationTopHelper(result, scratch, flags); 4799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if ((flags & DOUBLE_ALIGNMENT) != 0) { 4801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MakeSureDoubleAlignedHelper(result, scratch, gc_required, flags); 4802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 4803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference allocation_limit = 4805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationUtils::GetAllocationLimitReference(isolate(), flags); 4806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!object_size.is(result_end)) { 4807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(result_end, object_size); 4808a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(result_end, result); 4810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand limit_operand = ExternalOperand(allocation_limit); 4811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(result_end, limit_operand); 4812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block j(above, gc_required); 4813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4814bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if ((flags & ALLOCATION_FOLDING_DOMINATOR) == 0) { 4815bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // The top pointer is not updated for allocation folding dominators. 4816bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch UpdateAllocationTopHelper(result_end, scratch, flags); 4817bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 4818bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 4819bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // Tag the result. 4820bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch addp(result, Immediate(kHeapObjectTag)); 4821bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 4822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4823bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid MacroAssembler::FastAllocate(int object_size, Register result, 4824bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Register result_end, AllocationFlags flags) { 4825bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(!result.is(result_end)); 4826bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // Load address of new object into result. 4827bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch LoadAllocationTopHelper(result, no_reg, flags); 4828bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 4829bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if ((flags & DOUBLE_ALIGNMENT) != 0) { 4830bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch MakeSureDoubleAlignedHelper(result, no_reg, NULL, flags); 4831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 4832bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 4833bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch leap(result_end, Operand(result, object_size)); 4834bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 4835bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch UpdateAllocationTopHelper(result_end, no_reg, flags); 4836bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 4837bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch addp(result, Immediate(kHeapObjectTag)); 4838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4840bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid MacroAssembler::FastAllocate(Register object_size, Register result, 4841bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Register result_end, AllocationFlags flags) { 4842bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(!result.is(result_end)); 4843bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // Load address of new object into result. 4844bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch LoadAllocationTopHelper(result, no_reg, flags); 4845bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 4846bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if ((flags & DOUBLE_ALIGNMENT) != 0) { 4847bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch MakeSureDoubleAlignedHelper(result, no_reg, NULL, flags); 4848bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch } 4849bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 4850bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch leap(result_end, Operand(result, object_size, times_1, 0)); 4851bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 4852bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch UpdateAllocationTopHelper(result_end, no_reg, flags); 4853bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 4854bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch addp(result, Immediate(kHeapObjectTag)); 4855bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 4856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 48573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::AllocateHeapNumber(Register result, 48583ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Register scratch, 4859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* gc_required, 4860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MutableMode mode) { 48613ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Allocate heap number in new space. 4862bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Allocate(HeapNumber::kSize, result, scratch, no_reg, gc_required, 4863bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch NO_ALLOCATION_FLAGS); 4864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap::RootListIndex map_index = mode == MUTABLE 4866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? Heap::kMutableHeapNumberMapRootIndex 4867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : Heap::kHeapNumberMapRootIndex; 48683ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 48693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block // Set the map. 4870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadRoot(kScratchRegister, map_index); 4871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); 48723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block} 48733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block 4874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::AllocateJSValue(Register result, Register constructor, 4875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register value, Register scratch, 4876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label* gc_required) { 4877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!result.is(constructor)); 4878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!result.is(scratch)); 4879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!result.is(value)); 4880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Allocate JSValue in new space. 4882bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Allocate(JSValue::kSize, result, scratch, no_reg, gc_required, 4883bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch NO_ALLOCATION_FLAGS); 4884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Initialize the JSValue. 4886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoadGlobalFunctionInitialMap(constructor, scratch); 4887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(FieldOperand(result, HeapObject::kMapOffset), scratch); 4888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoadRoot(scratch, Heap::kEmptyFixedArrayRootIndex); 4889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(FieldOperand(result, JSObject::kPropertiesOffset), scratch); 4890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(FieldOperand(result, JSObject::kElementsOffset), scratch); 4891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(FieldOperand(result, JSValue::kValueOffset), value); 4892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); 4893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 4894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::InitializeFieldsWithFiller(Register current_address, 4896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register end_address, 48973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register filler) { 48983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label loop, entry; 4899109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch jmp(&entry, Label::kNear); 49003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bind(&loop); 4901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(Operand(current_address, 0), filler); 4902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch addp(current_address, Immediate(kPointerSize)); 49033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bind(&entry); 4904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cmpp(current_address, end_address); 4905109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch j(below, &loop, Label::kNear); 49063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 49073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 49083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4909d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockvoid MacroAssembler::LoadContext(Register dst, int context_chain_length) { 4910d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (context_chain_length > 0) { 4911d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block // Move up the chain of contexts to the context containing the slot. 4912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, Operand(rsi, Context::SlotOffset(Context::PREVIOUS_INDEX))); 4913d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block for (int i = 1; i < context_chain_length; i++) { 4914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, Operand(dst, Context::SlotOffset(Context::PREVIOUS_INDEX))); 4915d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 4916e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else { 4917e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // Slot is in the current function context. Move it into the 4918e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // destination register in case we store into it (the write barrier 4919e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch // cannot be allowed to destroy the context in rsi). 4920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(dst, rsi); 4921e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 4922e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 49233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // We should not have found a with context by walking the context 49243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // chain (i.e., the static scope chain and runtime context chain do 49253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // not agree). A variable occurring in such a scope should have 49263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // slot type LOOKUP and not CONTEXT. 492744f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 49283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CompareRoot(FieldOperand(dst, HeapObject::kMapOffset), 49293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Heap::kWithContextMapRootIndex); 4930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(not_equal, kVariableResolvedToWithContext); 4931d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block } 4932d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block} 4933d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 493444f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef _WIN64 493544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic const int kRegisterPassedArguments = 4; 493644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#else 493744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic const int kRegisterPassedArguments = 6; 493844f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 49397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 4940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 4941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::LoadNativeContextSlot(int index, Register dst) { 4942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(dst, NativeContextOperand()); 4943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movp(dst, ContextOperand(dst, index)); 4944b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 4945b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4946b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4947b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid MacroAssembler::LoadGlobalFunctionInitialMap(Register function, 4948b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Register map) { 4949b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Load the initial map. The global functions all have initial maps. 4950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(map, FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); 495144f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 4952b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Label ok, fail; 4953257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CheckMap(map, isolate()->factory()->meta_map(), &fail, DO_SMI_CHECK); 4954b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch jmp(&ok); 4955b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bind(&fail); 4956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Abort(kGlobalFunctionsMustHaveInitialMap); 4957b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch bind(&ok); 4958b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 4959b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 4960b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4961b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 49624515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkeint MacroAssembler::ArgumentStackSlotsForCFunctionCall(int num_arguments) { 49637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // On Windows 64 stack slots are reserved by the caller for all arguments 49647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // including the ones passed in registers, and space is always allocated for 49657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // the four register arguments even if the function takes fewer than four 49667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // arguments. 49677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // On AMD64 ABI (Linux/Mac) the first six arguments are passed in registers 49687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // and the caller does not reserve stack slots for them. 4969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(num_arguments >= 0); 49704515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke#ifdef _WIN64 497144f0eee88ff00398ff7f715fab053374d808c90dSteve Block const int kMinimumStackSlots = kRegisterPassedArguments; 49727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (num_arguments < kMinimumStackSlots) return kMinimumStackSlots; 49737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch return num_arguments; 49744515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke#else 49757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (num_arguments < kRegisterPassedArguments) return 0; 49767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch return num_arguments - kRegisterPassedArguments; 49774515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke#endif 49784515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke} 49794515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 49807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 4981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::EmitSeqStringSetCharCheck(Register string, 4982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register index, 4983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register value, 4984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t encoding_mask) { 4985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label is_object; 4986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JumpIfNotSmi(string, &is_object); 4987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Abort(kNonObject); 4988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&is_object); 4989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Push(value); 4991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(value, FieldOperand(string, HeapObject::kMapOffset)); 4992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movzxbp(value, FieldOperand(value, Map::kInstanceTypeOffset)); 4993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andb(value, Immediate(kStringRepresentationMask | kStringEncodingMask)); 4995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(value, Immediate(encoding_mask)); 4996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Pop(value); 4997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(equal, kUnexpectedStringType); 4998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The index is assumed to be untagged coming in, tag it to compare with the 5000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // string length without using a temp register, it is restored at the end of 5001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // this function. 5002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Integer32ToSmi(index, index); 5003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiCompare(index, FieldOperand(string, String::kLengthOffset)); 5004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(less, kIndexIsTooLarge); 5005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5006c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch SmiCompare(index, Smi::kZero); 5007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Check(greater_equal, kIndexIsNegative); 5008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Restore the index 5010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiToInteger32(index, index); 5011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 50144515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkevoid MacroAssembler::PrepareCallCFunction(int num_arguments) { 5015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int frame_alignment = base::OS::ActivationFrameAlignment(); 5016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(frame_alignment != 0); 5017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(num_arguments >= 0); 501844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 50194515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke // Make stack end at alignment and allocate space for arguments and old rsp. 5020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(kScratchRegister, rsp); 5021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(base::bits::IsPowerOfTwo32(frame_alignment)); 50224515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke int argument_slots_on_stack = 50234515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke ArgumentStackSlotsForCFunctionCall(num_arguments); 5024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch subp(rsp, Immediate((argument_slots_on_stack + 1) * kRegisterSize)); 5025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(rsp, Immediate(-frame_alignment)); 5026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(Operand(rsp, argument_slots_on_stack * kRegisterSize), kScratchRegister); 50274515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke} 50284515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 50294515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 50304515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkevoid MacroAssembler::CallCFunction(ExternalReference function, 50314515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke int num_arguments) { 503244f0eee88ff00398ff7f715fab053374d808c90dSteve Block LoadAddress(rax, function); 50334515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke CallCFunction(rax, num_arguments); 50344515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke} 50354515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 50364515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 50374515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkevoid MacroAssembler::CallCFunction(Register function, int num_arguments) { 5038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(has_frame()); 50396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Check stack alignment. 504044f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (emit_debug_code()) { 50416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block CheckStackAlignment(); 50426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 50436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 50444515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke call(function); 5045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(base::OS::ActivationFrameAlignment() != 0); 5046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(num_arguments >= 0); 50474515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke int argument_slots_on_stack = 50484515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke ArgumentStackSlotsForCFunctionCall(num_arguments); 5049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rsp, Operand(rsp, argument_slots_on_stack * kRegisterSize)); 50504515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke} 50514515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 5052d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 5053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 5054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool AreAliased(Register reg1, 5055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg2, 5056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg3, 5057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg4, 5058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg5, 5059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg6, 5060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg7, 5061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg8) { 5062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int n_of_valid_regs = reg1.is_valid() + reg2.is_valid() + 5063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reg3.is_valid() + reg4.is_valid() + reg5.is_valid() + reg6.is_valid() + 5064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reg7.is_valid() + reg8.is_valid(); 5065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RegList regs = 0; 5067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reg1.is_valid()) regs |= reg1.bit(); 5068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reg2.is_valid()) regs |= reg2.bit(); 5069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reg3.is_valid()) regs |= reg3.bit(); 5070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reg4.is_valid()) regs |= reg4.bit(); 5071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reg5.is_valid()) regs |= reg5.bit(); 5072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reg6.is_valid()) regs |= reg6.bit(); 5073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reg7.is_valid()) regs |= reg7.bit(); 5074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (reg8.is_valid()) regs |= reg8.bit(); 5075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int n_of_non_aliasing_regs = NumRegs(regs); 5076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return n_of_valid_regs != n_of_non_aliasing_regs; 50783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 5079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 50803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 50813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochCodePatcher::CodePatcher(Isolate* isolate, byte* address, int size) 50838b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch : address_(address), 50848b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch size_(size), 5085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch masm_(isolate, address, size + Assembler::kGap, CodeObjectRequired::kNo) { 5086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create a new macro assembler pointing to the address of the code to patch. 5087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The size is adjusted with kGap on order for the assembler to generate size 5088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // bytes of instructions without failing with buffer size constraints. 5089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 5090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCodePatcher::~CodePatcher() { 5094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Indicate that code has changed. 5095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Assembler::FlushICache(masm_.isolate(), address_, size_); 5096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check that the code was patched as expected. 5098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(masm_.pc_ == address_ + size_); 5099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 5100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 5101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 51023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 51033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::CheckPageFlag( 51043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register object, 51053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register scratch, 51063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int mask, 51073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Condition cc, 51083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* condition_met, 51093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label::Distance condition_met_distance) { 5110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(cc == zero || cc == not_zero); 51113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (scratch.is(object)) { 5112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(scratch, Immediate(~Page::kPageAlignmentMask)); 51133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 5114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(scratch, Immediate(~Page::kPageAlignmentMask)); 5115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(scratch, object); 51163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 51173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (mask < (1 << kBitsPerByte)) { 51183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch testb(Operand(scratch, MemoryChunk::kFlagsOffset), 51193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Immediate(static_cast<uint8_t>(mask))); 51203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 51213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch testl(Operand(scratch, MemoryChunk::kFlagsOffset), Immediate(mask)); 51223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 51233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(cc, condition_met, condition_met_distance); 51243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 51253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 51263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 51273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::JumpIfBlack(Register object, 51283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register bitmap_scratch, 51293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register mask_scratch, 51303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label* on_black, 51313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Label::Distance on_black_distance) { 5132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!AreAliased(object, bitmap_scratch, mask_scratch, rcx)); 5133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 51343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GetMarkBits(object, bitmap_scratch, mask_scratch); 51353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(strcmp(Marking::kBlackBitPattern, "11") == 0); 51373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // The mask_scratch register contains a 1 at the position of the first bit 5138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // and a 1 at a position of the second bit. All other positions are zero. 5139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rcx, mask_scratch); 5140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(rcx, Operand(bitmap_scratch, MemoryChunk::kHeaderSize)); 5141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(mask_scratch, rcx); 51423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(equal, on_black, on_black_distance); 51433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 51443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 51453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 51463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::GetMarkBits(Register addr_reg, 51473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register bitmap_reg, 51483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register mask_reg) { 5149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!AreAliased(addr_reg, bitmap_reg, mask_reg, rcx)); 5150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(bitmap_reg, addr_reg); 51513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Sign extended 32 bit immediate. 5152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(bitmap_reg, Immediate(~Page::kPageAlignmentMask)); 5153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rcx, addr_reg); 51543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int shift = 51553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Bitmap::kBitsPerCellLog2 + kPointerSizeLog2 - Bitmap::kBytesPerCellLog2; 51563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch shrl(rcx, Immediate(shift)); 5157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(rcx, 51583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Immediate((Page::kPageAlignmentMask >> shift) & 51593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ~(Bitmap::kBytesPerCell - 1))); 51603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addp(bitmap_reg, rcx); 5162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rcx, addr_reg); 51633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch shrl(rcx, Immediate(kPointerSizeLog2)); 5164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch andp(rcx, Immediate((1 << Bitmap::kBitsPerCellLog2) - 1)); 5165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch movl(mask_reg, Immediate(3)); 5166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shlp_cl(mask_reg); 51673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 51683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 51693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::JumpIfWhite(Register value, Register bitmap_scratch, 5171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register mask_scratch, Label* value_is_white, 5172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label::Distance distance) { 5173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!AreAliased(value, bitmap_scratch, mask_scratch, rcx)); 51743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GetMarkBits(value, bitmap_scratch, mask_scratch); 51753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 51763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // If the value is black or grey we don't need to do anything. 5177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(strcmp(Marking::kWhiteBitPattern, "00") == 0); 5178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(strcmp(Marking::kBlackBitPattern, "11") == 0); 5179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(strcmp(Marking::kGreyBitPattern, "10") == 0); 5180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(strcmp(Marking::kImpossibleBitPattern, "01") == 0); 51813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 51823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Since both black and grey have a 1 in the first position and white does 51833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // not have a 1 there we only need to check one bit. 5184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch testp(Operand(bitmap_scratch, MemoryChunk::kHeaderSize), mask_scratch); 5185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch j(zero, value_is_white, distance); 51863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 51873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 51883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5189109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid MacroAssembler::CheckEnumCache(Label* call_runtime) { 5190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label next, start; 51913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register empty_fixed_array_value = r8; 51923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LoadRoot(empty_fixed_array_value, Heap::kEmptyFixedArrayRootIndex); 5193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rcx, rax); 5194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if the enum length field is properly initialized, indicating that 5196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // there is an enum cache. 5197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rbx, FieldOperand(rcx, HeapObject::kMapOffset)); 5198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EnumLength(rdx, rbx); 5200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Cmp(rdx, Smi::FromInt(kInvalidEnumCacheSentinel)); 5201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(equal, call_runtime); 5202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jmp(&start); 5204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 52053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bind(&next); 52063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rbx, FieldOperand(rcx, HeapObject::kMapOffset)); 5208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // For all objects but the receiver, check that the cache is empty. 5210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch EnumLength(rdx, rbx); 5211c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Cmp(rdx, Smi::kZero); 52123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(not_equal, call_runtime); 52133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&start); 52153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check that there are no elements. Register rcx contains the current JS 5217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // object we've reached through the prototype chain. 5218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label no_elements; 5219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(empty_fixed_array_value, 5220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FieldOperand(rcx, JSObject::kElementsOffset)); 5221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch j(equal, &no_elements); 52223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Second chance, the object may be using the empty slow element dictionary. 5224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadRoot(kScratchRegister, Heap::kEmptySlowElementDictionaryRootIndex); 5225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(kScratchRegister, FieldOperand(rcx, JSObject::kElementsOffset)); 52263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(not_equal, call_runtime); 52273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bind(&no_elements); 5229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movp(rcx, FieldOperand(rbx, Map::kPrototypeOffset)); 5230109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CompareRoot(rcx, Heap::kNullValueRootIndex); 52313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch j(not_equal, &next); 52323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 52333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5234109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 5235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::TestJSArrayForAllocationMemento( 5236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register receiver_reg, 5237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch_reg, 5238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* no_memento_found) { 52393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Label map_check; 52403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Label top_check; 5241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference new_space_allocation_top = 5242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference::new_space_allocation_top_address(isolate()); 52433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch const int kMementoMapOffset = JSArray::kSize - kHeapObjectTag; 5244c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch const int kMementoLastWordOffset = 5245c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch kMementoMapOffset + AllocationMemento::kSize - kPointerSize; 52463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 52473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Bail out if the object is not in new space. 52483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch JumpIfNotInNewSpace(receiver_reg, scratch_reg, no_memento_found); 52493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // If the object is in new space, we need to check whether it is on the same 52503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // page as the current top. 5251c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch leap(scratch_reg, Operand(receiver_reg, kMementoLastWordOffset)); 52523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch xorp(scratch_reg, ExternalOperand(new_space_allocation_top)); 52533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch testp(scratch_reg, Immediate(~Page::kPageAlignmentMask)); 52543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch j(zero, &top_check); 52553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // The object is on a different page than allocation top. Bail out if the 52563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // object sits on the page boundary as no memento can follow and we cannot 52573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // touch the memory following it. 5258c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch leap(scratch_reg, Operand(receiver_reg, kMementoLastWordOffset)); 52593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch xorp(scratch_reg, receiver_reg); 52603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch testp(scratch_reg, Immediate(~Page::kPageAlignmentMask)); 52613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch j(not_zero, no_memento_found); 52623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Continue with the actual map check. 52633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch jmp(&map_check); 52643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // If top is on the same page as the current object, we need to check whether 52653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // we are below top. 52663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch bind(&top_check); 5267c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch leap(scratch_reg, Operand(receiver_reg, kMementoLastWordOffset)); 5268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cmpp(scratch_reg, ExternalOperand(new_space_allocation_top)); 5269c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch j(greater_equal, no_memento_found); 52703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Memento map check. 52713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch bind(&map_check); 52723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch CompareRoot(MemOperand(receiver_reg, kMementoMapOffset), 5273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap::kAllocationMementoMapRootIndex); 5274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::TruncatingDiv(Register dividend, int32_t divisor) { 5277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dividend.is(rax)); 5278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!dividend.is(rdx)); 5279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::MagicNumbersForDivision<uint32_t> mag = 5280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch base::SignedDivisionByConstant(static_cast<uint32_t>(divisor)); 5281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(rax, Immediate(mag.multiplier)); 5282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch imull(dividend); 5283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool neg = (mag.multiplier & (static_cast<uint32_t>(1) << 31)) != 0; 5284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (divisor > 0 && neg) addl(rdx, dividend); 5285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (divisor < 0 && !neg && mag.multiplier > 0) subl(rdx, dividend); 5286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mag.shift > 0) sarl(rdx, Immediate(mag.shift)); 5287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch movl(rax, dividend); 5288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shrl(rax, Immediate(31)); 5289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch addl(rdx, rax); 5290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 5291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 52923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 5294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 5295f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 5296f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#endif // V8_TARGET_ARCH_X64 5297