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, &not_zero_src, Label::kNear);
3368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Set(dst, 63);  // 63^31 == 32
3369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bind(&not_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, &not_zero_src, Label::kNear);
3383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Set(dst, 63);  // 63^31 == 32
3384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bind(&not_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, &not_zero_src, Label::kNear);
3398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Set(dst, 127);  // 127^63 == 64
3399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bind(&not_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, &not_zero_src, Label::kNear);
3413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Set(dst, 127);  // 127^63 == 64
3414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bind(&not_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, &not_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(&not_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, &not_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(&not_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, &not_zero_src, Label::kNear);
3458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Set(dst, 32);  // The result of tzcnt is 32 if src = 0.
3459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bind(&not_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, &not_zero_src, Label::kNear);
3472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Set(dst, 32);  // The result of tzcnt is 32 if src = 0.
3473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bind(&not_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