1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2013 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#include "src/compiler/code-generator.h"
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#include <limits>
8c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
9f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/compilation-info.h"
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/code-generator-impl.h"
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/gap-resolver.h"
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/node-matchers.h"
13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/osr.h"
1462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/heap/heap-inl.h"
15f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/wasm/wasm-module.h"
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/x64/assembler-x64.h"
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/x64/macro-assembler-x64.h"
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace compiler {
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define __ masm()->
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Adds X64 specific methods for decoding operands.
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass X64OperandConverter : public InstructionOperandConverter {
27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  X64OperandConverter(CodeGenerator* gen, Instruction* instr)
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : InstructionOperandConverter(gen, instr) {}
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Immediate InputImmediate(size_t index) {
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return ToImmediate(instr_->InputAt(index));
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Operand InputOperand(size_t index, int extra = 0) {
36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return ToOperand(instr_->InputAt(index), extra);
37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
39958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Operand OutputOperand() { return ToOperand(instr_->Output()); }
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Immediate ToImmediate(InstructionOperand* operand) {
42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Constant constant = ToConstant(operand);
43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (constant.type() == Constant::kFloat64) {
44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK_EQ(0, bit_cast<int64_t>(constant.ToFloat64()));
45014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return Immediate(0);
46014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
4762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (RelocInfo::IsWasmReference(constant.rmode())) {
48bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      return Immediate(constant.ToInt32(), constant.rmode());
49bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return Immediate(constant.ToInt32());
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Operand ToOperand(InstructionOperand* op, int extra = 0) {
54bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    DCHECK(op->IsStackSlot() || op->IsFPStackSlot());
553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return SlotToOperand(AllocatedOperand::cast(op)->index(), extra);
563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Operand SlotToOperand(int slot_index, int extra = 0) {
593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    FrameOffset offset = frame_access_state()->GetFrameOffset(slot_index);
60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return Operand(offset.from_stack_pointer() ? rsp : rbp,
61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                   offset.offset() + extra);
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static size_t NextOffset(size_t* offset) {
65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    size_t i = *offset;
66958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    (*offset)++;
67958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return i;
68958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
69958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
70958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static ScaleFactor ScaleFor(AddressingMode one, AddressingMode mode) {
71958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    STATIC_ASSERT(0 == static_cast<int>(times_1));
72958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    STATIC_ASSERT(1 == static_cast<int>(times_2));
73958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    STATIC_ASSERT(2 == static_cast<int>(times_4));
74958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    STATIC_ASSERT(3 == static_cast<int>(times_8));
75958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    int scale = static_cast<int>(mode - one);
76958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(scale >= 0 && scale < 4);
77958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return static_cast<ScaleFactor>(scale);
78958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
79958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Operand MemoryOperand(size_t* offset) {
81958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    AddressingMode mode = AddressingModeField::decode(instr_->opcode());
82958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    switch (mode) {
83958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case kMode_MR: {
84958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        Register base = InputRegister(NextOffset(offset));
85958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        int32_t disp = 0;
86958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        return Operand(base, disp);
87958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
88958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case kMode_MRI: {
89958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        Register base = InputRegister(NextOffset(offset));
90958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        int32_t disp = InputInt32(NextOffset(offset));
91958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        return Operand(base, disp);
92958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
93958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case kMode_MR1:
94958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case kMode_MR2:
95958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case kMode_MR4:
96958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case kMode_MR8: {
97958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        Register base = InputRegister(NextOffset(offset));
98958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        Register index = InputRegister(NextOffset(offset));
99958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        ScaleFactor scale = ScaleFor(kMode_MR1, mode);
100958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        int32_t disp = 0;
101958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        return Operand(base, index, scale, disp);
102958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
103958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case kMode_MR1I:
104958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case kMode_MR2I:
105958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case kMode_MR4I:
106958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case kMode_MR8I: {
107958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        Register base = InputRegister(NextOffset(offset));
108958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        Register index = InputRegister(NextOffset(offset));
109958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        ScaleFactor scale = ScaleFor(kMode_MR1I, mode);
110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        int32_t disp = InputInt32(NextOffset(offset));
111958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        return Operand(base, index, scale, disp);
112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case kMode_M1: {
114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        Register base = InputRegister(NextOffset(offset));
115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        int32_t disp = 0;
116958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        return Operand(base, disp);
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
118958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case kMode_M2:
119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        UNREACHABLE();  // Should use kModeMR with more compact encoding instead
120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        return Operand(no_reg, 0);
121958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case kMode_M4:
122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case kMode_M8: {
123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        Register index = InputRegister(NextOffset(offset));
124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        ScaleFactor scale = ScaleFor(kMode_M1, mode);
125958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        int32_t disp = 0;
126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        return Operand(index, scale, disp);
127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case kMode_M1I:
129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case kMode_M2I:
130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case kMode_M4I:
131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case kMode_M8I: {
132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        Register index = InputRegister(NextOffset(offset));
133958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        ScaleFactor scale = ScaleFor(kMode_M1I, mode);
134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        int32_t disp = InputInt32(NextOffset(offset));
135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        return Operand(index, scale, disp);
136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
137f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      case kMode_Root: {
138f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        Register base = kRootRegister;
139f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        int32_t disp = InputInt32(NextOffset(offset));
140f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        return Operand(base, disp);
141f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case kMode_None:
143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        UNREACHABLE();
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return Operand(no_reg, 0);
145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    UNREACHABLE();
147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return Operand(no_reg, 0);
148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Operand MemoryOperand(size_t first_input = 0) {
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return MemoryOperand(&first_input);
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
156958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace {
157958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool HasImmediateInput(Instruction* instr, size_t index) {
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return instr->InputAt(index)->IsImmediate();
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass OutOfLineLoadZero final : public OutOfLineCode {
164958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public:
165958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  OutOfLineLoadZero(CodeGenerator* gen, Register result)
166958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      : OutOfLineCode(gen), result_(result) {}
167958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Generate() final { __ xorl(result_, result_); }
169958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
170958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private:
171958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Register const result_;
172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier};
173958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
174f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass OutOfLineLoadFloat32NaN final : public OutOfLineCode {
175958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public:
176f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  OutOfLineLoadFloat32NaN(CodeGenerator* gen, XMMRegister result)
177958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      : OutOfLineCode(gen), result_(result) {}
178958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
179f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void Generate() final {
180f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    __ Xorps(result_, result_);
181f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    __ Divss(result_, result_);
182f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
183958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private:
185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  XMMRegister const result_;
186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier};
187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
188f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass OutOfLineLoadFloat64NaN final : public OutOfLineCode {
189f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public:
190f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  OutOfLineLoadFloat64NaN(CodeGenerator* gen, XMMRegister result)
191f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : OutOfLineCode(gen), result_(result) {}
192f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
193f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void Generate() final {
194f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    __ Xorpd(result_, result_);
195f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    __ Divsd(result_, result_);
196f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
197f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
198f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
199f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  XMMRegister const result_;
200f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
201958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass OutOfLineTruncateDoubleToI final : public OutOfLineCode {
203958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public:
204958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  OutOfLineTruncateDoubleToI(CodeGenerator* gen, Register result,
205f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                             XMMRegister input,
206f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                             UnwindingInfoWriter* unwinding_info_writer)
207f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : OutOfLineCode(gen),
208f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        result_(result),
209f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        input_(input),
210f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        unwinding_info_writer_(unwinding_info_writer) {}
211958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Generate() final {
213958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ subp(rsp, Immediate(kDoubleSize));
214f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    unwinding_info_writer_->MaybeIncreaseBaseOffsetAt(__ pc_offset(),
215f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                                      kDoubleSize);
216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ Movsd(MemOperand(rsp, 0), input_);
217958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ SlowTruncateToI(result_, rsp, 0);
218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ addp(rsp, Immediate(kDoubleSize));
219f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    unwinding_info_writer_->MaybeIncreaseBaseOffsetAt(__ pc_offset(),
220f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                                      -kDoubleSize);
221958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
222958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
223958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private:
224958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Register const result_;
225958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  XMMRegister const input_;
226f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  UnwindingInfoWriter* const unwinding_info_writer_;
227958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier};
228958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass OutOfLineRecordWrite final : public OutOfLineCode {
231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  OutOfLineRecordWrite(CodeGenerator* gen, Register object, Operand operand,
233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       Register value, Register scratch0, Register scratch1,
234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       RecordWriteMode mode)
235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : OutOfLineCode(gen),
236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        object_(object),
237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        operand_(operand),
238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        value_(value),
239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        scratch0_(scratch0),
240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        scratch1_(scratch1),
241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        mode_(mode) {}
242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Generate() final {
244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (mode_ > RecordWriteMode::kValueIsPointer) {
245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ JumpIfSmi(value_, exit());
246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
247109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    __ CheckPageFlag(value_, scratch0_,
248109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                     MemoryChunk::kPointersToHereAreInterestingMask, zero,
249109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                     exit());
250109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    RememberedSetAction const remembered_set_action =
251109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        mode_ > RecordWriteMode::kValueIsMap ? EMIT_REMEMBERED_SET
252109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                             : OMIT_REMEMBERED_SET;
253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SaveFPRegsMode const save_fp_mode =
254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs;
255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    RecordWriteStub stub(isolate(), object_, scratch0_, scratch1_,
256109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                         remembered_set_action, save_fp_mode);
257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ leap(scratch1_, operand_);
258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ CallStub(&stub);
259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Register const object_;
263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Operand const operand_;
264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Register const value_;
265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Register const scratch0_;
266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Register const scratch1_;
267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RecordWriteMode const mode_;
268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
270f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochclass WasmOutOfLineTrap final : public OutOfLineCode {
271f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch public:
27262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  WasmOutOfLineTrap(CodeGenerator* gen, int pc, bool frame_elided,
27362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                    int32_t position, Instruction* instr)
274f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : OutOfLineCode(gen),
27562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        gen_(gen),
276f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        pc_(pc),
277f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        frame_elided_(frame_elided),
27862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        position_(position),
27962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        instr_(instr) {}
280f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
28162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // TODO(eholk): Refactor this method to take the code generator as a
28262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // parameter.
283f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void Generate() final {
28462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    __ RecordProtectedInstructionLanding(pc_);
285f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
286f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (frame_elided_) {
28762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      __ EnterFrame(StackFrame::WASM_COMPILED);
288f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
289f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
290f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    wasm::TrapReason trap_id = wasm::kTrapMemOutOfBounds;
291f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    int trap_reason = wasm::WasmOpcodes::TrapReasonToMessageId(trap_id);
292f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    __ Push(Smi::FromInt(trap_reason));
293f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    __ Push(Smi::FromInt(position_));
29462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    __ Move(rsi, gen_->isolate()->native_context());
295f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    __ CallRuntime(Runtime::kThrowWasmError);
29662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
29762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (instr_->reference_map() != nullptr) {
29862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      gen_->RecordSafepoint(instr_->reference_map(), Safepoint::kSimple, 0,
29962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                            Safepoint::kNoLazyDeopt);
30062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
301f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
302f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
303f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch private:
30462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  CodeGenerator* gen_;
30562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  int pc_;
306f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool frame_elided_;
307f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int32_t position_;
30862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Instruction* instr_;
309f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch};
310f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
31162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid EmitOOLTrapIfNeeded(Zone* zone, CodeGenerator* codegen,
31262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                         InstructionCode opcode, size_t input_count,
31362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                         X64OperandConverter& i, int pc, Instruction* instr) {
31462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  const X64MemoryProtection protection =
31562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      static_cast<X64MemoryProtection>(MiscField::decode(opcode));
31662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (protection == X64MemoryProtection::kProtected) {
31762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    const bool frame_elided = !codegen->frame_access_state()->has_frame();
31862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    const int32_t position = i.InputInt32(input_count - 1);
31962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    new (zone) WasmOutOfLineTrap(codegen, pc, frame_elided, position, instr);
32062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
32162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
322958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}  // namespace
323958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
324958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
325958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define ASSEMBLE_UNOP(asm_instr)         \
326958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  do {                                   \
327958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (instr->Output()->IsRegister()) { \
328958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ asm_instr(i.OutputRegister());  \
329958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {                             \
330958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ asm_instr(i.OutputOperand());   \
331958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }                                    \
332958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } while (0)
333958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
334958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
335958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define ASSEMBLE_BINOP(asm_instr)                              \
336958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  do {                                                         \
337958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (HasImmediateInput(instr, 1)) {                         \
338958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (instr->InputAt(0)->IsRegister()) {                   \
339958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ asm_instr(i.InputRegister(0), i.InputImmediate(1)); \
340958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      } else {                                                 \
341958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ asm_instr(i.InputOperand(0), i.InputImmediate(1));  \
342958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }                                                        \
343958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {                                                   \
344958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (instr->InputAt(1)->IsRegister()) {                   \
345958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ asm_instr(i.InputRegister(0), i.InputRegister(1));  \
346958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      } else {                                                 \
347958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ asm_instr(i.InputRegister(0), i.InputOperand(1));   \
348958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }                                                        \
349958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }                                                          \
350958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } while (0)
351958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
352109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#define ASSEMBLE_COMPARE(asm_instr)                                   \
353109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  do {                                                                \
354109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (AddressingModeField::decode(instr->opcode()) != kMode_None) { \
355109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      size_t index = 0;                                               \
356109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      Operand left = i.MemoryOperand(&index);                         \
357109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (HasImmediateInput(instr, index)) {                          \
358109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        __ asm_instr(left, i.InputImmediate(index));                  \
359109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      } else {                                                        \
360109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        __ asm_instr(left, i.InputRegister(index));                   \
361109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }                                                               \
362109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    } else {                                                          \
363109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (HasImmediateInput(instr, 1)) {                              \
364109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        if (instr->InputAt(0)->IsRegister()) {                        \
365109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          __ asm_instr(i.InputRegister(0), i.InputImmediate(1));      \
366109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        } else {                                                      \
367109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          __ asm_instr(i.InputOperand(0), i.InputImmediate(1));       \
368109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        }                                                             \
369109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      } else {                                                        \
370109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        if (instr->InputAt(1)->IsRegister()) {                        \
371109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          __ asm_instr(i.InputRegister(0), i.InputRegister(1));       \
372109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        } else {                                                      \
373109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          __ asm_instr(i.InputRegister(0), i.InputOperand(1));        \
374109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        }                                                             \
375109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }                                                               \
376109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }                                                                 \
377109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  } while (0)
378958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
379958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define ASSEMBLE_MULT(asm_instr)                              \
380958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  do {                                                        \
381958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (HasImmediateInput(instr, 1)) {                        \
382958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (instr->InputAt(0)->IsRegister()) {                  \
383958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ asm_instr(i.OutputRegister(), i.InputRegister(0),  \
384958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                     i.InputImmediate(1));                    \
385958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      } else {                                                \
386958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ asm_instr(i.OutputRegister(), i.InputOperand(0),   \
387958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                     i.InputImmediate(1));                    \
388958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }                                                       \
389958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {                                                  \
390958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (instr->InputAt(1)->IsRegister()) {                  \
391958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ asm_instr(i.OutputRegister(), i.InputRegister(1)); \
392958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      } else {                                                \
393958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ asm_instr(i.OutputRegister(), i.InputOperand(1));  \
394958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }                                                       \
395958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }                                                         \
396958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } while (0)
397958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
398958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
399958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define ASSEMBLE_SHIFT(asm_instr, width)                                   \
400958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  do {                                                                     \
401958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (HasImmediateInput(instr, 1)) {                                     \
402958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (instr->Output()->IsRegister()) {                                 \
403958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ asm_instr(i.OutputRegister(), Immediate(i.InputInt##width(1))); \
404958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      } else {                                                             \
405958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ asm_instr(i.OutputOperand(), Immediate(i.InputInt##width(1)));  \
406958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }                                                                    \
407958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {                                                               \
408958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (instr->Output()->IsRegister()) {                                 \
409958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ asm_instr##_cl(i.OutputRegister());                             \
410958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      } else {                                                             \
411958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ asm_instr##_cl(i.OutputOperand());                              \
412958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }                                                                    \
413958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }                                                                      \
414958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } while (0)
415958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
416958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_MOVX(asm_instr)                            \
418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  do {                                                      \
419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (instr->addressing_mode() != kMode_None) {           \
420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ asm_instr(i.OutputRegister(), i.MemoryOperand());  \
421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (instr->InputAt(0)->IsRegister()) {           \
422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ asm_instr(i.OutputRegister(), i.InputRegister(0)); \
423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {                                                \
424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ asm_instr(i.OutputRegister(), i.InputOperand(0));  \
425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }                                                       \
426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } while (0)
427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_SSE_BINOP(asm_instr)                                   \
429958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  do {                                                                  \
430bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (instr->InputAt(1)->IsFPRegister()) {                            \
431958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ asm_instr(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); \
432958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {                                                            \
433958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ asm_instr(i.InputDoubleRegister(0), i.InputOperand(1));        \
434958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }                                                                   \
435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } while (0)
436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_SSE_UNOP(asm_instr)                                    \
438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  do {                                                                  \
439bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (instr->InputAt(0)->IsFPRegister()) {                            \
440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); \
441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {                                                            \
442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ asm_instr(i.OutputDoubleRegister(), i.InputOperand(0));        \
443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }                                                                   \
444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } while (0)
445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define ASSEMBLE_AVX_BINOP(asm_instr)                                  \
447958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  do {                                                                 \
448958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    CpuFeatureScope avx_scope(masm(), AVX);                            \
449bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (instr->InputAt(1)->IsFPRegister()) {                           \
450958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0), \
451958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                   i.InputDoubleRegister(1));                          \
452958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {                                                           \
453958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0), \
454958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                   i.InputOperand(1));                                 \
455958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }                                                                  \
456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } while (0)
457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
458f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#define ASSEMBLE_CHECKED_LOAD_FLOAT(asm_instr, OutOfLineLoadNaN)             \
459958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  do {                                                                       \
460958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto result = i.OutputDoubleRegister();                                  \
461958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto buffer = i.InputRegister(0);                                        \
462958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto index1 = i.InputRegister(1);                                        \
463bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    auto index2 = i.InputUint32(2);                                          \
464958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    OutOfLineCode* ool;                                                      \
465958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (instr->InputAt(3)->IsRegister()) {                                   \
466958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto length = i.InputRegister(3);                                      \
467c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      DCHECK_EQ(0u, index2);                                                 \
468958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ cmpl(index1, length);                                               \
469958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ool = new (zone()) OutOfLineLoadNaN(this, result);                     \
470958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {                                                                 \
471bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      auto length = i.InputUint32(3);                                        \
47213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      RelocInfo::Mode rmode = i.ToConstant(instr->InputAt(3)).rmode();       \
473958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      DCHECK_LE(index2, length);                                             \
47413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ cmpl(index1, Immediate(length - index2, rmode));                    \
475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      class OutOfLineLoadFloat final : public OutOfLineCode {                \
476958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier       public:                                                               \
477958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        OutOfLineLoadFloat(CodeGenerator* gen, XMMRegister result,           \
478958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                           Register buffer, Register index1, int32_t index2, \
47913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                           int32_t length, RelocInfo::Mode rmode)            \
480958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            : OutOfLineCode(gen),                                            \
481958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier              result_(result),                                               \
482958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier              buffer_(buffer),                                               \
483958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier              index1_(index1),                                               \
484958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier              index2_(index2),                                               \
48513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch              length_(length),                                               \
48613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch              rmode_(rmode) {}                                               \
487958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                                             \
488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        void Generate() final {                                              \
489958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          __ leal(kScratchRegister, Operand(index1_, index2_));              \
490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ Pcmpeqd(result_, result_);                                      \
49113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          __ cmpl(kScratchRegister, Immediate(length_, rmode_));             \
492958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          __ j(above_equal, exit());                                         \
493958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          __ asm_instr(result_,                                              \
494958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                       Operand(buffer_, kScratchRegister, times_1, 0));      \
495958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        }                                                                    \
496958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                                             \
497958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier       private:                                                              \
498958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        XMMRegister const result_;                                           \
499958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        Register const buffer_;                                              \
500958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        Register const index1_;                                              \
501958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        int32_t const index2_;                                               \
502958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        int32_t const length_;                                               \
50313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        RelocInfo::Mode rmode_;                                              \
504958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      };                                                                     \
50513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ool = new (zone()) OutOfLineLoadFloat(this, result, buffer, index1,    \
50613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                            index2, length, rmode);          \
507958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }                                                                        \
508958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ j(above_equal, ool->entry());                                         \
509958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ asm_instr(result, Operand(buffer, index1, times_1, index2));          \
510958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ bind(ool->exit());                                                    \
511958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } while (false)
512958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
513958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr)                               \
514958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  do {                                                                         \
515958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto result = i.OutputRegister();                                          \
516958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto buffer = i.InputRegister(0);                                          \
517958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto index1 = i.InputRegister(1);                                          \
518bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    auto index2 = i.InputUint32(2);                                            \
519958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    OutOfLineCode* ool;                                                        \
520958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (instr->InputAt(3)->IsRegister()) {                                     \
521958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto length = i.InputRegister(3);                                        \
522c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      DCHECK_EQ(0u, index2);                                                   \
523958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ cmpl(index1, length);                                                 \
524958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ool = new (zone()) OutOfLineLoadZero(this, result);                      \
525958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {                                                                   \
526bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      auto length = i.InputUint32(3);                                          \
52713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      RelocInfo::Mode rmode = i.ToConstant(instr->InputAt(3)).rmode();         \
528958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      DCHECK_LE(index2, length);                                               \
52913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ cmpl(index1, Immediate(length - index2, rmode));                      \
530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      class OutOfLineLoadInteger final : public OutOfLineCode {                \
531958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier       public:                                                                 \
532958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        OutOfLineLoadInteger(CodeGenerator* gen, Register result,              \
533958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                             Register buffer, Register index1, int32_t index2, \
53413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                             int32_t length, RelocInfo::Mode rmode)            \
535958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            : OutOfLineCode(gen),                                              \
536958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier              result_(result),                                                 \
537958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier              buffer_(buffer),                                                 \
538958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier              index1_(index1),                                                 \
539958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier              index2_(index2),                                                 \
54013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch              length_(length),                                                 \
54113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch              rmode_(rmode) {}                                                 \
542958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                                               \
543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        void Generate() final {                                                \
544958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          Label oob;                                                           \
545958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          __ leal(kScratchRegister, Operand(index1_, index2_));                \
54613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          __ cmpl(kScratchRegister, Immediate(length_, rmode_));               \
547958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          __ j(above_equal, &oob, Label::kNear);                               \
548958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          __ asm_instr(result_,                                                \
549958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                       Operand(buffer_, kScratchRegister, times_1, 0));        \
550958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          __ jmp(exit());                                                      \
551958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          __ bind(&oob);                                                       \
552958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          __ xorl(result_, result_);                                           \
553958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        }                                                                      \
554958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                                               \
555958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier       private:                                                                \
556958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        Register const result_;                                                \
557958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        Register const buffer_;                                                \
558958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        Register const index1_;                                                \
559958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        int32_t const index2_;                                                 \
560958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        int32_t const length_;                                                 \
56113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        RelocInfo::Mode const rmode_;                                          \
562958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      };                                                                       \
56313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ool = new (zone()) OutOfLineLoadInteger(this, result, buffer, index1,    \
56413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                              index2, length, rmode);          \
565958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }                                                                          \
566958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ j(above_equal, ool->entry());                                           \
567958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ asm_instr(result, Operand(buffer, index1, times_1, index2));            \
568958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    __ bind(ool->exit());                                                      \
569958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } while (false)
570958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
571958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define ASSEMBLE_CHECKED_STORE_FLOAT(asm_instr)                              \
572958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  do {                                                                       \
573958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto buffer = i.InputRegister(0);                                        \
574958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto index1 = i.InputRegister(1);                                        \
575bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    auto index2 = i.InputUint32(2);                                          \
576958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto value = i.InputDoubleRegister(4);                                   \
577958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (instr->InputAt(3)->IsRegister()) {                                   \
578958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto length = i.InputRegister(3);                                      \
579c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      DCHECK_EQ(0u, index2);                                                 \
580958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      Label done;                                                            \
581958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ cmpl(index1, length);                                               \
582958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ j(above_equal, &done, Label::kNear);                                \
583958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ asm_instr(Operand(buffer, index1, times_1, index2), value);         \
584958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ bind(&done);                                                        \
585958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {                                                                 \
586bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      auto length = i.InputUint32(3);                                        \
58713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      RelocInfo::Mode rmode = i.ToConstant(instr->InputAt(3)).rmode();       \
588958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      DCHECK_LE(index2, length);                                             \
58913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ cmpl(index1, Immediate(length - index2, rmode));                    \
590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      class OutOfLineStoreFloat final : public OutOfLineCode {               \
591958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier       public:                                                               \
592958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        OutOfLineStoreFloat(CodeGenerator* gen, Register buffer,             \
593958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                            Register index1, int32_t index2, int32_t length, \
59413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                            XMMRegister value, RelocInfo::Mode rmode)        \
595958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            : OutOfLineCode(gen),                                            \
596958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier              buffer_(buffer),                                               \
597958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier              index1_(index1),                                               \
598958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier              index2_(index2),                                               \
599958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier              length_(length),                                               \
60013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch              value_(value),                                                 \
60113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch              rmode_(rmode) {}                                               \
602958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                                             \
603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        void Generate() final {                                              \
604958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          __ leal(kScratchRegister, Operand(index1_, index2_));              \
60513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          __ cmpl(kScratchRegister, Immediate(length_, rmode_));             \
606958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          __ j(above_equal, exit());                                         \
607958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          __ asm_instr(Operand(buffer_, kScratchRegister, times_1, 0),       \
608958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                       value_);                                              \
609958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        }                                                                    \
610958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                                             \
611958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier       private:                                                              \
612958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        Register const buffer_;                                              \
613958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        Register const index1_;                                              \
614958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        int32_t const index2_;                                               \
615958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        int32_t const length_;                                               \
616958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        XMMRegister const value_;                                            \
61713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        RelocInfo::Mode rmode_;                                              \
618958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      };                                                                     \
61913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      auto ool = new (zone()) OutOfLineStoreFloat(                           \
62013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          this, buffer, index1, index2, length, value, rmode);               \
621958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ j(above_equal, ool->entry());                                       \
622958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ asm_instr(Operand(buffer, index1, times_1, index2), value);         \
623958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ bind(ool->exit());                                                  \
624958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }                                                                        \
625958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } while (false)
626958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
627958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Value)                  \
628958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  do {                                                                         \
629958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto buffer = i.InputRegister(0);                                          \
630958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto index1 = i.InputRegister(1);                                          \
631bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    auto index2 = i.InputUint32(2);                                            \
632958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (instr->InputAt(3)->IsRegister()) {                                     \
633958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto length = i.InputRegister(3);                                        \
634c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      DCHECK_EQ(0u, index2);                                                   \
635958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      Label done;                                                              \
636958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ cmpl(index1, length);                                                 \
637958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ j(above_equal, &done, Label::kNear);                                  \
638958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ asm_instr(Operand(buffer, index1, times_1, index2), value);           \
639958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ bind(&done);                                                          \
640958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {                                                                   \
641bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      auto length = i.InputUint32(3);                                          \
64213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      RelocInfo::Mode rmode = i.ToConstant(instr->InputAt(3)).rmode();         \
643958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      DCHECK_LE(index2, length);                                               \
64413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ cmpl(index1, Immediate(length - index2, rmode));                      \
645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      class OutOfLineStoreInteger final : public OutOfLineCode {               \
646958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier       public:                                                                 \
647958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        OutOfLineStoreInteger(CodeGenerator* gen, Register buffer,             \
648958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                              Register index1, int32_t index2, int32_t length, \
64913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                              Value value, RelocInfo::Mode rmode)              \
650958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            : OutOfLineCode(gen),                                              \
651958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier              buffer_(buffer),                                                 \
652958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier              index1_(index1),                                                 \
653958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier              index2_(index2),                                                 \
654958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier              length_(length),                                                 \
65513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch              value_(value),                                                   \
65613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch              rmode_(rmode) {}                                                 \
657958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                                               \
658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        void Generate() final {                                                \
659958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          __ leal(kScratchRegister, Operand(index1_, index2_));                \
66013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          __ cmpl(kScratchRegister, Immediate(length_, rmode_));               \
661958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          __ j(above_equal, exit());                                           \
662958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          __ asm_instr(Operand(buffer_, kScratchRegister, times_1, 0),         \
663958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                       value_);                                                \
664958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        }                                                                      \
665958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                                               \
666958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier       private:                                                                \
667958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        Register const buffer_;                                                \
668958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        Register const index1_;                                                \
669958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        int32_t const index2_;                                                 \
670958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        int32_t const length_;                                                 \
671958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        Value const value_;                                                    \
67213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        RelocInfo::Mode rmode_;                                                \
673958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      };                                                                       \
67413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      auto ool = new (zone()) OutOfLineStoreInteger(                           \
67513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch          this, buffer, index1, index2, length, value, rmode);                 \
676958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ j(above_equal, ool->entry());                                         \
677958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ asm_instr(Operand(buffer, index1, times_1, index2), value);           \
678958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ bind(ool->exit());                                                    \
679958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }                                                                          \
680958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } while (false)
681958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
682958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr)                \
683958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  do {                                                           \
684958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (instr->InputAt(4)->IsRegister()) {                       \
685958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      Register value = i.InputRegister(4);                       \
686958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Register);  \
687958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {                                                     \
688958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      Immediate value = i.InputImmediate(4);                     \
689958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Immediate); \
690958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }                                                            \
691958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } while (false)
692958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
69313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#define ASSEMBLE_IEEE754_BINOP(name)                                          \
69413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  do {                                                                        \
69513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    __ PrepareCallCFunction(2);                                               \
69613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    __ CallCFunction(ExternalReference::ieee754_##name##_function(isolate()), \
69713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                     2);                                                      \
69813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  } while (false)
69913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
70013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch#define ASSEMBLE_IEEE754_UNOP(name)                                           \
70113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  do {                                                                        \
70213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    __ PrepareCallCFunction(1);                                               \
70313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    __ CallCFunction(ExternalReference::ieee754_##name##_function(isolate()), \
70413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                     1);                                                      \
70513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  } while (false)
70613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
7073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid CodeGenerator::AssembleDeconstructFrame() {
708f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  unwinding_info_writer_.MarkFrameDeconstructed(__ pc_offset());
7093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ movq(rsp, rbp);
7103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ popq(rbp);
7113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
7123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
713f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid CodeGenerator::AssemblePrepareTailCall() {
7143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (frame_access_state()->has_frame()) {
715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ movq(rbp, MemOperand(rbp, 0));
716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  frame_access_state()->SetFrameAccessToSP();
718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
7203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid CodeGenerator::AssemblePopArgumentsAdaptorFrame(Register args_reg,
7213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                                     Register scratch1,
7223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                                     Register scratch2,
7233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                                     Register scratch3) {
7243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3));
7253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Label done;
7263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
7273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Check if current frame is an arguments adaptor frame.
72862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  __ cmpp(Operand(rbp, CommonFrameConstants::kContextOrFrameTypeOffset),
72962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          Immediate(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
7303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ j(not_equal, &done, Label::kNear);
7313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
7323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Load arguments count from current arguments adaptor frame (note, it
7333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // does not include receiver).
7343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Register caller_args_count_reg = scratch1;
7353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ SmiToInteger32(
7363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      caller_args_count_reg,
7373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      Operand(rbp, ArgumentsAdaptorFrameConstants::kLengthOffset));
7383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
7393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  ParameterCount callee_args_count(args_reg);
7403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2,
7413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                        scratch3, ReturnAddressState::kOnStack);
7423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  __ bind(&done);
7433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
745f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochnamespace {
746f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
747f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid AdjustStackPointerForTailCall(MacroAssembler* masm,
748f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                   FrameAccessState* state,
749f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                   int new_slot_above_sp,
750f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                   bool allow_shrinkage = true) {
751f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int current_sp_offset = state->GetSPToFPSlotCount() +
752f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                          StandardFrameConstants::kFixedSlotCountAboveFp;
753f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int stack_slot_delta = new_slot_above_sp - current_sp_offset;
754f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (stack_slot_delta > 0) {
755f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    masm->subq(rsp, Immediate(stack_slot_delta * kPointerSize));
756f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    state->IncreaseSPDelta(stack_slot_delta);
757f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else if (allow_shrinkage && stack_slot_delta < 0) {
758f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    masm->addq(rsp, Immediate(-stack_slot_delta * kPointerSize));
759f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    state->IncreaseSPDelta(stack_slot_delta);
760f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
761f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
762f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
763f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}  // namespace
764f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
765f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid CodeGenerator::AssembleTailCallBeforeGap(Instruction* instr,
766f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                              int first_unused_stack_slot) {
767f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CodeGenerator::PushTypeFlags flags(kImmediatePush | kScalarPush);
768f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ZoneVector<MoveOperands*> pushes(zone());
769f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  GetPushCompatibleMoves(instr, flags, &pushes);
770f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
771f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (!pushes.empty() &&
772f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      (LocationOperand::cast(pushes.back()->destination()).index() + 1 ==
773f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch       first_unused_stack_slot)) {
774f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    X64OperandConverter g(this, instr);
775f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    for (auto move : pushes) {
776f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      LocationOperand destination_location(
777f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          LocationOperand::cast(move->destination()));
778f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      InstructionOperand source(move->source());
779f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      AdjustStackPointerForTailCall(masm(), frame_access_state(),
780f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                    destination_location.index());
781f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (source.IsStackSlot()) {
782f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        LocationOperand source_location(LocationOperand::cast(source));
783f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Push(g.SlotToOperand(source_location.index()));
784f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      } else if (source.IsRegister()) {
785f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        LocationOperand source_location(LocationOperand::cast(source));
786f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Push(source_location.GetRegister());
787f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      } else if (source.IsImmediate()) {
788f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Push(Immediate(ImmediateOperand::cast(source).inline_value()));
789f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      } else {
790f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        // Pushes of non-scalar data types is not supported.
791f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        UNIMPLEMENTED();
792f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
793f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      frame_access_state()->IncreaseSPDelta(1);
794f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      move->Eliminate();
795f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
796f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
797f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  AdjustStackPointerForTailCall(masm(), frame_access_state(),
798f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                first_unused_stack_slot, false);
799f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
800f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
801f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid CodeGenerator::AssembleTailCallAfterGap(Instruction* instr,
802f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                             int first_unused_stack_slot) {
803f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  AdjustStackPointerForTailCall(masm(), frame_access_state(),
804f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                first_unused_stack_slot);
805f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
806f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Assembles an instruction after register allocation, producing machine code.
808bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochCodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
809bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    Instruction* instr) {
810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  X64OperandConverter i(this, instr);
8113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  InstructionCode opcode = instr->opcode();
8123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  ArchOpcode arch_opcode = ArchOpcodeField::decode(opcode);
8133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  switch (arch_opcode) {
814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kArchCallCodeObject: {
815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      EnsureSpaceForLazyDeopt();
816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (HasImmediateInput(instr, 0)) {
817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0));
818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ Call(code, RelocInfo::CODE_TARGET);
819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Register reg = i.InputRegister(0);
821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ addp(reg, Immediate(Code::kHeaderSize - kHeapObjectTag));
822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ call(reg);
823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      RecordCallPosition(instr);
825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      frame_access_state()->ClearSPDelta();
826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
8283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case kArchTailCallCodeObjectFromJSFunction:
829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchTailCallCodeObject: {
8303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (arch_opcode == kArchTailCallCodeObjectFromJSFunction) {
8313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister,
8323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                         i.TempRegister(0), i.TempRegister(1),
8333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                         i.TempRegister(2));
8343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (HasImmediateInput(instr, 0)) {
836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0));
837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ jmp(code, RelocInfo::CODE_TARGET);
838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Register reg = i.InputRegister(0);
840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ addp(reg, Immediate(Code::kHeaderSize - kHeapObjectTag));
841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ jmp(reg);
842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
843f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      unwinding_info_writer_.MarkBlockWillExit();
844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      frame_access_state()->ClearSPDelta();
845f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      frame_access_state()->SetFrameAccessToDefault();
846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
848bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case kArchTailCallAddress: {
849bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      CHECK(!HasImmediateInput(instr, 0));
850bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      Register reg = i.InputRegister(0);
851bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      __ jmp(reg);
852f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      unwinding_info_writer_.MarkBlockWillExit();
853bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      frame_access_state()->ClearSPDelta();
854f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      frame_access_state()->SetFrameAccessToDefault();
855bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      break;
856bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kArchCallJSFunction: {
858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      EnsureSpaceForLazyDeopt();
859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Register func = i.InputRegister(0);
860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (FLAG_debug_code) {
861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Check the function's context matches the context argument.
862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ cmpp(rsi, FieldOperand(func, JSFunction::kContextOffset));
863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ Assert(equal, kWrongFunctionContext);
864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ Call(FieldOperand(func, JSFunction::kCodeEntryOffset));
866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      frame_access_state()->ClearSPDelta();
867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      RecordCallPosition(instr);
868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
870c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case kArchTailCallJSFunctionFromJSFunction: {
871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Register func = i.InputRegister(0);
872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (FLAG_debug_code) {
873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Check the function's context matches the context argument.
874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ cmpp(rsi, FieldOperand(func, JSFunction::kContextOffset));
875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Assert(equal, kWrongFunctionContext);
876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
877c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      AssemblePopArgumentsAdaptorFrame(kJavaScriptCallArgCountRegister,
878c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                       i.TempRegister(0), i.TempRegister(1),
879c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                       i.TempRegister(2));
880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ jmp(FieldOperand(func, JSFunction::kCodeEntryOffset));
881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      frame_access_state()->ClearSPDelta();
882f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      frame_access_state()->SetFrameAccessToDefault();
883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchPrepareCallCFunction: {
886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Frame alignment requires using FP-relative frame addressing.
887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      frame_access_state()->SetFrameAccessToFP();
888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int const num_parameters = MiscField::decode(instr->opcode());
889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ PrepareCallCFunction(num_parameters);
890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchPrepareTailCall:
893f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      AssemblePrepareTailCall();
894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchCallCFunction: {
896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int const num_parameters = MiscField::decode(instr->opcode());
897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (HasImmediateInput(instr, 0)) {
898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        ExternalReference ref = i.InputExternalReference(0);
899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ CallCFunction(ref, num_parameters);
900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Register func = i.InputRegister(0);
902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ CallCFunction(func, num_parameters);
903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      frame_access_state()->SetFrameAccessToDefault();
905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      frame_access_state()->ClearSPDelta();
906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kArchJmp:
909958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      AssembleArchJump(i.InputRpo(0));
910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchLookupSwitch:
912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      AssembleArchLookupSwitch(instr);
913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchTableSwitch:
915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      AssembleArchTableSwitch(instr);
916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
91713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kArchComment: {
91813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      Address comment_string = i.InputExternalReference(0).address();
91913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ RecordComment(reinterpret_cast<const char*>(comment_string));
92013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
92113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
92213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kArchDebugBreak:
92313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ int3();
92413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kArchNop:
926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchThrowTerminator:
927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // don't emit code for nops.
928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchDeoptimize: {
930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int deopt_state_id =
931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          BuildTranslation(instr, -1, 0, OutputFrameStateCombine::Ignore());
93262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      CodeGenResult result =
93362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          AssembleDeoptimizerCall(deopt_state_id, current_source_position_);
934bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (result != kSuccess) return result;
935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kArchRet:
938c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      AssembleReturn(instr->InputAt(0));
939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
940958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kArchStackPointer:
941958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ movq(i.OutputRegister(), rsp);
942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchFramePointer:
944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ movq(i.OutputRegister(), rbp);
945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
946109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case kArchParentFramePointer:
9473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (frame_access_state()->has_frame()) {
948109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        __ movq(i.OutputRegister(), Operand(rbp, 0));
949109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      } else {
950109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        __ movq(i.OutputRegister(), rbp);
951109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
952109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      break;
953958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kArchTruncateDoubleToI: {
954958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto result = i.OutputRegister();
955958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto input = i.InputDoubleRegister(0);
956f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      auto ool = new (zone()) OutOfLineTruncateDoubleToI(
957f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          this, result, input, &unwinding_info_writer_);
958bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      // We use Cvttsd2siq instead of Cvttsd2si due to performance reasons. The
959bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      // use of Cvttsd2siq requires the movl below to avoid sign extension.
960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Cvttsd2siq(result, input);
961958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ cmpq(result, Immediate(1));
962958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ j(overflow, ool->entry());
963958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ bind(ool->exit());
964bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      __ movl(result, result);
965958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
966958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kArchStoreWithWriteBarrier: {
968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      RecordWriteMode mode =
969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          static_cast<RecordWriteMode>(MiscField::decode(instr->opcode()));
970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Register object = i.InputRegister(0);
971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      size_t index = 0;
972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Operand operand = i.MemoryOperand(&index);
973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Register value = i.InputRegister(index);
974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Register scratch0 = i.TempRegister(0);
975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Register scratch1 = i.TempRegister(1);
976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      auto ool = new (zone()) OutOfLineRecordWrite(this, object, operand, value,
977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                   scratch0, scratch1, mode);
978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ movp(operand, value);
979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ CheckPageFlag(object, scratch0,
980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       MemoryChunk::kPointersFromHereAreInterestingMask,
981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       not_zero, ool->entry());
982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ bind(ool->exit());
983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
985109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case kArchStackSlot: {
986109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      FrameOffset offset =
987109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          frame_access_state()->GetFrameOffset(i.InputInt32(0));
988109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      Register base;
989109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (offset.from_stack_pointer()) {
990109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        base = rsp;
991109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      } else {
992109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        base = rbp;
993109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
994109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ leaq(i.OutputRegister(), Operand(base, offset.offset()));
995109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      break;
996109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
997f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kIeee754Float64Acos:
998f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSEMBLE_IEEE754_UNOP(acos);
999f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1000f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kIeee754Float64Acosh:
1001f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSEMBLE_IEEE754_UNOP(acosh);
1002f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1003f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kIeee754Float64Asin:
1004f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSEMBLE_IEEE754_UNOP(asin);
1005f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1006f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kIeee754Float64Asinh:
1007f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSEMBLE_IEEE754_UNOP(asinh);
1008f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
100913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kIeee754Float64Atan:
101013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSEMBLE_IEEE754_UNOP(atan);
101113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
101213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kIeee754Float64Atanh:
101313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSEMBLE_IEEE754_UNOP(atanh);
101413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
1015f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kIeee754Float64Atan2:
1016f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSEMBLE_IEEE754_BINOP(atan2);
1017f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
101813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kIeee754Float64Cbrt:
101913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSEMBLE_IEEE754_UNOP(cbrt);
102013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
102113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kIeee754Float64Cos:
102213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSEMBLE_IEEE754_UNOP(cos);
102313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
1024f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kIeee754Float64Cosh:
1025f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSEMBLE_IEEE754_UNOP(cosh);
1026f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
102713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kIeee754Float64Exp:
102813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSEMBLE_IEEE754_UNOP(exp);
102913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
103013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kIeee754Float64Expm1:
103113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSEMBLE_IEEE754_UNOP(expm1);
103213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
103313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kIeee754Float64Log:
103413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSEMBLE_IEEE754_UNOP(log);
103513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
103613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kIeee754Float64Log1p:
103713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSEMBLE_IEEE754_UNOP(log1p);
103813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
103913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kIeee754Float64Log2:
104013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSEMBLE_IEEE754_UNOP(log2);
104113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
104213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kIeee754Float64Log10:
104313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSEMBLE_IEEE754_UNOP(log10);
104413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
1045f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kIeee754Float64Pow: {
1046f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // TODO(bmeurer): Improve integration of the stub.
1047f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ Movsd(xmm2, xmm0);
1048f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      MathPowStub stub(isolate(), MathPowStub::DOUBLE);
1049f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ CallStub(&stub);
1050f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ Movsd(xmm0, xmm3);
1051f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1052f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
105313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kIeee754Float64Sin:
105413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSEMBLE_IEEE754_UNOP(sin);
105513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
1056f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kIeee754Float64Sinh:
1057f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSEMBLE_IEEE754_UNOP(sinh);
1058f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
105913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kIeee754Float64Tan:
106013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ASSEMBLE_IEEE754_UNOP(tan);
106113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
1062f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kIeee754Float64Tanh:
1063f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSEMBLE_IEEE754_UNOP(tanh);
1064f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64Add32:
1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ASSEMBLE_BINOP(addl);
1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64Add:
1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ASSEMBLE_BINOP(addq);
1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64Sub32:
1072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ASSEMBLE_BINOP(subl);
1073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64Sub:
1075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ASSEMBLE_BINOP(subq);
1076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64And32:
1078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ASSEMBLE_BINOP(andl);
1079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64And:
1081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ASSEMBLE_BINOP(andq);
1082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
10833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case kX64Cmp8:
10843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      ASSEMBLE_COMPARE(cmpb);
10853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
10863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case kX64Cmp16:
10873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      ASSEMBLE_COMPARE(cmpw);
10883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
1089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64Cmp32:
1090109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      ASSEMBLE_COMPARE(cmpl);
1091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64Cmp:
1093109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      ASSEMBLE_COMPARE(cmpq);
1094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
10953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case kX64Test8:
10963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      ASSEMBLE_COMPARE(testb);
10973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
10983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    case kX64Test16:
10993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      ASSEMBLE_COMPARE(testw);
11003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      break;
1101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64Test32:
1102109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      ASSEMBLE_COMPARE(testl);
1103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64Test:
1105109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      ASSEMBLE_COMPARE(testq);
1106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64Imul32:
1108958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ASSEMBLE_MULT(imull);
1109958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kX64Imul:
1111958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ASSEMBLE_MULT(imulq);
1112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kX64ImulHigh32:
1114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (instr->InputAt(1)->IsRegister()) {
1115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ imull(i.InputRegister(1));
1116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
1117958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ imull(i.InputOperand(1));
1118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kX64UmulHigh32:
1121958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (instr->InputAt(1)->IsRegister()) {
1122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ mull(i.InputRegister(1));
1123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
1124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ mull(i.InputOperand(1));
1125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64Idiv32:
1128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ cdq();
1129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ idivl(i.InputRegister(1));
1130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64Idiv:
1132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ cqo();
1133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ idivq(i.InputRegister(1));
1134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64Udiv32:
1136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ xorl(rdx, rdx);
1137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ divl(i.InputRegister(1));
1138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64Udiv:
1140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ xorq(rdx, rdx);
1141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ divq(i.InputRegister(1));
1142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kX64Not:
1144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ASSEMBLE_UNOP(notq);
1145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kX64Not32:
1147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ASSEMBLE_UNOP(notl);
1148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kX64Neg:
1150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ASSEMBLE_UNOP(negq);
1151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kX64Neg32:
1153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ASSEMBLE_UNOP(negl);
1154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64Or32:
1156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ASSEMBLE_BINOP(orl);
1157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64Or:
1159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ASSEMBLE_BINOP(orq);
1160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64Xor32:
1162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ASSEMBLE_BINOP(xorl);
1163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64Xor:
1165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ASSEMBLE_BINOP(xorq);
1166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64Shl32:
1168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ASSEMBLE_SHIFT(shll, 5);
1169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64Shl:
1171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ASSEMBLE_SHIFT(shlq, 6);
1172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64Shr32:
1174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ASSEMBLE_SHIFT(shrl, 5);
1175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64Shr:
1177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ASSEMBLE_SHIFT(shrq, 6);
1178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64Sar32:
1180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ASSEMBLE_SHIFT(sarl, 5);
1181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64Sar:
1183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ASSEMBLE_SHIFT(sarq, 6);
1184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64Ror32:
1186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ASSEMBLE_SHIFT(rorl, 5);
1187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64Ror:
1189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ASSEMBLE_SHIFT(rorq, 6);
1190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX64Lzcnt:
1192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->InputAt(0)->IsRegister()) {
1193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Lzcntq(i.OutputRegister(), i.InputRegister(0));
1194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Lzcntq(i.OutputRegister(), i.InputOperand(0));
1196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX64Lzcnt32:
1199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->InputAt(0)->IsRegister()) {
1200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Lzcntl(i.OutputRegister(), i.InputRegister(0));
1201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Lzcntl(i.OutputRegister(), i.InputOperand(0));
1203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX64Tzcnt:
1206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->InputAt(0)->IsRegister()) {
1207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Tzcntq(i.OutputRegister(), i.InputRegister(0));
1208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Tzcntq(i.OutputRegister(), i.InputOperand(0));
1210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX64Tzcnt32:
1213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->InputAt(0)->IsRegister()) {
1214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Tzcntl(i.OutputRegister(), i.InputRegister(0));
1215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Tzcntl(i.OutputRegister(), i.InputOperand(0));
1217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX64Popcnt:
1220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->InputAt(0)->IsRegister()) {
1221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Popcntq(i.OutputRegister(), i.InputRegister(0));
1222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Popcntq(i.OutputRegister(), i.InputOperand(0));
1224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX64Popcnt32:
1227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->InputAt(0)->IsRegister()) {
1228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Popcntl(i.OutputRegister(), i.InputRegister(0));
1229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Popcntl(i.OutputRegister(), i.InputOperand(0));
1231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSSEFloat32Cmp:
1234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_SSE_BINOP(Ucomiss);
1235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSSEFloat32Add:
1237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_SSE_BINOP(addss);
1238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSSEFloat32Sub:
1240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_SSE_BINOP(subss);
1241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSSEFloat32Mul:
1243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_SSE_BINOP(mulss);
1244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSSEFloat32Div:
1246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_SSE_BINOP(divss);
1247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Don't delete this mov. It may improve performance on some CPUs,
1248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // when there is a (v)mulss depending on the result.
1249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ movaps(i.OutputDoubleRegister(), i.OutputDoubleRegister());
1250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSSEFloat32Abs: {
1252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // TODO(bmeurer): Use RIP relative 128-bit constants.
1253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
1254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ psrlq(kScratchDoubleReg, 33);
1255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ andps(i.OutputDoubleRegister(), kScratchDoubleReg);
1256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSSEFloat32Neg: {
1259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // TODO(bmeurer): Use RIP relative 128-bit constants.
1260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
1261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ psllq(kScratchDoubleReg, 31);
1262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ xorps(i.OutputDoubleRegister(), kScratchDoubleReg);
1263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSSEFloat32Sqrt:
1266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_SSE_UNOP(sqrtss);
1267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSSEFloat32ToFloat64:
1269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_SSE_UNOP(Cvtss2sd);
1270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSSEFloat32Round: {
1272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      CpuFeatureScope sse_scope(masm(), SSE4_1);
1273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      RoundingMode const mode =
1274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          static_cast<RoundingMode>(MiscField::decode(instr->opcode()));
1275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Roundss(i.OutputDoubleRegister(), i.InputDoubleRegister(0), mode);
1276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1278109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case kSSEFloat32ToInt32:
1279bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (instr->InputAt(0)->IsFPRegister()) {
1280109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        __ Cvttss2si(i.OutputRegister(), i.InputDoubleRegister(0));
1281109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      } else {
1282109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        __ Cvttss2si(i.OutputRegister(), i.InputOperand(0));
1283109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
1284109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      break;
1285109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case kSSEFloat32ToUint32: {
1286bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (instr->InputAt(0)->IsFPRegister()) {
1287109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        __ Cvttss2siq(i.OutputRegister(), i.InputDoubleRegister(0));
1288109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      } else {
1289109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        __ Cvttss2siq(i.OutputRegister(), i.InputOperand(0));
1290109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
1291109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      break;
1292109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
1293958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kSSEFloat64Cmp:
1294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_SSE_BINOP(Ucomisd);
1295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kSSEFloat64Add:
1297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_SSE_BINOP(addsd);
1298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kSSEFloat64Sub:
1300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_SSE_BINOP(subsd);
1301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kSSEFloat64Mul:
1303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_SSE_BINOP(mulsd);
1304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kSSEFloat64Div:
1306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_SSE_BINOP(divsd);
1307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Don't delete this mov. It may improve performance on some CPUs,
1308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // when there is a (v)mulsd depending on the result.
1309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Movapd(i.OutputDoubleRegister(), i.OutputDoubleRegister());
1310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kSSEFloat64Mod: {
1312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ subq(rsp, Immediate(kDoubleSize));
1313f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(),
1314f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                                       kDoubleSize);
1315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Move values to st(0) and st(1).
1316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Movsd(Operand(rsp, 0), i.InputDoubleRegister(1));
1317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ fld_d(Operand(rsp, 0));
1318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Movsd(Operand(rsp, 0), i.InputDoubleRegister(0));
1319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ fld_d(Operand(rsp, 0));
1320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Loop while fprem isn't done.
1321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Label mod_loop;
1322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ bind(&mod_loop);
1323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // This instructions traps on all kinds inputs, but we are assuming the
1324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // floating point control word is set to ignore them all.
1325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ fprem();
1326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // The following 2 instruction implicitly use rax.
1327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ fnstsw_ax();
1328958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (CpuFeatures::IsSupported(SAHF)) {
1329958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        CpuFeatureScope sahf_scope(masm(), SAHF);
1330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ sahf();
1331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
1332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ shrl(rax, Immediate(8));
1333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ andl(rax, Immediate(0xFF));
1334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ pushq(rax);
1335f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(),
1336f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                                         kPointerSize);
1337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ popfq();
1338f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(),
1339f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                                         -kPointerSize);
1340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ j(parity_even, &mod_loop);
1342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Move output to stack and clean up.
1343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ fstp(1);
1344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ fstp_d(Operand(rsp, 0));
1345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Movsd(i.OutputDoubleRegister(), Operand(rsp, 0));
1346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ addq(rsp, Immediate(kDoubleSize));
1347f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(),
1348f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                                       -kDoubleSize);
1349f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1350f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
1351f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kSSEFloat32Max: {
1352f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Label compare_nan, compare_swap, done_compare;
1353f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (instr->InputAt(1)->IsFPRegister()) {
1354f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Ucomiss(i.InputDoubleRegister(0), i.InputDoubleRegister(1));
1355f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      } else {
1356f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Ucomiss(i.InputDoubleRegister(0), i.InputOperand(1));
1357f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
1358f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      auto ool =
1359f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          new (zone()) OutOfLineLoadFloat32NaN(this, i.OutputDoubleRegister());
1360f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ j(parity_even, ool->entry());
1361f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ j(above, &done_compare, Label::kNear);
1362f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ j(below, &compare_swap, Label::kNear);
1363f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ Movmskps(kScratchRegister, i.InputDoubleRegister(0));
1364f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ testl(kScratchRegister, Immediate(1));
1365f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ j(zero, &done_compare, Label::kNear);
1366f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ bind(&compare_swap);
1367f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (instr->InputAt(1)->IsFPRegister()) {
1368f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Movss(i.InputDoubleRegister(0), i.InputDoubleRegister(1));
1369f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      } else {
1370f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Movss(i.InputDoubleRegister(0), i.InputOperand(1));
1371f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
1372f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ bind(&done_compare);
1373f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ bind(ool->exit());
1374f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1375f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
1376f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kSSEFloat32Min: {
1377f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Label compare_swap, done_compare;
1378f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (instr->InputAt(1)->IsFPRegister()) {
1379f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Ucomiss(i.InputDoubleRegister(0), i.InputDoubleRegister(1));
1380f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      } else {
1381f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Ucomiss(i.InputDoubleRegister(0), i.InputOperand(1));
1382f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
1383f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      auto ool =
1384f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          new (zone()) OutOfLineLoadFloat32NaN(this, i.OutputDoubleRegister());
1385f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ j(parity_even, ool->entry());
1386f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ j(below, &done_compare, Label::kNear);
1387f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ j(above, &compare_swap, Label::kNear);
1388f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (instr->InputAt(1)->IsFPRegister()) {
1389f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Movmskps(kScratchRegister, i.InputDoubleRegister(1));
1390f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      } else {
1391f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Movss(kScratchDoubleReg, i.InputOperand(1));
1392f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Movmskps(kScratchRegister, kScratchDoubleReg);
1393f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
1394f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ testl(kScratchRegister, Immediate(1));
1395f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ j(zero, &done_compare, Label::kNear);
1396f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ bind(&compare_swap);
1397f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (instr->InputAt(1)->IsFPRegister()) {
1398f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Movss(i.InputDoubleRegister(0), i.InputDoubleRegister(1));
1399f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      } else {
1400f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Movss(i.InputDoubleRegister(0), i.InputOperand(1));
1401f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
1402f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ bind(&done_compare);
1403f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ bind(ool->exit());
1404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1406f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kSSEFloat64Max: {
1407f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Label compare_nan, compare_swap, done_compare;
1408f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (instr->InputAt(1)->IsFPRegister()) {
1409f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Ucomisd(i.InputDoubleRegister(0), i.InputDoubleRegister(1));
1410f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      } else {
1411f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Ucomisd(i.InputDoubleRegister(0), i.InputOperand(1));
1412f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
1413f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      auto ool =
1414f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          new (zone()) OutOfLineLoadFloat64NaN(this, i.OutputDoubleRegister());
1415f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ j(parity_even, ool->entry());
1416f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ j(above, &done_compare, Label::kNear);
1417f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ j(below, &compare_swap, Label::kNear);
1418f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ Movmskpd(kScratchRegister, i.InputDoubleRegister(0));
1419f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ testl(kScratchRegister, Immediate(1));
1420f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ j(zero, &done_compare, Label::kNear);
1421f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ bind(&compare_swap);
1422f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (instr->InputAt(1)->IsFPRegister()) {
1423f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Movsd(i.InputDoubleRegister(0), i.InputDoubleRegister(1));
1424f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      } else {
1425f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Movsd(i.InputDoubleRegister(0), i.InputOperand(1));
1426f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
1427f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ bind(&done_compare);
1428f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ bind(ool->exit());
1429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1430f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
1431f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kSSEFloat64Min: {
1432f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Label compare_swap, done_compare;
1433f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (instr->InputAt(1)->IsFPRegister()) {
1434f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Ucomisd(i.InputDoubleRegister(0), i.InputDoubleRegister(1));
1435f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      } else {
1436f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Ucomisd(i.InputDoubleRegister(0), i.InputOperand(1));
1437f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
1438f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      auto ool =
1439f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          new (zone()) OutOfLineLoadFloat64NaN(this, i.OutputDoubleRegister());
1440f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ j(parity_even, ool->entry());
1441f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ j(below, &done_compare, Label::kNear);
1442f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ j(above, &compare_swap, Label::kNear);
1443f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (instr->InputAt(1)->IsFPRegister()) {
1444f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Movmskpd(kScratchRegister, i.InputDoubleRegister(1));
1445f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      } else {
1446f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Movsd(kScratchDoubleReg, i.InputOperand(1));
1447f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Movmskpd(kScratchRegister, kScratchDoubleReg);
1448f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
1449f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ testl(kScratchRegister, Immediate(1));
1450f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ j(zero, &done_compare, Label::kNear);
1451f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ bind(&compare_swap);
1452f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (instr->InputAt(1)->IsFPRegister()) {
1453f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Movsd(i.InputDoubleRegister(0), i.InputDoubleRegister(1));
1454f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      } else {
1455f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Movsd(i.InputDoubleRegister(0), i.InputOperand(1));
1456f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
1457f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ bind(&done_compare);
1458f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ bind(ool->exit());
1459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1460f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
1461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSSEFloat64Abs: {
1462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // TODO(bmeurer): Use RIP relative 128-bit constants.
1463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
1464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ psrlq(kScratchDoubleReg, 1);
1465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ andpd(i.OutputDoubleRegister(), kScratchDoubleReg);
1466958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSSEFloat64Neg: {
1469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // TODO(bmeurer): Use RIP relative 128-bit constants.
1470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
1471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ psllq(kScratchDoubleReg, 63);
1472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ xorpd(i.OutputDoubleRegister(), kScratchDoubleReg);
1473958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1474958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSSEFloat64Sqrt:
1476f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      ASSEMBLE_SSE_UNOP(Sqrtsd);
1477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSSEFloat64Round: {
1479958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      CpuFeatureScope sse_scope(masm(), SSE4_1);
1480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      RoundingMode const mode =
1481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          static_cast<RoundingMode>(MiscField::decode(instr->opcode()));
1482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Roundsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0), mode);
1483958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1484958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSSEFloat64ToFloat32:
1486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_SSE_UNOP(Cvtsd2ss);
1487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSSEFloat64ToInt32:
1489bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (instr->InputAt(0)->IsFPRegister()) {
1490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Cvttsd2si(i.OutputRegister(), i.InputDoubleRegister(0));
1491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
1492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Cvttsd2si(i.OutputRegister(), i.InputOperand(0));
1493958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
1494958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSSEFloat64ToUint32: {
1496bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (instr->InputAt(0)->IsFPRegister()) {
1497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Cvttsd2siq(i.OutputRegister(), i.InputDoubleRegister(0));
1498958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      } else {
1499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Cvttsd2siq(i.OutputRegister(), i.InputOperand(0));
1500958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
15013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (MiscField::decode(instr->opcode())) {
15023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        __ AssertZeroExtended(i.OutputRegister());
15033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
1504958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSSEFloat32ToInt64:
1507bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (instr->InputAt(0)->IsFPRegister()) {
1508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Cvttss2siq(i.OutputRegister(), i.InputDoubleRegister(0));
1509958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      } else {
1510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Cvttss2siq(i.OutputRegister(), i.InputOperand(0));
1511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->OutputCount() > 1) {
1513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Set(i.OutputRegister(1), 1);
1514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Label done;
1515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Label fail;
1516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Move(kScratchDoubleReg, static_cast<float>(INT64_MIN));
1517bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        if (instr->InputAt(0)->IsFPRegister()) {
1518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ Ucomiss(kScratchDoubleReg, i.InputDoubleRegister(0));
1519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else {
1520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ Ucomiss(kScratchDoubleReg, i.InputOperand(0));
1521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
1522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // If the input is NaN, then the conversion fails.
1523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ j(parity_even, &fail);
1524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // If the input is INT64_MIN, then the conversion succeeds.
1525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ j(equal, &done);
1526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ cmpq(i.OutputRegister(0), Immediate(1));
1527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // If the conversion results in INT64_MIN, but the input was not
1528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // INT64_MIN, then the conversion fails.
1529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ j(no_overflow, &done);
1530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ bind(&fail);
1531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Set(i.OutputRegister(1), 0);
1532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ bind(&done);
1533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSSEFloat64ToInt64:
1536bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (instr->InputAt(0)->IsFPRegister()) {
1537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Cvttsd2siq(i.OutputRegister(0), i.InputDoubleRegister(0));
1538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
1539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Cvttsd2siq(i.OutputRegister(0), i.InputOperand(0));
1540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->OutputCount() > 1) {
1542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Set(i.OutputRegister(1), 1);
1543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Label done;
1544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Label fail;
1545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Move(kScratchDoubleReg, static_cast<double>(INT64_MIN));
1546bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        if (instr->InputAt(0)->IsFPRegister()) {
1547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ Ucomisd(kScratchDoubleReg, i.InputDoubleRegister(0));
1548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else {
1549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          __ Ucomisd(kScratchDoubleReg, i.InputOperand(0));
1550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
1551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // If the input is NaN, then the conversion fails.
1552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ j(parity_even, &fail);
1553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // If the input is INT64_MIN, then the conversion succeeds.
1554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ j(equal, &done);
1555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ cmpq(i.OutputRegister(0), Immediate(1));
1556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // If the conversion results in INT64_MIN, but the input was not
1557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // INT64_MIN, then the conversion fails.
1558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ j(no_overflow, &done);
1559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ bind(&fail);
1560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Set(i.OutputRegister(1), 0);
1561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ bind(&done);
1562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSSEFloat32ToUint64: {
1565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Label done;
1566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Label success;
1567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->OutputCount() > 1) {
1568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Set(i.OutputRegister(1), 0);
1569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // There does not exist a Float32ToUint64 instruction, so we have to use
1571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // the Float32ToInt64 instruction.
1572bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (instr->InputAt(0)->IsFPRegister()) {
1573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Cvttss2siq(i.OutputRegister(), i.InputDoubleRegister(0));
1574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Cvttss2siq(i.OutputRegister(), i.InputOperand(0));
1576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Check if the result of the Float32ToInt64 conversion is positive, we
1578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // are already done.
1579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ testq(i.OutputRegister(), i.OutputRegister());
1580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ j(positive, &success);
1581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // The result of the first conversion was negative, which means that the
1582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // input value was not within the positive int64 range. We subtract 2^64
1583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // and convert it again to see if it is within the uint64 range.
1584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Move(kScratchDoubleReg, -9223372036854775808.0f);
1585bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (instr->InputAt(0)->IsFPRegister()) {
1586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ addss(kScratchDoubleReg, i.InputDoubleRegister(0));
1587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ addss(kScratchDoubleReg, i.InputOperand(0));
1589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Cvttss2siq(i.OutputRegister(), kScratchDoubleReg);
1591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ testq(i.OutputRegister(), i.OutputRegister());
1592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // The only possible negative value here is 0x80000000000000000, which is
1593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // used on x64 to indicate an integer overflow.
1594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ j(negative, &done);
1595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // The input value is within uint64 range and the second conversion worked
1596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // successfully, but we still have to undo the subtraction we did
1597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // earlier.
1598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Set(kScratchRegister, 0x8000000000000000);
1599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ orq(i.OutputRegister(), kScratchRegister);
1600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ bind(&success);
1601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->OutputCount() > 1) {
1602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Set(i.OutputRegister(1), 1);
1603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ bind(&done);
1605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSSEFloat64ToUint64: {
1608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Label done;
1609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Label success;
1610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->OutputCount() > 1) {
1611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Set(i.OutputRegister(1), 0);
1612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // There does not exist a Float64ToUint64 instruction, so we have to use
1614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // the Float64ToInt64 instruction.
1615bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (instr->InputAt(0)->IsFPRegister()) {
1616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Cvttsd2siq(i.OutputRegister(), i.InputDoubleRegister(0));
1617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Cvttsd2siq(i.OutputRegister(), i.InputOperand(0));
1619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Check if the result of the Float64ToInt64 conversion is positive, we
1621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // are already done.
1622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ testq(i.OutputRegister(), i.OutputRegister());
1623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ j(positive, &success);
1624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // The result of the first conversion was negative, which means that the
1625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // input value was not within the positive int64 range. We subtract 2^64
1626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // and convert it again to see if it is within the uint64 range.
1627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Move(kScratchDoubleReg, -9223372036854775808.0);
1628bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (instr->InputAt(0)->IsFPRegister()) {
1629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ addsd(kScratchDoubleReg, i.InputDoubleRegister(0));
1630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ addsd(kScratchDoubleReg, i.InputOperand(0));
1632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Cvttsd2siq(i.OutputRegister(), kScratchDoubleReg);
1634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ testq(i.OutputRegister(), i.OutputRegister());
1635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // The only possible negative value here is 0x80000000000000000, which is
1636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // used on x64 to indicate an integer overflow.
1637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ j(negative, &done);
1638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // The input value is within uint64 range and the second conversion worked
1639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // successfully, but we still have to undo the subtraction we did
1640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // earlier.
1641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Set(kScratchRegister, 0x8000000000000000);
1642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ orq(i.OutputRegister(), kScratchRegister);
1643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ bind(&success);
1644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->OutputCount() > 1) {
1645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Set(i.OutputRegister(1), 1);
1646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ bind(&done);
1648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1650958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kSSEInt32ToFloat64:
1651958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (instr->InputAt(0)->IsRegister()) {
1652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Cvtlsi2sd(i.OutputDoubleRegister(), i.InputRegister(0));
1653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Cvtlsi2sd(i.OutputDoubleRegister(), i.InputOperand(0));
1655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1657109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case kSSEInt32ToFloat32:
1658109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (instr->InputAt(0)->IsRegister()) {
1659109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        __ Cvtlsi2ss(i.OutputDoubleRegister(), i.InputRegister(0));
1660109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      } else {
1661109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        __ Cvtlsi2ss(i.OutputDoubleRegister(), i.InputOperand(0));
1662109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
1663109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      break;
1664014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSSEInt64ToFloat32:
1665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->InputAt(0)->IsRegister()) {
1666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Cvtqsi2ss(i.OutputDoubleRegister(), i.InputRegister(0));
1667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
1668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Cvtqsi2ss(i.OutputDoubleRegister(), i.InputOperand(0));
1669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSSEInt64ToFloat64:
1672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->InputAt(0)->IsRegister()) {
1673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Cvtqsi2sd(i.OutputDoubleRegister(), i.InputRegister(0));
1674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Cvtqsi2sd(i.OutputDoubleRegister(), i.InputOperand(0));
1676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSSEUint64ToFloat32:
1679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->InputAt(0)->IsRegister()) {
1680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ movq(kScratchRegister, i.InputRegister(0));
1681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ movq(kScratchRegister, i.InputOperand(0));
1683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Cvtqui2ss(i.OutputDoubleRegister(), kScratchRegister,
1685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                   i.TempRegister(0));
1686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSSEUint64ToFloat64:
1688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->InputAt(0)->IsRegister()) {
1689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ movq(kScratchRegister, i.InputRegister(0));
1690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ movq(kScratchRegister, i.InputOperand(0));
1692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Cvtqui2sd(i.OutputDoubleRegister(), kScratchRegister,
1694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                   i.TempRegister(0));
1695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1696958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kSSEUint32ToFloat64:
1697958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (instr->InputAt(0)->IsRegister()) {
1698958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ movl(kScratchRegister, i.InputRegister(0));
1699958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      } else {
1700958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ movl(kScratchRegister, i.InputOperand(0));
1701958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
1702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Cvtqsi2sd(i.OutputDoubleRegister(), kScratchRegister);
1703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1704109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case kSSEUint32ToFloat32:
1705109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (instr->InputAt(0)->IsRegister()) {
1706109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        __ movl(kScratchRegister, i.InputRegister(0));
1707109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      } else {
1708109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        __ movl(kScratchRegister, i.InputOperand(0));
1709109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
1710109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      __ Cvtqsi2ss(i.OutputDoubleRegister(), kScratchRegister);
1711109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      break;
1712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSSEFloat64ExtractLowWord32:
1713bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (instr->InputAt(0)->IsFPStackSlot()) {
1714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ movl(i.OutputRegister(), i.InputOperand(0));
1715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Movd(i.OutputRegister(), i.InputDoubleRegister(0));
1717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1718958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSSEFloat64ExtractHighWord32:
1720bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (instr->InputAt(0)->IsFPStackSlot()) {
1721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ movl(i.OutputRegister(), i.InputOperand(0, kDoubleSize / 2));
1722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Pextrd(i.OutputRegister(), i.InputDoubleRegister(0), 1);
1724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSSEFloat64InsertLowWord32:
1727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->InputAt(1)->IsRegister()) {
1728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Pinsrd(i.OutputDoubleRegister(), i.InputRegister(1), 0);
1729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Pinsrd(i.OutputDoubleRegister(), i.InputOperand(1), 0);
1731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSSEFloat64InsertHighWord32:
1734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->InputAt(1)->IsRegister()) {
1735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Pinsrd(i.OutputDoubleRegister(), i.InputRegister(1), 1);
1736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Pinsrd(i.OutputDoubleRegister(), i.InputOperand(1), 1);
1738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1740014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kSSEFloat64LoadLowWord32:
1741014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->InputAt(0)->IsRegister()) {
1742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Movd(i.OutputDoubleRegister(), i.InputRegister(0));
1743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Movd(i.OutputDoubleRegister(), i.InputOperand(0));
1745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kAVXFloat32Cmp: {
1748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      CpuFeatureScope avx_scope(masm(), AVX);
1749bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (instr->InputAt(1)->IsFPRegister()) {
1750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ vucomiss(i.InputDoubleRegister(0), i.InputDoubleRegister(1));
1751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ vucomiss(i.InputDoubleRegister(0), i.InputOperand(1));
1753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kAVXFloat32Add:
1757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_AVX_BINOP(vaddss);
1758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kAVXFloat32Sub:
1760014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_AVX_BINOP(vsubss);
1761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kAVXFloat32Mul:
1763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_AVX_BINOP(vmulss);
1764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kAVXFloat32Div:
1766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_AVX_BINOP(vdivss);
1767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Don't delete this mov. It may improve performance on some CPUs,
1768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // when there is a (v)mulss depending on the result.
1769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Movaps(i.OutputDoubleRegister(), i.OutputDoubleRegister());
1770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kAVXFloat64Cmp: {
1772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      CpuFeatureScope avx_scope(masm(), AVX);
1773bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (instr->InputAt(1)->IsFPRegister()) {
1774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ vucomisd(i.InputDoubleRegister(0), i.InputDoubleRegister(1));
1775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ vucomisd(i.InputDoubleRegister(0), i.InputOperand(1));
1777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1780958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kAVXFloat64Add:
1781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_AVX_BINOP(vaddsd);
1782958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1783958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kAVXFloat64Sub:
1784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_AVX_BINOP(vsubsd);
1785958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1786958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kAVXFloat64Mul:
1787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_AVX_BINOP(vmulsd);
1788958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
1789958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kAVXFloat64Div:
1790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_AVX_BINOP(vdivsd);
1791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Don't delete this mov. It may improve performance on some CPUs,
1792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // when there is a (v)mulsd depending on the result.
1793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Movapd(i.OutputDoubleRegister(), i.OutputDoubleRegister());
1794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kAVXFloat32Abs: {
1796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // TODO(bmeurer): Use RIP relative 128-bit constants.
1797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      CpuFeatureScope avx_scope(masm(), AVX);
1798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ vpcmpeqd(kScratchDoubleReg, kScratchDoubleReg, kScratchDoubleReg);
1799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ vpsrlq(kScratchDoubleReg, kScratchDoubleReg, 33);
1800bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (instr->InputAt(0)->IsFPRegister()) {
1801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ vandps(i.OutputDoubleRegister(), kScratchDoubleReg,
1802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  i.InputDoubleRegister(0));
1803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ vandps(i.OutputDoubleRegister(), kScratchDoubleReg,
1805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  i.InputOperand(0));
1806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kAVXFloat32Neg: {
1810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // TODO(bmeurer): Use RIP relative 128-bit constants.
1811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      CpuFeatureScope avx_scope(masm(), AVX);
1812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ vpcmpeqd(kScratchDoubleReg, kScratchDoubleReg, kScratchDoubleReg);
1813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ vpsllq(kScratchDoubleReg, kScratchDoubleReg, 31);
1814bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (instr->InputAt(0)->IsFPRegister()) {
1815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ vxorps(i.OutputDoubleRegister(), kScratchDoubleReg,
1816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  i.InputDoubleRegister(0));
1817958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      } else {
1818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ vxorps(i.OutputDoubleRegister(), kScratchDoubleReg,
1819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  i.InputOperand(0));
1820958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
1821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kAVXFloat64Abs: {
1824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // TODO(bmeurer): Use RIP relative 128-bit constants.
1825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      CpuFeatureScope avx_scope(masm(), AVX);
1826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ vpcmpeqd(kScratchDoubleReg, kScratchDoubleReg, kScratchDoubleReg);
1827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ vpsrlq(kScratchDoubleReg, kScratchDoubleReg, 1);
1828bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (instr->InputAt(0)->IsFPRegister()) {
1829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ vandpd(i.OutputDoubleRegister(), kScratchDoubleReg,
1830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  i.InputDoubleRegister(0));
1831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ vandpd(i.OutputDoubleRegister(), kScratchDoubleReg,
1833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  i.InputOperand(0));
1834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kAVXFloat64Neg: {
1838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // TODO(bmeurer): Use RIP relative 128-bit constants.
1839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      CpuFeatureScope avx_scope(masm(), AVX);
1840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ vpcmpeqd(kScratchDoubleReg, kScratchDoubleReg, kScratchDoubleReg);
1841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ vpsllq(kScratchDoubleReg, kScratchDoubleReg, 63);
1842bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (instr->InputAt(0)->IsFPRegister()) {
1843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ vxorpd(i.OutputDoubleRegister(), kScratchDoubleReg,
1844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  i.InputDoubleRegister(0));
1845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ vxorpd(i.OutputDoubleRegister(), kScratchDoubleReg,
1847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  i.InputOperand(0));
1848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
185113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case kSSEFloat64SilenceNaN:
185213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ Xorpd(kScratchDoubleReg, kScratchDoubleReg);
185313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      __ Subsd(i.InputDoubleRegister(0), kScratchDoubleReg);
185413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
1855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX64Movsxbl:
185662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i,
185762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                          __ pc_offset(), instr);
1858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_MOVX(movsxbl);
1859958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ AssertZeroExtended(i.OutputRegister());
1860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64Movzxbl:
186262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i,
186362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                          __ pc_offset(), instr);
1864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_MOVX(movzxbl);
1865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ AssertZeroExtended(i.OutputRegister());
1866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1867f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kX64Movsxbq:
186862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i,
186962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                          __ pc_offset(), instr);
1870f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSEMBLE_MOVX(movsxbq);
1871f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1872f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kX64Movzxbq:
187362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i,
187462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                          __ pc_offset(), instr);
1875f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSEMBLE_MOVX(movzxbq);
1876f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ AssertZeroExtended(i.OutputRegister());
1877f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64Movb: {
187962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i,
188062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                          __ pc_offset(), instr);
1881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      size_t index = 0;
1882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Operand operand = i.MemoryOperand(&index);
1883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (HasImmediateInput(instr, index)) {
1884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ movb(operand, Immediate(i.InputInt8(index)));
1885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
1886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ movb(operand, i.InputRegister(index));
1887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64Movsxwl:
189162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i,
189262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                          __ pc_offset(), instr);
1893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_MOVX(movsxwl);
1894958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ AssertZeroExtended(i.OutputRegister());
1895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64Movzxwl:
189762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i,
189862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                          __ pc_offset(), instr);
1899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_MOVX(movzxwl);
1900958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ AssertZeroExtended(i.OutputRegister());
1901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1902f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kX64Movsxwq:
190362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i,
190462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                          __ pc_offset(), instr);
1905f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSEMBLE_MOVX(movsxwq);
1906f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1907f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case kX64Movzxwq:
190862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i,
190962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                          __ pc_offset(), instr);
1910f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSEMBLE_MOVX(movzxwq);
1911f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ AssertZeroExtended(i.OutputRegister());
1912f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
1913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64Movw: {
191462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i,
191562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                          __ pc_offset(), instr);
1916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      size_t index = 0;
1917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Operand operand = i.MemoryOperand(&index);
1918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (HasImmediateInput(instr, index)) {
1919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ movw(operand, Immediate(i.InputInt16(index)));
1920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
1921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ movw(operand, i.InputRegister(index));
1922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64Movl:
192662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i,
192762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                          __ pc_offset(), instr);
1928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (instr->HasOutput()) {
1929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (instr->addressing_mode() == kMode_None) {
1930958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          if (instr->InputAt(0)->IsRegister()) {
1931958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            __ movl(i.OutputRegister(), i.InputRegister(0));
1932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          } else {
1933958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            __ movl(i.OutputRegister(), i.InputOperand(0));
1934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          }
1935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        } else {
1936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          __ movl(i.OutputRegister(), i.MemoryOperand());
1937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
1938958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ AssertZeroExtended(i.OutputRegister());
1939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
1940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        size_t index = 0;
1941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Operand operand = i.MemoryOperand(&index);
1942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (HasImmediateInput(instr, index)) {
1943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          __ movl(operand, i.InputImmediate(index));
1944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        } else {
1945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          __ movl(operand, i.InputRegister(index));
1946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
1947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX64Movsxlq:
195062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i,
195162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                          __ pc_offset(), instr);
1952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_MOVX(movsxlq);
1953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64Movq:
195562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i,
195662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                          __ pc_offset(), instr);
1957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (instr->HasOutput()) {
1958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ movq(i.OutputRegister(), i.MemoryOperand());
1959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
1960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        size_t index = 0;
1961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Operand operand = i.MemoryOperand(&index);
1962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (HasImmediateInput(instr, index)) {
1963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          __ movq(operand, i.InputImmediate(index));
1964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        } else {
1965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          __ movq(operand, i.InputRegister(index));
1966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
1967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64Movss:
197062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i,
197162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                          __ pc_offset(), instr);
1972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (instr->HasOutput()) {
1973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ movss(i.OutputDoubleRegister(), i.MemoryOperand());
1974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
1975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        size_t index = 0;
1976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Operand operand = i.MemoryOperand(&index);
1977958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ movss(operand, i.InputDoubleRegister(index));
1978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
1980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64Movsd:
198162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i,
198262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                          __ pc_offset(), instr);
1983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (instr->HasOutput()) {
1984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Movsd(i.OutputDoubleRegister(), i.MemoryOperand());
1985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
1986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        size_t index = 0;
1987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Operand operand = i.MemoryOperand(&index);
1988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Movsd(operand, i.InputDoubleRegister(index));
1989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX64BitcastFI:
1992bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (instr->InputAt(0)->IsFPStackSlot()) {
1993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ movl(i.OutputRegister(), i.InputOperand(0));
1994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Movd(i.OutputRegister(), i.InputDoubleRegister(0));
1996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
1998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX64BitcastDL:
1999bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (instr->InputAt(0)->IsFPStackSlot()) {
2000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ movq(i.OutputRegister(), i.InputOperand(0));
2001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
2002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Movq(i.OutputRegister(), i.InputDoubleRegister(0));
2003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX64BitcastIF:
2006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->InputAt(0)->IsRegister()) {
2007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Movd(i.OutputDoubleRegister(), i.InputRegister(0));
2008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
2009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ movss(i.OutputDoubleRegister(), i.InputOperand(0));
2010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX64BitcastLD:
2013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->InputAt(0)->IsRegister()) {
2014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Movq(i.OutputDoubleRegister(), i.InputRegister(0));
2015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
2016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ Movsd(i.OutputDoubleRegister(), i.InputOperand(0));
2017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
2019958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kX64Lea32: {
2020958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      AddressingMode mode = AddressingModeField::decode(instr->opcode());
2021958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // Shorten "leal" to "addl", "subl" or "shll" if the register allocation
2022958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // and addressing mode just happens to work out. The "addl"/"subl" forms
2023958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // in these cases are faster based on measurements.
2024958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (i.InputRegister(0).is(i.OutputRegister())) {
2025958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        if (mode == kMode_MRI) {
2026958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          int32_t constant_summand = i.InputInt32(1);
2027958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          if (constant_summand > 0) {
2028958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            __ addl(i.OutputRegister(), Immediate(constant_summand));
2029958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          } else if (constant_summand < 0) {
2030958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            __ subl(i.OutputRegister(), Immediate(-constant_summand));
2031958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          }
2032958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        } else if (mode == kMode_MR1) {
2033958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          if (i.InputRegister(1).is(i.OutputRegister())) {
2034958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            __ shll(i.OutputRegister(), Immediate(1));
2035958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          } else {
2036c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            __ addl(i.OutputRegister(), i.InputRegister(1));
2037958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          }
2038958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        } else if (mode == kMode_M2) {
2039958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          __ shll(i.OutputRegister(), Immediate(1));
2040958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        } else if (mode == kMode_M4) {
2041958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          __ shll(i.OutputRegister(), Immediate(2));
2042958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        } else if (mode == kMode_M8) {
2043958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          __ shll(i.OutputRegister(), Immediate(3));
2044958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        } else {
2045958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          __ leal(i.OutputRegister(), i.MemoryOperand());
2046958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        }
2047c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      } else if (mode == kMode_MR1 &&
2048c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                 i.InputRegister(1).is(i.OutputRegister())) {
2049c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        __ addl(i.OutputRegister(), i.InputRegister(0));
2050958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      } else {
2051958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ leal(i.OutputRegister(), i.MemoryOperand());
2052958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
2053958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ AssertZeroExtended(i.OutputRegister());
2054958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
2055958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2056c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case kX64Lea: {
2057c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      AddressingMode mode = AddressingModeField::decode(instr->opcode());
2058c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // Shorten "leaq" to "addq", "subq" or "shlq" if the register allocation
2059c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // and addressing mode just happens to work out. The "addq"/"subq" forms
2060c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // in these cases are faster based on measurements.
2061c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (i.InputRegister(0).is(i.OutputRegister())) {
2062c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        if (mode == kMode_MRI) {
2063c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          int32_t constant_summand = i.InputInt32(1);
2064c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          if (constant_summand > 0) {
2065c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            __ addq(i.OutputRegister(), Immediate(constant_summand));
2066c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          } else if (constant_summand < 0) {
2067c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            __ subq(i.OutputRegister(), Immediate(-constant_summand));
2068c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          }
2069c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        } else if (mode == kMode_MR1) {
2070c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          if (i.InputRegister(1).is(i.OutputRegister())) {
2071c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            __ shlq(i.OutputRegister(), Immediate(1));
2072c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          } else {
2073c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            __ addq(i.OutputRegister(), i.InputRegister(1));
2074c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          }
2075c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        } else if (mode == kMode_M2) {
2076c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          __ shlq(i.OutputRegister(), Immediate(1));
2077c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        } else if (mode == kMode_M4) {
2078c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          __ shlq(i.OutputRegister(), Immediate(2));
2079c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        } else if (mode == kMode_M8) {
2080c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          __ shlq(i.OutputRegister(), Immediate(3));
2081c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        } else {
2082c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          __ leaq(i.OutputRegister(), i.MemoryOperand());
2083c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        }
2084c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      } else if (mode == kMode_MR1 &&
2085c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                 i.InputRegister(1).is(i.OutputRegister())) {
2086c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        __ addq(i.OutputRegister(), i.InputRegister(0));
2087c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      } else {
2088c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        __ leaq(i.OutputRegister(), i.MemoryOperand());
2089c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      }
2090958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
2091c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    }
2092958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kX64Dec32:
2093958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ decl(i.OutputRegister());
2094958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
2095958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kX64Inc32:
2096958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      __ incl(i.OutputRegister());
2097958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
2098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kX64Push:
209962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (AddressingModeField::decode(instr->opcode()) != kMode_None) {
210062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        size_t index = 0;
210162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        Operand operand = i.MemoryOperand(&index);
210262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        __ pushq(operand);
210362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        frame_access_state()->IncreaseSPDelta(1);
210462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(),
210562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                         kPointerSize);
210662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      } else if (HasImmediateInput(instr, 0)) {
2107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ pushq(i.InputImmediate(0));
2108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        frame_access_state()->IncreaseSPDelta(1);
2109f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(),
2110f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                                         kPointerSize);
211162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      } else if (instr->InputAt(0)->IsRegister()) {
211262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        __ pushq(i.InputRegister(0));
211362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        frame_access_state()->IncreaseSPDelta(1);
211462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(),
211562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                         kPointerSize);
211662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      } else if (instr->InputAt(0)->IsFPRegister()) {
211762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        // TODO(titzer): use another machine instruction?
211862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        __ subq(rsp, Immediate(kDoubleSize));
211962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
212062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(),
212162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                         kDoubleSize);
212262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        __ Movsd(Operand(rsp, 0), i.InputDoubleRegister(0));
2123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
212462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        __ pushq(i.InputOperand(0));
212562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        frame_access_state()->IncreaseSPDelta(1);
212662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(),
212762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                         kPointerSize);
2128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
2130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX64Poke: {
2131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int const slot = MiscField::decode(instr->opcode());
2132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (HasImmediateInput(instr, 0)) {
2133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ movq(Operand(rsp, slot * kPointerSize), i.InputImmediate(0));
2134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
2135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        __ movq(Operand(rsp, slot * kPointerSize), i.InputRegister(0));
2136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
2138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2139bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case kX64Xchgb: {
2140bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      size_t index = 0;
2141bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      Operand operand = i.MemoryOperand(&index);
2142bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      __ xchgb(i.InputRegister(index), operand);
2143bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      break;
2144bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
2145bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case kX64Xchgw: {
2146bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      size_t index = 0;
2147bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      Operand operand = i.MemoryOperand(&index);
2148bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      __ xchgw(i.InputRegister(index), operand);
2149bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      break;
2150bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
2151bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case kX64Xchgl: {
2152bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      size_t index = 0;
2153bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      Operand operand = i.MemoryOperand(&index);
2154bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      __ xchgl(i.InputRegister(index), operand);
2155bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      break;
2156bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
2157f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case kX64Int32x4Create: {
2158f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      CpuFeatureScope sse_scope(masm(), SSE4_1);
2159f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      XMMRegister dst = i.OutputSimd128Register();
2160f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      __ Movd(dst, i.InputRegister(0));
2161f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      __ shufps(dst, dst, 0x0);
2162f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      break;
2163f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
2164f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case kX64Int32x4ExtractLane: {
2165f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      CpuFeatureScope sse_scope(masm(), SSE4_1);
2166f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      __ Pextrd(i.OutputRegister(), i.InputSimd128Register(0), i.InputInt8(1));
2167f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      break;
2168f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
216962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case kX64Int32x4ReplaceLane: {
217062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      CpuFeatureScope sse_scope(masm(), SSE4_1);
217162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (instr->InputAt(2)->IsRegister()) {
217262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        __ Pinsrd(i.OutputSimd128Register(), i.InputRegister(2),
217362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                  i.InputInt8(1));
217462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      } else {
217562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        __ Pinsrd(i.OutputSimd128Register(), i.InputOperand(2), i.InputInt8(1));
217662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      }
217762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      break;
217862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
217962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case kX64Int32x4Add: {
218062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      CpuFeatureScope sse_scope(masm(), SSE4_1);
218162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      __ paddd(i.OutputSimd128Register(), i.InputSimd128Register(1));
218262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      break;
218362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
218462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case kX64Int32x4Sub: {
218562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      CpuFeatureScope sse_scope(masm(), SSE4_1);
218662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      __ psubd(i.OutputSimd128Register(), i.InputSimd128Register(1));
218762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      break;
218862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
2189958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kCheckedLoadInt8:
2190958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ASSEMBLE_CHECKED_LOAD_INTEGER(movsxbl);
2191958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
2192958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kCheckedLoadUint8:
2193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ASSEMBLE_CHECKED_LOAD_INTEGER(movzxbl);
2194958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
2195958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kCheckedLoadInt16:
2196958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ASSEMBLE_CHECKED_LOAD_INTEGER(movsxwl);
2197958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
2198958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kCheckedLoadUint16:
2199958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ASSEMBLE_CHECKED_LOAD_INTEGER(movzxwl);
2200958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
2201958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kCheckedLoadWord32:
2202958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ASSEMBLE_CHECKED_LOAD_INTEGER(movl);
2203958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
2204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kCheckedLoadWord64:
2205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_CHECKED_LOAD_INTEGER(movq);
2206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2207958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kCheckedLoadFloat32:
2208f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSEMBLE_CHECKED_LOAD_FLOAT(Movss, OutOfLineLoadFloat32NaN);
2209958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
2210958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kCheckedLoadFloat64:
2211f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ASSEMBLE_CHECKED_LOAD_FLOAT(Movsd, OutOfLineLoadFloat64NaN);
2212958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
2213958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kCheckedStoreWord8:
2214958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ASSEMBLE_CHECKED_STORE_INTEGER(movb);
2215958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
2216958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kCheckedStoreWord16:
2217958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ASSEMBLE_CHECKED_STORE_INTEGER(movw);
2218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
2219958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kCheckedStoreWord32:
2220958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      ASSEMBLE_CHECKED_STORE_INTEGER(movl);
2221958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
2222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kCheckedStoreWord64:
2223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_CHECKED_STORE_INTEGER(movq);
2224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2225958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kCheckedStoreFloat32:
2226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_CHECKED_STORE_FLOAT(Movss);
2227958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
2228958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case kCheckedStoreFloat64:
2229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ASSEMBLE_CHECKED_STORE_FLOAT(Movsd);
2230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case kX64StackCheck:
2232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ CompareRoot(rsp, Heap::kStackLimitRootIndex);
2233958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
2234bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case kAtomicLoadInt8:
2235bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case kAtomicLoadUint8:
2236bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case kAtomicLoadInt16:
2237bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case kAtomicLoadUint16:
2238bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case kAtomicLoadWord32:
2239bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case kAtomicStoreWord8:
2240bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case kAtomicStoreWord16:
2241bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case kAtomicStoreWord32:
2242bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      UNREACHABLE();  // Won't be generated by instruction selector.
2243bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      break;
2244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2245bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return kSuccess;
2246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // NOLINT(readability/fn_size)
2247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
224862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochnamespace {
2249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
225062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochCondition FlagsConditionToCondition(FlagsCondition condition) {
225162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  switch (condition) {
2252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kUnorderedEqual:
2253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kEqual:
225462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return equal;
2255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kUnorderedNotEqual:
2256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kNotEqual:
225762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return not_equal;
2258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kSignedLessThan:
225962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return less;
2260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kSignedGreaterThanOrEqual:
226162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return greater_equal;
2262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kSignedLessThanOrEqual:
226362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return less_equal;
2264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kSignedGreaterThan:
226562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return greater;
2266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kUnsignedLessThan:
226762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return below;
2268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kUnsignedGreaterThanOrEqual:
226962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return above_equal;
2270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kUnsignedLessThanOrEqual:
227162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return below_equal;
2272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kUnsignedGreaterThan:
227362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return above;
2274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kOverflow:
227562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return overflow;
2276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kNotOverflow:
227762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return no_overflow;
2278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    default:
2279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
2280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
228162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  UNREACHABLE();
228262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return no_condition;
228362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
228462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
228562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}  // namespace
228662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
228762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch// Assembles branches after this instruction.
228862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
228962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Label::Distance flabel_distance =
229062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      branch->fallthru ? Label::kNear : Label::kFar;
229162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Label* tlabel = branch->true_label;
229262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Label* flabel = branch->false_label;
229362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (branch->condition == kUnorderedEqual) {
229462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    __ j(parity_even, flabel, flabel_distance);
229562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else if (branch->condition == kUnorderedNotEqual) {
229662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    __ j(parity_even, tlabel);
229762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
229862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  __ j(FlagsConditionToCondition(branch->condition), tlabel);
229962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
2300958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (!branch->fallthru) __ jmp(flabel, flabel_distance);
2301958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2302958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2303958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleArchJump(RpoNumber target) {
2305958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (!IsNextInAssemblyOrder(target)) __ jmp(GetLabel(target));
2306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
230862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid CodeGenerator::AssembleArchTrap(Instruction* instr,
230962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                     FlagsCondition condition) {
231062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  class OutOfLineTrap final : public OutOfLineCode {
231162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch   public:
231262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    OutOfLineTrap(CodeGenerator* gen, bool frame_elided, Instruction* instr)
231362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        : OutOfLineCode(gen),
231462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          frame_elided_(frame_elided),
231562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          instr_(instr),
231662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          gen_(gen) {}
231762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
231862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    void Generate() final {
231962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      X64OperandConverter i(gen_, instr_);
232062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
232162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Builtins::Name trap_id =
232262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          static_cast<Builtins::Name>(i.InputInt32(instr_->InputCount() - 1));
232362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      bool old_has_frame = __ has_frame();
232462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (frame_elided_) {
232562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        __ set_has_frame(true);
232662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        __ EnterFrame(StackFrame::WASM_COMPILED);
232762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      }
232862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      GenerateCallToTrap(trap_id);
232962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (frame_elided_) {
233062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        __ set_has_frame(old_has_frame);
233162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      }
233262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
233362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
233462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch   private:
233562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    void GenerateCallToTrap(Builtins::Name trap_id) {
233662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (trap_id == Builtins::builtin_count) {
233762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        // We cannot test calls to the runtime in cctest/test-run-wasm.
233862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        // Therefore we emit a call to C here instead of a call to the runtime.
233962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        __ PrepareCallCFunction(0);
234062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        __ CallCFunction(
234162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            ExternalReference::wasm_call_trap_callback_for_testing(isolate()),
234262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            0);
234362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        __ LeaveFrame(StackFrame::WASM_COMPILED);
234462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        __ Ret();
234562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      } else {
234662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        gen_->AssembleSourcePosition(instr_);
234762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        __ Call(handle(isolate()->builtins()->builtin(trap_id), isolate()),
234862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                RelocInfo::CODE_TARGET);
234962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        ReferenceMap* reference_map =
235062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            new (gen_->zone()) ReferenceMap(gen_->zone());
235162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        gen_->RecordSafepoint(reference_map, Safepoint::kSimple, 0,
235262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                              Safepoint::kNoLazyDeopt);
235362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        if (FLAG_debug_code) {
235462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          __ ud2();
235562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        }
235662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      }
235762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
235862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
235962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    bool frame_elided_;
236062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Instruction* instr_;
236162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    CodeGenerator* gen_;
236262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  };
236362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  bool frame_elided = !frame_access_state()->has_frame();
236462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  auto ool = new (zone()) OutOfLineTrap(this, frame_elided, instr);
236562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Label* tlabel = ool->entry();
236662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Label end;
236762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (condition == kUnorderedEqual) {
236862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    __ j(parity_even, &end);
236962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else if (condition == kUnorderedNotEqual) {
237062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    __ j(parity_even, tlabel);
237162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
237262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  __ j(FlagsConditionToCondition(condition), tlabel);
237362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  __ bind(&end);
237462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
2375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Assembles boolean materializations after this instruction.
2377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CodeGenerator::AssembleArchBoolean(Instruction* instr,
2378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                        FlagsCondition condition) {
2379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  X64OperandConverter i(this, instr);
2380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Label done;
2381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Materialize a full 64-bit 1 or 0 value. The result register is always the
2383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // last output of the instruction.
2384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Label check;
2385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_NE(0u, instr->OutputCount());
2386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Register reg = i.OutputRegister(instr->OutputCount() - 1);
238762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (condition == kUnorderedEqual) {
238862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    __ j(parity_odd, &check, Label::kNear);
238962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    __ movl(reg, Immediate(0));
239062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    __ jmp(&done, Label::kNear);
239162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else if (condition == kUnorderedNotEqual) {
239262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    __ j(parity_odd, &check, Label::kNear);
239362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    __ movl(reg, Immediate(1));
239462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    __ jmp(&done, Label::kNear);
2395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ bind(&check);
239762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  __ setcc(FlagsConditionToCondition(condition), reg);
2398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ movzxbl(reg, reg);
2399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ bind(&done);
2400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleArchLookupSwitch(Instruction* instr) {
2404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  X64OperandConverter i(this, instr);
2405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Register input = i.InputRegister(0);
2406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t index = 2; index < instr->InputCount(); index += 2) {
2407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ cmpl(input, Immediate(i.InputInt32(index + 0)));
2408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ j(equal, GetLabel(i.InputRpo(index + 1)));
2409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AssembleArchJump(i.InputRpo(1));
2411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleArchTableSwitch(Instruction* instr) {
2415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  X64OperandConverter i(this, instr);
2416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Register input = i.InputRegister(0);
2417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int32_t const case_count = static_cast<int32_t>(instr->InputCount() - 2);
2418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label** cases = zone()->NewArray<Label*>(case_count);
2419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int32_t index = 0; index < case_count; ++index) {
2420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    cases[index] = GetLabel(i.InputRpo(index + 2));
2421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Label* const table = AddJumpTable(cases, case_count);
2423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ cmpl(input, Immediate(case_count));
2424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ j(above_equal, GetLabel(i.InputRpo(1)));
2425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ leaq(kScratchRegister, Operand(table));
2426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  __ jmp(Operand(kScratchRegister, input, times_8, 0));
2427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2429bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben MurdochCodeGenerator::CodeGenResult CodeGenerator::AssembleDeoptimizerCall(
243062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int deoptimization_id, SourcePosition pos) {
243162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DeoptimizeKind deoptimization_kind = GetDeoptimizationKind(deoptimization_id);
243262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DeoptimizeReason deoptimization_reason =
243362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      GetDeoptimizationReason(deoptimization_id);
243462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Deoptimizer::BailoutType bailout_type =
243562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      deoptimization_kind == DeoptimizeKind::kSoft ? Deoptimizer::SOFT
243662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                   : Deoptimizer::EAGER;
2437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
2438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      isolate(), deoptimization_id, bailout_type);
2439bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (deopt_entry == nullptr) return kTooManyDeoptimizationBailouts;
2440c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  __ RecordDeoptReason(deoptimization_reason, pos, deoptimization_id);
2441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  __ call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
2442bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return kSuccess;
2443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace {
2447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic const int kQuadWordSize = 16;
2449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace
2451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2452bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid CodeGenerator::FinishFrame(Frame* frame) {
2453bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
2454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2455bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  const RegList saves_fp = descriptor->CalleeSavedFPRegisters();
2456bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (saves_fp != 0) {
2457bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    frame->AlignSavedCalleeRegisterSlots();
2458bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (saves_fp != 0) {  // Save callee-saved XMM registers.
2459bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      const uint32_t saves_fp_count = base::bits::CountPopulation32(saves_fp);
2460bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      frame->AllocateSavedCalleeRegisterSlots(saves_fp_count *
2461bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                              (kQuadWordSize / kPointerSize));
2462bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
2463bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
2464bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  const RegList saves = descriptor->CalleeSavedRegisters();
2465bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (saves != 0) {  // Save callee-saved registers.
2466bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    int count = 0;
2467bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    for (int i = Register::kNumRegisters - 1; i >= 0; i--) {
2468bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (((1 << i) & saves)) {
2469bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        ++count;
2470bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      }
2471bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
2472bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    frame->AllocateSavedCalleeRegisterSlots(count);
2473bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
2474bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
2475bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
2476bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid CodeGenerator::AssembleConstructFrame() {
2477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
24783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (frame_access_state()->has_frame()) {
2479f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    int pc_base = __ pc_offset();
2480f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
24813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (descriptor->IsCFunctionCall()) {
24823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      __ pushq(rbp);
24833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      __ movq(rbp, rsp);
24843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    } else if (descriptor->IsJSFunctionCall()) {
24853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      __ Prologue(this->info()->GeneratePreagedPrologue());
2486c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (descriptor->PushArgumentCount()) {
2487c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        __ pushq(kJavaScriptCallArgCountRegister);
2488c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      }
24893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    } else {
24903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      __ StubPrologue(info()->GetOutputStackFrameType());
24913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
2492f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
2493f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (!descriptor->IsJSFunctionCall() || !info()->GeneratePreagedPrologue()) {
2494f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      unwinding_info_writer_.MarkFrameConstructed(pc_base);
2495f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
2496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2497c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  int shrink_slots =
2498c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      frame()->GetTotalFrameSlotCount() - descriptor->CalculateFixedFrameSize();
2499bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
2500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (info()->is_osr()) {
2501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // TurboFan OSR-compiled functions cannot be entered directly.
2502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ Abort(kShouldNotDirectlyEnterOsrFunction);
2503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Unoptimized code jumps directly to this entrypoint while the unoptimized
2505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // frame is still on the stack. Optimized code uses OSR values directly from
2506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // the unoptimized frame. Thus, all that needs to be done is to allocate the
2507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // remaining stack slots.
2508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --");
2509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    osr_pc_offset_ = __ pc_offset();
2510bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    shrink_slots -= static_cast<int>(OsrHelper(info()).UnoptimizedFrameSlots());
2511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const RegList saves_fp = descriptor->CalleeSavedFPRegisters();
2514bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (shrink_slots > 0) {
2515bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    __ subq(rsp, Immediate(shrink_slots * kPointerSize));
2516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (saves_fp != 0) {  // Save callee-saved XMM registers.
2519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const uint32_t saves_fp_count = base::bits::CountPopulation32(saves_fp);
2520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const int stack_size = saves_fp_count * kQuadWordSize;
2521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Adjust the stack pointer.
2522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ subp(rsp, Immediate(stack_size));
2523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Store the registers on the stack.
2524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int slot_idx = 0;
2525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) {
2526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!((1 << i) & saves_fp)) continue;
2527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ movdqu(Operand(rsp, kQuadWordSize * slot_idx),
2528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                XMMRegister::from_code(i));
2529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      slot_idx++;
2530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const RegList saves = descriptor->CalleeSavedRegisters();
2534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (saves != 0) {  // Save callee-saved registers.
2535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (int i = Register::kNumRegisters - 1; i >= 0; i--) {
2536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!((1 << i) & saves)) continue;
2537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ pushq(Register::from_code(i));
2538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2542c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochvoid CodeGenerator::AssembleReturn(InstructionOperand* pop) {
2543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
2544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Restore registers.
2546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const RegList saves = descriptor->CalleeSavedRegisters();
2547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (saves != 0) {
2548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (int i = 0; i < Register::kNumRegisters; i++) {
2549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!((1 << i) & saves)) continue;
2550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ popq(Register::from_code(i));
2551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const RegList saves_fp = descriptor->CalleeSavedFPRegisters();
2554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (saves_fp != 0) {
2555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const uint32_t saves_fp_count = base::bits::CountPopulation32(saves_fp);
2556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const int stack_size = saves_fp_count * kQuadWordSize;
2557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Load the registers from the stack.
2558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int slot_idx = 0;
2559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) {
2560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!((1 << i) & saves_fp)) continue;
2561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ movdqu(XMMRegister::from_code(i),
2562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                Operand(rsp, kQuadWordSize * slot_idx));
2563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      slot_idx++;
2564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Adjust the stack pointer.
2566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ addp(rsp, Immediate(stack_size));
2567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2569f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  unwinding_info_writer_.MarkBlockWillExit();
2570f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
2571c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // Might need rcx for scratch if pop_size is too big or if there is a variable
2572c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // pop count.
2573c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  DCHECK_EQ(0u, descriptor->CalleeSavedRegisters() & rcx.bit());
2574c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  DCHECK_EQ(0u, descriptor->CalleeSavedRegisters() & rdx.bit());
2575c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  size_t pop_size = descriptor->StackParameterCount() * kPointerSize;
2576c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  X64OperandConverter g(this, nullptr);
2577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (descriptor->IsCFunctionCall()) {
25783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    AssembleDeconstructFrame();
25793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  } else if (frame_access_state()->has_frame()) {
2580c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    if (pop->IsImmediate() && g.ToConstant(pop).ToInt32() == 0) {
2581c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // Canonicalize JSFunction return sites for now.
2582c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (return_label_.is_bound()) {
2583c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        __ jmp(&return_label_);
2584c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        return;
2585c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      } else {
2586c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        __ bind(&return_label_);
2587c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        AssembleDeconstructFrame();
2588c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      }
2589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
25903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      AssembleDeconstructFrame();
2591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2593c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
2594c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (pop->IsImmediate()) {
2595c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    DCHECK_EQ(Constant::kInt32, g.ToConstant(pop).type());
2596c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    pop_size += g.ToConstant(pop).ToInt32() * kPointerSize;
2597c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    CHECK_LT(pop_size, static_cast<size_t>(std::numeric_limits<int>::max()));
2598c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    __ Ret(static_cast<int>(pop_size), rcx);
2599c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  } else {
2600c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    Register pop_reg = g.ToRegister(pop);
2601c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    Register scratch_reg = pop_reg.is(rcx) ? rdx : rcx;
2602c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    __ popq(scratch_reg);
2603c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    __ leaq(rsp, Operand(rsp, pop_reg, times_8, static_cast<int>(pop_size)));
2604c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    __ jmp(scratch_reg);
2605c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
2606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CodeGenerator::AssembleMove(InstructionOperand* source,
2610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 InstructionOperand* destination) {
2611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  X64OperandConverter g(this, nullptr);
2612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Dispatch on the source and destination operand kinds.  Not all
2613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // combinations are possible.
2614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (source->IsRegister()) {
2615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(destination->IsRegister() || destination->IsStackSlot());
2616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Register src = g.ToRegister(source);
2617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (destination->IsRegister()) {
2618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ movq(g.ToRegister(destination), src);
2619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
2620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ movq(g.ToOperand(destination), src);
2621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (source->IsStackSlot()) {
2623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(destination->IsRegister() || destination->IsStackSlot());
2624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Operand src = g.ToOperand(source);
2625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (destination->IsRegister()) {
2626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Register dst = g.ToRegister(destination);
2627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ movq(dst, src);
2628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
2629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Spill on demand to use a temporary register for memory-to-memory
2630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // moves.
2631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Register tmp = kScratchRegister;
2632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Operand dst = g.ToOperand(destination);
2633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ movq(tmp, src);
2634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      __ movq(dst, tmp);
2635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (source->IsConstant()) {
2637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ConstantOperand* constant_source = ConstantOperand::cast(source);
2638958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Constant src = g.ToConstant(constant_source);
2639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (destination->IsRegister() || destination->IsStackSlot()) {
2640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Register dst = destination->IsRegister() ? g.ToRegister(destination)
2641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                               : kScratchRegister;
2642958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      switch (src.type()) {
2643bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        case Constant::kInt32: {
264462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          if (RelocInfo::IsWasmPtrReference(src.rmode())) {
2645bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch            __ movq(dst, src.ToInt64(), src.rmode());
2646bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          } else {
2647bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch            // TODO(dcarney): don't need scratch in this case.
2648bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch            int32_t value = src.ToInt32();
2649bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch            if (value == 0) {
2650bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch              __ xorl(dst, dst);
2651bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch            } else {
265262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch              if (RelocInfo::IsWasmSizeReference(src.rmode())) {
2653f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                __ movl(dst, Immediate(value, src.rmode()));
2654f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch              } else {
2655f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                __ movl(dst, Immediate(value));
2656f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch              }
2657bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch            }
2658bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          }
2659958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          break;
2660bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        }
2661958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        case Constant::kInt64:
266262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          if (RelocInfo::IsWasmPtrReference(src.rmode())) {
2663bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch            __ movq(dst, src.ToInt64(), src.rmode());
2664bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          } else {
266562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            DCHECK(!RelocInfo::IsWasmSizeReference(src.rmode()));
2666bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch            __ Set(dst, src.ToInt64());
2667bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          }
2668958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          break;
2669958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        case Constant::kFloat32:
2670958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          __ Move(dst,
2671958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                  isolate()->factory()->NewNumber(src.ToFloat32(), TENURED));
2672958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          break;
2673958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        case Constant::kFloat64:
2674958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          __ Move(dst,
2675958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                  isolate()->factory()->NewNumber(src.ToFloat64(), TENURED));
2676958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          break;
2677958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        case Constant::kExternalReference:
2678958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          __ Move(dst, src.ToExternalReference());
2679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          break;
2680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        case Constant::kHeapObject: {
2681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Handle<HeapObject> src_object = src.ToHeapObject();
2682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Heap::RootListIndex index;
2683f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          if (IsMaterializableFromRoot(src_object, &index)) {
2684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            __ LoadRoot(dst, index);
2685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          } else {
2686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            __ Move(dst, src_object);
2687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
2688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          break;
2689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
2690958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        case Constant::kRpoNumber:
2691958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          UNREACHABLE();  // TODO(dcarney): load of labels on x64.
2692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          break;
2693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (destination->IsStackSlot()) {
2695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ movq(g.ToOperand(destination), kScratchRegister);
2696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2697958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else if (src.type() == Constant::kFloat32) {
2698958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // TODO(turbofan): Can we do better here?
2699958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      uint32_t src_const = bit_cast<uint32_t>(src.ToFloat32());
2700bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (destination->IsFPRegister()) {
2701958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ Move(g.ToDoubleRegister(destination), src_const);
2702958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      } else {
2703bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        DCHECK(destination->IsFPStackSlot());
2704958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        Operand dst = g.ToOperand(destination);
2705958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ movl(dst, Immediate(src_const));
2706958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
2707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
2708958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      DCHECK_EQ(Constant::kFloat64, src.type());
2709958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      uint64_t src_const = bit_cast<uint64_t>(src.ToFloat64());
2710bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (destination->IsFPRegister()) {
2711958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ Move(g.ToDoubleRegister(destination), src_const);
2712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
2713bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        DCHECK(destination->IsFPStackSlot());
2714958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        __ movq(kScratchRegister, src_const);
2715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        __ movq(g.ToOperand(destination), kScratchRegister);
2716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2718bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  } else if (source->IsFPRegister()) {
2719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    XMMRegister src = g.ToDoubleRegister(source);
2720bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (destination->IsFPRegister()) {
2721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      XMMRegister dst = g.ToDoubleRegister(destination);
2722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      __ Movapd(dst, src);
2723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
2724bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      DCHECK(destination->IsFPStackSlot());
2725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Operand dst = g.ToOperand(destination);
2726f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      MachineRepresentation rep =
2727f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          LocationOperand::cast(source)->representation();
2728f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (rep != MachineRepresentation::kSimd128) {
2729f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Movsd(dst, src);
2730f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      } else {
2731f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Movups(dst, src);
2732f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
2733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2734bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  } else if (source->IsFPStackSlot()) {
2735bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    DCHECK(destination->IsFPRegister() || destination->IsFPStackSlot());
2736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Operand src = g.ToOperand(source);
2737f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    MachineRepresentation rep = LocationOperand::cast(source)->representation();
2738bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (destination->IsFPRegister()) {
2739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      XMMRegister dst = g.ToDoubleRegister(destination);
2740f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (rep != MachineRepresentation::kSimd128) {
2741f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Movsd(dst, src);
2742f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      } else {
2743f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Movups(dst, src);
2744f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
2745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
2746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Operand dst = g.ToOperand(destination);
2747f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (rep != MachineRepresentation::kSimd128) {
2748f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Movsd(kScratchDoubleReg, src);
2749f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Movsd(dst, kScratchDoubleReg);
2750f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      } else {
2751f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Movups(kScratchDoubleReg, src);
2752f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        __ Movups(dst, kScratchDoubleReg);
2753f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
2754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
2756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UNREACHABLE();
2757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CodeGenerator::AssembleSwap(InstructionOperand* source,
2762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 InstructionOperand* destination) {
2763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  X64OperandConverter g(this, nullptr);
2764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Dispatch on the source and destination operand kinds.  Not all
2765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // combinations are possible.
2766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (source->IsRegister() && destination->IsRegister()) {
2767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Register-register.
2768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Register src = g.ToRegister(source);
2769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Register dst = g.ToRegister(destination);
2770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ movq(kScratchRegister, src);
2771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ movq(src, dst);
2772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ movq(dst, kScratchRegister);
2773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (source->IsRegister() && destination->IsStackSlot()) {
2774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Register src = g.ToRegister(source);
2775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ pushq(src);
2776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    frame_access_state()->IncreaseSPDelta(1);
2777f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(),
2778f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                                     kPointerSize);
2779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Operand dst = g.ToOperand(destination);
2780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ movq(src, dst);
2781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    frame_access_state()->IncreaseSPDelta(-1);
2782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    dst = g.ToOperand(destination);
2783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ popq(dst);
2784f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(),
2785f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                                     -kPointerSize);
2786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if ((source->IsStackSlot() && destination->IsStackSlot()) ||
2787bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch             (source->IsFPStackSlot() && destination->IsFPStackSlot())) {
2788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Memory-memory.
2789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Operand src = g.ToOperand(source);
2790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Operand dst = g.ToOperand(destination);
2791f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    MachineRepresentation rep = LocationOperand::cast(source)->representation();
2792f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (rep != MachineRepresentation::kSimd128) {
2793f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Register tmp = kScratchRegister;
2794f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ movq(tmp, dst);
2795f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ pushq(src);
2796f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(),
2797f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                                       kPointerSize);
2798f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      frame_access_state()->IncreaseSPDelta(1);
2799f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      src = g.ToOperand(source);
2800f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ movq(src, tmp);
2801f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      frame_access_state()->IncreaseSPDelta(-1);
2802f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      dst = g.ToOperand(destination);
2803f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ popq(dst);
2804f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      unwinding_info_writer_.MaybeIncreaseBaseOffsetAt(__ pc_offset(),
2805f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                                       -kPointerSize);
2806f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    } else {
2807f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // Use the XOR trick to swap without a temporary.
2808f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ Movups(kScratchDoubleReg, src);
2809f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ Xorps(kScratchDoubleReg, dst);  // scratch contains src ^ dst.
2810f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ Movups(src, kScratchDoubleReg);
2811f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ Xorps(kScratchDoubleReg, dst);  // scratch contains src.
2812f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ Movups(dst, kScratchDoubleReg);
2813f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ Xorps(kScratchDoubleReg, src);  // scratch contains dst.
2814f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ Movups(src, kScratchDoubleReg);
2815f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
2816bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  } else if (source->IsFPRegister() && destination->IsFPRegister()) {
281713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    // XMM register-register swap.
2818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    XMMRegister src = g.ToDoubleRegister(source);
2819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    XMMRegister dst = g.ToDoubleRegister(destination);
282013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    __ Movapd(kScratchDoubleReg, src);
2821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ Movapd(src, dst);
282213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    __ Movapd(dst, kScratchDoubleReg);
2823bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  } else if (source->IsFPRegister() && destination->IsFPStackSlot()) {
282413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    // XMM register-memory swap.
2825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    XMMRegister src = g.ToDoubleRegister(source);
2826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Operand dst = g.ToOperand(destination);
2827f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    MachineRepresentation rep = LocationOperand::cast(source)->representation();
2828f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (rep != MachineRepresentation::kSimd128) {
2829f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ Movsd(kScratchDoubleReg, src);
2830f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ Movsd(src, dst);
2831f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ Movsd(dst, kScratchDoubleReg);
2832f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    } else {
2833f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ Movups(kScratchDoubleReg, src);
2834f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ Movups(src, dst);
2835f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      __ Movups(dst, kScratchDoubleReg);
2836f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
2837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
2838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // No other combinations are possible.
2839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UNREACHABLE();
2840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CodeGenerator::AssembleJumpTable(Label** targets, size_t target_count) {
2845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t index = 0; index < target_count; ++index) {
2846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ dq(targets[index]);
2847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CodeGenerator::EnsureSpaceForLazyDeopt() {
2852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!info()->ShouldEnsureSpaceForLazyDeopt()) {
2853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return;
2854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int space_needed = Deoptimizer::patch_size();
2857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Ensure that we have enough space after the previous lazy-bailout
2858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // instruction for patching the code here.
2859f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int current_pc = __ pc_offset();
2860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (current_pc < last_lazy_deopt_pc_ + space_needed) {
2861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
2862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    __ Nop(padding_size);
2863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef __
2867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace compiler
2869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
2870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace v8
2871