macro-assembler-x64.cc revision f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3
13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if V8_TARGET_ARCH_X64
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/bits.h"
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/division-by-constant.h"
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/bootstrapper.h"
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/codegen.h"
11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/debug/debug.h"
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/heap/heap.h"
13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/register-configuration.h"
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/x64/assembler-x64.h"
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/x64/macro-assembler-x64.h"
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochMacroAssembler::MacroAssembler(Isolate* arg_isolate, void* buffer, int size,
21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                               CodeObjectRequired create_code_object)
228b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    : Assembler(arg_isolate, buffer, size),
233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block      generating_stub_(false),
243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      has_frame_(false),
258b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      root_array_available_(true) {
26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (create_code_object == CodeObjectRequired::kYes) {
27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    code_object_ =
28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Handle<Object>::New(isolate()->heap()->undefined_value(), isolate());
298b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  }
3044f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
3144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
3244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const int64_t kInvalidRootRegisterDelta = -1;
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint64_t MacroAssembler::RootRegisterDelta(ExternalReference other) {
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (predictable_code_size() &&
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (other.address() < reinterpret_cast<Address>(isolate()) ||
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       other.address() >= reinterpret_cast<Address>(isolate() + 1))) {
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return kInvalidRootRegisterDelta;
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Address roots_register_value = kRootRegisterBias +
43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      reinterpret_cast<Address>(isolate()->heap()->roots_array_start());
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int64_t delta = kInvalidRootRegisterDelta;  // Bogus initialization.
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (kPointerSize == kInt64Size) {
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    delta = other.address() - roots_register_value;
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // For x32, zero extend the address to 64-bit and calculate the delta.
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uint64_t o = static_cast<uint32_t>(
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        reinterpret_cast<intptr_t>(other.address()));
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uint64_t r = static_cast<uint32_t>(
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        reinterpret_cast<intptr_t>(roots_register_value));
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    delta = o - r;
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return delta;
5744f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
5844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
5944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
6044f0eee88ff00398ff7f715fab053374d808c90dSteve BlockOperand MacroAssembler::ExternalOperand(ExternalReference target,
6144f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                        Register scratch) {
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (root_array_available_ && !serializer_enabled()) {
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int64_t delta = RootRegisterDelta(target);
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (delta != kInvalidRootRegisterDelta && is_int32(delta)) {
6544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      return Operand(kRootRegister, static_cast<int32_t>(delta));
6644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    }
6744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Move(scratch, target);
6944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return Operand(scratch, 0);
7044f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
7144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
7244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
7344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid MacroAssembler::Load(Register destination, ExternalReference source) {
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (root_array_available_ && !serializer_enabled()) {
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int64_t delta = RootRegisterDelta(source);
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (delta != kInvalidRootRegisterDelta && is_int32(delta)) {
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      movp(destination, Operand(kRootRegister, static_cast<int32_t>(delta)));
7844f0eee88ff00398ff7f715fab053374d808c90dSteve Block      return;
7944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    }
8044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
8144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Safe code.
8244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (destination.is(rax)) {
8344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    load_rax(source);
8444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  } else {
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Move(kScratchRegister, source);
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(destination, Operand(kScratchRegister, 0));
8744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
8844f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
8944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
9044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
9144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid MacroAssembler::Store(ExternalReference destination, Register source) {
92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (root_array_available_ && !serializer_enabled()) {
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int64_t delta = RootRegisterDelta(destination);
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (delta != kInvalidRootRegisterDelta && is_int32(delta)) {
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      movp(Operand(kRootRegister, static_cast<int32_t>(delta)), source);
9644f0eee88ff00398ff7f715fab053374d808c90dSteve Block      return;
9744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    }
9844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
9944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Safe code.
10044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (source.is(rax)) {
10144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    store_rax(destination);
10244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  } else {
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Move(kScratchRegister, destination);
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(Operand(kScratchRegister, 0), source);
10544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
10644f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
10744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
10844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
10944f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid MacroAssembler::LoadAddress(Register destination,
11044f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                 ExternalReference source) {
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (root_array_available_ && !serializer_enabled()) {
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int64_t delta = RootRegisterDelta(source);
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (delta != kInvalidRootRegisterDelta && is_int32(delta)) {
114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      leap(destination, Operand(kRootRegister, static_cast<int32_t>(delta)));
11544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      return;
11644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    }
11744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
11844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Safe code.
119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Move(destination, source);
12044f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
12144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
12244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
12344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockint MacroAssembler::LoadAddressSize(ExternalReference source) {
124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (root_array_available_ && !serializer_enabled()) {
12544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // This calculation depends on the internals of LoadAddress.
12644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // It's correctness is ensured by the asserts in the Call
12744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // instruction below.
128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int64_t delta = RootRegisterDelta(source);
129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (delta != kInvalidRootRegisterDelta && is_int32(delta)) {
130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Operand is leap(scratch, Operand(kRootRegister, delta));
13144f0eee88ff00398ff7f715fab053374d808c90dSteve Block      // Opcodes : REX.W 8D ModRM Disp8/Disp32  - 4 or 7.
13244f0eee88ff00398ff7f715fab053374d808c90dSteve Block      int size = 4;
13344f0eee88ff00398ff7f715fab053374d808c90dSteve Block      if (!is_int8(static_cast<int32_t>(delta))) {
13444f0eee88ff00398ff7f715fab053374d808c90dSteve Block        size += 3;  // Need full four-byte displacement in lea.
13544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      }
13644f0eee88ff00398ff7f715fab053374d808c90dSteve Block      return size;
13744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    }
13844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Size of movp(destination, src);
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Assembler::kMoveAddressIntoScratchRegisterInstructionLength;
141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::PushAddress(ExternalReference source) {
145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int64_t address = reinterpret_cast<int64_t>(source.address());
146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_int32(address) && !serializer_enabled()) {
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (emit_debug_code()) {
148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Move(kScratchRegister, kZapValue, Assembler::RelocInfoNone());
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Push(Immediate(static_cast<int32_t>(address)));
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return;
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LoadAddress(kScratchRegister, source);
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Push(kScratchRegister);
155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1583ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::LoadRoot(Register destination, Heap::RootListIndex index) {
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(root_array_available_);
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(destination, Operand(kRootRegister,
161e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                            (index << kPointerSizeLog2) - kRootRegisterBias));
162e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch}
163e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
164e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
165e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochvoid MacroAssembler::LoadRootIndexed(Register destination,
166e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                                     Register variable_offset,
167e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                                     int fixed_offset) {
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(root_array_available_);
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(destination,
170e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch       Operand(kRootRegister,
171e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch               variable_offset, times_pointer_size,
172e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch               (fixed_offset << kPointerSizeLog2) - kRootRegisterBias));
173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
17625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsenvoid MacroAssembler::StoreRoot(Register source, Heap::RootListIndex index) {
177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(Heap::RootCanBeWrittenAfterInitialization(index));
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(root_array_available_);
179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(Operand(kRootRegister, (index << kPointerSizeLog2) - kRootRegisterBias),
180e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch       source);
18125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen}
18225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
18325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::PushRoot(Heap::RootListIndex index) {
185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(root_array_available_);
186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Push(Operand(kRootRegister, (index << kPointerSizeLog2) - kRootRegisterBias));
187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::CompareRoot(Register with, Heap::RootListIndex index) {
191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(root_array_available_);
192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  cmpp(with, Operand(kRootRegister,
193e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                     (index << kPointerSizeLog2) - kRootRegisterBias));
194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1971e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::CompareRoot(const Operand& with,
1981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block                                 Heap::RootListIndex index) {
199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(root_array_available_);
200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!with.AddressUsesRegister(kScratchRegister));
201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  LoadRoot(kScratchRegister, index);
202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  cmpp(with, kScratchRegister);
203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::RememberedSetHelper(Register object,  // For debug tests.
2073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                         Register addr,
2083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                         Register scratch,
2093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                         SaveFPRegsMode save_fp,
2103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                         RememberedSetFinalAction and_then) {
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (emit_debug_code()) {
2123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Label ok;
2133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    JumpIfNotInNewSpace(object, scratch, &ok, Label::kNear);
2143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int3();
2153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    bind(&ok);
2163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Load store buffer top.
2183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  ExternalReference store_buffer =
2193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      ExternalReference::store_buffer_top(isolate());
2203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  movp(scratch, ExternalOperand(store_buffer));
2213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Store pointer to buffer.
222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(Operand(scratch, 0), addr);
2233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Increment buffer top.
224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  addp(scratch, Immediate(kPointerSize));
2253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Write back new top of buffer.
2263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  movp(ExternalOperand(store_buffer), scratch);
2273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Call stub on end of buffer.
2283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Label done;
2293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Check for end of buffer.
2303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  testp(scratch, Immediate(StoreBuffer::kStoreBufferMask));
2313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (and_then == kReturnAtEnd) {
2323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Label buffer_overflowed;
2333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    j(equal, &buffer_overflowed, Label::kNear);
2343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ret(0);
2353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    bind(&buffer_overflowed);
2363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(and_then == kFallThroughAtEnd);
2383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    j(not_equal, &done, Label::kNear);
2393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StoreBufferOverflowStub store_buffer_overflow(isolate(), save_fp);
2413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  CallStub(&store_buffer_overflow);
2423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (and_then == kReturnAtEnd) {
2433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ret(0);
2443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(and_then == kFallThroughAtEnd);
2463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    bind(&done);
2476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
2487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
2497f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
2507f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
251257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::InNewSpace(Register object,
252257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                Register scratch,
253257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                Condition cc,
254257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                Label* branch,
2553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                Label::Distance distance) {
256f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  CheckPageFlag(object, scratch, MemoryChunk::kIsInNewSpaceMask, cc, branch,
257f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                distance);
258257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
259257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
260257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::RecordWriteField(
2623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Register object,
2633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int offset,
2643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Register value,
2653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Register dst,
2663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    SaveFPRegsMode save_fp,
2673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    RememberedSetAction remembered_set_action,
268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SmiCheck smi_check,
269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PointersToHereCheck pointers_to_here_check_for_value) {
2707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // First, check if a write barrier is even needed. The tests below
2713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // catch stores of Smis.
272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Label done;
273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Skip barrier if writing a smi.
2753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (smi_check == INLINE_SMI_CHECK) {
2763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    JumpIfSmi(value, &done);
2773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Although the object register is tagged, the offset is relative to the start
2803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // of the object, so so offset must be a multiple of kPointerSize.
281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(IsAligned(offset, kPointerSize));
2823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  leap(dst, FieldOperand(object, offset));
2843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (emit_debug_code()) {
2853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Label ok;
2863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    testb(dst, Immediate((1 << kPointerSizeLog2) - 1));
2873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    j(zero, &ok, Label::kNear);
2883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int3();
2893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    bind(&ok);
2903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RecordWrite(object, dst, value, save_fp, remembered_set_action,
293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              OMIT_SMI_CHECK, pointers_to_here_check_for_value);
2943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  bind(&done);
2964515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke
2973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Clobber clobbered input registers when running with the debug-code flag
2983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // turned on to provoke errors.
29944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (emit_debug_code()) {
300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Move(value, kZapValue, Assembler::RelocInfoNone());
301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Move(dst, kZapValue, Assembler::RelocInfoNone());
3024515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  }
3033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
3043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
3053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::RecordWriteArray(
307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Register object,
308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Register value,
309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Register index,
310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SaveFPRegsMode save_fp,
311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    RememberedSetAction remembered_set_action,
312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SmiCheck smi_check,
313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PointersToHereCheck pointers_to_here_check_for_value) {
3148defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // First, check if a write barrier is even needed. The tests below
3153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // catch stores of Smis.
3168defd9ff6930b4e24729971a61cf7469daf119beSteve Block  Label done;
3178defd9ff6930b4e24729971a61cf7469daf119beSteve Block
3183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Skip barrier if writing a smi.
3193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (smi_check == INLINE_SMI_CHECK) {
3203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    JumpIfSmi(value, &done);
3213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
3228defd9ff6930b4e24729971a61cf7469daf119beSteve Block
3233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Array access: calculate the destination address. Index is not a smi.
3243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Register dst = index;
325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  leap(dst, Operand(object, index, times_pointer_size,
3263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                   FixedArray::kHeaderSize - kHeapObjectTag));
3273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RecordWrite(object, dst, value, save_fp, remembered_set_action,
329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              OMIT_SMI_CHECK, pointers_to_here_check_for_value);
3308defd9ff6930b4e24729971a61cf7469daf119beSteve Block
3318defd9ff6930b4e24729971a61cf7469daf119beSteve Block  bind(&done);
3328defd9ff6930b4e24729971a61cf7469daf119beSteve Block
3333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Clobber clobbered input registers when running with the debug-code flag
3348defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // turned on to provoke errors.
33544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (emit_debug_code()) {
336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Move(value, kZapValue, Assembler::RelocInfoNone());
337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Move(index, kZapValue, Assembler::RelocInfoNone());
3388defd9ff6930b4e24729971a61cf7469daf119beSteve Block  }
3398defd9ff6930b4e24729971a61cf7469daf119beSteve Block}
3408defd9ff6930b4e24729971a61cf7469daf119beSteve Block
3418defd9ff6930b4e24729971a61cf7469daf119beSteve Block
342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::RecordWriteForMap(Register object,
343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                       Register map,
344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                       Register dst,
345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                       SaveFPRegsMode fp_mode) {
346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!object.is(kScratchRegister));
347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!object.is(map));
348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!object.is(dst));
349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!map.is(dst));
350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AssertNotSmi(object);
3514515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke
35244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (emit_debug_code()) {
353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Label ok;
354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (map.is(kScratchRegister)) pushq(map);
355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CompareMap(map, isolate()->factory()->meta_map());
356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (map.is(kScratchRegister)) popq(map);
357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    j(equal, &ok, Label::kNear);
358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int3();
359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bind(&ok);
3604515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  }
3614515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke
362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!FLAG_incremental_marking) {
363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return;
364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (emit_debug_code()) {
367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Label ok;
368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (map.is(kScratchRegister)) pushq(map);
369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    cmpp(map, FieldOperand(object, HeapObject::kMapOffset));
370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (map.is(kScratchRegister)) popq(map);
371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    j(equal, &ok, Label::kNear);
372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int3();
373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bind(&ok);
374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Compute the address.
377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  leap(dst, FieldOperand(object, HeapObject::kMapOffset));
378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // First, check if a write barrier is even needed. The tests below
380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // catch stores of smis and stores into the young generation.
381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Label done;
382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // A single check of the map's pages interesting flag suffices, since it is
384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // only set during incremental collection, and then it's also guaranteed that
385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // the from object's page's interesting flag is also set.  This optimization
386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // relies on the fact that maps can never be in new space.
387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CheckPageFlag(map,
388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                map,  // Used as scratch.
389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                MemoryChunk::kPointersToHereAreInterestingMask,
390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                zero,
391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                &done,
392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                Label::kNear);
393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RecordWriteStub stub(isolate(), object, map, dst, OMIT_REMEMBERED_SET,
395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       fp_mode);
396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CallStub(&stub);
397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bind(&done);
399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Count number of write barriers in generated code.
401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate()->counters()->write_barriers_static()->Increment();
402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1);
403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Clobber clobbered registers when running with the debug-code flag
405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // turned on to provoke errors.
406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (emit_debug_code()) {
407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Move(dst, kZapValue, Assembler::RelocInfoNone());
408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Move(map, kZapValue, Assembler::RelocInfoNone());
409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::RecordWrite(
414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Register object,
415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Register address,
416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Register value,
417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SaveFPRegsMode fp_mode,
418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    RememberedSetAction remembered_set_action,
419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SmiCheck smi_check,
420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PointersToHereCheck pointers_to_here_check_for_value) {
421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!object.is(value));
422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!object.is(address));
423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!value.is(address));
424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AssertNotSmi(object);
425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (remembered_set_action == OMIT_REMEMBERED_SET &&
4273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      !FLAG_incremental_marking) {
4283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return;
4293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
4306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (emit_debug_code()) {
4323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Label ok;
433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    cmpp(value, Operand(address, 0));
4343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    j(equal, &ok, Label::kNear);
4353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int3();
4363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    bind(&ok);
4373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
4386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
4393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // First, check if a write barrier is even needed. The tests below
4403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // catch stores of smis and stores into the young generation.
4413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Label done;
4423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (smi_check == INLINE_SMI_CHECK) {
4443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Skip barrier if writing a smi.
4453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    JumpIfSmi(value, &done);
446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
4473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (pointers_to_here_check_for_value != kPointersToHereAreAlwaysInteresting) {
449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CheckPageFlag(value,
450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  value,  // Used as scratch.
451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  MemoryChunk::kPointersToHereAreInterestingMask,
452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  zero,
453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  &done,
454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  Label::kNear);
455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  CheckPageFlag(object,
4583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                value,  // Used as scratch.
4593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                MemoryChunk::kPointersFromHereAreInterestingMask,
4603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                zero,
4613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                &done,
4623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                Label::kNear);
4633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RecordWriteStub stub(isolate(), object, value, address, remembered_set_action,
465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       fp_mode);
4663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  CallStub(&stub);
467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bind(&done);
4694515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke
470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Count number of write barriers in generated code.
471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate()->counters()->write_barriers_static()->Increment();
472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1);
473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Clobber clobbered registers when running with the debug-code flag
4754515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  // turned on to provoke errors.
47644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (emit_debug_code()) {
477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Move(address, kZapValue, Assembler::RelocInfoNone());
478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Move(value, kZapValue, Assembler::RelocInfoNone());
4796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
4806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
4816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
482109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid MacroAssembler::RecordWriteCodeEntryField(Register js_function,
483109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                               Register code_entry,
484109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                               Register scratch) {
485109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  const int offset = JSFunction::kCodeEntryOffset;
486109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
487109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // The input registers are fixed to make calling the C write barrier function
488109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // easier.
489109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DCHECK(js_function.is(rdi));
490109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DCHECK(code_entry.is(rcx));
491bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK(scratch.is(r15));
492109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
493109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Since a code entry (value) is always in old space, we don't need to update
494109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // remembered set. If incremental marking is off, there is nothing for us to
495109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // do.
496109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (!FLAG_incremental_marking) return;
497109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
498109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  AssertNotSmi(js_function);
499109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
500109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (emit_debug_code()) {
501109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    Label ok;
502109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    leap(scratch, FieldOperand(js_function, offset));
503109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    cmpp(code_entry, Operand(scratch, 0));
504109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    j(equal, &ok, Label::kNear);
505109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    int3();
506109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    bind(&ok);
507109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
508109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
509109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // First, check if a write barrier is even needed. The tests below
510109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // catch stores of Smis and stores into young gen.
511109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Label done;
512109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
513109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  CheckPageFlag(code_entry, scratch,
514109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                MemoryChunk::kPointersToHereAreInterestingMask, zero, &done,
515109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                Label::kNear);
516109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  CheckPageFlag(js_function, scratch,
517109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                MemoryChunk::kPointersFromHereAreInterestingMask, zero, &done,
518109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                Label::kNear);
519109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
520109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Save input registers.
521109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Push(js_function);
522109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Push(code_entry);
523109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
524109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  const Register dst = scratch;
525109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  leap(dst, FieldOperand(js_function, offset));
526109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
527109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Save caller-saved registers.
528109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  PushCallerSaved(kDontSaveFPRegs, js_function, code_entry);
529109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
530109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  int argument_count = 3;
531109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  PrepareCallCFunction(argument_count);
532109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
533109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Load the argument registers.
534109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (arg_reg_1.is(rcx)) {
535109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // Windows calling convention.
536109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    DCHECK(arg_reg_2.is(rdx) && arg_reg_3.is(r8));
537109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
538109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    movp(arg_reg_1, js_function);  // rcx gets rdi.
539bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    movp(arg_reg_2, dst);          // rdx gets r15.
540109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  } else {
541109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // AMD64 calling convention.
542109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    DCHECK(arg_reg_1.is(rdi) && arg_reg_2.is(rsi) && arg_reg_3.is(rdx));
543109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
544109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // rdi is already loaded with js_function.
545bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    movp(arg_reg_2, dst);  // rsi gets r15.
546109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
547109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Move(arg_reg_3, ExternalReference::isolate_address(isolate()));
548109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
549109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  {
550109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    AllowExternalCallThatCantCauseGC scope(this);
551109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    CallCFunction(
552109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        ExternalReference::incremental_marking_record_write_code_entry_function(
553109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            isolate()),
554109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        argument_count);
555109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
556109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
557109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Restore caller-saved registers.
558109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  PopCallerSaved(kDontSaveFPRegs, js_function, code_entry);
559109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
560109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Restore input registers.
561109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Pop(code_entry);
562109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Pop(js_function);
563109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
564109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  bind(&done);
565109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
5663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Assert(Condition cc, BailoutReason reason) {
568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (emit_debug_code()) Check(cc, reason);
569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
572756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickvoid MacroAssembler::AssertFastElements(Register elements) {
57344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (emit_debug_code()) {
574257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Label ok;
575756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    CompareRoot(FieldOperand(elements, HeapObject::kMapOffset),
576756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick                Heap::kFixedArrayMapRootIndex);
577257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    j(equal, &ok, Label::kNear);
578756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    CompareRoot(FieldOperand(elements, HeapObject::kMapOffset),
5793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                Heap::kFixedDoubleArrayMapRootIndex);
5803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    j(equal, &ok, Label::kNear);
5813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    CompareRoot(FieldOperand(elements, HeapObject::kMapOffset),
582756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick                Heap::kFixedCOWArrayMapRootIndex);
583257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    j(equal, &ok, Label::kNear);
584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Abort(kJSObjectWithFastElementsMapHasSlowElements);
585756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    bind(&ok);
586756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  }
587756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick}
588756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
589756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Check(Condition cc, BailoutReason reason) {
591257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Label L;
592257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  j(cc, &L, Label::kNear);
593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Abort(reason);
5943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Control will not return here.
595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bind(&L);
596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5996ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid MacroAssembler::CheckStackAlignment() {
600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int frame_alignment = base::OS::ActivationFrameAlignment();
6016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  int frame_alignment_mask = frame_alignment - 1;
6026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (frame_alignment > kPointerSize) {
603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(base::bits::IsPowerOfTwo32(frame_alignment));
604257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Label alignment_as_expected;
605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    testp(rsp, Immediate(frame_alignment_mask));
606257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    j(zero, &alignment_as_expected, Label::kNear);
6076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    // Abort if stack is not aligned.
6086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    int3();
6096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    bind(&alignment_as_expected);
6106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
6116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
6126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
6136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::NegativeZeroTest(Register result,
615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                      Register op,
616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                      Label* then_label) {
617257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Label ok;
618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  testl(result, result);
619257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  j(not_zero, &ok, Label::kNear);
620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  testl(op, op);
621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  j(sign, then_label);
622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bind(&ok);
623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Abort(BailoutReason reason) {
627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const char* msg = GetBailoutReason(reason);
629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (msg != NULL) {
630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    RecordComment("Abort message: ");
631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    RecordComment(msg);
632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_trap_on_abort) {
635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int3();
636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return;
637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
640f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Check if Abort() has already been initialized.
641f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DCHECK(isolate()->builtins()->Abort()->IsHeapObject());
642f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
643f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Move(rdx, Smi::FromInt(static_cast<int>(reason)));
6443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!has_frame_) {
6463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // We don't actually want to generate a pile of code for this, so just
6473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // claim there is a stack frame, without generating one.
6483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    FrameScope scope(this, StackFrame::NONE);
649f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Call(isolate()->builtins()->Abort(), RelocInfo::CODE_TARGET);
6503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
651f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Call(isolate()->builtins()->Abort(), RelocInfo::CODE_TARGET);
6523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
6533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Control will not return here.
654d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  int3();
655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::CallStub(CodeStub* stub, TypeFeedbackId ast_id) {
659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(AllowThisStubCall(stub));  // Calls are not allowed in some stubs
660257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id);
661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
664e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid MacroAssembler::TailCallStub(CodeStub* stub) {
665e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  Jump(stub->GetCode(), RelocInfo::CODE_TARGET);
666e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
667e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
668e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
66985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdochvoid MacroAssembler::StubReturn(int argc) {
670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(argc >= 1 && generating_stub());
67185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  ret((argc - 1) * kPointerSize);
672592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch}
673592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch
674592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch
6753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool MacroAssembler::AllowThisStubCall(CodeStub* stub) {
676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return has_frame_ || !stub->SometimesSetsUpAFrame();
677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
68080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsenvoid MacroAssembler::IndexFromHash(Register hash, Register index) {
68180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // The assert checks that the constants for the maximum number of digits
68280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // for an array index cached in the hash field and the number of bits
68380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // reserved for it does not conflict.
684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(TenToThe(String::kMaxCachedArrayIndexLength) <
68580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen         (1 << String::kArrayIndexValueBits));
686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!hash.is(index)) {
687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movl(index, hash);
688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DecodeFieldToSmi<String::ArrayIndexValueBits>(index);
6901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}
6911e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
6921e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
69344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid MacroAssembler::CallRuntime(const Runtime::Function* f,
694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 int num_arguments,
695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 SaveFPRegsMode save_doubles) {
696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If the expected number of arguments of the runtime function is
697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // constant, we check that the actual number of arguments match the
698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // expectation.
699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(f->nargs < 0 || f->nargs == num_arguments);
700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7014515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  // TODO(1236192): Most runtime routines don't need the number of
7024515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  // arguments passed in because it is constant. At some point we
7034515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  // should remove this need and make the runtime routine entry code
7044515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  // smarter.
7058defd9ff6930b4e24729971a61cf7469daf119beSteve Block  Set(rax, num_arguments);
70644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  LoadAddress(rbx, ExternalReference(f, isolate()));
707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CEntryStub ces(isolate(), f->result_size, save_doubles);
7084515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  CallStub(&ces);
709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
712402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuvoid MacroAssembler::CallExternalReference(const ExternalReference& ext,
713402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu                                           int num_arguments) {
7148defd9ff6930b4e24729971a61cf7469daf119beSteve Block  Set(rax, num_arguments);
71544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  LoadAddress(rbx, ext);
716402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CEntryStub stub(isolate(), 1);
718402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  CallStub(&stub);
719402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu}
720402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
721402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::TailCallRuntime(Runtime::FunctionId fid) {
723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ----------- S t a t e -------------
724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //  -- rsp[0]                 : return address
725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //  -- rsp[8]                 : argument num_arguments - 1
726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  //  ...
727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  //  -- rsp[8 * num_arguments] : argument 0 (receiver)
728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //
729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //  For runtime functions with variable arguments:
730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //  -- rax                    : number of  arguments
731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // -----------------------------------
732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const Runtime::Function* function = Runtime::FunctionForId(fid);
734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(1, function->result_size);
735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (function->nargs >= 0) {
736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Set(rax, function->nargs);
737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  JumpToExternalReference(ExternalReference(fid, isolate()));
739bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch}
740bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch
741f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::JumpToExternalReference(const ExternalReference& ext,
742f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                             bool builtin_exit_frame) {
743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Set the entry point and jump to the C entry runtime stub.
74444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  LoadAddress(rbx, ext);
745f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CEntryStub ces(isolate(), 1, kDontSaveFPRegs, kArgvOnStack,
746f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                 builtin_exit_frame);
7473ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  jmp(ces.GetCode(), RelocInfo::CODE_TARGET);
748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define REG(Name) \
751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  { Register::kCode_##Name }
7523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic const Register saved_regs[] = {
7543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  REG(rax), REG(rcx), REG(rdx), REG(rbx), REG(rbp), REG(rsi), REG(rdi), REG(r8),
7553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  REG(r9), REG(r10), REG(r11)
7563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
7573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#undef REG
7593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic const int kNumberOfSavedRegs = sizeof(saved_regs) / sizeof(Register);
7613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::PushCallerSaved(SaveFPRegsMode fp_mode,
7643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                     Register exclusion1,
7653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                     Register exclusion2,
7663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                     Register exclusion3) {
7673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // We don't allow a GC during a store buffer overflow so there is no need to
7683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // store the registers in any particular way, but we do have to store and
7693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // restore them.
7703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  for (int i = 0; i < kNumberOfSavedRegs; i++) {
7713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Register reg = saved_regs[i];
7723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (!reg.is(exclusion1) && !reg.is(exclusion2) && !reg.is(exclusion3)) {
773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      pushq(reg);
7743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
7753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
7763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // R12 to r15 are callee save on all platforms.
7773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (fp_mode == kSaveFPRegs) {
778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    subp(rsp, Immediate(kDoubleSize * XMMRegister::kMaxNumRegisters));
779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) {
7803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      XMMRegister reg = XMMRegister::from_code(i);
781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Movsd(Operand(rsp, i * kDoubleSize), reg);
7823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
7833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
7843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
7853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
7873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::PopCallerSaved(SaveFPRegsMode fp_mode,
7883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    Register exclusion1,
7893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    Register exclusion2,
7903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    Register exclusion3) {
7913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (fp_mode == kSaveFPRegs) {
792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) {
7933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      XMMRegister reg = XMMRegister::from_code(i);
794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Movsd(reg, Operand(rsp, i * kDoubleSize));
7953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    addp(rsp, Immediate(kDoubleSize * XMMRegister::kMaxNumRegisters));
7973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
7983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  for (int i = kNumberOfSavedRegs - 1; i >= 0; i--) {
7993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Register reg = saved_regs[i];
8003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (!reg.is(exclusion1) && !reg.is(exclusion2) && !reg.is(exclusion3)) {
801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      popq(reg);
802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtss2sd(XMMRegister dst, XMMRegister src) {
808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vcvtss2sd(dst, src, src);
811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    cvtss2sd(dst, src);
813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtss2sd(XMMRegister dst, const Operand& src) {
818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vcvtss2sd(dst, dst, src);
821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    cvtss2sd(dst, src);
823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtsd2ss(XMMRegister dst, XMMRegister src) {
828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vcvtsd2ss(dst, src, src);
831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    cvtsd2ss(dst, src);
833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtsd2ss(XMMRegister dst, const Operand& src) {
838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vcvtsd2ss(dst, dst, src);
841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    cvtsd2ss(dst, src);
843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Cvtlsi2sd(XMMRegister dst, Register src) {
848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vxorpd(dst, dst, dst);
851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vcvtlsi2sd(dst, dst, src);
852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    xorpd(dst, dst);
854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    cvtlsi2sd(dst, src);
855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Cvtlsi2sd(XMMRegister dst, const Operand& src) {
860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vxorpd(dst, dst, dst);
863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vcvtlsi2sd(dst, dst, src);
864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    xorpd(dst, dst);
866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    cvtlsi2sd(dst, src);
867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
871109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid MacroAssembler::Cvtlsi2ss(XMMRegister dst, Register src) {
872109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
873109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    CpuFeatureScope scope(this, AVX);
874109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    vxorps(dst, dst, dst);
875109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    vcvtlsi2ss(dst, dst, src);
876109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  } else {
877109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    xorps(dst, dst);
878109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    cvtlsi2ss(dst, src);
879109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
880109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
881109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
882109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
883109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid MacroAssembler::Cvtlsi2ss(XMMRegister dst, const Operand& src) {
884109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
885109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    CpuFeatureScope scope(this, AVX);
886109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    vxorps(dst, dst, dst);
887109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    vcvtlsi2ss(dst, dst, src);
888109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  } else {
889109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    xorps(dst, dst);
890109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    cvtlsi2ss(dst, src);
891109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
892109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
893109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
894109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtqsi2ss(XMMRegister dst, Register src) {
896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vxorps(dst, dst, dst);
899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vcvtqsi2ss(dst, dst, src);
900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    xorps(dst, dst);
902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    cvtqsi2ss(dst, src);
903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtqsi2ss(XMMRegister dst, const Operand& src) {
908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vxorps(dst, dst, dst);
911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vcvtqsi2ss(dst, dst, src);
912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    xorps(dst, dst);
914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    cvtqsi2ss(dst, src);
915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtqsi2sd(XMMRegister dst, Register src) {
920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vxorpd(dst, dst, dst);
923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vcvtqsi2sd(dst, dst, src);
924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    xorpd(dst, dst);
926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    cvtqsi2sd(dst, src);
927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtqsi2sd(XMMRegister dst, const Operand& src) {
932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vxorpd(dst, dst, dst);
935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vcvtqsi2sd(dst, dst, src);
936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    xorpd(dst, dst);
938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    cvtqsi2sd(dst, src);
939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtqui2ss(XMMRegister dst, Register src, Register tmp) {
944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label msb_set_src;
945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label jmp_return;
946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  testq(src, src);
947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  j(sign, &msb_set_src, Label::kNear);
948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Cvtqsi2ss(dst, src);
949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  jmp(&jmp_return, Label::kNear);
950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bind(&msb_set_src);
951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  movq(tmp, src);
952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  shrq(src, Immediate(1));
953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Recover the least significant bit to avoid rounding errors.
954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  andq(tmp, Immediate(1));
955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  orq(src, tmp);
956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Cvtqsi2ss(dst, src);
957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  addss(dst, dst);
958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bind(&jmp_return);
959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtqui2sd(XMMRegister dst, Register src, Register tmp) {
963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label msb_set_src;
964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label jmp_return;
965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  testq(src, src);
966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  j(sign, &msb_set_src, Label::kNear);
967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Cvtqsi2sd(dst, src);
968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  jmp(&jmp_return, Label::kNear);
969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bind(&msb_set_src);
970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  movq(tmp, src);
971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  shrq(src, Immediate(1));
972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  andq(tmp, Immediate(1));
973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  orq(src, tmp);
974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Cvtqsi2sd(dst, src);
975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  addsd(dst, dst);
976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bind(&jmp_return);
977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvtsd2si(Register dst, XMMRegister src) {
981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vcvtsd2si(dst, src);
984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    cvtsd2si(dst, src);
986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
990109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid MacroAssembler::Cvttss2si(Register dst, XMMRegister src) {
991109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
992109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    CpuFeatureScope scope(this, AVX);
993109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    vcvttss2si(dst, src);
994109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  } else {
995109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    cvttss2si(dst, src);
996109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
997109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
998109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
999109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1000109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid MacroAssembler::Cvttss2si(Register dst, const Operand& src) {
1001109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
1002109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    CpuFeatureScope scope(this, AVX);
1003109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    vcvttss2si(dst, src);
1004109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  } else {
1005109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    cvttss2si(dst, src);
1006109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
1007109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
1008109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1009109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvttsd2si(Register dst, XMMRegister src) {
1011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
1012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
1013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vcvttsd2si(dst, src);
1014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    cvttsd2si(dst, src);
1016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvttsd2si(Register dst, const Operand& src) {
1021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
1022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
1023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vcvttsd2si(dst, src);
1024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    cvttsd2si(dst, src);
1026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvttss2siq(Register dst, XMMRegister src) {
1031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
1032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
1033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vcvttss2siq(dst, src);
1034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    cvttss2siq(dst, src);
1036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvttss2siq(Register dst, const Operand& src) {
1041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
1042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
1043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vcvttss2siq(dst, src);
1044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    cvttss2siq(dst, src);
1046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvttsd2siq(Register dst, XMMRegister src) {
1051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
1052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
1053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vcvttsd2siq(dst, src);
1054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    cvttsd2siq(dst, src);
1056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1058014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cvttsd2siq(Register dst, const Operand& src) {
1061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
1062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
1063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vcvttsd2siq(dst, src);
1064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    cvttsd2siq(dst, src);
1066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Load(Register dst, const Operand& src, Representation r) {
1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!r.IsDouble());
1072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (r.IsInteger8()) {
1073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movsxbq(dst, src);
1074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (r.IsUInteger8()) {
1075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movzxbl(dst, src);
1076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (r.IsInteger16()) {
1077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movsxwq(dst, src);
1078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (r.IsUInteger16()) {
1079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movzxwl(dst, src);
1080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (r.IsInteger32()) {
1081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movl(dst, src);
1082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(dst, src);
1084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Store(const Operand& dst, Register src, Representation r) {
1089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!r.IsDouble());
1090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (r.IsInteger8() || r.IsUInteger8()) {
1091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movb(dst, src);
1092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (r.IsInteger16() || r.IsUInteger16()) {
1093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movw(dst, src);
1094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (r.IsInteger32()) {
1095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movl(dst, src);
1096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (r.IsHeapObject()) {
1098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      AssertNotSmi(src);
1099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (r.IsSmi()) {
1100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      AssertSmi(src);
11013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
1102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(dst, src);
11033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
11043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
11053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
11063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Set(Register dst, int64_t x) {
1108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (x == 0) {
11098defd9ff6930b4e24729971a61cf7469daf119beSteve Block    xorl(dst, dst);
1110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else if (is_uint32(x)) {
1111d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    movl(dst, Immediate(static_cast<uint32_t>(x)));
11128b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  } else if (is_int32(x)) {
11138b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    movq(dst, Immediate(static_cast<int32_t>(x)));
1114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
1115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movq(dst, x);
1116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Set(const Operand& dst, intptr_t x) {
1120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (kPointerSize == kInt64Size) {
1121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (is_int32(x)) {
1122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      movp(dst, Immediate(static_cast<int32_t>(x)));
1123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
1124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Set(kScratchRegister, x);
1125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      movp(dst, kScratchRegister);
1126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
1128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(dst, Immediate(static_cast<int32_t>(x)));
1129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------
1134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Smi tagging, untagging and tag detection.
1135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool MacroAssembler::IsUnsafeInt(const int32_t x) {
1137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kMaxBits = 17;
1138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return !is_intn(x, kMaxBits);
1139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::SafeMove(Register dst, Smi* src) {
1143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!dst.is(kScratchRegister));
1144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (IsUnsafeInt(src->value()) && jit_cookie() != 0) {
1145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (SmiValuesAre32Bits()) {
1146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // JIT cookie can be converted to Smi.
1147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Move(dst, Smi::FromInt(src->value() ^ jit_cookie()));
1148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Move(kScratchRegister, Smi::FromInt(jit_cookie()));
1149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      xorp(dst, kScratchRegister);
1150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
1151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(SmiValuesAre31Bits());
1152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int32_t value = static_cast<int32_t>(reinterpret_cast<intptr_t>(src));
1153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      movp(dst, Immediate(value ^ jit_cookie()));
1154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      xorp(dst, Immediate(jit_cookie()));
1155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Move(dst, src);
1158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::SafePush(Smi* src) {
1163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (IsUnsafeInt(src->value()) && jit_cookie() != 0) {
1164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (SmiValuesAre32Bits()) {
1165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // JIT cookie can be converted to Smi.
1166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Push(Smi::FromInt(src->value() ^ jit_cookie()));
1167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Move(kScratchRegister, Smi::FromInt(jit_cookie()));
1168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      xorp(Operand(rsp, 0), kScratchRegister);
1169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
1170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(SmiValuesAre31Bits());
1171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int32_t value = static_cast<int32_t>(reinterpret_cast<intptr_t>(src));
1172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Push(Immediate(value ^ jit_cookie()));
1173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      xorp(Operand(rsp, 0), Immediate(jit_cookie()));
1174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Push(src);
1177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
11818defd9ff6930b4e24729971a61cf7469daf119beSteve BlockRegister MacroAssembler::GetSmiConstant(Smi* source) {
1182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  STATIC_ASSERT(kSmiTag == 0);
11838defd9ff6930b4e24729971a61cf7469daf119beSteve Block  int value = source->value();
11848defd9ff6930b4e24729971a61cf7469daf119beSteve Block  if (value == 0) {
11858defd9ff6930b4e24729971a61cf7469daf119beSteve Block    xorl(kScratchRegister, kScratchRegister);
11868defd9ff6930b4e24729971a61cf7469daf119beSteve Block    return kScratchRegister;
11878defd9ff6930b4e24729971a61cf7469daf119beSteve Block  }
11888defd9ff6930b4e24729971a61cf7469daf119beSteve Block  LoadSmiConstant(kScratchRegister, source);
11898defd9ff6930b4e24729971a61cf7469daf119beSteve Block  return kScratchRegister;
11908defd9ff6930b4e24729971a61cf7469daf119beSteve Block}
11918defd9ff6930b4e24729971a61cf7469daf119beSteve Block
1192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
11938defd9ff6930b4e24729971a61cf7469daf119beSteve Blockvoid MacroAssembler::LoadSmiConstant(Register dst, Smi* source) {
1194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  STATIC_ASSERT(kSmiTag == 0);
119544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int value = source->value();
119644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (value == 0) {
11978defd9ff6930b4e24729971a61cf7469daf119beSteve Block    xorl(dst, dst);
1198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Move(dst, source, Assembler::RelocInfoNone());
12008defd9ff6930b4e24729971a61cf7469daf119beSteve Block  }
12018defd9ff6930b4e24729971a61cf7469daf119beSteve Block}
12028defd9ff6930b4e24729971a61cf7469daf119beSteve Block
1203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
12040d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid MacroAssembler::Integer32ToSmi(Register dst, Register src) {
120569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  STATIC_ASSERT(kSmiTag == 0);
1206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!dst.is(src)) {
1207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    movl(dst, src);
1208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  shlp(dst, Immediate(kSmiShift));
1210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
12139dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenvoid MacroAssembler::Integer32ToSmiField(const Operand& dst, Register src) {
121444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (emit_debug_code()) {
12159dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen    testb(dst, Immediate(0x01));
1216257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Label ok;
1217257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    j(zero, &ok, Label::kNear);
1218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Abort(kInteger32ToSmiFieldWritingToNonSmiLocation);
12199dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen    bind(&ok);
12209dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  }
1221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (SmiValuesAre32Bits()) {
1223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(kSmiShift % kBitsPerByte == 0);
1224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movl(Operand(dst, kSmiShift / kBitsPerByte), src);
1225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(SmiValuesAre31Bits());
1227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Integer32ToSmi(kScratchRegister, src);
1228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(dst, kScratchRegister);
1229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
12309dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen}
12319dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
12329dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
12333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::Integer64PlusConstantToSmi(Register dst,
12343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block                                                Register src,
12353ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block                                                int constant) {
12363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  if (dst.is(src)) {
123744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    addl(dst, Immediate(constant));
12383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  } else {
123944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    leal(dst, Operand(src, constant));
12403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
1241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  shlp(dst, Immediate(kSmiShift));
1242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiToInteger32(Register dst, Register src) {
124669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  STATIC_ASSERT(kSmiTag == 0);
1247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!dst.is(src)) {
1248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(dst, src);
1249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (SmiValuesAre32Bits()) {
1252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    shrp(dst, Immediate(kSmiShift));
1253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(SmiValuesAre31Bits());
1255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    sarl(dst, Immediate(kSmiShift));
1256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
12607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid MacroAssembler::SmiToInteger32(Register dst, const Operand& src) {
1261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (SmiValuesAre32Bits()) {
1262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movl(dst, Operand(src, kSmiShift / kBitsPerByte));
1263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(SmiValuesAre31Bits());
1265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movl(dst, src);
1266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    sarl(dst, Immediate(kSmiShift));
1267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
12687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
12697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
12707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
1271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiToInteger64(Register dst, Register src) {
127269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  STATIC_ASSERT(kSmiTag == 0);
12733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  if (!dst.is(src)) {
1274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(dst, src);
1275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  sarp(dst, Immediate(kSmiShift));
1277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (kPointerSize == kInt32Size) {
1278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Sign extend to 64-bit.
1279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movsxlq(dst, dst);
1280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
12849dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenvoid MacroAssembler::SmiToInteger64(Register dst, const Operand& src) {
1285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (SmiValuesAre32Bits()) {
1286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movsxlq(dst, Operand(src, kSmiShift / kBitsPerByte));
1287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(SmiValuesAre31Bits());
1289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(dst, src);
1290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SmiToInteger64(dst, dst);
1291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
12929dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen}
12939dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
12949dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
12953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::SmiTest(Register src) {
1296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AssertSmi(src);
1297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  testp(src, src);
1298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
130144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid MacroAssembler::SmiCompare(Register smi1, Register smi2) {
1302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AssertSmi(smi1);
1303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AssertSmi(smi2);
1304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  cmpp(smi1, smi2);
1305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
13083ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::SmiCompare(Register dst, Smi* src) {
1309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AssertSmi(dst);
131044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Cmp(dst, src);
131144f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
131244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
131344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
131444f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid MacroAssembler::Cmp(Register dst, Smi* src) {
1315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!dst.is(kScratchRegister));
13163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  if (src->value() == 0) {
1317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    testp(dst, dst);
13183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  } else {
1319756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    Register constant_reg = GetSmiConstant(src);
1320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    cmpp(dst, constant_reg);
1321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1325f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkevoid MacroAssembler::SmiCompare(Register dst, const Operand& src) {
1326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AssertSmi(dst);
1327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AssertSmi(src);
1328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  cmpp(dst, src);
13296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
13306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
13316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
13323ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::SmiCompare(const Operand& dst, Register src) {
1333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AssertSmi(dst);
1334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AssertSmi(src);
1335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  cmpp(dst, src);
1336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
13393ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::SmiCompare(const Operand& dst, Smi* src) {
1340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AssertSmi(dst);
1341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (SmiValuesAre32Bits()) {
1342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    cmpl(Operand(dst, kSmiShift / kBitsPerByte), Immediate(src->value()));
1343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(SmiValuesAre31Bits());
1345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    cmpl(dst, Immediate(src));
134644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
1347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
135044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid MacroAssembler::Cmp(const Operand& dst, Smi* src) {
135144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // The Operand cannot use the smi register.
135244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Register smi_reg = GetSmiConstant(src);
1353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!dst.AddressUsesRegister(smi_reg));
1354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  cmpp(dst, smi_reg);
135544f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
135644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
135744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
13589dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenvoid MacroAssembler::SmiCompareInteger32(const Operand& dst, Register src) {
1359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (SmiValuesAre32Bits()) {
1360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    cmpl(Operand(dst, kSmiShift / kBitsPerByte), src);
1361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(SmiValuesAre31Bits());
1363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SmiToInteger32(kScratchRegister, dst);
1364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    cmpl(kScratchRegister, src);
1365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
13669dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen}
13679dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
13689dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
13693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::PositiveSmiTimesPowerOfTwoToInteger64(Register dst,
13703ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block                                                           Register src,
13713ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block                                                           int power) {
1372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(power >= 0);
1373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(power < 64);
13743ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  if (power == 0) {
13753ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    SmiToInteger64(dst, src);
13763ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    return;
13773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
13783ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  if (!dst.is(src)) {
1379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(dst, src);
13803ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
13813ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  if (power < kSmiShift) {
1382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    sarp(dst, Immediate(kSmiShift - power));
13833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  } else if (power > kSmiShift) {
1384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    shlp(dst, Immediate(power - kSmiShift));
13853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
1386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
13897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid MacroAssembler::PositiveSmiDivPowerOfTwoToInteger32(Register dst,
13907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                                                         Register src,
13917f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                                                         int power) {
1392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((0 <= power) && (power < 32));
13937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  if (dst.is(src)) {
1394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    shrp(dst, Immediate(power + kSmiShift));
13957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  } else {
13967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch    UNIMPLEMENTED();  // Not used.
13977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  }
13987f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
13997f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
14007f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
1401257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SmiOrIfSmis(Register dst, Register src1, Register src2,
1402257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                 Label* on_not_smis,
1403257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                 Label::Distance near_jump) {
1404257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (dst.is(src1) || dst.is(src2)) {
1405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!src1.is(kScratchRegister));
1406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!src2.is(kScratchRegister));
1407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(kScratchRegister, src1);
1408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    orp(kScratchRegister, src2);
1409257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    JumpIfNotSmi(kScratchRegister, on_not_smis, near_jump);
1410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(dst, kScratchRegister);
1411257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  } else {
1412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(dst, src1);
1413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    orp(dst, src2);
1414257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    JumpIfNotSmi(dst, on_not_smis, near_jump);
1415257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1416257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1417257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1418257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
14193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockCondition MacroAssembler::CheckSmi(Register src) {
142069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  STATIC_ASSERT(kSmiTag == 0);
1421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  testb(src, Immediate(kSmiTagMask));
14223ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  return zero;
1423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
14261e0659c275bb392c045087af4f6b0d7565cb3d77Steve BlockCondition MacroAssembler::CheckSmi(const Operand& src) {
142769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  STATIC_ASSERT(kSmiTag == 0);
14281e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  testb(src, Immediate(kSmiTagMask));
14291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  return zero;
14301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}
14311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
14321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
1433f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochCondition MacroAssembler::CheckNonNegativeSmi(Register src) {
143469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  STATIC_ASSERT(kSmiTag == 0);
1435e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // Test that both bits of the mask 0x8000000000000001 are zero.
1436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(kScratchRegister, src);
1437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  rolp(kScratchRegister, Immediate(1));
14388defd9ff6930b4e24729971a61cf7469daf119beSteve Block  testb(kScratchRegister, Immediate(3));
1439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return zero;
1440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCondition MacroAssembler::CheckBothSmi(Register first, Register second) {
1444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (first.is(second)) {
1445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return CheckSmi(first);
1446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
144769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  STATIC_ASSERT(kSmiTag == 0 && kHeapObjectTag == 1 && kHeapObjectTagMask == 3);
1448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (SmiValuesAre32Bits()) {
1449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    leal(kScratchRegister, Operand(first, second, times_1, 0));
1450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    testb(kScratchRegister, Immediate(0x03));
1451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(SmiValuesAre31Bits());
1453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movl(kScratchRegister, first);
1454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    orl(kScratchRegister, second);
1455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    testb(kScratchRegister, Immediate(kSmiTagMask));
1456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
14573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  return zero;
1458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1461f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochCondition MacroAssembler::CheckBothNonNegativeSmi(Register first,
1462f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch                                                  Register second) {
1463d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  if (first.is(second)) {
1464f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch    return CheckNonNegativeSmi(first);
1465d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  }
1466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(kScratchRegister, first);
1467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  orp(kScratchRegister, second);
1468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  rolp(kScratchRegister, Immediate(1));
1469f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  testl(kScratchRegister, Immediate(3));
1470d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  return zero;
1471d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
1472d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1473d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
1474bb769b257e753aafcbd96767abb2abc645eaa20cBen MurdochCondition MacroAssembler::CheckEitherSmi(Register first,
1475bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch                                         Register second,
1476bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch                                         Register scratch) {
1477e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  if (first.is(second)) {
1478e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    return CheckSmi(first);
1479e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
1480bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  if (scratch.is(second)) {
1481bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch    andl(scratch, first);
1482bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  } else {
1483bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch    if (!scratch.is(first)) {
1484bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch      movl(scratch, first);
1485bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch    }
1486bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch    andl(scratch, second);
1487bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  }
1488bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  testb(scratch, Immediate(kSmiTagMask));
1489e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  return zero;
1490e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
1491e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
1492e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
14933ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockCondition MacroAssembler::CheckInteger32ValidSmiValue(Register src) {
1494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (SmiValuesAre32Bits()) {
1495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // A 32-bit integer value can always be converted to a smi.
1496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return always;
1497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(SmiValuesAre31Bits());
1499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    cmpl(src, Immediate(0xc0000000));
1500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return positive;
1501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
15053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockCondition MacroAssembler::CheckUInteger32ValidSmiValue(Register src) {
1506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (SmiValuesAre32Bits()) {
1507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // An unsigned 32-bit integer value is valid as long as the high bit
1508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // is not set.
1509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    testl(src, src);
1510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return positive;
1511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(SmiValuesAre31Bits());
1513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    testl(src, Immediate(0xc0000000));
1514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return zero;
1515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
15191e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::CheckSmiToIndicator(Register dst, Register src) {
15201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  if (dst.is(src)) {
15211e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    andl(dst, Immediate(kSmiTagMask));
15221e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  } else {
15231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    movl(dst, Immediate(kSmiTagMask));
15241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    andl(dst, src);
15251e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
15261e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}
15271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
15281e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
15291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::CheckSmiToIndicator(Register dst, const Operand& src) {
15301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  if (!(src.AddressUsesRegister(dst))) {
15311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    movl(dst, Immediate(kSmiTagMask));
15321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    andl(dst, src);
15331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  } else {
15341e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    movl(dst, src);
15351e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    andl(dst, Immediate(kSmiTagMask));
15361e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
15371e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}
15381e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
15391e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
1540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::JumpIfValidSmiValue(Register src,
1541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                         Label* on_valid,
1542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                         Label::Distance near_jump) {
1543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Condition is_valid = CheckInteger32ValidSmiValue(src);
1544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  j(is_valid, on_valid, near_jump);
1545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1548257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::JumpIfNotValidSmiValue(Register src,
1549257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                            Label* on_invalid,
1550257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                            Label::Distance near_jump) {
1551257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Condition is_valid = CheckInteger32ValidSmiValue(src);
1552257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  j(NegateCondition(is_valid), on_invalid, near_jump);
1553257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1554257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1555257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::JumpIfUIntValidSmiValue(Register src,
1557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                             Label* on_valid,
1558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                             Label::Distance near_jump) {
1559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Condition is_valid = CheckUInteger32ValidSmiValue(src);
1560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  j(is_valid, on_valid, near_jump);
1561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1564257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::JumpIfUIntNotValidSmiValue(Register src,
1565257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                                Label* on_invalid,
1566257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                                Label::Distance near_jump) {
1567257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Condition is_valid = CheckUInteger32ValidSmiValue(src);
1568257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  j(NegateCondition(is_valid), on_invalid, near_jump);
1569257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1570257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1571257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1572257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::JumpIfSmi(Register src,
1573257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                               Label* on_smi,
1574257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                               Label::Distance near_jump) {
1575257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Condition smi = CheckSmi(src);
1576257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  j(smi, on_smi, near_jump);
1577257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1578257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1579257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1580257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::JumpIfNotSmi(Register src,
1581257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                  Label* on_not_smi,
1582257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                  Label::Distance near_jump) {
1583257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Condition smi = CheckSmi(src);
1584257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  j(NegateCondition(smi), on_not_smi, near_jump);
1585257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1586257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1587257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1588257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::JumpUnlessNonNegativeSmi(
1589257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Register src, Label* on_not_smi_or_negative,
1590257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Label::Distance near_jump) {
1591257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Condition non_negative_smi = CheckNonNegativeSmi(src);
1592257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  j(NegateCondition(non_negative_smi), on_not_smi_or_negative, near_jump);
1593257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1594257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1595257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1596257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::JumpIfSmiEqualsConstant(Register src,
1597257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                             Smi* constant,
1598257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                             Label* on_equals,
1599257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                             Label::Distance near_jump) {
1600257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  SmiCompare(src, constant);
1601257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  j(equal, on_equals, near_jump);
1602257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1603257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1604257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1605257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::JumpIfNotBothSmi(Register src1,
1606257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                      Register src2,
1607257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                      Label* on_not_both_smi,
1608257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                      Label::Distance near_jump) {
1609257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Condition both_smi = CheckBothSmi(src1, src2);
1610257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  j(NegateCondition(both_smi), on_not_both_smi, near_jump);
1611257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1612257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1613257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1614257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::JumpUnlessBothNonNegativeSmi(Register src1,
1615257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                                  Register src2,
1616257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                                  Label* on_not_both_smi,
1617257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                                  Label::Distance near_jump) {
1618257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Condition both_smi = CheckBothNonNegativeSmi(src1, src2);
1619257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  j(NegateCondition(both_smi), on_not_both_smi, near_jump);
1620257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1621257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1622257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
16233ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::SmiAddConstant(Register dst, Register src, Smi* constant) {
16243ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  if (constant->value() == 0) {
16253ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    if (!dst.is(src)) {
1626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      movp(dst, src);
16273ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    }
16288defd9ff6930b4e24729971a61cf7469daf119beSteve Block    return;
16293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  } else if (dst.is(src)) {
1630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!dst.is(kScratchRegister));
1631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Register constant_reg = GetSmiConstant(constant);
1632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    addp(dst, constant_reg);
1633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
1634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LoadSmiConstant(dst, constant);
1635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    addp(dst, src);
1636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1640f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkevoid MacroAssembler::SmiAddConstant(const Operand& dst, Smi* constant) {
1641f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  if (constant->value() != 0) {
1642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (SmiValuesAre32Bits()) {
1643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      addl(Operand(dst, kSmiShift / kBitsPerByte),
1644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           Immediate(constant->value()));
1645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
1646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(SmiValuesAre31Bits());
1647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      addp(dst, Immediate(constant));
1648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1649f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  }
1650f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke}
1651f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
1652f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
1653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::SmiAddConstant(Register dst, Register src, Smi* constant,
1654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                    SmiOperationConstraints constraints,
1655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    Label* bailout_label,
1656257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                    Label::Distance near_jump) {
1657257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (constant->value() == 0) {
1658257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (!dst.is(src)) {
1659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      movp(dst, src);
1660257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
1661257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  } else if (dst.is(src)) {
1662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!dst.is(kScratchRegister));
1663257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    LoadSmiConstant(kScratchRegister, constant);
1664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    addp(dst, kScratchRegister);
1665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (constraints & SmiOperationConstraint::kBailoutOnNoOverflow) {
1666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      j(no_overflow, bailout_label, near_jump);
1667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(constraints & SmiOperationConstraint::kPreserveSourceRegister);
1668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      subp(dst, kScratchRegister);
1669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (constraints & SmiOperationConstraint::kBailoutOnOverflow) {
1670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (constraints & SmiOperationConstraint::kPreserveSourceRegister) {
1671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Label done;
1672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        j(no_overflow, &done, Label::kNear);
1673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        subp(dst, kScratchRegister);
1674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        jmp(bailout_label, near_jump);
1675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        bind(&done);
1676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
1677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Bailout if overflow without reserving src.
1678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        j(overflow, bailout_label, near_jump);
1679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
1681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UNREACHABLE();
1682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1683257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  } else {
1684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(constraints & SmiOperationConstraint::kPreserveSourceRegister);
1685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(constraints & SmiOperationConstraint::kBailoutOnOverflow);
1686257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    LoadSmiConstant(dst, constant);
1687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    addp(dst, src);
1688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    j(overflow, bailout_label, near_jump);
1689257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1690257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1691257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1692257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
16933ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::SmiSubConstant(Register dst, Register src, Smi* constant) {
16943ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  if (constant->value() == 0) {
1695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (!dst.is(src)) {
1696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      movp(dst, src);
1697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
16983ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  } else if (dst.is(src)) {
1699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!dst.is(kScratchRegister));
17008defd9ff6930b4e24729971a61cf7469daf119beSteve Block    Register constant_reg = GetSmiConstant(constant);
1701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    subp(dst, constant_reg);
17023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  } else {
17033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    if (constant->value() == Smi::kMinValue) {
17048defd9ff6930b4e24729971a61cf7469daf119beSteve Block      LoadSmiConstant(dst, constant);
17059dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen      // Adding and subtracting the min-value gives the same result, it only
17069dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen      // differs on the overflow bit, which we don't check here.
1707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      addp(dst, src);
1708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
17099dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen      // Subtract by adding the negation.
17108defd9ff6930b4e24729971a61cf7469daf119beSteve Block      LoadSmiConstant(dst, Smi::FromInt(-constant->value()));
1711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      addp(dst, src);
1712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::SmiSubConstant(Register dst, Register src, Smi* constant,
1718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                    SmiOperationConstraints constraints,
1719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    Label* bailout_label,
1720257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                    Label::Distance near_jump) {
1721257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (constant->value() == 0) {
1722257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (!dst.is(src)) {
1723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      movp(dst, src);
1724257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
1725257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  } else if (dst.is(src)) {
1726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!dst.is(kScratchRegister));
1727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LoadSmiConstant(kScratchRegister, constant);
1728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    subp(dst, kScratchRegister);
1729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (constraints & SmiOperationConstraint::kBailoutOnNoOverflow) {
1730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      j(no_overflow, bailout_label, near_jump);
1731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(constraints & SmiOperationConstraint::kPreserveSourceRegister);
1732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      addp(dst, kScratchRegister);
1733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (constraints & SmiOperationConstraint::kBailoutOnOverflow) {
1734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (constraints & SmiOperationConstraint::kPreserveSourceRegister) {
1735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Label done;
1736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        j(no_overflow, &done, Label::kNear);
1737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        addp(dst, kScratchRegister);
1738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        jmp(bailout_label, near_jump);
1739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        bind(&done);
1740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
1741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Bailout if overflow without reserving src.
1742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        j(overflow, bailout_label, near_jump);
1743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1744257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    } else {
1745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UNREACHABLE();
1746257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
1747257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  } else {
1748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(constraints & SmiOperationConstraint::kPreserveSourceRegister);
1749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(constraints & SmiOperationConstraint::kBailoutOnOverflow);
1750257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (constant->value() == Smi::kMinValue) {
1751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(!dst.is(kScratchRegister));
1752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      movp(dst, src);
1753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      LoadSmiConstant(kScratchRegister, constant);
1754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      subp(dst, kScratchRegister);
1755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      j(overflow, bailout_label, near_jump);
1756257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    } else {
1757257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      // Subtract by adding the negation.
1758257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      LoadSmiConstant(dst, Smi::FromInt(-(constant->value())));
1759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      addp(dst, src);
1760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      j(overflow, bailout_label, near_jump);
1761257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
1762257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1763257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1764257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1765257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1766257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SmiNeg(Register dst,
1767257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                            Register src,
1768257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                            Label* on_smi_result,
1769257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                            Label::Distance near_jump) {
1770257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (dst.is(src)) {
1771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!dst.is(kScratchRegister));
1772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(kScratchRegister, src);
1773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    negp(dst);  // Low 32 bits are retained as zero by negation.
1774257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // Test if result is zero or Smi::kMinValue.
1775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    cmpp(dst, kScratchRegister);
1776257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    j(not_equal, on_smi_result, near_jump);
1777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(src, kScratchRegister);
1778257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  } else {
1779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(dst, src);
1780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    negp(dst);
1781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    cmpp(dst, src);
1782257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // If the result is zero or Smi::kMinValue, negation failed to create a smi.
1783257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    j(not_equal, on_smi_result, near_jump);
1784257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1785257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1786257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1787257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<class T>
1789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void SmiAddHelper(MacroAssembler* masm,
1790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         Register dst,
1791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         Register src1,
1792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         T src2,
1793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         Label* on_not_smi_result,
1794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         Label::Distance near_jump) {
1795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (dst.is(src1)) {
1796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Label done;
1797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    masm->addp(dst, src2);
1798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    masm->j(no_overflow, &done, Label::kNear);
1799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Restore src1.
1800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    masm->subp(dst, src2);
1801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    masm->jmp(on_not_smi_result, near_jump);
1802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    masm->bind(&done);
1803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    masm->movp(dst, src1);
1805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    masm->addp(dst, src2);
1806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    masm->j(overflow, on_not_smi_result, near_jump);
1807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1811257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SmiAdd(Register dst,
1812257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                            Register src1,
1813257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                            Register src2,
1814257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                            Label* on_not_smi_result,
1815257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                            Label::Distance near_jump) {
1816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_NOT_NULL(on_not_smi_result);
1817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!dst.is(src2));
1818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SmiAddHelper<Register>(this, dst, src1, src2, on_not_smi_result, near_jump);
1819257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1820257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1821257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1822257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SmiAdd(Register dst,
1823257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                            Register src1,
1824257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                            const Operand& src2,
1825257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                            Label* on_not_smi_result,
1826257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                            Label::Distance near_jump) {
1827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_NOT_NULL(on_not_smi_result);
1828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!src2.AddressUsesRegister(dst));
1829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SmiAddHelper<Operand>(this, dst, src1, src2, on_not_smi_result, near_jump);
1830257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1831257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1832257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
18330d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid MacroAssembler::SmiAdd(Register dst,
18340d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                            Register src1,
18350d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                            Register src2) {
18360d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // No overflow checking. Use only when it's known that
18370d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // overflowing is impossible.
183844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (!dst.is(src1)) {
1839257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (emit_debug_code()) {
1840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      movp(kScratchRegister, src1);
1841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      addp(kScratchRegister, src2);
1842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Check(no_overflow, kSmiAdditionOverflow);
1843257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
1844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    leap(dst, Operand(src1, src2, times_1, 0));
1845257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  } else {
1846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    addp(dst, src2);
1847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Assert(no_overflow, kSmiAdditionOverflow);
1848257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1849257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1850257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1851257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<class T>
1853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void SmiSubHelper(MacroAssembler* masm,
1854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         Register dst,
1855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         Register src1,
1856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         T src2,
1857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         Label* on_not_smi_result,
1858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         Label::Distance near_jump) {
1859257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (dst.is(src1)) {
1860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Label done;
1861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    masm->subp(dst, src2);
1862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    masm->j(no_overflow, &done, Label::kNear);
1863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Restore src1.
1864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    masm->addp(dst, src2);
1865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    masm->jmp(on_not_smi_result, near_jump);
1866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    masm->bind(&done);
1867257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  } else {
1868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    masm->movp(dst, src1);
1869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    masm->subp(dst, src2);
1870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    masm->j(overflow, on_not_smi_result, near_jump);
1871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::SmiSub(Register dst,
1876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            Register src1,
1877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            Register src2,
1878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            Label* on_not_smi_result,
1879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            Label::Distance near_jump) {
1880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_NOT_NULL(on_not_smi_result);
1881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!dst.is(src2));
1882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SmiSubHelper<Register>(this, dst, src1, src2, on_not_smi_result, near_jump);
1883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
18860d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid MacroAssembler::SmiSub(Register dst,
1887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            Register src1,
1888257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                            const Operand& src2,
1889257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                            Label* on_not_smi_result,
1890257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                            Label::Distance near_jump) {
1891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_NOT_NULL(on_not_smi_result);
1892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!src2.AddressUsesRegister(dst));
1893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SmiSubHelper<Operand>(this, dst, src1, src2, on_not_smi_result, near_jump);
1894257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1895257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1896257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<class T>
1898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void SmiSubNoOverflowHelper(MacroAssembler* masm,
1899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   Register dst,
1900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   Register src1,
1901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   T src2) {
19020d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // No overflow checking. Use only when it's known that
19030d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // overflowing is impossible (e.g., subtracting two positive smis).
190444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (!dst.is(src1)) {
1905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    masm->movp(dst, src1);
1906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  masm->subp(dst, src2);
1908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  masm->Assert(no_overflow, kSmiSubtractionOverflow);
1909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::SmiSub(Register dst, Register src1, Register src2) {
1913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!dst.is(src2));
1914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SmiSubNoOverflowHelper<Register>(this, dst, src1, src2);
1915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::SmiSub(Register dst,
1919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            Register src1,
1920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            const Operand& src2) {
1921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SmiSubNoOverflowHelper<Operand>(this, dst, src1, src2);
1922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1925257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SmiMul(Register dst,
1926257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                            Register src1,
1927257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                            Register src2,
1928257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                            Label* on_not_smi_result,
1929257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                            Label::Distance near_jump) {
1930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!dst.is(src2));
1931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!dst.is(kScratchRegister));
1932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!src1.is(kScratchRegister));
1933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!src2.is(kScratchRegister));
1934257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1935257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (dst.is(src1)) {
1936257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Label failure, zero_correct_result;
1937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(kScratchRegister, src1);  // Create backup for later testing.
1938257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    SmiToInteger64(dst, src1);
1939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    imulp(dst, src2);
1940257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    j(overflow, &failure, Label::kNear);
1941257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1942257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // Check for negative zero result.  If product is zero, and one
1943257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // argument is negative, go to slow case.
1944257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Label correct_result;
1945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    testp(dst, dst);
1946257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    j(not_zero, &correct_result, Label::kNear);
1947257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(dst, kScratchRegister);
1949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    xorp(dst, src2);
1950257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // Result was positive zero.
1951257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    j(positive, &zero_correct_result, Label::kNear);
1952257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1953257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    bind(&failure);  // Reused failure exit, restores src1.
1954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(src1, kScratchRegister);
1955257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    jmp(on_not_smi_result, near_jump);
1956257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1957257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    bind(&zero_correct_result);
1958257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Set(dst, 0);
1959257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1960257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    bind(&correct_result);
1961257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  } else {
1962257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    SmiToInteger64(dst, src1);
1963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    imulp(dst, src2);
1964257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    j(overflow, on_not_smi_result, near_jump);
1965257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // Check for negative zero result.  If product is zero, and one
1966257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // argument is negative, go to slow case.
1967257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Label correct_result;
1968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    testp(dst, dst);
1969257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    j(not_zero, &correct_result, Label::kNear);
1970257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // One of src1 and src2 is zero, the check whether the other is
1971257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // negative.
1972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(kScratchRegister, src1);
1973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    xorp(kScratchRegister, src2);
1974257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    j(negative, on_not_smi_result, near_jump);
1975257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    bind(&correct_result);
1976257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1977257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
1978257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1979257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1980257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SmiDiv(Register dst,
1981257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                            Register src1,
1982257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                            Register src2,
1983257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                            Label* on_not_smi_result,
1984257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                            Label::Distance near_jump) {
1985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!src1.is(kScratchRegister));
1986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!src2.is(kScratchRegister));
1987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!dst.is(kScratchRegister));
1988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!src2.is(rax));
1989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!src2.is(rdx));
1990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!src1.is(rdx));
1991257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1992257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Check for 0 divisor (result is +/-Infinity).
1993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  testp(src2, src2);
1994257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  j(zero, on_not_smi_result, near_jump);
1995257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
1996257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (src1.is(rax)) {
1997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(kScratchRegister, src1);
1998257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1999257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  SmiToInteger32(rax, src1);
2000257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // We need to rule out dividing Smi::kMinValue by -1, since that would
2001257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // overflow in idiv and raise an exception.
2002257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // We combine this with negative zero test (negative zero only happens
2003257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // when dividing zero by a negative number).
2004257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2005257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // We overshoot a little and go to slow case if we divide min-value
2006257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // by any negative value, not just -1.
2007257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Label safe_div;
2008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  testl(rax, Immediate(~Smi::kMinValue));
2009257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  j(not_zero, &safe_div, Label::kNear);
2010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  testp(src2, src2);
2011257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (src1.is(rax)) {
2012257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    j(positive, &safe_div, Label::kNear);
2013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(src1, kScratchRegister);
2014257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    jmp(on_not_smi_result, near_jump);
2015257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  } else {
2016257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    j(negative, on_not_smi_result, near_jump);
2017257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
2018257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  bind(&safe_div);
2019257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2020257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  SmiToInteger32(src2, src2);
2021257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Sign extend src1 into edx:eax.
2022257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  cdq();
2023257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  idivl(src2);
2024257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Integer32ToSmi(src2, src2);
2025257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Check that the remainder is zero.
2026257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  testl(rdx, rdx);
2027257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (src1.is(rax)) {
2028257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Label smi_result;
2029257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    j(zero, &smi_result, Label::kNear);
2030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(src1, kScratchRegister);
2031257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    jmp(on_not_smi_result, near_jump);
2032257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    bind(&smi_result);
2033257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  } else {
2034257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    j(not_zero, on_not_smi_result, near_jump);
2035257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
2036257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (!dst.is(src1) && src1.is(rax)) {
2037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(src1, kScratchRegister);
2038257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
2039257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Integer32ToSmi(dst, rax);
2040257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
2041257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2042257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2043257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SmiMod(Register dst,
2044257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                            Register src1,
2045257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                            Register src2,
2046257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                            Label* on_not_smi_result,
2047257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                            Label::Distance near_jump) {
2048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!dst.is(kScratchRegister));
2049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!src1.is(kScratchRegister));
2050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!src2.is(kScratchRegister));
2051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!src2.is(rax));
2052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!src2.is(rdx));
2053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!src1.is(rdx));
2054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!src1.is(src2));
2055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  testp(src2, src2);
2057257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  j(zero, on_not_smi_result, near_jump);
2058257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2059257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (src1.is(rax)) {
2060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(kScratchRegister, src1);
2061257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
2062257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  SmiToInteger32(rax, src1);
2063257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  SmiToInteger32(src2, src2);
2064257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2065257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Test for the edge case of dividing Smi::kMinValue by -1 (will overflow).
2066257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Label safe_div;
2067257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  cmpl(rax, Immediate(Smi::kMinValue));
2068257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  j(not_equal, &safe_div, Label::kNear);
2069257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  cmpl(src2, Immediate(-1));
2070257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  j(not_equal, &safe_div, Label::kNear);
2071257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Retag inputs and go slow case.
2072257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Integer32ToSmi(src2, src2);
2073257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (src1.is(rax)) {
2074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(src1, kScratchRegister);
2075257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
2076257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  jmp(on_not_smi_result, near_jump);
2077257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  bind(&safe_div);
2078257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2079257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Sign extend eax into edx:eax.
2080257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  cdq();
2081257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  idivl(src2);
2082257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Restore smi tags on inputs.
2083257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Integer32ToSmi(src2, src2);
2084257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (src1.is(rax)) {
2085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(src1, kScratchRegister);
2086257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
2087257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Check for a negative zero result.  If the result is zero, and the
2088257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // dividend is negative, go slow to return a floating point negative zero.
2089257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Label smi_result;
2090257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  testl(rdx, rdx);
2091257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  j(not_zero, &smi_result, Label::kNear);
2092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  testp(src1, src1);
2093257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  j(negative, on_not_smi_result, near_jump);
2094257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  bind(&smi_result);
2095257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Integer32ToSmi(dst, rdx);
2096257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
2097257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2098257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiNot(Register dst, Register src) {
2100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!dst.is(kScratchRegister));
2101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!src.is(kScratchRegister));
2102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (SmiValuesAre32Bits()) {
2103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Set tag and padding bits before negating, so that they are zero
2104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // afterwards.
2105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movl(kScratchRegister, Immediate(~0));
2106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
2107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(SmiValuesAre31Bits());
2108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movl(kScratchRegister, Immediate(1));
2109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (dst.is(src)) {
2111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    xorp(dst, kScratchRegister);
2112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
2113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    leap(dst, Operand(src, kScratchRegister, times_1, 0));
2114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  notp(dst);
2116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiAnd(Register dst, Register src1, Register src2) {
2120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!dst.is(src2));
2121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!dst.is(src1)) {
2122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(dst, src1);
2123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  andp(dst, src2);
2125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
21283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::SmiAndConstant(Register dst, Register src, Smi* constant) {
21293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  if (constant->value() == 0) {
21309fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block    Set(dst, 0);
21313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  } else if (dst.is(src)) {
2132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!dst.is(kScratchRegister));
21338defd9ff6930b4e24729971a61cf7469daf119beSteve Block    Register constant_reg = GetSmiConstant(constant);
2134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    andp(dst, constant_reg);
21353ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  } else {
21368defd9ff6930b4e24729971a61cf7469daf119beSteve Block    LoadSmiConstant(dst, constant);
2137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    andp(dst, src);
2138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiOr(Register dst, Register src1, Register src2) {
2143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!dst.is(src1)) {
2144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!src1.is(src2));
2145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(dst, src1);
2146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  orp(dst, src2);
2148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
21513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::SmiOrConstant(Register dst, Register src, Smi* constant) {
21523ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  if (dst.is(src)) {
2153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!dst.is(kScratchRegister));
21548defd9ff6930b4e24729971a61cf7469daf119beSteve Block    Register constant_reg = GetSmiConstant(constant);
2155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    orp(dst, constant_reg);
21563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  } else {
21578defd9ff6930b4e24729971a61cf7469daf119beSteve Block    LoadSmiConstant(dst, constant);
2158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    orp(dst, src);
2159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
21623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
2163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiXor(Register dst, Register src1, Register src2) {
2164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!dst.is(src1)) {
2165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!src1.is(src2));
2166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(dst, src1);
2167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  xorp(dst, src2);
2169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
21723ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::SmiXorConstant(Register dst, Register src, Smi* constant) {
21733ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  if (dst.is(src)) {
2174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!dst.is(kScratchRegister));
21758defd9ff6930b4e24729971a61cf7469daf119beSteve Block    Register constant_reg = GetSmiConstant(constant);
2176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    xorp(dst, constant_reg);
21773ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  } else {
21788defd9ff6930b4e24729971a61cf7469daf119beSteve Block    LoadSmiConstant(dst, constant);
2179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    xorp(dst, src);
2180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiShiftArithmeticRightConstant(Register dst,
2185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                     Register src,
2186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                     int shift_value) {
2187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(is_uint5(shift_value));
2188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (shift_value > 0) {
2189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (dst.is(src)) {
2190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      sarp(dst, Immediate(shift_value + kSmiShift));
2191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      shlp(dst, Immediate(kSmiShift));
2192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
2193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      UNIMPLEMENTED();  // Not used.
2194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
2195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiShiftLeftConstant(Register dst,
2200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                          Register src,
2201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          int shift_value,
2202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          Label* on_not_smi_result,
2203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          Label::Distance near_jump) {
2204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (SmiValuesAre32Bits()) {
2205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!dst.is(src)) {
2206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      movp(dst, src);
2207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (shift_value > 0) {
2209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Shift amount specified by lower 5 bits, not six as the shl opcode.
2210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      shlq(dst, Immediate(shift_value & 0x1f));
2211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
2213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(SmiValuesAre31Bits());
2214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (dst.is(src)) {
2215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      UNIMPLEMENTED();  // Not used.
2216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
2217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SmiToInteger32(dst, src);
2218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      shll(dst, Immediate(shift_value));
2219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      JumpIfNotValidSmiValue(dst, on_not_smi_result, near_jump);
2220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Integer32ToSmi(dst, dst);
2221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2226257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SmiShiftLogicalRightConstant(
2227257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Register dst, Register src, int shift_value,
2228257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Label* on_not_smi_result, Label::Distance near_jump) {
2229257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Logic right shift interprets its result as an *unsigned* number.
2230257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (dst.is(src)) {
2231257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    UNIMPLEMENTED();  // Not used.
2232257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  } else {
2233257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (shift_value == 0) {
2234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      testp(src, src);
2235257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      j(negative, on_not_smi_result, near_jump);
2236257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
2237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (SmiValuesAre32Bits()) {
2238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      movp(dst, src);
2239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      shrp(dst, Immediate(shift_value + kSmiShift));
2240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      shlp(dst, Immediate(kSmiShift));
2241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
2242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(SmiValuesAre31Bits());
2243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SmiToInteger32(dst, src);
2244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      shrp(dst, Immediate(shift_value));
2245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      JumpIfUIntNotValidSmiValue(dst, on_not_smi_result, near_jump);
2246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Integer32ToSmi(dst, dst);
2247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2248257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
2249257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
2250257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2251257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiShiftLeft(Register dst,
2253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                  Register src1,
2254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  Register src2,
2255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  Label* on_not_smi_result,
2256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  Label::Distance near_jump) {
2257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (SmiValuesAre32Bits()) {
2258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!dst.is(rcx));
2259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!dst.is(src1)) {
2260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      movp(dst, src1);
2261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Untag shift amount.
2263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SmiToInteger32(rcx, src2);
2264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Shift amount specified by lower 5 bits, not six as the shl opcode.
2265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    andp(rcx, Immediate(0x1f));
2266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    shlq_cl(dst);
2267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
2268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(SmiValuesAre31Bits());
2269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!dst.is(kScratchRegister));
2270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!src1.is(kScratchRegister));
2271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!src2.is(kScratchRegister));
2272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!dst.is(src2));
2273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!dst.is(rcx));
2274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (src1.is(rcx) || src2.is(rcx)) {
2276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      movq(kScratchRegister, rcx);
2277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (dst.is(src1)) {
2279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      UNIMPLEMENTED();  // Not used.
2280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
2281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Label valid_result;
2282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SmiToInteger32(dst, src1);
2283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SmiToInteger32(rcx, src2);
2284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      shll_cl(dst);
2285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      JumpIfValidSmiValue(dst, &valid_result, Label::kNear);
2286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // As src1 or src2 could not be dst, we do not need to restore them for
2287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // clobbering dst.
2288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (src1.is(rcx) || src2.is(rcx)) {
2289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (src1.is(rcx)) {
2290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          movq(src1, kScratchRegister);
2291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        } else {
2292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          movq(src2, kScratchRegister);
2293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
2294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      jmp(on_not_smi_result, near_jump);
2296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      bind(&valid_result);
2297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Integer32ToSmi(dst, dst);
2298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2303257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SmiShiftLogicalRight(Register dst,
2304257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                          Register src1,
2305257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                          Register src2,
2306257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                          Label* on_not_smi_result,
2307257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                          Label::Distance near_jump) {
2308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!dst.is(kScratchRegister));
2309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!src1.is(kScratchRegister));
2310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!src2.is(kScratchRegister));
2311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!dst.is(src2));
2312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!dst.is(rcx));
2313257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (src1.is(rcx) || src2.is(rcx)) {
2314257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    movq(kScratchRegister, rcx);
2315257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
2316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (dst.is(src1)) {
2317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UNIMPLEMENTED();  // Not used.
2318257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  } else {
2319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Label valid_result;
2320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SmiToInteger32(dst, src1);
2321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SmiToInteger32(rcx, src2);
2322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    shrl_cl(dst);
2323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    JumpIfUIntValidSmiValue(dst, &valid_result, Label::kNear);
2324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // As src1 or src2 could not be dst, we do not need to restore them for
2325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // clobbering dst.
2326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (src1.is(rcx) || src2.is(rcx)) {
2327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (src1.is(rcx)) {
2328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        movq(src1, kScratchRegister);
2329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
2330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        movq(src2, kScratchRegister);
2331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch     }
2333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    jmp(on_not_smi_result, near_jump);
2334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bind(&valid_result);
2335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Integer32ToSmi(dst, dst);
2336257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
2337257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
2338257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2339257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SmiShiftArithmeticRight(Register dst,
2341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                             Register src1,
2342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                             Register src2) {
2343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!dst.is(kScratchRegister));
2344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!src1.is(kScratchRegister));
2345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!src2.is(kScratchRegister));
2346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!dst.is(rcx));
2347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  SmiToInteger32(rcx, src2);
2349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!dst.is(src1)) {
2350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(dst, src1);
23513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
2352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SmiToInteger32(dst, dst);
2353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  sarl_cl(dst);
2354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Integer32ToSmi(dst, dst);
2355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2358257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::SelectNonSmi(Register dst,
2359257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                  Register src1,
2360257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                  Register src2,
2361257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                  Label* on_not_smis,
2362257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                  Label::Distance near_jump) {
2363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!dst.is(kScratchRegister));
2364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!src1.is(kScratchRegister));
2365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!src2.is(kScratchRegister));
2366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!dst.is(src1));
2367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!dst.is(src2));
2368257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Both operands must not be smis.
2369257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#ifdef DEBUG
2370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Condition not_both_smis = NegateCondition(CheckBothSmi(src1, src2));
2371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Check(not_both_smis, kBothRegistersWereSmisInSelectNonSmi);
2372257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#endif
237369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  STATIC_ASSERT(kSmiTag == 0);
2374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(static_cast<Smi*>(0), Smi::FromInt(0));
2375257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  movl(kScratchRegister, Immediate(kSmiTagMask));
2376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  andp(kScratchRegister, src1);
2377257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  testl(kScratchRegister, src2);
2378257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // If non-zero then both are smis.
2379257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  j(not_zero, on_not_smis, near_jump);
2380257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2381257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Exactly one operand is a smi.
2382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_EQ(1, static_cast<int>(kSmiTagMask));
2383257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // kScratchRegister still holds src1 & kSmiTag, which is either zero or one.
2384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  subp(kScratchRegister, Immediate(1));
2385257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // If src1 is a smi, then scratch register all 1s, else it is all 0s.
2386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(dst, src1);
2387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  xorp(dst, src2);
2388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  andp(dst, kScratchRegister);
2389257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // If src1 is a smi, dst holds src1 ^ src2, else it is zero.
2390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  xorp(dst, src1);
2391257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // If src1 is a smi, dst is src2, else it is src1, i.e., the non-smi.
2392257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
2393257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2394257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
23953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve BlockSmiIndex MacroAssembler::SmiToIndex(Register dst,
23963ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block                                    Register src,
23973ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block                                    int shift) {
2398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (SmiValuesAre32Bits()) {
2399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(is_uint6(shift));
2400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // There is a possible optimization if shift is in the range 60-63, but that
2401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // will (and must) never happen.
2402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!dst.is(src)) {
2403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      movp(dst, src);
2404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (shift < kSmiShift) {
2406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      sarp(dst, Immediate(kSmiShift - shift));
2407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
2408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      shlp(dst, Immediate(shift - kSmiShift));
2409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return SmiIndex(dst, times_1);
24113ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  } else {
2412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(SmiValuesAre31Bits());
2413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(shift >= times_1 && shift <= (static_cast<int>(times_8) + 1));
2414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!dst.is(src)) {
2415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      movp(dst, src);
2416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // We have to sign extend the index register to 64-bit as the SMI might
2418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // be negative.
2419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movsxlq(dst, dst);
2420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (shift == times_1) {
2421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      sarq(dst, Immediate(kSmiShift));
2422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return SmiIndex(dst, times_1);
2423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return SmiIndex(dst, static_cast<ScaleFactor>(shift - 1));
24253ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
2426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockSmiIndex MacroAssembler::SmiToNegativeIndex(Register dst,
2430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                            Register src,
2431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                            int shift) {
2432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (SmiValuesAre32Bits()) {
2433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Register src holds a positive smi.
2434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(is_uint6(shift));
2435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!dst.is(src)) {
2436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      movp(dst, src);
2437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    negp(dst);
2439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (shift < kSmiShift) {
2440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      sarp(dst, Immediate(kSmiShift - shift));
2441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
2442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      shlp(dst, Immediate(shift - kSmiShift));
2443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return SmiIndex(dst, times_1);
24453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  } else {
2446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(SmiValuesAre31Bits());
2447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(shift >= times_1 && shift <= (static_cast<int>(times_8) + 1));
2448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!dst.is(src)) {
2449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      movp(dst, src);
2450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    negq(dst);
2452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (shift == times_1) {
2453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      sarq(dst, Immediate(kSmiShift));
2454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return SmiIndex(dst, times_1);
2455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return SmiIndex(dst, static_cast<ScaleFactor>(shift - 1));
24573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
2458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
246144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid MacroAssembler::AddSmiField(Register dst, const Operand& src) {
2462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (SmiValuesAre32Bits()) {
2463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK_EQ(0, kSmiShift % kBitsPerByte);
2464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    addl(dst, Operand(src, kSmiShift / kBitsPerByte));
2465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
2466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(SmiValuesAre31Bits());
2467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SmiToInteger32(kScratchRegister, src);
2468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    addl(dst, kScratchRegister);
2469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Push(Smi* source) {
2474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t smi = reinterpret_cast<intptr_t>(source);
2475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_int32(smi)) {
2476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Push(Immediate(static_cast<int32_t>(smi)));
2477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
2478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Register constant = GetSmiConstant(source);
2479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Push(constant);
2480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::PushRegisterAsTwoSmis(Register src, Register scratch) {
2485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!src.is(scratch));
2486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(scratch, src);
2487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // High bits.
2488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  shrp(src, Immediate(kPointerSize * kBitsPerByte - kSmiShift));
2489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  shlp(src, Immediate(kSmiShift));
2490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Push(src);
2491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Low bits.
2492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  shlp(scratch, Immediate(kSmiShift));
2493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Push(scratch);
2494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::PopRegisterAsTwoSmis(Register dst, Register scratch) {
2498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!dst.is(scratch));
2499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Pop(scratch);
2500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Low bits.
2501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  shrp(scratch, Immediate(kSmiShift));
2502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Pop(dst);
2503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  shrp(dst, Immediate(kSmiShift));
2504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // High bits.
2505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  shlp(dst, Immediate(kPointerSize * kBitsPerByte - kSmiShift));
2506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  orp(dst, scratch);
2507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Test(const Operand& src, Smi* source) {
2511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (SmiValuesAre32Bits()) {
2512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    testl(Operand(src, kIntSize), Immediate(source->value()));
2513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
2514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(SmiValuesAre31Bits());
2515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    testl(src, Immediate(source));
2516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ----------------------------------------------------------------------------
2521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2523257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::JumpIfNotString(Register object,
2524257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                     Register object_map,
2525257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                     Label* not_string,
2526257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                     Label::Distance near_jump) {
2527257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Condition is_smi = CheckSmi(object);
2528257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  j(is_smi, not_string, near_jump);
2529257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  CmpObjectType(object, FIRST_NONSTRING_TYPE, object_map);
2530257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  j(above_equal, not_string, near_jump);
2531257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
2532257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2533257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::JumpIfNotBothSequentialOneByteStrings(
2535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Register first_object, Register second_object, Register scratch1,
2536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Register scratch2, Label* on_fail, Label::Distance near_jump) {
2537257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Check that both objects are not smis.
2538257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Condition either_smi = CheckEitherSmi(first_object, second_object);
2539257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  j(either_smi, on_fail, near_jump);
2540257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2541257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Load instance type for both strings.
2542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(scratch1, FieldOperand(first_object, HeapObject::kMapOffset));
2543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(scratch2, FieldOperand(second_object, HeapObject::kMapOffset));
2544257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  movzxbl(scratch1, FieldOperand(scratch1, Map::kInstanceTypeOffset));
2545257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  movzxbl(scratch2, FieldOperand(scratch2, Map::kInstanceTypeOffset));
2546257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Check that both are flat one-byte strings.
2548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kNotStringTag != 0);
2549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const int kFlatOneByteStringMask =
2550257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask;
2551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const int kFlatOneByteStringTag =
2552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      kStringTag | kOneByteStringTag | kSeqStringTag;
2553257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  andl(scratch1, Immediate(kFlatOneByteStringMask));
2555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  andl(scratch2, Immediate(kFlatOneByteStringMask));
2556257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Interleave the bits to check both scratch1 and scratch2 in one test.
2557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_EQ(0, kFlatOneByteStringMask & (kFlatOneByteStringMask << 3));
2558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  leap(scratch1, Operand(scratch1, scratch2, times_8, 0));
2559257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  cmpl(scratch1,
2560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       Immediate(kFlatOneByteStringTag + (kFlatOneByteStringTag << 3)));
2561257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  j(not_equal, on_fail, near_jump);
2562257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
2563257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2564257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::JumpIfInstanceTypeIsNotSequentialOneByte(
2566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Register instance_type, Register scratch, Label* failure,
2567257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Label::Distance near_jump) {
2568257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (!scratch.is(instance_type)) {
2569257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    movl(scratch, instance_type);
2570257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
2571257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const int kFlatOneByteStringMask =
2573257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask;
2574257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  andl(scratch, Immediate(kFlatOneByteStringMask));
2576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  cmpl(scratch, Immediate(kStringTag | kSeqStringTag | kOneByteStringTag));
2577257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  j(not_equal, failure, near_jump);
2578257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
2579257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2580257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialOneByte(
2582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Register first_object_instance_type, Register second_object_instance_type,
2583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Register scratch1, Register scratch2, Label* on_fail,
2584257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Label::Distance near_jump) {
2585257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Load instance type for both strings.
2586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(scratch1, first_object_instance_type);
2587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(scratch2, second_object_instance_type);
2588257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Check that both are flat one-byte strings.
2590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kNotStringTag != 0);
2591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const int kFlatOneByteStringMask =
2592257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask;
2593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const int kFlatOneByteStringTag =
2594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      kStringTag | kOneByteStringTag | kSeqStringTag;
2595257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  andl(scratch1, Immediate(kFlatOneByteStringMask));
2597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  andl(scratch2, Immediate(kFlatOneByteStringMask));
2598257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Interleave the bits to check both scratch1 and scratch2 in one test.
2599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_EQ(0, kFlatOneByteStringMask & (kFlatOneByteStringMask << 3));
2600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  leap(scratch1, Operand(scratch1, scratch2, times_8, 0));
2601257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  cmpl(scratch1,
2602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       Immediate(kFlatOneByteStringTag + (kFlatOneByteStringTag << 3)));
2603257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  j(not_equal, on_fail, near_jump);
2604257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
2605257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2606257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
2607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<class T>
2608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void JumpIfNotUniqueNameHelper(MacroAssembler* masm,
2609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      T operand_or_register,
2610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      Label* not_unique_name,
2611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      Label::Distance distance) {
2612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0);
2613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Label succeed;
2614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  masm->testb(operand_or_register,
2615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              Immediate(kIsNotStringMask | kIsNotInternalizedMask));
2616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  masm->j(zero, &succeed, Label::kNear);
2617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  masm->cmpb(operand_or_register, Immediate(static_cast<uint8_t>(SYMBOL_TYPE)));
2618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  masm->j(not_equal, not_unique_name, distance);
2619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  masm->bind(&succeed);
2621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::JumpIfNotUniqueNameInstanceType(Operand operand,
2625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                     Label* not_unique_name,
2626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                     Label::Distance distance) {
2627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  JumpIfNotUniqueNameHelper<Operand>(this, operand, not_unique_name, distance);
2628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::JumpIfNotUniqueNameInstanceType(Register reg,
2632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                     Label* not_unique_name,
2633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                     Label::Distance distance) {
2634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  JumpIfNotUniqueNameHelper<Register>(this, reg, not_unique_name, distance);
2635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
263744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
26380d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid MacroAssembler::Move(Register dst, Register src) {
26390d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  if (!dst.is(src)) {
2640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(dst, src);
26416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
26426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
26436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
26446ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
2645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Move(Register dst, Handle<Object> source) {
2646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AllowDeferredHandleDereference smi_check;
2647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (source->IsSmi()) {
26483ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    Move(dst, Smi::cast(*source));
2649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
2650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MoveHeapObject(dst, source);
2651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Move(const Operand& dst, Handle<Object> source) {
2656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AllowDeferredHandleDereference smi_check;
2657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (source->IsSmi()) {
26583ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    Move(dst, Smi::cast(*source));
2659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
2660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MoveHeapObject(kScratchRegister, source);
2661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(dst, kScratchRegister);
2662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2666958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid MacroAssembler::Move(XMMRegister dst, uint32_t src) {
2667958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (src == 0) {
2668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Xorpd(dst, dst);
2669958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } else {
2670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    unsigned pop = base::bits::CountPopulation32(src);
2671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_NE(0u, pop);
2672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (pop == 32) {
2673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Pcmpeqd(dst, dst);
2674958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {
2675958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      movl(kScratchRegister, Immediate(src));
2676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Movq(dst, kScratchRegister);
2677958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2678958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2679958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2680958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2681958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2682958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid MacroAssembler::Move(XMMRegister dst, uint64_t src) {
2683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (src == 0) {
2684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Xorpd(dst, dst);
2685958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } else {
2686958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    unsigned nlz = base::bits::CountLeadingZeros64(src);
2687958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    unsigned ntz = base::bits::CountTrailingZeros64(src);
2688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    unsigned pop = base::bits::CountPopulation64(src);
2689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_NE(0u, pop);
2690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (pop == 64) {
2691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Pcmpeqd(dst, dst);
2692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (pop + ntz == 64) {
2693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Pcmpeqd(dst, dst);
2694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Psllq(dst, ntz);
2695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (pop + nlz == 64) {
2696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Pcmpeqd(dst, dst);
2697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Psrlq(dst, nlz);
2698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
2699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      uint32_t lower = static_cast<uint32_t>(src);
2700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      uint32_t upper = static_cast<uint32_t>(src >> 32);
2701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (upper == 0) {
2702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Move(dst, lower);
2703958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      } else {
2704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        movq(kScratchRegister, src);
2705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Movq(dst, kScratchRegister);
2706958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
2707958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2708958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2709958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2710958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2711958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movaps(XMMRegister dst, XMMRegister src) {
2713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
2714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
2715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vmovaps(dst, src);
27163ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  } else {
2717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    movaps(dst, src);
27183ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
2719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2721f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::Movups(XMMRegister dst, XMMRegister src) {
2722f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (CpuFeatures::IsSupported(AVX)) {
2723f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    CpuFeatureScope scope(this, AVX);
2724f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    vmovups(dst, src);
2725f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else {
2726f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    movups(dst, src);
2727f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
2728f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
2729f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
2730f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::Movups(XMMRegister dst, const Operand& src) {
2731f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (CpuFeatures::IsSupported(AVX)) {
2732f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    CpuFeatureScope scope(this, AVX);
2733f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    vmovups(dst, src);
2734f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else {
2735f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    movups(dst, src);
2736f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
2737f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
2738f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
2739f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::Movups(const Operand& dst, XMMRegister src) {
2740f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (CpuFeatures::IsSupported(AVX)) {
2741f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    CpuFeatureScope scope(this, AVX);
2742f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    vmovups(dst, src);
2743f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else {
2744f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    movups(dst, src);
2745f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
2746f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
2747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movapd(XMMRegister dst, XMMRegister src) {
2749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
2750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
2751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vmovapd(dst, src);
2752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
2753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    movapd(dst, src);
2754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2757f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::Movupd(XMMRegister dst, const Operand& src) {
2758f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (CpuFeatures::IsSupported(AVX)) {
2759f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    CpuFeatureScope scope(this, AVX);
2760f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    vmovupd(dst, src);
2761f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else {
2762f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    movupd(dst, src);
2763f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
2764f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
2765f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
2766f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::Movupd(const Operand& dst, XMMRegister src) {
2767f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (CpuFeatures::IsSupported(AVX)) {
2768f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    CpuFeatureScope scope(this, AVX);
2769f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    vmovupd(dst, src);
2770f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else {
2771f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    movupd(dst, src);
2772f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
2773f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
2774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movsd(XMMRegister dst, XMMRegister src) {
2776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
2777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
2778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vmovsd(dst, dst, src);
2779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
2780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    movsd(dst, src);
2781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movsd(XMMRegister dst, const Operand& src) {
2786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
2787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
2788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vmovsd(dst, src);
27893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
2790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    movsd(dst, src);
27913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
27923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
27933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
27943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movsd(const Operand& dst, XMMRegister src) {
2796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
2797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
2798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vmovsd(dst, src);
27993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
2800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    movsd(dst, src);
28013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
28023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
28033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
28043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movss(XMMRegister dst, XMMRegister src) {
2806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
2807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
2808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vmovss(dst, dst, src);
2809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
2810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    movss(dst, src);
2811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2812958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2813958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2814958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movss(XMMRegister dst, const Operand& src) {
2816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
2817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
2818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vmovss(dst, src);
2819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
2820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    movss(dst, src);
2821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2822958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2823958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2824958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movss(const Operand& dst, XMMRegister src) {
2826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
2827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
2828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vmovss(dst, src);
2829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
2830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    movss(dst, src);
2831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movd(XMMRegister dst, Register src) {
2836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
2837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
2838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vmovd(dst, src);
2839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
2840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    movd(dst, src);
2841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movd(XMMRegister dst, const Operand& src) {
2846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
2847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
2848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vmovd(dst, src);
28493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
2850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    movd(dst, src);
28513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
28523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
28533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
28543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movd(Register dst, XMMRegister src) {
2856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
2857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
2858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vmovd(dst, src);
28593ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  } else {
2860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    movd(dst, src);
28613ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
28623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
28633ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
28643ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
2865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movq(XMMRegister dst, Register src) {
2866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
2867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
2868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vmovq(dst, src);
2869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
2870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    movq(dst, src);
2871e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
2872e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
2873e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
2874e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
2875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movq(Register dst, XMMRegister src) {
2876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
2877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
2878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vmovq(dst, src);
2879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
2880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    movq(dst, src);
2881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2884f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::Movmskps(Register dst, XMMRegister src) {
2885f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (CpuFeatures::IsSupported(AVX)) {
2886f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    CpuFeatureScope scope(this, AVX);
2887f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    vmovmskps(dst, src);
2888f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else {
2889f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    movmskps(dst, src);
2890f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
2891f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
2892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Movmskpd(Register dst, XMMRegister src) {
2894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
2895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
2896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vmovmskpd(dst, src);
2897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
2898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    movmskpd(dst, src);
2899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2902f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::Xorps(XMMRegister dst, XMMRegister src) {
2903f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (CpuFeatures::IsSupported(AVX)) {
2904f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    CpuFeatureScope scope(this, AVX);
2905f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    vxorps(dst, dst, src);
2906f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else {
2907f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    xorps(dst, src);
2908f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
2909f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
2910f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
2911f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::Xorps(XMMRegister dst, const Operand& src) {
2912f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (CpuFeatures::IsSupported(AVX)) {
2913f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    CpuFeatureScope scope(this, AVX);
2914f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    vxorps(dst, dst, src);
2915f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else {
2916f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    xorps(dst, src);
2917f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
2918f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
2919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Roundss(XMMRegister dst, XMMRegister src,
2921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             RoundingMode mode) {
2922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
2923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
2924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vroundss(dst, dst, src, mode);
2925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
2926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    roundss(dst, src, mode);
2927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Roundsd(XMMRegister dst, XMMRegister src,
2932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             RoundingMode mode) {
2933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
2934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
2935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vroundsd(dst, dst, src, mode);
2936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
2937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    roundsd(dst, src, mode);
2938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Sqrtsd(XMMRegister dst, XMMRegister src) {
2943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
2944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
2945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vsqrtsd(dst, dst, src);
2946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
2947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    sqrtsd(dst, src);
2948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Sqrtsd(XMMRegister dst, const Operand& src) {
2953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
2954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
2955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vsqrtsd(dst, dst, src);
2956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
2957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    sqrtsd(dst, src);
2958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Ucomiss(XMMRegister src1, XMMRegister src2) {
2963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
2964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
2965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vucomiss(src1, src2);
2966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
2967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ucomiss(src1, src2);
2968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Ucomiss(XMMRegister src1, const Operand& src2) {
2973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
2974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
2975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vucomiss(src1, src2);
2976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
2977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ucomiss(src1, src2);
2978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Ucomisd(XMMRegister src1, XMMRegister src2) {
2983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
2984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
2985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vucomisd(src1, src2);
2986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
2987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ucomisd(src1, src2);
2988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Ucomisd(XMMRegister src1, const Operand& src2) {
2993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(AVX)) {
2994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, AVX);
2995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    vucomisd(src1, src2);
2996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
2997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ucomisd(src1, src2);
2998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3001f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// ----------------------------------------------------------------------------
3002f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
3003f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::Absps(XMMRegister dst) {
3004f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Andps(dst,
3005f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        ExternalOperand(ExternalReference::address_of_float_abs_constant()));
3006f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
3007f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
3008f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::Negps(XMMRegister dst) {
3009f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Xorps(dst,
3010f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        ExternalOperand(ExternalReference::address_of_float_neg_constant()));
3011f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
3012f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
3013f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::Abspd(XMMRegister dst) {
3014f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Andps(dst,
3015f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        ExternalOperand(ExternalReference::address_of_double_abs_constant()));
3016f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
3017f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
3018f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::Negpd(XMMRegister dst) {
3019f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Xorps(dst,
3020f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        ExternalOperand(ExternalReference::address_of_double_neg_constant()));
3021f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
3022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cmp(Register dst, Handle<Object> source) {
3024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllowDeferredHandleDereference smi_check;
3025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (source->IsSmi()) {
3026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Cmp(dst, Smi::cast(*source));
3027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
3028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MoveHeapObject(kScratchRegister, source);
3029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    cmpp(dst, kScratchRegister);
3030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Cmp(const Operand& dst, Handle<Object> source) {
3035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllowDeferredHandleDereference smi_check;
3036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (source->IsSmi()) {
3037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Cmp(dst, Smi::cast(*source));
3038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
3039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MoveHeapObject(kScratchRegister, source);
3040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    cmpp(dst, kScratchRegister);
3041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Push(Handle<Object> source) {
3046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllowDeferredHandleDereference smi_check;
3047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (source->IsSmi()) {
3048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Push(Smi::cast(*source));
3049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
3050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MoveHeapObject(kScratchRegister, source);
3051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Push(kScratchRegister);
3052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::MoveHeapObject(Register result,
3057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                    Handle<Object> object) {
3058014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(object->IsHeapObject());
3059f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Move(result, object, RelocInfo::EMBEDDED_OBJECT);
3060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::LoadGlobalCell(Register dst, Handle<Cell> cell) {
3064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (dst.is(rax)) {
3065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AllowDeferredHandleDereference embedding_raw_address;
3066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    load_rax(cell.location(), RelocInfo::CELL);
3067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
3068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Move(dst, cell, RelocInfo::CELL);
3069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    movp(dst, Operand(dst, 0));
3070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::CmpWeakValue(Register value, Handle<WeakCell> cell,
3075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  Register scratch) {
3076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Move(scratch, cell, RelocInfo::EMBEDDED_OBJECT);
3077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  cmpp(value, FieldOperand(scratch, WeakCell::kValueOffset));
3078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::GetWeakValue(Register value, Handle<WeakCell> cell) {
3082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Move(value, cell, RelocInfo::EMBEDDED_OBJECT);
3083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  movp(value, FieldOperand(value, WeakCell::kValueOffset));
3084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::LoadWeakValue(Register value, Handle<WeakCell> cell,
3088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                   Label* miss) {
3089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GetWeakValue(value, cell);
3090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  JumpIfSmi(value, miss);
3091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Drop(int stack_elements) {
3095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (stack_elements > 0) {
3096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    addp(rsp, Immediate(stack_elements * kPointerSize));
3097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::DropUnderReturnAddress(int stack_elements,
3102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            Register scratch) {
3103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(stack_elements > 0);
3104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (kPointerSize == kInt64Size && stack_elements == 1) {
3105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    popq(MemOperand(rsp, 0));
3106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return;
3107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  PopReturnAddressTo(scratch);
3110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Drop(stack_elements);
3111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  PushReturnAddressFrom(scratch);
3112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Push(Register src) {
3116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (kPointerSize == kInt64Size) {
3117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    pushq(src);
3118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
3119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // x32 uses 64-bit push for rbp in the prologue.
3120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(src.code() != rbp.code());
3121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    leal(rsp, Operand(rsp, -4));
3122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    movp(Operand(rsp, 0), src);
3123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Push(const Operand& src) {
3128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (kPointerSize == kInt64Size) {
3129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    pushq(src);
3130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
3131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    movp(kScratchRegister, src);
3132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    leal(rsp, Operand(rsp, -4));
3133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    movp(Operand(rsp, 0), kScratchRegister);
3134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::PushQuad(const Operand& src) {
3139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (kPointerSize == kInt64Size) {
3140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    pushq(src);
3141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
3142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    movp(kScratchRegister, src);
3143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    pushq(kScratchRegister);
3144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Push(Immediate value) {
3149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (kPointerSize == kInt64Size) {
3150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    pushq(value);
3151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
3152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    leal(rsp, Operand(rsp, -4));
3153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    movp(Operand(rsp, 0), value);
3154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::PushImm32(int32_t imm32) {
3159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (kPointerSize == kInt64Size) {
3160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    pushq_imm32(imm32);
3161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
3162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    leal(rsp, Operand(rsp, -4));
3163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    movp(Operand(rsp, 0), Immediate(imm32));
3164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Pop(Register dst) {
3169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (kPointerSize == kInt64Size) {
3170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    popq(dst);
3171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
3172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // x32 uses 64-bit pop for rbp in the epilogue.
3173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(dst.code() != rbp.code());
3174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    movp(dst, Operand(rsp, 0));
3175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    leal(rsp, Operand(rsp, 4));
3176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Pop(const Operand& dst) {
3181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (kPointerSize == kInt64Size) {
3182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    popq(dst);
3183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
3184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Register scratch = dst.AddressUsesRegister(kScratchRegister)
3185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        ? kRootRegister : kScratchRegister;
3186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    movp(scratch, Operand(rsp, 0));
3187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    movp(dst, scratch);
3188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    leal(rsp, Operand(rsp, 4));
3189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (scratch.is(kRootRegister)) {
3190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Restore kRootRegister.
3191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InitializeRootRegister();
3192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::PopQuad(const Operand& dst) {
3198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (kPointerSize == kInt64Size) {
3199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    popq(dst);
3200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
3201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    popq(kScratchRegister);
3202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(dst, kScratchRegister);
3203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::LoadSharedFunctionInfoSpecialField(Register dst,
3208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                        Register base,
3209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                        int offset) {
3210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(offset > SharedFunctionInfo::kLengthOffset &&
3211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         offset <= SharedFunctionInfo::kSize &&
3212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         (((offset - SharedFunctionInfo::kLengthOffset) / kIntSize) % 2 == 1));
3213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (kPointerSize == kInt64Size) {
3214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movsxlq(dst, FieldOperand(base, offset));
3215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
3216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(dst, FieldOperand(base, offset));
3217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SmiToInteger32(dst, dst);
3218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::TestBitSharedFunctionInfoSpecialField(Register base,
3223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                           int offset,
3224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                           int bits) {
3225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(offset > SharedFunctionInfo::kLengthOffset &&
3226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         offset <= SharedFunctionInfo::kSize &&
3227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         (((offset - SharedFunctionInfo::kLengthOffset) / kIntSize) % 2 == 1));
3228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (kPointerSize == kInt32Size) {
3229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // On x32, this field is represented by SMI.
3230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bits += kSmiShift;
3231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
32323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int byte_offset = bits / kBitsPerByte;
32333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int bit_in_byte = bits & (kBitsPerByte - 1);
3234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  testb(FieldOperand(base, offset + byte_offset), Immediate(1 << bit_in_byte));
32353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
32363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
32373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Jump(ExternalReference ext) {
323944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  LoadAddress(kScratchRegister, ext);
3240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  jmp(kScratchRegister);
3241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Jump(const Operand& op) {
3245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (kPointerSize == kInt64Size) {
3246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    jmp(op);
3247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
3248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(kScratchRegister, op);
3249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    jmp(kScratchRegister);
3250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Jump(Address destination, RelocInfo::Mode rmode) {
3255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Move(kScratchRegister, destination, rmode);
3256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  jmp(kScratchRegister);
3257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Jump(Handle<Code> code_object, RelocInfo::Mode rmode) {
32613ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // TODO(X64): Inline this
32623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  jmp(code_object, rmode);
3263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
326644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockint MacroAssembler::CallSize(ExternalReference ext) {
326744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Opcode for call kScratchRegister is: Rex.B FF D4 (three bytes).
3268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return LoadAddressSize(ext) +
3269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         Assembler::kCallScratchRegisterInstructionLength;
327044f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
327144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
327244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
3273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Call(ExternalReference ext) {
327444f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG
327544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int end_position = pc_offset() + CallSize(ext);
327644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif
327744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  LoadAddress(kScratchRegister, ext);
3278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  call(kScratchRegister);
327944f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG
328044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(end_position, pc_offset());
328144f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif
3282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Call(const Operand& op) {
3286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (kPointerSize == kInt64Size && !CpuFeatures::IsSupported(ATOM)) {
3287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    call(op);
3288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
3289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(kScratchRegister, op);
3290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    call(kScratchRegister);
3291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Call(Address destination, RelocInfo::Mode rmode) {
329644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG
3297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int end_position = pc_offset() + CallSize(destination);
329844f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif
3299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Move(kScratchRegister, destination, rmode);
3300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  call(kScratchRegister);
330144f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG
330244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(pc_offset(), end_position);
330344f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif
3304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3307257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::Call(Handle<Code> code_object,
3308257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                          RelocInfo::Mode rmode,
3309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          TypeFeedbackId ast_id) {
331044f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG
331144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int end_position = pc_offset() + CallSize(code_object);
331244f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif
3313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(RelocInfo::IsCodeTarget(rmode) ||
3314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      rmode == RelocInfo::CODE_AGE_SEQUENCE);
3315257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  call(code_object, rmode, ast_id);
331644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG
331744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK_EQ(end_position, pc_offset());
331844f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif
3319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Pextrd(Register dst, XMMRegister src, int8_t imm8) {
3323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (imm8 == 0) {
3324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Movd(dst, src);
3325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return;
3326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(SSE4_1)) {
3328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope sse_scope(this, SSE4_1);
3329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    pextrd(dst, src, imm8);
3330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return;
3331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3332f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK_EQ(1, imm8);
3333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  movq(dst, src);
3334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  shrq(dst, Immediate(32));
3335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Pinsrd(XMMRegister dst, Register src, int8_t imm8) {
3339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(SSE4_1)) {
3340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope sse_scope(this, SSE4_1);
3341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    pinsrd(dst, src, imm8);
3342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return;
3343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
334413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Movd(kScratchDoubleReg, src);
3345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (imm8 == 1) {
334613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    punpckldq(dst, kScratchDoubleReg);
3347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
3348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_EQ(0, imm8);
334913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    Movss(dst, kScratchDoubleReg);
3350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Pinsrd(XMMRegister dst, const Operand& src, int8_t imm8) {
3355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(imm8 == 0 || imm8 == 1);
3356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(SSE4_1)) {
3357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope sse_scope(this, SSE4_1);
3358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    pinsrd(dst, src, imm8);
3359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return;
3360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
336113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Movd(kScratchDoubleReg, src);
3362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (imm8 == 1) {
336313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    punpckldq(dst, kScratchDoubleReg);
3364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
3365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_EQ(0, imm8);
336613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    Movss(dst, kScratchDoubleReg);
3367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Lzcntl(Register dst, Register src) {
3372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(LZCNT)) {
3373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, LZCNT);
3374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    lzcntl(dst, src);
3375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return;
3376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label not_zero_src;
3378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bsrl(dst, src);
3379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  j(not_zero, &not_zero_src, Label::kNear);
3380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Set(dst, 63);  // 63^31 == 32
3381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bind(&not_zero_src);
3382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  xorl(dst, Immediate(31));  // for x in [0..31], 31^x == 31 - x
3383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Lzcntl(Register dst, const Operand& src) {
3387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(LZCNT)) {
3388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, LZCNT);
3389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    lzcntl(dst, src);
3390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return;
3391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label not_zero_src;
3393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bsrl(dst, src);
3394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  j(not_zero, &not_zero_src, Label::kNear);
3395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Set(dst, 63);  // 63^31 == 32
3396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bind(&not_zero_src);
3397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  xorl(dst, Immediate(31));  // for x in [0..31], 31^x == 31 - x
3398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Lzcntq(Register dst, Register src) {
3402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(LZCNT)) {
3403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, LZCNT);
3404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    lzcntq(dst, src);
3405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return;
3406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label not_zero_src;
3408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bsrq(dst, src);
3409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  j(not_zero, &not_zero_src, Label::kNear);
3410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Set(dst, 127);  // 127^63 == 64
3411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bind(&not_zero_src);
3412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  xorl(dst, Immediate(63));  // for x in [0..63], 63^x == 63 - x
3413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Lzcntq(Register dst, const Operand& src) {
3417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(LZCNT)) {
3418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, LZCNT);
3419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    lzcntq(dst, src);
3420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return;
3421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label not_zero_src;
3423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bsrq(dst, src);
3424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  j(not_zero, &not_zero_src, Label::kNear);
3425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Set(dst, 127);  // 127^63 == 64
3426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bind(&not_zero_src);
3427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  xorl(dst, Immediate(63));  // for x in [0..63], 63^x == 63 - x
3428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Tzcntq(Register dst, Register src) {
3432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(BMI1)) {
3433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, BMI1);
3434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    tzcntq(dst, src);
3435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return;
3436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label not_zero_src;
3438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bsfq(dst, src);
3439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  j(not_zero, &not_zero_src, Label::kNear);
3440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Define the result of tzcnt(0) separately, because bsf(0) is undefined.
3441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Set(dst, 64);
3442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bind(&not_zero_src);
3443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Tzcntq(Register dst, const Operand& src) {
3447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(BMI1)) {
3448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, BMI1);
3449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    tzcntq(dst, src);
3450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return;
3451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label not_zero_src;
3453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bsfq(dst, src);
3454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  j(not_zero, &not_zero_src, Label::kNear);
3455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Define the result of tzcnt(0) separately, because bsf(0) is undefined.
3456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Set(dst, 64);
3457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bind(&not_zero_src);
3458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Tzcntl(Register dst, Register src) {
3462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(BMI1)) {
3463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, BMI1);
3464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    tzcntl(dst, src);
3465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return;
3466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label not_zero_src;
3468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bsfl(dst, src);
3469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  j(not_zero, &not_zero_src, Label::kNear);
3470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Set(dst, 32);  // The result of tzcnt is 32 if src = 0.
3471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bind(&not_zero_src);
3472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Tzcntl(Register dst, const Operand& src) {
3476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(BMI1)) {
3477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, BMI1);
3478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    tzcntl(dst, src);
3479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return;
3480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label not_zero_src;
3482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bsfl(dst, src);
3483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  j(not_zero, &not_zero_src, Label::kNear);
3484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Set(dst, 32);  // The result of tzcnt is 32 if src = 0.
3485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bind(&not_zero_src);
3486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Popcntl(Register dst, Register src) {
3490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(POPCNT)) {
3491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, POPCNT);
3492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    popcntl(dst, src);
3493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return;
3494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UNREACHABLE();
3496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Popcntl(Register dst, const Operand& src) {
3500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(POPCNT)) {
3501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, POPCNT);
3502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    popcntl(dst, src);
3503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return;
3504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UNREACHABLE();
3506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Popcntq(Register dst, Register src) {
3510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(POPCNT)) {
3511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, POPCNT);
3512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    popcntq(dst, src);
3513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return;
3514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UNREACHABLE();
3516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::Popcntq(Register dst, const Operand& src) {
3520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(POPCNT)) {
3521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CpuFeatureScope scope(this, POPCNT);
3522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    popcntq(dst, src);
3523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return;
3524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UNREACHABLE();
3526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
35291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::Pushad() {
3530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Push(rax);
3531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Push(rcx);
3532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Push(rdx);
3533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Push(rbx);
35341e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Not pushing rsp or rbp.
3535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Push(rsi);
3536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Push(rdi);
3537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Push(r8);
3538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Push(r9);
35391e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // r10 is kScratchRegister.
3540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Push(r11);
3541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Push(r12);
35421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // r13 is kRootRegister.
3543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Push(r14);
3544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Push(r15);
3545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  STATIC_ASSERT(12 == kNumSafepointSavedRegisters);
3546e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // Use lea for symmetry with Popad.
3547e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  int sp_delta =
3548e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      (kNumSafepointRegisters - kNumSafepointSavedRegisters) * kPointerSize;
3549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  leap(rsp, Operand(rsp, -sp_delta));
35501e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}
35511e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
35521e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
35531e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::Popad() {
3554e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  // Popad must not change the flags, so use lea instead of addq.
3555e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  int sp_delta =
3556e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      (kNumSafepointRegisters - kNumSafepointSavedRegisters) * kPointerSize;
3557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  leap(rsp, Operand(rsp, sp_delta));
3558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Pop(r15);
3559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Pop(r14);
3560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Pop(r12);
3561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Pop(r11);
3562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Pop(r9);
3563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Pop(r8);
3564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Pop(rdi);
3565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Pop(rsi);
3566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Pop(rbx);
3567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Pop(rdx);
3568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Pop(rcx);
3569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Pop(rax);
35701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}
35711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
35721e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
35731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::Dropad() {
3574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  addp(rsp, Immediate(kNumSafepointRegisters * kPointerSize));
35751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}
35761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
35771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
35781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// Order general registers are pushed by Pushad:
357944f0eee88ff00398ff7f715fab053374d808c90dSteve Block// rax, rcx, rdx, rbx, rsi, rdi, r8, r9, r11, r14, r15.
35803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochconst int
35813ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochMacroAssembler::kSafepointPushRegisterIndices[Register::kNumRegisters] = {
35821e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    0,
35831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    1,
35841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    2,
35851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    3,
35861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    -1,
35871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    -1,
35881e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    4,
35891e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    5,
35901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    6,
35911e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    7,
35921e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    -1,
35931e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    8,
359444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    9,
3595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    -1,
3596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    10,
3597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    11
35981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block};
35991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
36001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
3601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::StoreToSafepointRegisterSlot(Register dst,
3602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                  const Immediate& imm) {
3603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(SafepointRegisterSlot(dst), imm);
3604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3607e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochvoid MacroAssembler::StoreToSafepointRegisterSlot(Register dst, Register src) {
3608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(SafepointRegisterSlot(dst), src);
3609e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch}
3610e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
3611e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
3612e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochvoid MacroAssembler::LoadFromSafepointRegisterSlot(Register dst, Register src) {
3613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(dst, SafepointRegisterSlot(src));
3614e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch}
3615e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
3616e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
3617e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen MurdochOperand MacroAssembler::SafepointRegisterSlot(Register reg) {
3618e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  return Operand(rsp, SafepointRegisterStackIndex(reg.code()) * kPointerSize);
3619e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch}
3620e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
3621e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
3622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::PushStackHandler() {
3623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Adjust this code if not the case.
3624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  STATIC_ASSERT(StackHandlerConstants::kSize == 1 * kPointerSize);
36253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0);
36263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
36273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Link the current handler as the next handler.
36283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ExternalReference handler_address(Isolate::kHandlerAddress, isolate());
3629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Push(ExternalOperand(handler_address));
3630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
36313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Set this new handler as the current one.
3632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(ExternalOperand(handler_address), rsp);
3633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::PopStackHandler() {
36373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0);
36383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ExternalReference handler_address(Isolate::kHandlerAddress, isolate());
3639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Pop(ExternalOperand(handler_address));
3640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  addp(rsp, Immediate(StackHandlerConstants::kSize - kPointerSize));
3641e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
3642e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
3643e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
3644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::Ret() {
3645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ret(0);
3646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
36491e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::Ret(int bytes_dropped, Register scratch) {
36501e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  if (is_uint16(bytes_dropped)) {
36511e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    ret(bytes_dropped);
36521e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  } else {
3653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PopReturnAddressTo(scratch);
3654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    addp(rsp, Immediate(bytes_dropped));
3655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PushReturnAddressFrom(scratch);
36561e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    ret(0);
36571e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
36581e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}
36591e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
36601e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
3661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::FCmp() {
36623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  fucomip();
36638defd9ff6930b4e24729971a61cf7469daf119beSteve Block  fstp(0);
3664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::CmpObjectType(Register heap_object,
3668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                   InstanceType type,
3669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                   Register map) {
3670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(map, FieldOperand(heap_object, HeapObject::kMapOffset));
3671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CmpInstanceType(map, type);
3672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::CmpInstanceType(Register map, InstanceType type) {
3676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  cmpb(FieldOperand(map, Map::kInstanceTypeOffset),
3677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block       Immediate(static_cast<int8_t>(type)));
3678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
36813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid MacroAssembler::CheckFastElements(Register map,
36823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                       Label* fail,
36833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                       Label::Distance distance) {
3684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
3685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
3686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(FAST_ELEMENTS == 2);
3687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3);
36883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  cmpb(FieldOperand(map, Map::kBitField2Offset),
3689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       Immediate(Map::kMaximumBitField2FastHoleyElementValue));
36903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  j(above, fail, distance);
36913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
36923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
36933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
36943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::CheckFastObjectElements(Register map,
36953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                             Label* fail,
36963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                             Label::Distance distance) {
3697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
3698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
3699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(FAST_ELEMENTS == 2);
3700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3);
37013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  cmpb(FieldOperand(map, Map::kBitField2Offset),
3702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       Immediate(Map::kMaximumBitField2FastHoleySmiElementValue));
37033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  j(below_equal, fail, distance);
3704592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch  cmpb(FieldOperand(map, Map::kBitField2Offset),
3705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       Immediate(Map::kMaximumBitField2FastHoleyElementValue));
3706592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch  j(above, fail, distance);
3707592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch}
3708592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch
3709592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch
3710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::CheckFastSmiElements(Register map,
3711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          Label* fail,
3712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          Label::Distance distance) {
3713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
3714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
37153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  cmpb(FieldOperand(map, Map::kBitField2Offset),
3716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       Immediate(Map::kMaximumBitField2FastHoleySmiElementValue));
37173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  j(above, fail, distance);
37183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
37193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
37203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
37213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::StoreNumberToDoubleElements(
37223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Register maybe_number,
37233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Register elements,
37243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Register index,
37253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    XMMRegister xmm_scratch,
3726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Label* fail,
3727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int elements_offset) {
3728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label smi_value, done;
37293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
37303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  JumpIfSmi(maybe_number, &smi_value, Label::kNear);
37313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
37323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  CheckMap(maybe_number,
37333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch           isolate()->factory()->heap_number_map(),
37343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch           fail,
37353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch           DONT_DO_SMI_CHECK);
37363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Double value, turn potential sNaN into qNaN.
3738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Move(xmm_scratch, 1.0);
3739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  mulsd(xmm_scratch, FieldOperand(maybe_number, HeapNumber::kValueOffset));
3740014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  jmp(&done, Label::kNear);
37413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
37423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bind(&smi_value);
37433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Value is a smi. convert to a double and store.
37443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Preserve original value.
37453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  SmiToInteger32(kScratchRegister, maybe_number);
3746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Cvtlsi2sd(xmm_scratch, kScratchRegister);
3747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bind(&done);
3748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Movsd(FieldOperand(elements, index, times_8,
3749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                     FixedDoubleArray::kHeaderSize - elements_offset),
37503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        xmm_scratch);
37513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
37523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
37533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::CompareMap(Register obj, Handle<Map> map) {
37553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Cmp(FieldOperand(obj, HeapObject::kMapOffset), map);
37563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
37573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
37583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
37593100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescuvoid MacroAssembler::CheckMap(Register obj,
37603100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                              Handle<Map> map,
37613100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                              Label* fail,
3762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              SmiCheckType smi_check_type) {
3763257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (smi_check_type == DO_SMI_CHECK) {
37643100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    JumpIfSmi(obj, fail);
37653100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  }
37663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CompareMap(obj, map);
37683100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  j(not_equal, fail);
37693100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
37703100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
37713100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
3772257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::ClampUint8(Register reg) {
3773257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Label done;
3774257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  testl(reg, Immediate(0xFFFFFF00));
3775257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  j(zero, &done, Label::kNear);
3776257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  setcc(negative, reg);  // 1 if negative, 0 if positive.
3777257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  decb(reg);  // 0 if negative, 255 if positive.
3778257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  bind(&done);
3779257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
3780257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
3781257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
3782257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::ClampDoubleToUint8(XMMRegister input_reg,
3783257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                        XMMRegister temp_xmm_reg,
3784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                        Register result_reg) {
3785257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Label done;
3786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Label conv_failure;
3787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Xorpd(temp_xmm_reg, temp_xmm_reg);
3788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Cvtsd2si(result_reg, input_reg);
3789257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  testl(result_reg, Immediate(0xFFFFFF00));
3790257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  j(zero, &done, Label::kNear);
3791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  cmpl(result_reg, Immediate(1));
3792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  j(overflow, &conv_failure, Label::kNear);
3793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movl(result_reg, Immediate(0));
3794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  setcc(sign, result_reg);
3795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  subl(result_reg, Immediate(1));
3796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  andl(result_reg, Immediate(255));
3797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  jmp(&done, Label::kNear);
3798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bind(&conv_failure);
3799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Set(result_reg, 0);
3800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Ucomisd(input_reg, temp_xmm_reg);
3801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  j(below, &done, Label::kNear);
3802257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Set(result_reg, 255);
3803257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  bind(&done);
3804257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
3805257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
3806257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
3807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::LoadUint32(XMMRegister dst,
3808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                Register src) {
3809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (FLAG_debug_code) {
3810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    cmpq(src, Immediate(0xffffffff));
3811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Assert(below_equal, kInputGPRIsExpectedToHaveUpper32Cleared);
3812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Cvtqsi2sd(dst, src);
3814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::SlowTruncateToI(Register result_reg,
3818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     Register input_reg,
3819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     int offset) {
3820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DoubleToIStub stub(isolate(), input_reg, result_reg, offset, true);
3821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  call(stub.GetCode(), RelocInfo::CODE_TARGET);
3822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::TruncateHeapNumberToI(Register result_reg,
3826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           Register input_reg) {
3827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Label done;
382813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Movsd(kScratchDoubleReg, FieldOperand(input_reg, HeapNumber::kValueOffset));
382913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Cvttsd2siq(result_reg, kScratchDoubleReg);
3830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  cmpq(result_reg, Immediate(1));
3831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  j(no_overflow, &done, Label::kNear);
3832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Slow case.
3834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (input_reg.is(result_reg)) {
3835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    subp(rsp, Immediate(kDoubleSize));
383613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    Movsd(MemOperand(rsp, 0), kScratchDoubleReg);
3837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SlowTruncateToI(result_reg, rsp, 0);
3838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    addp(rsp, Immediate(kDoubleSize));
3839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
3840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SlowTruncateToI(result_reg, input_reg);
3841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bind(&done);
3844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Keep our invariant that the upper 32 bits are zero.
3845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movl(result_reg, result_reg);
3846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::TruncateDoubleToI(Register result_reg,
3850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                       XMMRegister input_reg) {
3851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Label done;
3852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Cvttsd2siq(result_reg, input_reg);
3853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  cmpq(result_reg, Immediate(1));
3854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  j(no_overflow, &done, Label::kNear);
3855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  subp(rsp, Immediate(kDoubleSize));
3857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Movsd(MemOperand(rsp, 0), input_reg);
3858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SlowTruncateToI(result_reg, rsp, 0);
3859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  addp(rsp, Immediate(kDoubleSize));
3860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bind(&done);
3862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Keep our invariant that the upper 32 bits are zero.
3863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movl(result_reg, result_reg);
3864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::DoubleToI(Register result_reg, XMMRegister input_reg,
3868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               XMMRegister scratch,
3869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               MinusZeroMode minus_zero_mode,
3870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               Label* lost_precision, Label* is_nan,
3871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               Label* minus_zero, Label::Distance dst) {
3872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Cvttsd2si(result_reg, input_reg);
387313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Cvtlsi2sd(kScratchDoubleReg, result_reg);
387413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Ucomisd(kScratchDoubleReg, input_reg);
3875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  j(not_equal, lost_precision, dst);
3876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  j(parity_even, is_nan, dst);  // NaN.
3877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (minus_zero_mode == FAIL_ON_MINUS_ZERO) {
3878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Label done;
3879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // The integer converted back is equal to the original. We
3880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // only have to test if we got -0 as an input.
3881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    testl(result_reg, result_reg);
3882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    j(not_zero, &done, Label::kNear);
3883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Movmskpd(result_reg, input_reg);
3884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Bit 0 contains the sign of the double in input_reg.
3885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // If input was positive, we are ok and return 0, otherwise
3886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // jump to minus_zero.
3887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    andl(result_reg, Immediate(1));
3888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    j(not_zero, minus_zero, dst);
3889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bind(&done);
3890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3894257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::LoadInstanceDescriptors(Register map,
3895257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                             Register descriptors) {
3896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(descriptors, FieldOperand(map, Map::kDescriptorsOffset));
3897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::NumberOfOwnDescriptors(Register dst, Register map) {
3901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movl(dst, FieldOperand(map, Map::kBitField3Offset));
3902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DecodeField<Map::NumberOfOwnDescriptorsBits>(dst);
3903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::EnumLength(Register dst, Register map) {
3907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(Map::EnumLengthBits::kShift == 0);
3908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movl(dst, FieldOperand(map, Map::kBitField3Offset));
3909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  andl(dst, Immediate(Map::EnumLengthBits::kMask));
3910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Integer32ToSmi(dst, dst);
3911257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
3912257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
3913257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
3914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::LoadAccessor(Register dst, Register holder,
3915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  int accessor_index,
3916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  AccessorComponent accessor) {
3917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  movp(dst, FieldOperand(holder, HeapObject::kMapOffset));
3918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LoadInstanceDescriptors(dst, dst);
3919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  movp(dst, FieldOperand(dst, DescriptorArray::GetValueOffset(accessor_index)));
3920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int offset = accessor == ACCESSOR_GETTER ? AccessorPair::kGetterOffset
3921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           : AccessorPair::kSetterOffset;
3922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  movp(dst, FieldOperand(dst, offset));
3923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3926958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid MacroAssembler::DispatchWeakMap(Register obj, Register scratch1,
3927958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                     Register scratch2, Handle<WeakCell> cell,
3928958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                     Handle<Code> success,
3929958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                     SmiCheckType smi_check_type) {
3930257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Label fail;
3931257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (smi_check_type == DO_SMI_CHECK) {
3932257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    JumpIfSmi(obj, &fail);
3933257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
3934958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  movq(scratch1, FieldOperand(obj, HeapObject::kMapOffset));
3935958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  CmpWeakValue(scratch1, cell, scratch2);
3936257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  j(equal, success, RelocInfo::CODE_TARGET);
3937257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  bind(&fail);
3938257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
3939257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
3940257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
3941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertNumber(Register object) {
3942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (emit_debug_code()) {
3943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Label ok;
3944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Condition is_smi = CheckSmi(object);
3945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    j(is_smi, &ok, Label::kNear);
3946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Cmp(FieldOperand(object, HeapObject::kMapOffset),
3947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        isolate()->factory()->heap_number_map());
3948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Check(equal, kOperandIsNotANumber);
3949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bind(&ok);
3950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3951402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu}
3952402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
39533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid MacroAssembler::AssertNotNumber(Register object) {
39543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (emit_debug_code()) {
39553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Condition is_smi = CheckSmi(object);
39563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Check(NegateCondition(is_smi), kOperandIsANumber);
39573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Cmp(FieldOperand(object, HeapObject::kMapOffset),
39583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        isolate()->factory()->heap_number_map());
39593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Check(not_equal, kOperandIsANumber);
39603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
39613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
3962402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
3963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertNotSmi(Register object) {
3964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (emit_debug_code()) {
3965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Condition is_smi = CheckSmi(object);
3966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Check(NegateCondition(is_smi), kOperandIsASmi);
3967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3968756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick}
3969756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
3970756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
3971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertSmi(Register object) {
3972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (emit_debug_code()) {
3973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Condition is_smi = CheckSmi(object);
3974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Check(is_smi, kOperandIsNotASmi);
3975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
397644f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
397744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
397844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
3979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertSmi(const Operand& object) {
3980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (emit_debug_code()) {
3981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Condition is_smi = CheckSmi(object);
3982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Check(is_smi, kOperandIsNotASmi);
3983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertZeroExtended(Register int32_register) {
3988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (emit_debug_code()) {
3989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!int32_register.is(kScratchRegister));
3990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movq(kScratchRegister, V8_INT64_C(0x0000000100000000));
3991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    cmpq(kScratchRegister, int32_register);
3992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Check(above_equal, k32BitValueInRegisterIsNotZeroExtended);
3993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertString(Register object) {
3998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (emit_debug_code()) {
3999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    testb(object, Immediate(kSmiTagMask));
4000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Check(not_equal, kOperandIsASmiAndNotAString);
4001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Push(object);
4002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(object, FieldOperand(object, HeapObject::kMapOffset));
4003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CmpInstanceType(object, FIRST_NONSTRING_TYPE);
4004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Pop(object);
4005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Check(below, kOperandIsNotAString);
4006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
40076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
40086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
40096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
4010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertName(Register object) {
4011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (emit_debug_code()) {
4012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    testb(object, Immediate(kSmiTagMask));
4013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Check(not_equal, kOperandIsASmiAndNotAName);
4014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Push(object);
4015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(object, FieldOperand(object, HeapObject::kMapOffset));
4016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CmpInstanceType(object, LAST_NAME_TYPE);
4017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Pop(object);
4018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Check(below_equal, kOperandIsNotAName);
4019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
40203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
40213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
40223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::AssertFunction(Register object) {
4024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (emit_debug_code()) {
4025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    testb(object, Immediate(kSmiTagMask));
4026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Check(not_equal, kOperandIsASmiAndNotAFunction);
4027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Push(object);
4028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CmpObjectType(object, JS_FUNCTION_TYPE, object);
4029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Pop(object);
4030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Check(equal, kOperandIsNotAFunction);
4031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
4032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::AssertBoundFunction(Register object) {
4036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (emit_debug_code()) {
4037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    testb(object, Immediate(kSmiTagMask));
4038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Check(not_equal, kOperandIsASmiAndNotABoundFunction);
4039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Push(object);
4040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CmpObjectType(object, JS_BOUND_FUNCTION_TYPE, object);
4041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Pop(object);
4042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Check(equal, kOperandIsNotABoundFunction);
4043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
4044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4046bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid MacroAssembler::AssertGeneratorObject(Register object) {
4047bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (emit_debug_code()) {
4048bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    testb(object, Immediate(kSmiTagMask));
4049bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    Check(not_equal, kOperandIsASmiAndNotAGeneratorObject);
4050bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    Push(object);
4051bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    CmpObjectType(object, JS_GENERATOR_OBJECT_TYPE, object);
4052bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    Pop(object);
4053bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    Check(equal, kOperandIsNotAGeneratorObject);
4054bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
4055bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
4056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4057109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid MacroAssembler::AssertReceiver(Register object) {
4058109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (emit_debug_code()) {
4059109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    testb(object, Immediate(kSmiTagMask));
4060109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    Check(not_equal, kOperandIsASmiAndNotAReceiver);
4061109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    Push(object);
4062109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
4063109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    CmpObjectType(object, FIRST_JS_RECEIVER_TYPE, object);
4064109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    Pop(object);
4065109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    Check(above_equal, kOperandIsNotAReceiver);
4066109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
4067109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
4068109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
4069109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
4070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertUndefinedOrAllocationSite(Register object) {
4071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (emit_debug_code()) {
4072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Label done_checking;
4073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AssertNotSmi(object);
4074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Cmp(object, isolate()->factory()->undefined_value());
4075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    j(equal, &done_checking);
4076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Cmp(FieldOperand(object, 0), isolate()->factory()->allocation_site_map());
4077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Assert(equal, kExpectedUndefinedOrCell);
4078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bind(&done_checking);
4079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4080e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch}
4081e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
4082e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
4083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AssertRootValue(Register src,
4084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     Heap::RootListIndex root_value_index,
4085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     BailoutReason reason) {
4086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (emit_debug_code()) {
4087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!src.is(kScratchRegister));
4088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LoadRoot(kScratchRegister, root_value_index);
4089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    cmpp(src, kScratchRegister);
4090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Check(equal, reason);
4091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
40929dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen}
40939dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
40949dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
40959dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
4096d91b9f7d46489a9ee00f9cb415630299c76a502bLeon ClarkeCondition MacroAssembler::IsObjectStringType(Register heap_object,
4097d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                                             Register map,
4098d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                                             Register instance_type) {
4099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(map, FieldOperand(heap_object, HeapObject::kMapOffset));
41004515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  movzxbl(instance_type, FieldOperand(map, Map::kInstanceTypeOffset));
410169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  STATIC_ASSERT(kNotStringTag != 0);
4102d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  testb(instance_type, Immediate(kIsNotStringMask));
4103d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  return zero;
4104d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke}
4105d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
4106d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
4107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochCondition MacroAssembler::IsObjectNameType(Register heap_object,
4108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           Register map,
4109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           Register instance_type) {
4110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(map, FieldOperand(heap_object, HeapObject::kMapOffset));
4111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movzxbl(instance_type, FieldOperand(map, Map::kInstanceTypeOffset));
4112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  cmpb(instance_type, Immediate(static_cast<uint8_t>(LAST_NAME_TYPE)));
4113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return below_equal;
4114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::GetMapConstructor(Register result, Register map,
4118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       Register temp) {
4119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label done, loop;
4120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  movp(result, FieldOperand(map, Map::kConstructorOrBackPointerOffset));
4121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bind(&loop);
4122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  JumpIfSmi(result, &done, Label::kNear);
4123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CmpObjectType(result, MAP_TYPE, temp);
4124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  j(not_equal, &done, Label::kNear);
4125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  movp(result, FieldOperand(result, Map::kConstructorOrBackPointerOffset));
4126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  jmp(&loop);
4127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bind(&done);
4128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
41293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::TryGetFunctionPrototype(Register function, Register result,
4132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                             Label* miss) {
4133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Get the prototype or initial map from the function.
4134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(result,
4135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block       FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
4136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If the prototype or initial map is the hole, don't return it and
4138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // simply miss the cache instead. This will allow us to allocate a
4139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // prototype object on-demand in the runtime system.
4140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CompareRoot(result, Heap::kTheHoleValueRootIndex);
4141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  j(equal, miss);
4142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If the function does not have an initial map, we're done.
4144257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Label done;
4145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CmpObjectType(result, MAP_TYPE, kScratchRegister);
4146257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  j(not_equal, &done, Label::kNear);
4147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Get the prototype from the initial map.
4149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(result, FieldOperand(result, Map::kPrototypeOffset));
4150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // All done.
4152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bind(&done);
4153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
4154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::SetCounter(StatsCounter* counter, int value) {
4157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (FLAG_native_code_counters && counter->Enabled()) {
415844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Operand counter_operand = ExternalOperand(ExternalReference(counter));
41598b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    movl(counter_operand, Immediate(value));
4160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
4161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
4162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::IncrementCounter(StatsCounter* counter, int value) {
4165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(value > 0);
4166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (FLAG_native_code_counters && counter->Enabled()) {
416744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Operand counter_operand = ExternalOperand(ExternalReference(counter));
4168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (value == 1) {
416944f0eee88ff00398ff7f715fab053374d808c90dSteve Block      incl(counter_operand);
4170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
417144f0eee88ff00398ff7f715fab053374d808c90dSteve Block      addl(counter_operand, Immediate(value));
4172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
4173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
4174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
4175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::DecrementCounter(StatsCounter* counter, int value) {
4178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(value > 0);
4179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (FLAG_native_code_counters && counter->Enabled()) {
418044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Operand counter_operand = ExternalOperand(ExternalReference(counter));
4181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (value == 1) {
418244f0eee88ff00398ff7f715fab053374d808c90dSteve Block      decl(counter_operand);
4183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
418444f0eee88ff00398ff7f715fab053374d808c90dSteve Block      subl(counter_operand, Immediate(value));
4185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
4186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
4187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
4188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4190402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescuvoid MacroAssembler::DebugBreak() {
41919fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block  Set(rax, 0);  // No arguments.
4192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LoadAddress(rbx,
4193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              ExternalReference(Runtime::kHandleDebuggerStatement, isolate()));
4194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CEntryStub ces(isolate(), 1);
4195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(AllowThisStubCall(&ces));
4196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Call(ces.GetCode(), RelocInfo::DEBUGGER_STATEMENT);
4197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
41993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid MacroAssembler::PrepareForTailCall(const ParameterCount& callee_args_count,
42003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                        Register caller_args_count_reg,
42013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                        Register scratch0, Register scratch1,
42023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                        ReturnAddressState ra_state) {
42033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#if DEBUG
42043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (callee_args_count.is_reg()) {
42053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    DCHECK(!AreAliased(callee_args_count.reg(), caller_args_count_reg, scratch0,
42063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                       scratch1));
42073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  } else {
42083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    DCHECK(!AreAliased(caller_args_count_reg, scratch0, scratch1));
42093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
42103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#endif
42113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
42123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Calculate the destination address where we will put the return address
42133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // after we drop current frame.
42143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Register new_sp_reg = scratch0;
42153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (callee_args_count.is_reg()) {
42163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    subp(caller_args_count_reg, callee_args_count.reg());
42173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    leap(new_sp_reg, Operand(rbp, caller_args_count_reg, times_pointer_size,
42183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                             StandardFrameConstants::kCallerPCOffset));
42193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  } else {
42203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    leap(new_sp_reg, Operand(rbp, caller_args_count_reg, times_pointer_size,
42213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                             StandardFrameConstants::kCallerPCOffset -
42223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                 callee_args_count.immediate() * kPointerSize));
42233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
42243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
42253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (FLAG_debug_code) {
42263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    cmpp(rsp, new_sp_reg);
42273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Check(below, kStackAccessBelowStackPointer);
42283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
42293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
42303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Copy return address from caller's frame to current frame's return address
42313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // to avoid its trashing and let the following loop copy it to the right
42323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // place.
42333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Register tmp_reg = scratch1;
42343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (ra_state == ReturnAddressState::kOnStack) {
42353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    movp(tmp_reg, Operand(rbp, StandardFrameConstants::kCallerPCOffset));
42363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    movp(Operand(rsp, 0), tmp_reg);
42373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  } else {
42383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    DCHECK(ReturnAddressState::kNotOnStack == ra_state);
42393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Push(Operand(rbp, StandardFrameConstants::kCallerPCOffset));
42403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
42413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
42423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Restore caller's frame pointer now as it could be overwritten by
42433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // the copying loop.
42443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  movp(rbp, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
42453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
42463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // +2 here is to copy both receiver and return address.
42473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Register count_reg = caller_args_count_reg;
42483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (callee_args_count.is_reg()) {
42493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    leap(count_reg, Operand(callee_args_count.reg(), 2));
42503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  } else {
42513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    movp(count_reg, Immediate(callee_args_count.immediate() + 2));
42523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // TODO(ishell): Unroll copying loop for small immediate values.
42533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
42543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
42553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Now copy callee arguments to the caller frame going backwards to avoid
42563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // callee arguments corruption (source and destination areas could overlap).
42573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Label loop, entry;
42583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  jmp(&entry, Label::kNear);
42593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  bind(&loop);
42603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  decp(count_reg);
42613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  movp(tmp_reg, Operand(rsp, count_reg, times_pointer_size, 0));
42623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  movp(Operand(new_sp_reg, count_reg, times_pointer_size, 0), tmp_reg);
42633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  bind(&entry);
42643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  cmpp(count_reg, Immediate(0));
42653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  j(not_equal, &loop, Label::kNear);
42663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
42673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Leave current frame.
42683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  movp(rsp, new_sp_reg);
42693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
4270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::InvokeFunction(Register function,
4272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                    Register new_target,
4273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                    const ParameterCount& actual,
4274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                    InvokeFlag flag,
4275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                    const CallWrapper& call_wrapper) {
4276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  movp(rbx, FieldOperand(function, JSFunction::kSharedFunctionInfoOffset));
4277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LoadSharedFunctionInfoSpecialField(
4278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      rbx, rbx, SharedFunctionInfo::kFormalParameterCountOffset);
4279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ParameterCount expected(rbx);
4281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InvokeFunction(function, new_target, expected, actual, flag, call_wrapper);
4282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::InvokeFunction(Handle<JSFunction> function,
4286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                    const ParameterCount& expected,
4287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                    const ParameterCount& actual,
4288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                    InvokeFlag flag,
4289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                    const CallWrapper& call_wrapper) {
4290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Move(rdi, function);
4291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InvokeFunction(rdi, no_reg, expected, actual, flag, call_wrapper);
4292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
4293257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
4294257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
4295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::InvokeFunction(Register function,
4296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                    Register new_target,
4297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                    const ParameterCount& expected,
4298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                    const ParameterCount& actual,
4299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                    InvokeFlag flag,
4300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                    const CallWrapper& call_wrapper) {
4301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(function.is(rdi));
4302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  movp(rsi, FieldOperand(function, JSFunction::kContextOffset));
4303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InvokeFunctionCode(rdi, new_target, expected, actual, flag, call_wrapper);
4304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::InvokeFunctionCode(Register function, Register new_target,
4308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                        const ParameterCount& expected,
4309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                        const ParameterCount& actual,
4310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                        InvokeFlag flag,
4311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                        const CallWrapper& call_wrapper) {
43123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // You can't call a function without a valid frame.
4313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(flag == JUMP_FUNCTION || has_frame());
4314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(function.is(rdi));
4315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_IMPLIES(new_target.is_valid(), new_target.is(rdx));
4316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (call_wrapper.NeedsDebugStepCheck()) {
4318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FloodFunctionIfStepping(function, new_target, expected, actual);
4319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
4320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Clear the new.target register if not given.
4322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!new_target.is_valid()) {
4323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LoadRoot(rdx, Heap::kUndefinedValueRootIndex);
4324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
43253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4326257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Label done;
43273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool definitely_mismatches = false;
4328e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  InvokePrologue(expected,
4329e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                 actual,
4330e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                 &done,
43313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                 &definitely_mismatches,
4332e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                 flag,
4333257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                 Label::kNear,
4334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                 call_wrapper);
43353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!definitely_mismatches) {
4336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // We call indirectly through the code field in the function to
4337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // allow recompilation to take effect without changing any of the
4338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // call sites.
4339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Operand code = FieldOperand(function, JSFunction::kCodeEntryOffset);
43403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (flag == CALL_FUNCTION) {
43413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      call_wrapper.BeforeCall(CallSize(code));
43423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      call(code);
43433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      call_wrapper.AfterCall();
43443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    } else {
4345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(flag == JUMP_FUNCTION);
43463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      jmp(code);
43473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
43483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    bind(&done);
4349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
4350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
4351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4353257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid MacroAssembler::InvokePrologue(const ParameterCount& expected,
4354257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                    const ParameterCount& actual,
4355257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                    Label* done,
43563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    bool* definitely_mismatches,
4357257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                    InvokeFlag flag,
4358257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                    Label::Distance near_jump,
4359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    const CallWrapper& call_wrapper) {
4360257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  bool definitely_matches = false;
43613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  *definitely_mismatches = false;
4362257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  Label invoke;
4363257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (expected.is_immediate()) {
4364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(actual.is_immediate());
4365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Set(rax, actual.immediate());
4366257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (expected.immediate() == actual.immediate()) {
4367257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      definitely_matches = true;
4368257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    } else {
4369257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      if (expected.immediate() ==
4370257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch              SharedFunctionInfo::kDontAdaptArgumentsSentinel) {
4371257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        // Don't worry about adapting arguments for built-ins that
4372257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        // don't want that done. Skip adaption code by making it look
4373257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        // like we have a match between expected and actual number of
4374257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        // arguments.
4375257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        definitely_matches = true;
4376257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      } else {
43773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        *definitely_mismatches = true;
4378257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        Set(rbx, expected.immediate());
4379257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      }
4380257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
4381257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  } else {
4382257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (actual.is_immediate()) {
4383257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      // Expected is in register, actual is immediate. This is the
4384257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      // case when we invoke function values without going through the
4385257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      // IC mechanism.
4386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Set(rax, actual.immediate());
4387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      cmpp(expected.reg(), Immediate(actual.immediate()));
4388257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      j(equal, &invoke, Label::kNear);
4389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(expected.reg().is(rbx));
4390257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    } else if (!expected.reg().is(actual.reg())) {
4391257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      // Both expected and actual are in (different) registers. This
4392257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      // is the case when we invoke functions using call and apply.
4393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      cmpp(expected.reg(), actual.reg());
4394257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      j(equal, &invoke, Label::kNear);
4395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(actual.reg().is(rax));
4396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(expected.reg().is(rbx));
4397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
4398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Move(rax, actual.reg());
4399257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
4400257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
4401257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
4402257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (!definitely_matches) {
4403257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    Handle<Code> adaptor = isolate()->builtins()->ArgumentsAdaptorTrampoline();
4404257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (flag == CALL_FUNCTION) {
4405257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      call_wrapper.BeforeCall(CallSize(adaptor));
4406257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Call(adaptor, RelocInfo::CODE_TARGET);
4407257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      call_wrapper.AfterCall();
44083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (!*definitely_mismatches) {
44093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        jmp(done, near_jump);
44103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
4411257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    } else {
4412257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      Jump(adaptor, RelocInfo::CODE_TARGET);
4413257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
4414257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    bind(&invoke);
44151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
4416402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu}
4417402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
4418402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
4419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::FloodFunctionIfStepping(Register fun, Register new_target,
4420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                             const ParameterCount& expected,
4421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                             const ParameterCount& actual) {
4422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label skip_flooding;
442313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  ExternalReference last_step_action =
442413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ExternalReference::debug_last_step_action_address(isolate());
442513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Operand last_step_action_operand = ExternalOperand(last_step_action);
442613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  STATIC_ASSERT(StepFrame > StepIn);
442713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  cmpb(last_step_action_operand, Immediate(StepIn));
442813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  j(less, &skip_flooding);
4429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  {
4430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FrameScope frame(this,
4431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                     has_frame() ? StackFrame::NONE : StackFrame::INTERNAL);
4432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (expected.is_reg()) {
4433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Integer32ToSmi(expected.reg(), expected.reg());
4434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Push(expected.reg());
4435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
4436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (actual.is_reg()) {
4437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Integer32ToSmi(actual.reg(), actual.reg());
4438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Push(actual.reg());
4439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
4440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (new_target.is_valid()) {
4441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Push(new_target);
4442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
4443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Push(fun);
4444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Push(fun);
4445109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    CallRuntime(Runtime::kDebugPrepareStepInIfStepping);
4446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Pop(fun);
4447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (new_target.is_valid()) {
4448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Pop(new_target);
4449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
4450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (actual.is_reg()) {
4451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Pop(actual.reg());
4452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SmiToInteger64(actual.reg(), actual.reg());
4453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
4454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (expected.is_reg()) {
4455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Pop(expected.reg());
4456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SmiToInteger64(expected.reg(), expected.reg());
4457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
4458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
4459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bind(&skip_flooding);
4460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
44623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid MacroAssembler::StubPrologue(StackFrame::Type type) {
44633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  pushq(rbp);  // Caller's frame pointer.
44643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  movp(rbp, rsp);
44653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Push(Smi::FromInt(type));
4466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Prologue(bool code_pre_aging) {
4469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PredictableCodeSizeScope predictible_code_size_scope(this,
4470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      kNoCodeAgeSequenceLength);
4471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (code_pre_aging) {
4472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Pre-age the code.
4473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Call(isolate()->builtins()->MarkCodeAsExecutedOnce(),
4474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         RelocInfo::CODE_AGE_SEQUENCE);
4475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Nop(kNoCodeAgeSequenceLength - Assembler::kShortCallInstructionLength);
4476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
4477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    pushq(rbp);  // Caller's frame pointer.
4478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(rbp, rsp);
4479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Push(rsi);  // Callee's context.
4480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Push(rdi);  // Callee's JS function.
4481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::EmitLoadTypeFeedbackVector(Register vector) {
4486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  movp(vector, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
448713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  movp(vector, FieldOperand(vector, JSFunction::kLiteralsOffset));
448813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  movp(vector, FieldOperand(vector, LiteralsArray::kFeedbackVectorOffset));
4489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
4490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4492958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid MacroAssembler::EnterFrame(StackFrame::Type type,
4493958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                bool load_constant_pool_pointer_reg) {
4494958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Out-of-line constant pool not implemented on x64.
4495958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  UNREACHABLE();
4496958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
4497958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
4498958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
4499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::EnterFrame(StackFrame::Type type) {
4500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  pushq(rbp);
4501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(rbp, rsp);
45023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  Push(Smi::FromInt(type));
45033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (type == StackFrame::INTERNAL) {
45043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Move(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT);
45053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    Push(kScratchRegister);
45063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
450744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (emit_debug_code()) {
4508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Move(kScratchRegister,
4509257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch         isolate()->factory()->undefined_value(),
4510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block         RelocInfo::EMBEDDED_OBJECT);
4511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    cmpp(Operand(rsp, 0), kScratchRegister);
4512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Check(not_equal, kCodeObjectNotProperlyPatched);
4513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
4514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
4515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::LeaveFrame(StackFrame::Type type) {
451844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (emit_debug_code()) {
45193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    Move(kScratchRegister, Smi::FromInt(type));
45203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    cmpp(Operand(rbp, CommonFrameConstants::kContextOrFrameTypeOffset),
45213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch         kScratchRegister);
4522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Check(equal, kStackFrameTypesMustMatch);
4523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
4524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(rsp, rbp);
4525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  popq(rbp);
4526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
4527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4528f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::EnterBuiltinFrame(Register context, Register target,
4529f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                       Register argc) {
4530f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Push(rbp);
4531f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Move(rbp, rsp);
4532f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Push(context);
4533f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Push(target);
4534f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Push(argc);
4535f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
4536f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
4537f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::LeaveBuiltinFrame(Register context, Register target,
4538f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                       Register argc) {
4539f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Pop(argc);
4540f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Pop(target);
4541f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Pop(context);
4542f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  leave();
4543f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
4544f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
4545f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::EnterExitFramePrologue(bool save_rax,
4546f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                            StackFrame::Type frame_type) {
4547f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DCHECK(frame_type == StackFrame::EXIT ||
4548f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch         frame_type == StackFrame::BUILTIN_EXIT);
4549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
45503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Set up the frame structure on the stack.
4551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // All constants are relative to the frame pointer of the exit frame.
45523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DCHECK_EQ(kFPOnStackSize + kPCOnStackSize,
45533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            ExitFrameConstants::kCallerSPDisplacement);
45543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DCHECK_EQ(kFPOnStackSize, ExitFrameConstants::kCallerPCOffset);
45553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DCHECK_EQ(0 * kPointerSize, ExitFrameConstants::kCallerFPOffset);
4556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  pushq(rbp);
4557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(rbp, rsp);
4558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
455980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // Reserve room for entry stack pointer and push the code object.
4560f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Push(Smi::FromInt(frame_type));
45613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DCHECK_EQ(-2 * kPointerSize, ExitFrameConstants::kSPOffset);
4562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Push(Immediate(0));  // Saved entry sp, patched before call.
4563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Move(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT);
4564f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Push(kScratchRegister);  // Accessed from ExitFrame::code_slot.
4565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Save the frame pointer and the context in top.
4567bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  if (save_rax) {
4568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(r14, rax);  // Backup rax in callee-save register.
4569bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  }
4570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4571589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Store(ExternalReference(Isolate::kCEntryFPAddress, isolate()), rbp);
4572589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  Store(ExternalReference(Isolate::kContextAddress, isolate()), rsi);
4573958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Store(ExternalReference(Isolate::kCFunctionAddress, isolate()), rbx);
4574bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch}
4575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
45768a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
45771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space,
45781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block                                            bool save_doubles) {
4579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef _WIN64
45801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  const int kShadowSpace = 4;
45811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  arg_stack_space += kShadowSpace;
4582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
45831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // Optionally save all XMM registers.
45841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  if (save_doubles) {
4585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int space = XMMRegister::kMaxNumRegisters * kDoubleSize +
4586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                arg_stack_space * kRegisterSize;
4587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    subp(rsp, Immediate(space));
45883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    int offset = -ExitFrameConstants::kFixedFrameSizeFromFp;
458913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    const RegisterConfiguration* config = RegisterConfiguration::Crankshaft();
4590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
4591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DoubleRegister reg =
4592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          DoubleRegister::from_code(config->GetAllocatableDoubleCode(i));
4593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Movsd(Operand(rbp, offset - ((i + 1) * kDoubleSize)), reg);
45941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    }
45951e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  } else if (arg_stack_space > 0) {
4596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    subp(rsp, Immediate(arg_stack_space * kRegisterSize));
45978a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
4598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Get the required frame alignment for the OS.
4600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const int kFrameAlignment = base::OS::ActivationFrameAlignment();
4601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (kFrameAlignment > 0) {
4602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(base::bits::IsPowerOfTwo32(kFrameAlignment));
4603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(is_int8(kFrameAlignment));
4604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    andp(rsp, Immediate(-kFrameAlignment));
4605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
4606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Patch the saved entry sp.
4608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(Operand(rbp, ExitFrameConstants::kSPOffset), rsp);
4609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
4610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4611f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid MacroAssembler::EnterExitFrame(int arg_stack_space, bool save_doubles,
4612f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                    StackFrame::Type frame_type) {
4613f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EnterExitFramePrologue(true, frame_type);
4614bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch
46153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Set up argv in callee-saved register r15. It is reused in LeaveExitFrame,
4616bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  // so it must be retained across the C-call.
4617bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize;
4618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  leap(r15, Operand(rbp, r14, times_pointer_size, offset));
4619bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch
46201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  EnterExitFrameEpilogue(arg_stack_space, save_doubles);
4621bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch}
4622bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch
4623bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch
46248a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wangvoid MacroAssembler::EnterApiExitFrame(int arg_stack_space) {
4625f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  EnterExitFramePrologue(false, StackFrame::EXIT);
46261e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  EnterExitFrameEpilogue(arg_stack_space, false);
4627bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch}
4628bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch
4629bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch
4630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::LeaveExitFrame(bool save_doubles, bool pop_arguments) {
4631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Registers:
463244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // r15 : argv
46331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  if (save_doubles) {
46343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    int offset = -ExitFrameConstants::kFixedFrameSizeFromFp;
463513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    const RegisterConfiguration* config = RegisterConfiguration::Crankshaft();
4636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (int i = 0; i < config->num_allocatable_double_registers(); ++i) {
4637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DoubleRegister reg =
4638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          DoubleRegister::from_code(config->GetAllocatableDoubleCode(i));
4639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Movsd(reg, Operand(rbp, offset - ((i + 1) * kDoubleSize)));
46401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    }
46411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
4642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (pop_arguments) {
4644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Get the return address from the stack and restore the frame pointer.
4645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    movp(rcx, Operand(rbp, kFPOnStackSize));
4646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    movp(rbp, Operand(rbp, 0 * kPointerSize));
4647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Drop everything up to and including the arguments and the receiver
4649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // from the caller stack.
4650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    leap(rsp, Operand(r15, 1 * kPointerSize));
4651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
4652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PushReturnAddressFrom(rcx);
4653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
4654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Otherwise just leave the exit frame.
4655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    leave();
4656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
46578a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
4658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LeaveExitFrameEpilogue(true);
46598a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
46608a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
46618a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
4662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::LeaveApiExitFrame(bool restore_context) {
4663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(rsp, rbp);
4664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  popq(rbp);
46658a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
4666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LeaveExitFrameEpilogue(restore_context);
46678a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
46688a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
46698a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
4670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::LeaveExitFrameEpilogue(bool restore_context) {
4671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Restore current context from top and clear it in debug mode.
4672589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  ExternalReference context_address(Isolate::kContextAddress, isolate());
467344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Operand context_operand = ExternalOperand(context_address);
4674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (restore_context) {
4675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(rsi, context_operand);
4676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
4678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(context_operand, Immediate(0));
4679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
4680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Clear the top frame.
4682589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress,
468344f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                       isolate());
468444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Operand c_entry_fp_operand = ExternalOperand(c_entry_fp_address);
4685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(c_entry_fp_operand, Immediate(0));
4686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
4687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::CheckAccessGlobalProxy(Register holder_reg,
4690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                            Register scratch,
4691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                            Label* miss) {
4692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Label same_contexts;
4693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!holder_reg.is(scratch));
4695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!scratch.is(kScratchRegister));
46963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Load current lexical context from the active StandardFrame, which
46973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // may require crawling past STUB frames.
46983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Label load_context;
46993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Label has_context;
47003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  movp(scratch, rbp);
47013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  bind(&load_context);
47023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DCHECK(SmiValuesAre32Bits());
47033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // This is "JumpIfNotSmi" but without loading the value into a register.
47043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  cmpl(MemOperand(scratch, CommonFrameConstants::kContextOrFrameTypeOffset),
47053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch       Immediate(0));
47063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  j(not_equal, &has_context);
47073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  movp(scratch, MemOperand(scratch, CommonFrameConstants::kCallerFPOffset));
47083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  jmp(&load_context);
47093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  bind(&has_context);
47103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  movp(scratch,
47113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch       MemOperand(scratch, CommonFrameConstants::kContextOrFrameTypeOffset));
4712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // When generating debug code, make sure the lexical context is set.
471444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (emit_debug_code()) {
4715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    cmpp(scratch, Immediate(0));
4716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Check(not_equal, kWeShouldNotHaveAnEmptyLexicalContext);
4717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
4718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Load the native context of the current context.
4719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  movp(scratch, ContextOperand(scratch, Context::NATIVE_CONTEXT_INDEX));
4720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Check the context is a native context.
472244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (emit_debug_code()) {
4723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Cmp(FieldOperand(scratch, HeapObject::kMapOffset),
4724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        isolate()->factory()->native_context_map());
4725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Check(equal, kJSGlobalObjectNativeContextShouldBeANativeContext);
4726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
4727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check if both contexts are the same.
4729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  cmpp(scratch, FieldOperand(holder_reg, JSGlobalProxy::kNativeContextOffset));
4730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  j(equal, &same_contexts);
4731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compare security tokens.
4733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check that the security token in the calling global object is
4734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // compatible with the security token in the receiving global
4735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // object.
4736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Check the context is a native context.
473844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (emit_debug_code()) {
4739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Preserve original value of holder_reg.
4740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Push(holder_reg);
4741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(holder_reg,
4742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         FieldOperand(holder_reg, JSGlobalProxy::kNativeContextOffset));
4743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    CompareRoot(holder_reg, Heap::kNullValueRootIndex);
4744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Check(not_equal, kJSGlobalProxyContextShouldNotBeNull);
4745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Read the first word and compare to native_context_map(),
4747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(holder_reg, FieldOperand(holder_reg, HeapObject::kMapOffset));
4748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CompareRoot(holder_reg, Heap::kNativeContextMapRootIndex);
4749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Check(equal, kJSGlobalObjectNativeContextShouldBeANativeContext);
4750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Pop(holder_reg);
4751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
4752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(kScratchRegister,
4754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       FieldOperand(holder_reg, JSGlobalProxy::kNativeContextOffset));
47553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  int token_offset =
47563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block      Context::kHeaderSize + Context::SECURITY_TOKEN_INDEX * kPointerSize;
4757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(scratch, FieldOperand(scratch, token_offset));
4758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  cmpp(scratch, FieldOperand(kScratchRegister, token_offset));
4759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  j(not_equal, miss);
4760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bind(&same_contexts);
4762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
4763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Compute the hash code from the untagged key.  This must be kept in sync with
4766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ComputeIntegerHash in utils.h and KeyedLoadGenericStub in
4767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// code-stub-hydrogen.cc
4768c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdochvoid MacroAssembler::GetNumberHash(Register r0, Register scratch) {
4769c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  // First of all we assign the hash seed to scratch.
4770c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  LoadRoot(scratch, Heap::kHashSeedRootIndex);
4771c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  SmiToInteger32(scratch, scratch);
4772c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch
4773c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  // Xor original key with a seed.
4774c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  xorl(r0, scratch);
4775c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch
4776c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  // Compute the hash code from the untagged key.  This must be kept in sync
4777c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  // with ComputeIntegerHash in utils.h.
4778c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  //
4779c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  // hash = ~hash + (hash << 15);
4780c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  movl(scratch, r0);
4781c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  notl(r0);
4782c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  shll(scratch, Immediate(15));
4783c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  addl(r0, scratch);
4784c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  // hash = hash ^ (hash >> 12);
4785c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  movl(scratch, r0);
4786c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  shrl(scratch, Immediate(12));
4787c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  xorl(r0, scratch);
4788c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  // hash = hash + (hash << 2);
4789c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  leal(r0, Operand(r0, r0, times_4, 0));
4790c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  // hash = hash ^ (hash >> 4);
4791c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  movl(scratch, r0);
4792c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  shrl(scratch, Immediate(4));
4793c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  xorl(r0, scratch);
4794c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  // hash = hash * 2057;
4795c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  imull(r0, r0, Immediate(2057));
4796c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  // hash = hash ^ (hash >> 16);
4797c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  movl(scratch, r0);
4798c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  shrl(scratch, Immediate(16));
4799c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  xorl(r0, scratch);
4800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  andl(r0, Immediate(0x3fffffff));
4801c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch}
4802c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch
4803c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch
4804c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch
48053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid MacroAssembler::LoadFromNumberDictionary(Label* miss,
48063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                              Register elements,
48073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                              Register key,
48083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                              Register r0,
48093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                              Register r1,
48103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                              Register r2,
48113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                              Register result) {
48123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Register use:
48133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  //
48143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // elements - holds the slow-case elements of the receiver on entry.
48153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  //            Unchanged unless 'result' is the same register.
48163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  //
48173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // key      - holds the smi key on entry.
48183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  //            Unchanged unless 'result' is the same register.
48193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  //
48203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Scratch registers:
48213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  //
48223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // r0 - holds the untagged key on entry and holds the hash once computed.
48233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  //
48243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // r1 - used to hold the capacity mask of the dictionary
48253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  //
48263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // r2 - used for the index into the dictionary.
48273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  //
48283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // result - holds the result on exit if the load succeeded.
48293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  //          Allowed to be the same as 'key' or 'result'.
48303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  //          Unchanged on bailout so 'key' or 'result' can be used
48313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  //          in further computation.
48323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
48333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Label done;
48343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
4835c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  GetNumberHash(r0, r1);
48363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
48373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Compute capacity mask.
4838c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  SmiToInteger32(r1, FieldOperand(elements,
4839c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch                                  SeededNumberDictionary::kCapacityOffset));
48403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  decl(r1);
48413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
48423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Generate an unrolled loop that performs a few probes before giving up.
4843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < kNumberDictionaryProbes; i++) {
48443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    // Use r2 for index calculations and keep the hash intact in r0.
4845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(r2, r0);
48463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    // Compute the masked index: (hash + i + i * i) & mask.
48473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    if (i > 0) {
4848c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch      addl(r2, Immediate(SeededNumberDictionary::GetProbeOffset(i)));
48493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    }
4850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    andp(r2, r1);
48513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
48523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    // Scale the index by multiplying by the entry size.
4853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(SeededNumberDictionary::kEntrySize == 3);
4854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    leap(r2, Operand(r2, r2, times_2, 0));  // r2 = r2 * 3
48553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
48563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    // Check if the key matches.
4857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    cmpp(key, FieldOperand(elements,
48583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                           r2,
48593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                           times_pointer_size,
4860c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch                           SeededNumberDictionary::kElementsStartOffset));
4861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (i != (kNumberDictionaryProbes - 1)) {
48623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      j(equal, &done);
48633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    } else {
48643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      j(not_equal, miss);
48653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    }
48663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
48673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
48683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  bind(&done);
4869958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Check that the value is a field property.
48703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  const int kDetailsOffset =
4871c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch      SeededNumberDictionary::kElementsStartOffset + 2 * kPointerSize;
4872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(DATA, 0);
48733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset),
4874589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch       Smi::FromInt(PropertyDetails::TypeField::kMask));
48753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  j(not_zero, miss);
48763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
48773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Get the value at the masked, scaled index.
48783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  const int kValueOffset =
4879c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch      SeededNumberDictionary::kElementsStartOffset + kPointerSize;
4880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(result, FieldOperand(elements, r2, times_pointer_size, kValueOffset));
48813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
48823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
48833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
4884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::LoadAllocationTopHelper(Register result,
4885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                             Register scratch,
4886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                             AllocationFlags flags) {
4887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ExternalReference allocation_top =
4888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      AllocationUtils::GetAllocationTopReference(isolate(), flags);
4889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Just return if allocation top is already known.
4891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if ((flags & RESULT_CONTAINS_TOP) != 0) {
4892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // No use of scratch if allocation top is provided.
4893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!scratch.is_valid());
4894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
4895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Assert that result actually contains top on entry.
4896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Operand top_operand = ExternalOperand(allocation_top);
4897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    cmpp(result, top_operand);
4898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Check(equal, kUnexpectedAllocationTop);
4899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
4900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return;
4901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
4902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
49036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Move address of new object to result. Use scratch register if available,
49046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // and keep address in scratch until call to UpdateAllocationTopHelper.
49056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (scratch.is_valid()) {
4906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LoadAddress(scratch, allocation_top);
4907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(result, Operand(scratch, 0));
4908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
4909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Load(result, allocation_top);
4910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::MakeSureDoubleAlignedHelper(Register result,
4915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                 Register scratch,
4916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                 Label* gc_required,
4917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                 AllocationFlags flags) {
4918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (kPointerSize == kDoubleSize) {
4919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (FLAG_debug_code) {
4920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      testl(result, Immediate(kDoubleAlignmentMask));
4921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Check(zero, kAllocationIsNotDoubleAligned);
4922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
49236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  } else {
4924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Align the next allocation. Storing the filler map without checking top
4925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // is safe in new-space because the limit of the heap is aligned there.
4926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(kPointerSize * 2 == kDoubleSize);
4927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(kPointerAlignment * 2 == kDoubleAlignment);
4928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Make sure scratch is not clobbered by this function as it might be
4929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // used in UpdateAllocationTopHelper later.
4930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!scratch.is(kScratchRegister));
4931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Label aligned;
4932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    testl(result, Immediate(kDoubleAlignmentMask));
4933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    j(zero, &aligned, Label::kNear);
4934bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (((flags & ALLOCATION_FOLDED) == 0) && ((flags & PRETENURE) != 0)) {
4935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ExternalReference allocation_limit =
4936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          AllocationUtils::GetAllocationLimitReference(isolate(), flags);
4937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      cmpp(result, ExternalOperand(allocation_limit));
4938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      j(above_equal, gc_required);
4939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
4940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LoadRoot(kScratchRegister, Heap::kOnePointerFillerMapRootIndex);
4941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(Operand(result, 0), kScratchRegister);
4942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    addp(result, Immediate(kDoubleSize / 2));
4943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bind(&aligned);
4944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
4945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
4946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid MacroAssembler::UpdateAllocationTopHelper(Register result_end,
4949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                               Register scratch,
4950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                               AllocationFlags flags) {
495144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (emit_debug_code()) {
4952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    testp(result_end, Immediate(kObjectAlignmentMask));
4953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Check(zero, kUnalignedAllocationInNewSpace);
4954d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
4955d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
4956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ExternalReference allocation_top =
4957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      AllocationUtils::GetAllocationTopReference(isolate(), flags);
4958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Update new top.
496044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (scratch.is_valid()) {
496144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // Scratch already contains address of allocation top.
4962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(Operand(scratch, 0), result_end);
4963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
4964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Store(allocation_top, result_end);
4965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
4966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
4967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Allocate(int object_size,
4970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              Register result,
4971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              Register result_end,
4972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              Register scratch,
4973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              Label* gc_required,
4974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              AllocationFlags flags) {
4975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((flags & (RESULT_CONTAINS_TOP | SIZE_IN_WORDS)) == 0);
4976f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  DCHECK(object_size <= kMaxRegularHeapObjectSize);
4977bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK((flags & ALLOCATION_FOLDED) == 0);
49785913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  if (!FLAG_inline_new) {
497944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (emit_debug_code()) {
49805913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      // Trash the registers to simulate an allocation failure.
49815913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      movl(result, Immediate(0x7091));
49825913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      if (result_end.is_valid()) {
49835913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck        movl(result_end, Immediate(0x7191));
49845913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      }
49855913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      if (scratch.is_valid()) {
49865913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck        movl(scratch, Immediate(0x7291));
49875913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      }
49885913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    }
49895913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    jmp(gc_required);
49905913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    return;
49915913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  }
4992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!result.is(result_end));
4993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Load address of new object into result.
49958a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  LoadAllocationTopHelper(result, scratch, flags);
4996a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if ((flags & DOUBLE_ALIGNMENT) != 0) {
4998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MakeSureDoubleAlignedHelper(result, scratch, gc_required, flags);
4999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5001a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Calculate new top and bail out if new space is exhausted.
5002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ExternalReference allocation_limit =
5003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      AllocationUtils::GetAllocationLimitReference(isolate(), flags);
50046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
50056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Register top_reg = result_end.is_valid() ? result_end : result;
50066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
50071e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  if (!top_reg.is(result)) {
5008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(top_reg, result);
50096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
5010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  addp(top_reg, Immediate(object_size));
5011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Operand limit_operand = ExternalOperand(allocation_limit);
5012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  cmpp(top_reg, limit_operand);
5013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  j(above, gc_required);
5014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5015bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if ((flags & ALLOCATION_FOLDING_DOMINATOR) == 0) {
5016bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    // The top pointer is not updated for allocation folding dominators.
5017bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    UpdateAllocationTopHelper(top_reg, scratch, flags);
5018bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
5019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
50206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (top_reg.is(result)) {
5021bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    subp(result, Immediate(object_size - kHeapObjectTag));
5022bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  } else {
5023bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    // Tag the result.
5024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(kHeapObjectTag == 1);
5025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    incp(result);
5026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
5027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Allocate(int header_size,
5031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              ScaleFactor element_size,
5032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              Register element_count,
5033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              Register result,
5034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              Register result_end,
5035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              Register scratch,
5036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              Label* gc_required,
5037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              AllocationFlags flags) {
5038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((flags & SIZE_IN_WORDS) == 0);
5039bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK((flags & ALLOCATION_FOLDING_DOMINATOR) == 0);
5040bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK((flags & ALLOCATION_FOLDED) == 0);
5041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  leap(result_end, Operand(element_count, element_size, header_size));
5042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Allocate(result_end, result, result_end, scratch, gc_required, flags);
5043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::Allocate(Register object_size,
5047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              Register result,
5048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              Register result_end,
5049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              Register scratch,
5050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              Label* gc_required,
5051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              AllocationFlags flags) {
5052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((flags & SIZE_IN_WORDS) == 0);
5053bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK((flags & ALLOCATION_FOLDED) == 0);
50545913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  if (!FLAG_inline_new) {
505544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (emit_debug_code()) {
50565913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      // Trash the registers to simulate an allocation failure.
50575913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      movl(result, Immediate(0x7091));
50585913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      movl(result_end, Immediate(0x7191));
50595913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      if (scratch.is_valid()) {
50605913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck        movl(scratch, Immediate(0x7291));
50615913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      }
50625913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      // object_size is left unchanged by this function.
50635913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    }
50645913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    jmp(gc_required);
50655913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    return;
50665913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  }
5067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!result.is(result_end));
50685913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck
5069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Load address of new object into result.
50708a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  LoadAllocationTopHelper(result, scratch, flags);
5071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if ((flags & DOUBLE_ALIGNMENT) != 0) {
5073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MakeSureDoubleAlignedHelper(result, scratch, gc_required, flags);
5074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ExternalReference allocation_limit =
5077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      AllocationUtils::GetAllocationLimitReference(isolate(), flags);
5078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!object_size.is(result_end)) {
5079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(result_end, object_size);
5080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
5081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  addp(result_end, result);
5082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Operand limit_operand = ExternalOperand(allocation_limit);
5083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  cmpp(result_end, limit_operand);
5084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  j(above, gc_required);
5085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5086bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if ((flags & ALLOCATION_FOLDING_DOMINATOR) == 0) {
5087bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    // The top pointer is not updated for allocation folding dominators.
5088bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    UpdateAllocationTopHelper(result_end, scratch, flags);
5089bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
5090bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
5091bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // Tag the result.
5092bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  addp(result, Immediate(kHeapObjectTag));
5093bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
5094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5095bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid MacroAssembler::FastAllocate(int object_size, Register result,
5096bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                  Register result_end, AllocationFlags flags) {
5097bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK(!result.is(result_end));
5098bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // Load address of new object into result.
5099bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  LoadAllocationTopHelper(result, no_reg, flags);
5100bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
5101bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if ((flags & DOUBLE_ALIGNMENT) != 0) {
5102bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    MakeSureDoubleAlignedHelper(result, no_reg, NULL, flags);
5103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
5104bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
5105bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  leap(result_end, Operand(result, object_size));
5106bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
5107bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  UpdateAllocationTopHelper(result_end, no_reg, flags);
5108bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
5109bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  addp(result, Immediate(kHeapObjectTag));
5110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5112bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid MacroAssembler::FastAllocate(Register object_size, Register result,
5113bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                  Register result_end, AllocationFlags flags) {
5114bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK(!result.is(result_end));
5115bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // Load address of new object into result.
5116bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  LoadAllocationTopHelper(result, no_reg, flags);
5117bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
5118bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if ((flags & DOUBLE_ALIGNMENT) != 0) {
5119bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    MakeSureDoubleAlignedHelper(result, no_reg, NULL, flags);
5120bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
5121bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
5122bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  leap(result_end, Operand(result, object_size, times_1, 0));
5123bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
5124bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  UpdateAllocationTopHelper(result_end, no_reg, flags);
5125bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
5126bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  addp(result, Immediate(kHeapObjectTag));
5127bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
5128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
51293ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid MacroAssembler::AllocateHeapNumber(Register result,
51303ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block                                        Register scratch,
5131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                        Label* gc_required,
5132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                        MutableMode mode) {
51333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Allocate heap number in new space.
5134bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Allocate(HeapNumber::kSize, result, scratch, no_reg, gc_required,
5135bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch           NO_ALLOCATION_FLAGS);
5136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Heap::RootListIndex map_index = mode == MUTABLE
5138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ? Heap::kMutableHeapNumberMapRootIndex
5139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : Heap::kHeapNumberMapRootIndex;
51403ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
51413ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Set the map.
5142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LoadRoot(kScratchRegister, map_index);
5143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister);
51443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
51453ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
51463ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
5147e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid MacroAssembler::AllocateTwoByteString(Register result,
5148e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke                                           Register length,
5149e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke                                           Register scratch1,
5150e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke                                           Register scratch2,
5151e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke                                           Register scratch3,
5152e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke                                           Label* gc_required) {
5153e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Calculate the number of bytes needed for the characters in the string while
5154e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // observing object alignment.
51556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  const int kHeaderAlignment = SeqTwoByteString::kHeaderSize &
51566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                               kObjectAlignmentMask;
5157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kShortSize == 2);
5158e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // scratch1 = length * 2 + kObjectAlignmentMask.
5159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  leap(scratch1, Operand(length, length, times_1, kObjectAlignmentMask +
51606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                kHeaderAlignment));
5161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  andp(scratch1, Immediate(~kObjectAlignmentMask));
51626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (kHeaderAlignment > 0) {
5163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    subp(scratch1, Immediate(kHeaderAlignment));
51646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
5165e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
5166e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Allocate two byte string in new space.
5167bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Allocate(SeqTwoByteString::kHeaderSize, times_1, scratch1, result, scratch2,
5168bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch           scratch3, gc_required, NO_ALLOCATION_FLAGS);
5169e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
5170e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Set the map, length and hash field.
5171e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  LoadRoot(kScratchRegister, Heap::kStringMapRootIndex);
5172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister);
51736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Integer32ToSmi(scratch1, length);
5174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(FieldOperand(result, String::kLengthOffset), scratch1);
5175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(FieldOperand(result, String::kHashFieldOffset),
5176e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke       Immediate(String::kEmptyHashField));
5177e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
5178e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
5179e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
5180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AllocateOneByteString(Register result, Register length,
5181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           Register scratch1, Register scratch2,
5182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           Register scratch3,
5183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           Label* gc_required) {
5184e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Calculate the number of bytes needed for the characters in the string while
5185e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // observing object alignment.
5186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const int kHeaderAlignment = SeqOneByteString::kHeaderSize &
51876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                               kObjectAlignmentMask;
5188e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  movl(scratch1, length);
5189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(kCharSize == 1);
5190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  addp(scratch1, Immediate(kObjectAlignmentMask + kHeaderAlignment));
5191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  andp(scratch1, Immediate(~kObjectAlignmentMask));
51926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (kHeaderAlignment > 0) {
5193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    subp(scratch1, Immediate(kHeaderAlignment));
51946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
5195e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
5196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Allocate one-byte string in new space.
5197bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Allocate(SeqOneByteString::kHeaderSize, times_1, scratch1, result, scratch2,
5198bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch           scratch3, gc_required, NO_ALLOCATION_FLAGS);
5199e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
5200e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Set the map, length and hash field.
5201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LoadRoot(kScratchRegister, Heap::kOneByteStringMapRootIndex);
5202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister);
52036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Integer32ToSmi(scratch1, length);
5204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(FieldOperand(result, String::kLengthOffset), scratch1);
5205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(FieldOperand(result, String::kHashFieldOffset),
5206e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke       Immediate(String::kEmptyHashField));
5207e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
5208e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
5209e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
5210589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochvoid MacroAssembler::AllocateTwoByteConsString(Register result,
5211e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke                                        Register scratch1,
5212e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke                                        Register scratch2,
5213e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke                                        Label* gc_required) {
5214e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Allocate heap number in new space.
5215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required,
5216bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch           NO_ALLOCATION_FLAGS);
5217e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
5218e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Set the map. The other fields are left uninitialized.
5219e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  LoadRoot(kScratchRegister, Heap::kConsStringMapRootIndex);
5220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister);
5221e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
5222e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
5223e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
5224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AllocateOneByteConsString(Register result,
5225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                               Register scratch1,
5226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                               Register scratch2,
5227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                               Label* gc_required) {
5228bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required,
5229bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch           NO_ALLOCATION_FLAGS);
5230e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
5231e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Set the map. The other fields are left uninitialized.
5232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LoadRoot(kScratchRegister, Heap::kConsOneByteStringMapRootIndex);
5233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister);
5234e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
5235e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
5236e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
5237589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochvoid MacroAssembler::AllocateTwoByteSlicedString(Register result,
5238589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                                          Register scratch1,
5239589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                                          Register scratch2,
5240589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                                          Label* gc_required) {
5241589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Allocate heap number in new space.
5242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required,
5243bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch           NO_ALLOCATION_FLAGS);
5244589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
5245589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Set the map. The other fields are left uninitialized.
5246589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  LoadRoot(kScratchRegister, Heap::kSlicedStringMapRootIndex);
5247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister);
5248589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch}
5249589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
5250589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
5251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::AllocateOneByteSlicedString(Register result,
5252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                 Register scratch1,
5253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                 Register scratch2,
5254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                 Label* gc_required) {
5255589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Allocate heap number in new space.
5256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required,
5257bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch           NO_ALLOCATION_FLAGS);
5258589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
5259589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Set the map. The other fields are left uninitialized.
5260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LoadRoot(kScratchRegister, Heap::kSlicedOneByteStringMapRootIndex);
5261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister);
5262589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch}
5263589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
5264589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
5265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::AllocateJSValue(Register result, Register constructor,
5266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     Register value, Register scratch,
5267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     Label* gc_required) {
5268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!result.is(constructor));
5269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!result.is(scratch));
5270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!result.is(value));
5271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Allocate JSValue in new space.
5273bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Allocate(JSValue::kSize, result, scratch, no_reg, gc_required,
5274bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch           NO_ALLOCATION_FLAGS);
5275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Initialize the JSValue.
5277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LoadGlobalFunctionInitialMap(constructor, scratch);
5278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  movp(FieldOperand(result, HeapObject::kMapOffset), scratch);
5279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LoadRoot(scratch, Heap::kEmptyFixedArrayRootIndex);
5280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  movp(FieldOperand(result, JSObject::kPropertiesOffset), scratch);
5281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  movp(FieldOperand(result, JSObject::kElementsOffset), scratch);
5282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  movp(FieldOperand(result, JSValue::kValueOffset), value);
5283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize);
5284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
5285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
528744f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Copy memory, byte-by-byte, from source to destination.  Not optimized for
528844f0eee88ff00398ff7f715fab053374d808c90dSteve Block// long or aligned copies.  The contents of scratch and length are destroyed.
528944f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Destination is incremented by length, source, length and scratch are
529044f0eee88ff00398ff7f715fab053374d808c90dSteve Block// clobbered.
529144f0eee88ff00398ff7f715fab053374d808c90dSteve Block// A simpler loop is faster on small copies, but slower on large ones.
529244f0eee88ff00398ff7f715fab053374d808c90dSteve Block// The cld() instruction must have been emitted, to set the direction flag(),
529344f0eee88ff00398ff7f715fab053374d808c90dSteve Block// before calling this function.
529444f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid MacroAssembler::CopyBytes(Register destination,
529544f0eee88ff00398ff7f715fab053374d808c90dSteve Block                               Register source,
529644f0eee88ff00398ff7f715fab053374d808c90dSteve Block                               Register length,
529744f0eee88ff00398ff7f715fab053374d808c90dSteve Block                               int min_length,
529844f0eee88ff00398ff7f715fab053374d808c90dSteve Block                               Register scratch) {
5299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(min_length >= 0);
5300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (emit_debug_code()) {
530144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    cmpl(length, Immediate(min_length));
5302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Assert(greater_equal, kInvalidMinLength);
530344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
5304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Label short_loop, len8, len16, len24, done, short_string;
530544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
5306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const int kLongStringLimit = 4 * kPointerSize;
530744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (min_length <= kLongStringLimit) {
5308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    cmpl(length, Immediate(kPointerSize));
5309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    j(below, &short_string, Label::kNear);
531044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
531144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
5312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(source.is(rsi));
5313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(destination.is(rdi));
5314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(length.is(rcx));
5315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (min_length <= kLongStringLimit) {
5317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    cmpl(length, Immediate(2 * kPointerSize));
5318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    j(below_equal, &len8, Label::kNear);
5319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    cmpl(length, Immediate(3 * kPointerSize));
5320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    j(below_equal, &len16, Label::kNear);
5321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    cmpl(length, Immediate(4 * kPointerSize));
5322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    j(below_equal, &len24, Label::kNear);
5323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
532444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
532544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Because source is 8-byte aligned in our uses of this function,
532644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // we keep source aligned for the rep movs operation by copying the odd bytes
532744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // at the end of the ranges.
5328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(scratch, length);
5329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  shrl(length, Immediate(kPointerSizeLog2));
5330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  repmovsp();
533144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // Move remaining bytes of length.
5332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  andl(scratch, Immediate(kPointerSize - 1));
5333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(length, Operand(source, scratch, times_1, -kPointerSize));
5334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(Operand(destination, scratch, times_1, -kPointerSize), length);
5335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  addp(destination, scratch);
533644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
533744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (min_length <= kLongStringLimit) {
5338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    jmp(&done, Label::kNear);
5339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bind(&len24);
5340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(scratch, Operand(source, 2 * kPointerSize));
5341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(Operand(destination, 2 * kPointerSize), scratch);
5342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bind(&len16);
5343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(scratch, Operand(source, kPointerSize));
5344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(Operand(destination, kPointerSize), scratch);
5345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bind(&len8);
5346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(scratch, Operand(source, 0));
5347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(Operand(destination, 0), scratch);
5348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Move remaining bytes of length.
5349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(scratch, Operand(source, length, times_1, -kPointerSize));
5350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(Operand(destination, length, times_1, -kPointerSize), scratch);
5351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    addp(destination, length);
5352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    jmp(&done, Label::kNear);
535344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
535444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    bind(&short_string);
535544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (min_length == 0) {
535644f0eee88ff00398ff7f715fab053374d808c90dSteve Block      testl(length, length);
5357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      j(zero, &done, Label::kNear);
535844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    }
535944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
536044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    bind(&short_loop);
5361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movb(scratch, Operand(source, 0));
5362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movb(Operand(destination, 0), scratch);
5363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    incp(source);
5364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    incp(destination);
5365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    decl(length);
5366109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    j(not_zero, &short_loop, Label::kNear);
536744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
5368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bind(&done);
537044f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
537144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
537244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
5373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::InitializeFieldsWithFiller(Register current_address,
5374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                Register end_address,
53753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                                Register filler) {
53763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Label loop, entry;
5377109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  jmp(&entry, Label::kNear);
53783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bind(&loop);
5379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  movp(Operand(current_address, 0), filler);
5380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  addp(current_address, Immediate(kPointerSize));
53813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bind(&entry);
5382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  cmpp(current_address, end_address);
5383109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  j(below, &loop, Label::kNear);
53843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
53853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
53863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5387d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockvoid MacroAssembler::LoadContext(Register dst, int context_chain_length) {
5388d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  if (context_chain_length > 0) {
5389d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    // Move up the chain of contexts to the context containing the slot.
5390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(dst, Operand(rsi, Context::SlotOffset(Context::PREVIOUS_INDEX)));
5391d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    for (int i = 1; i < context_chain_length; i++) {
5392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      movp(dst, Operand(dst, Context::SlotOffset(Context::PREVIOUS_INDEX)));
5393d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    }
5394e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  } else {
5395e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    // Slot is in the current function context.  Move it into the
5396e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    // destination register in case we store into it (the write barrier
5397e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    // cannot be allowed to destroy the context in rsi).
5398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(dst, rsi);
5399e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
5400e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
54013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // We should not have found a with context by walking the context
54023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // chain (i.e., the static scope chain and runtime context chain do
54033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // not agree).  A variable occurring in such a scope should have
54043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // slot type LOOKUP and not CONTEXT.
540544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (emit_debug_code()) {
54063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    CompareRoot(FieldOperand(dst, HeapObject::kMapOffset),
54073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                Heap::kWithContextMapRootIndex);
5408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Check(not_equal, kVariableResolvedToWithContext);
5409d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
5410d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
5411d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
54123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
54133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::LoadTransitionedArrayMapConditional(
54143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ElementsKind expected_kind,
54153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ElementsKind transitioned_kind,
54163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Register map_in_out,
54173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Register scratch,
54183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Label* no_map_match) {
5419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(IsFastElementsKind(expected_kind));
5420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(IsFastElementsKind(transitioned_kind));
54213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
54223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Check that the function's map is the same as the expected cached map.
5423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  movp(scratch, NativeContextOperand());
5424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  cmpp(map_in_out,
5425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       ContextOperand(scratch, Context::ArrayMapIndex(expected_kind)));
54263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  j(not_equal, no_map_match);
54273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
54283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Use the transitioned cached map.
5429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  movp(map_in_out,
5430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       ContextOperand(scratch, Context::ArrayMapIndex(transitioned_kind)));
54313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
54323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
54333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
543444f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef _WIN64
543544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic const int kRegisterPassedArguments = 4;
543644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#else
543744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic const int kRegisterPassedArguments = 6;
543844f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif
54397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::LoadNativeContextSlot(int index, Register dst) {
5442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  movp(dst, NativeContextOperand());
5443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  movp(dst, ContextOperand(dst, index));
5444b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
5445b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5446b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5447b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid MacroAssembler::LoadGlobalFunctionInitialMap(Register function,
5448b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                                  Register map) {
5449b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Load the initial map.  The global functions all have initial maps.
5450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(map, FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
545144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (emit_debug_code()) {
5452b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    Label ok, fail;
5453257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    CheckMap(map, isolate()->factory()->meta_map(), &fail, DO_SMI_CHECK);
5454b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    jmp(&ok);
5455b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    bind(&fail);
5456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Abort(kGlobalFunctionsMustHaveInitialMap);
5457b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    bind(&ok);
5458b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
5459b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
5460b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5461b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
54624515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkeint MacroAssembler::ArgumentStackSlotsForCFunctionCall(int num_arguments) {
54637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // On Windows 64 stack slots are reserved by the caller for all arguments
54647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // including the ones passed in registers, and space is always allocated for
54657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // the four register arguments even if the function takes fewer than four
54667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // arguments.
54677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // On AMD64 ABI (Linux/Mac) the first six arguments are passed in registers
54687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // and the caller does not reserve stack slots for them.
5469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(num_arguments >= 0);
54704515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke#ifdef _WIN64
547144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  const int kMinimumStackSlots = kRegisterPassedArguments;
54727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  if (num_arguments < kMinimumStackSlots) return kMinimumStackSlots;
54737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  return num_arguments;
54744515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke#else
54757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  if (num_arguments < kRegisterPassedArguments) return 0;
54767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  return num_arguments - kRegisterPassedArguments;
54774515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke#endif
54784515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke}
54794515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke
54807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
5481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::EmitSeqStringSetCharCheck(Register string,
5482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                               Register index,
5483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                               Register value,
5484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                               uint32_t encoding_mask) {
5485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Label is_object;
5486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  JumpIfNotSmi(string, &is_object);
5487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Abort(kNonObject);
5488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bind(&is_object);
5489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Push(value);
5491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(value, FieldOperand(string, HeapObject::kMapOffset));
5492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movzxbp(value, FieldOperand(value, Map::kInstanceTypeOffset));
5493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  andb(value, Immediate(kStringRepresentationMask | kStringEncodingMask));
5495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  cmpp(value, Immediate(encoding_mask));
5496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Pop(value);
5497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Check(equal, kUnexpectedStringType);
5498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The index is assumed to be untagged coming in, tag it to compare with the
5500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // string length without using a temp register, it is restored at the end of
5501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // this function.
5502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Integer32ToSmi(index, index);
5503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SmiCompare(index, FieldOperand(string, String::kLengthOffset));
5504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Check(less, kIndexIsTooLarge);
5505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SmiCompare(index, Smi::FromInt(0));
5507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Check(greater_equal, kIndexIsNegative);
5508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Restore the index
5510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SmiToInteger32(index, index);
5511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
55144515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkevoid MacroAssembler::PrepareCallCFunction(int num_arguments) {
5515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int frame_alignment = base::OS::ActivationFrameAlignment();
5516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(frame_alignment != 0);
5517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(num_arguments >= 0);
551844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
55194515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  // Make stack end at alignment and allocate space for arguments and old rsp.
5520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(kScratchRegister, rsp);
5521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(base::bits::IsPowerOfTwo32(frame_alignment));
55224515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  int argument_slots_on_stack =
55234515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke      ArgumentStackSlotsForCFunctionCall(num_arguments);
5524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  subp(rsp, Immediate((argument_slots_on_stack + 1) * kRegisterSize));
5525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  andp(rsp, Immediate(-frame_alignment));
5526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(Operand(rsp, argument_slots_on_stack * kRegisterSize), kScratchRegister);
55274515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke}
55284515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke
55294515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke
55304515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkevoid MacroAssembler::CallCFunction(ExternalReference function,
55314515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke                                   int num_arguments) {
553244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  LoadAddress(rax, function);
55334515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  CallCFunction(rax, num_arguments);
55344515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke}
55354515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke
55364515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke
55374515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkevoid MacroAssembler::CallCFunction(Register function, int num_arguments) {
5538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(has_frame());
55396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Check stack alignment.
554044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (emit_debug_code()) {
55416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    CheckStackAlignment();
55426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
55436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
55444515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  call(function);
5545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(base::OS::ActivationFrameAlignment() != 0);
5546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(num_arguments >= 0);
55474515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  int argument_slots_on_stack =
55484515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke      ArgumentStackSlotsForCFunctionCall(num_arguments);
5549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(rsp, Operand(rsp, argument_slots_on_stack * kRegisterSize));
55504515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke}
55514515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke
5552d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
5553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
5554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool AreAliased(Register reg1,
5555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                Register reg2,
5556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                Register reg3,
5557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                Register reg4,
5558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                Register reg5,
5559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                Register reg6,
5560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                Register reg7,
5561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                Register reg8) {
5562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int n_of_valid_regs = reg1.is_valid() + reg2.is_valid() +
5563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      reg3.is_valid() + reg4.is_valid() + reg5.is_valid() + reg6.is_valid() +
5564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      reg7.is_valid() + reg8.is_valid();
5565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RegList regs = 0;
5567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (reg1.is_valid()) regs |= reg1.bit();
5568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (reg2.is_valid()) regs |= reg2.bit();
5569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (reg3.is_valid()) regs |= reg3.bit();
5570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (reg4.is_valid()) regs |= reg4.bit();
5571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (reg5.is_valid()) regs |= reg5.bit();
5572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (reg6.is_valid()) regs |= reg6.bit();
5573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (reg7.is_valid()) regs |= reg7.bit();
5574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (reg8.is_valid()) regs |= reg8.bit();
5575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int n_of_non_aliasing_regs = NumRegs(regs);
5576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return n_of_valid_regs != n_of_non_aliasing_regs;
55783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
5579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
55803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
55813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochCodePatcher::CodePatcher(Isolate* isolate, byte* address, int size)
55838b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    : address_(address),
55848b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch      size_(size),
5585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      masm_(isolate, address, size + Assembler::kGap, CodeObjectRequired::kNo) {
5586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Create a new macro assembler pointing to the address of the code to patch.
5587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The size is adjusted with kGap on order for the assembler to generate size
5588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // bytes of instructions without failing with buffer size constraints.
5589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap);
5590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCodePatcher::~CodePatcher() {
5594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Indicate that code has changed.
5595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Assembler::FlushICache(masm_.isolate(), address_, size_);
5596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check that the code was patched as expected.
5598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(masm_.pc_ == address_ + size_);
5599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap);
5600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
56023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
56033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::CheckPageFlag(
56043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Register object,
56053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Register scratch,
56063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    int mask,
56073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Condition cc,
56083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Label* condition_met,
56093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    Label::Distance condition_met_distance) {
5610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(cc == zero || cc == not_zero);
56113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (scratch.is(object)) {
5612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    andp(scratch, Immediate(~Page::kPageAlignmentMask));
56133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
5614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    movp(scratch, Immediate(~Page::kPageAlignmentMask));
5615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    andp(scratch, object);
56163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
56173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (mask < (1 << kBitsPerByte)) {
56183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    testb(Operand(scratch, MemoryChunk::kFlagsOffset),
56193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          Immediate(static_cast<uint8_t>(mask)));
56203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
56213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    testl(Operand(scratch, MemoryChunk::kFlagsOffset), Immediate(mask));
56223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
56233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  j(cc, condition_met, condition_met_distance);
56243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
56253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
56263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
56273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::JumpIfBlack(Register object,
56283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Register bitmap_scratch,
56293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Register mask_scratch,
56303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Label* on_black,
56313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Label::Distance on_black_distance) {
5632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!AreAliased(object, bitmap_scratch, mask_scratch, rcx));
5633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
56343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GetMarkBits(object, bitmap_scratch, mask_scratch);
56353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(strcmp(Marking::kBlackBitPattern, "11") == 0);
56373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // The mask_scratch register contains a 1 at the position of the first bit
5638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // and a 1 at a position of the second bit. All other positions are zero.
5639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(rcx, mask_scratch);
5640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  andp(rcx, Operand(bitmap_scratch, MemoryChunk::kHeaderSize));
5641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  cmpp(mask_scratch, rcx);
56423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  j(equal, on_black, on_black_distance);
56433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
56443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
56453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
56463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid MacroAssembler::GetMarkBits(Register addr_reg,
56473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Register bitmap_reg,
56483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                 Register mask_reg) {
5649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!AreAliased(addr_reg, bitmap_reg, mask_reg, rcx));
5650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(bitmap_reg, addr_reg);
56513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Sign extended 32 bit immediate.
5652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  andp(bitmap_reg, Immediate(~Page::kPageAlignmentMask));
5653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(rcx, addr_reg);
56543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int shift =
56553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Bitmap::kBitsPerCellLog2 + kPointerSizeLog2 - Bitmap::kBytesPerCellLog2;
56563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  shrl(rcx, Immediate(shift));
5657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  andp(rcx,
56583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch       Immediate((Page::kPageAlignmentMask >> shift) &
56593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                 ~(Bitmap::kBytesPerCell - 1)));
56603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  addp(bitmap_reg, rcx);
5662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(rcx, addr_reg);
56633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  shrl(rcx, Immediate(kPointerSizeLog2));
5664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  andp(rcx, Immediate((1 << Bitmap::kBitsPerCellLog2) - 1));
5665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  movl(mask_reg, Immediate(3));
5666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  shlp_cl(mask_reg);
56673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
56683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
56693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid MacroAssembler::JumpIfWhite(Register value, Register bitmap_scratch,
5671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 Register mask_scratch, Label* value_is_white,
5672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 Label::Distance distance) {
5673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!AreAliased(value, bitmap_scratch, mask_scratch, rcx));
56743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  GetMarkBits(value, bitmap_scratch, mask_scratch);
56753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
56763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // If the value is black or grey we don't need to do anything.
5677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(strcmp(Marking::kWhiteBitPattern, "00") == 0);
5678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(strcmp(Marking::kBlackBitPattern, "11") == 0);
5679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(strcmp(Marking::kGreyBitPattern, "10") == 0);
5680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(strcmp(Marking::kImpossibleBitPattern, "01") == 0);
56813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
56823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Since both black and grey have a 1 in the first position and white does
56833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // not have a 1 there we only need to check one bit.
5684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  testp(Operand(bitmap_scratch, MemoryChunk::kHeaderSize), mask_scratch);
5685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  j(zero, value_is_white, distance);
56863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
56873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
56883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5689109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid MacroAssembler::CheckEnumCache(Label* call_runtime) {
5690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Label next, start;
56913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Register empty_fixed_array_value = r8;
56923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  LoadRoot(empty_fixed_array_value, Heap::kEmptyFixedArrayRootIndex);
5693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(rcx, rax);
5694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Check if the enum length field is properly initialized, indicating that
5696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // there is an enum cache.
5697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(rbx, FieldOperand(rcx, HeapObject::kMapOffset));
5698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EnumLength(rdx, rbx);
5700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Cmp(rdx, Smi::FromInt(kInvalidEnumCacheSentinel));
5701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  j(equal, call_runtime);
5702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  jmp(&start);
5704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
57053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bind(&next);
57063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(rbx, FieldOperand(rcx, HeapObject::kMapOffset));
5708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // For all objects but the receiver, check that the cache is empty.
5710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EnumLength(rdx, rbx);
5711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Cmp(rdx, Smi::FromInt(0));
57123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  j(not_equal, call_runtime);
57133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bind(&start);
57153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Check that there are no elements. Register rcx contains the current JS
5717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // object we've reached through the prototype chain.
5718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Label no_elements;
5719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  cmpp(empty_fixed_array_value,
5720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       FieldOperand(rcx, JSObject::kElementsOffset));
5721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  j(equal, &no_elements);
57223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Second chance, the object may be using the empty slow element dictionary.
5724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LoadRoot(kScratchRegister, Heap::kEmptySlowElementDictionaryRootIndex);
5725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  cmpp(kScratchRegister, FieldOperand(rcx, JSObject::kElementsOffset));
57263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  j(not_equal, call_runtime);
57273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bind(&no_elements);
5729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(rcx, FieldOperand(rbx, Map::kPrototypeOffset));
5730109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  CompareRoot(rcx, Heap::kNullValueRootIndex);
57313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  j(not_equal, &next);
57323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
57333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5734109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
5735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::TestJSArrayForAllocationMemento(
5736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Register receiver_reg,
5737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Register scratch_reg,
5738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Label* no_memento_found) {
57393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Label map_check;
57403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Label top_check;
5741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ExternalReference new_space_allocation_top =
5742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ExternalReference::new_space_allocation_top_address(isolate());
57433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  const int kMementoMapOffset = JSArray::kSize - kHeapObjectTag;
57443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  const int kMementoEndOffset = kMementoMapOffset + AllocationMemento::kSize;
57453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
57463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Bail out if the object is not in new space.
57473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  JumpIfNotInNewSpace(receiver_reg, scratch_reg, no_memento_found);
57483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // If the object is in new space, we need to check whether it is on the same
57493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // page as the current top.
57503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  leap(scratch_reg, Operand(receiver_reg, kMementoEndOffset));
57513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  xorp(scratch_reg, ExternalOperand(new_space_allocation_top));
57523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  testp(scratch_reg, Immediate(~Page::kPageAlignmentMask));
57533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  j(zero, &top_check);
57543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // The object is on a different page than allocation top. Bail out if the
57553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // object sits on the page boundary as no memento can follow and we cannot
57563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // touch the memory following it.
57573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  leap(scratch_reg, Operand(receiver_reg, kMementoEndOffset));
57583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  xorp(scratch_reg, receiver_reg);
57593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  testp(scratch_reg, Immediate(~Page::kPageAlignmentMask));
57603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  j(not_zero, no_memento_found);
57613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Continue with the actual map check.
57623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  jmp(&map_check);
57633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // If top is on the same page as the current object, we need to check whether
57643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // we are below top.
57653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  bind(&top_check);
57663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  leap(scratch_reg, Operand(receiver_reg, kMementoEndOffset));
5767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  cmpp(scratch_reg, ExternalOperand(new_space_allocation_top));
5768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  j(greater, no_memento_found);
57693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Memento map check.
57703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  bind(&map_check);
57713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  CompareRoot(MemOperand(receiver_reg, kMementoMapOffset),
5772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              Heap::kAllocationMementoMapRootIndex);
5773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::JumpIfDictionaryInPrototypeChain(
5777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Register object,
5778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Register scratch0,
5779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Register scratch1,
5780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Label* found) {
5781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(scratch0.is(kScratchRegister) && scratch1.is(kScratchRegister)));
5782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!scratch1.is(scratch0));
5783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Register current = scratch0;
5784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label loop_again, end;
5785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(current, object);
5787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  movp(current, FieldOperand(current, HeapObject::kMapOffset));
5788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  movp(current, FieldOperand(current, Map::kPrototypeOffset));
5789014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CompareRoot(current, Heap::kNullValueRootIndex);
5790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  j(equal, &end);
5791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Loop based on the map going up the prototype chain.
5793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bind(&loop_again);
5794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(current, FieldOperand(current, HeapObject::kMapOffset));
5795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  STATIC_ASSERT(JS_PROXY_TYPE < JS_OBJECT_TYPE);
5796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  STATIC_ASSERT(JS_VALUE_TYPE < JS_OBJECT_TYPE);
5797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CmpInstanceType(current, JS_OBJECT_TYPE);
5798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  j(below, found);
5799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(scratch1, FieldOperand(current, Map::kBitField2Offset));
5800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DecodeField<Map::ElementsKindBits>(scratch1);
5801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  cmpp(scratch1, Immediate(DICTIONARY_ELEMENTS));
5802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  j(equal, found);
5803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movp(current, FieldOperand(current, Map::kPrototypeOffset));
5804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CompareRoot(current, Heap::kNullValueRootIndex);
5805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  j(not_equal, &loop_again);
5806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bind(&end);
5808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid MacroAssembler::TruncatingDiv(Register dividend, int32_t divisor) {
5812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!dividend.is(rax));
5813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!dividend.is(rdx));
5814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  base::MagicNumbersForDivision<uint32_t> mag =
5815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      base::SignedDivisionByConstant(static_cast<uint32_t>(divisor));
5816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movl(rax, Immediate(mag.multiplier));
5817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  imull(dividend);
5818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool neg = (mag.multiplier & (static_cast<uint32_t>(1) << 31)) != 0;
5819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (divisor > 0 && neg) addl(rdx, dividend);
5820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (divisor < 0 && !neg && mag.multiplier > 0) subl(rdx, dividend);
5821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (mag.shift > 0) sarl(rdx, Immediate(mag.shift));
5822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  movl(rax, dividend);
5823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  shrl(rax, Immediate(31));
5824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  addl(rdx, rax);
5825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
58273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
5829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
5830f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
5831f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#endif  // V8_TARGET_ARCH_X64
5832