1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2014 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
5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include <algorithm>
6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
7014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/base/adapters.h"
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/instruction-selector-impl.h"
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/node-matchers.h"
10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/node-properties.h"
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace compiler {
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Adds X64-specific methods for generating operands.
17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass X64OperandGenerator final : public OperandGenerator {
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit X64OperandGenerator(InstructionSelector* selector)
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : OperandGenerator(selector) {}
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool CanBeImmediate(Node* node) {
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    switch (node->opcode()) {
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case IrOpcode::kInt32Constant:
25bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      case IrOpcode::kRelocatableInt32Constant:
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return true;
27958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case IrOpcode::kInt64Constant: {
28958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        const int64_t value = OpParameter<int64_t>(node);
29958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        return value == static_cast<int64_t>(static_cast<int32_t>(value));
30958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case IrOpcode::kNumberConstant: {
32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        const double value = OpParameter<double>(node);
33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return bit_cast<int64_t>(value) == 0;
34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      default:
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return false;
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
40f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int32_t GetImmediateIntegerValue(Node* node) {
41f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    DCHECK(CanBeImmediate(node));
42f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (node->opcode() == IrOpcode::kInt32Constant) {
43f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return OpParameter<int32_t>(node);
44f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
45f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    DCHECK_EQ(IrOpcode::kInt64Constant, node->opcode());
46f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return static_cast<int32_t>(OpParameter<int64_t>(node));
47f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
48f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
49bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  bool CanBeMemoryOperand(InstructionCode opcode, Node* node, Node* input,
50bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                          int effect_level) {
513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (input->opcode() != IrOpcode::kLoad ||
523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        !selector()->CanCover(node, input)) {
533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      return false;
543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
55bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (effect_level != selector()->GetEffectLevel(input)) {
56bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      return false;
57bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    MachineRepresentation rep =
593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        LoadRepresentationOf(input->op()).representation();
603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    switch (opcode) {
6162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      case kX64Push:
623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      case kX64Cmp:
633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      case kX64Test:
64f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        return rep == MachineRepresentation::kWord64 || IsAnyTagged(rep);
653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      case kX64Cmp32:
663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      case kX64Test32:
673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        return rep == MachineRepresentation::kWord32;
683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      case kX64Cmp16:
693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      case kX64Test16:
703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        return rep == MachineRepresentation::kWord16;
713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      case kX64Cmp8:
723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      case kX64Test8:
733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        return rep == MachineRepresentation::kWord8;
743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      default:
753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        break;
763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return false;
783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
80958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  AddressingMode GenerateMemoryOperandInputs(Node* index, int scale_exponent,
81958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                             Node* base, Node* displacement,
82f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                             DisplacementMode displacement_mode,
83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                             InstructionOperand inputs[],
84958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                             size_t* input_count) {
85958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    AddressingMode mode = kMode_MRI;
8662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (base != nullptr && (index != nullptr || displacement != nullptr)) {
8762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (base->opcode() == IrOpcode::kInt32Constant &&
8862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          OpParameter<int32_t>(base) == 0) {
8962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        base = nullptr;
9062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      } else if (base->opcode() == IrOpcode::kInt64Constant &&
9162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                 OpParameter<int64_t>(base) == 0) {
9262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        base = nullptr;
9362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      }
9462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (base != nullptr) {
96958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      inputs[(*input_count)++] = UseRegister(base);
97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (index != nullptr) {
98958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        DCHECK(scale_exponent >= 0 && scale_exponent <= 3);
99958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        inputs[(*input_count)++] = UseRegister(index);
100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (displacement != nullptr) {
101f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          inputs[(*input_count)++] = displacement_mode
102f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                         ? UseNegatedImmediate(displacement)
103f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                         : UseImmediate(displacement);
104958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          static const AddressingMode kMRnI_modes[] = {kMode_MR1I, kMode_MR2I,
105958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                       kMode_MR4I, kMode_MR8I};
106958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          mode = kMRnI_modes[scale_exponent];
107958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        } else {
108958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          static const AddressingMode kMRn_modes[] = {kMode_MR1, kMode_MR2,
109958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                      kMode_MR4, kMode_MR8};
110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          mode = kMRn_modes[scale_exponent];
111958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        }
112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      } else {
113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (displacement == nullptr) {
114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          mode = kMode_MR;
115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        } else {
116f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          inputs[(*input_count)++] = displacement_mode == kNegativeDisplacement
117f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                         ? UseNegatedImmediate(displacement)
118f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                         : UseImmediate(displacement);
119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          mode = kMode_MRI;
120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        }
121958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {
123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      DCHECK(scale_exponent >= 0 && scale_exponent <= 3);
124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (displacement != nullptr) {
12562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        if (index == nullptr) {
12662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          inputs[(*input_count)++] = UseRegister(displacement);
12762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          mode = kMode_MR;
12862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        } else {
12962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          inputs[(*input_count)++] = UseRegister(index);
13062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          inputs[(*input_count)++] = displacement_mode == kNegativeDisplacement
13162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                         ? UseNegatedImmediate(displacement)
13262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                         : UseImmediate(displacement);
13362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          static const AddressingMode kMnI_modes[] = {kMode_MRI, kMode_M2I,
13462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                                      kMode_M4I, kMode_M8I};
13562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          mode = kMnI_modes[scale_exponent];
13662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        }
137958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      } else {
13862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        inputs[(*input_count)++] = UseRegister(index);
139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        static const AddressingMode kMn_modes[] = {kMode_MR, kMode_MR1,
140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                   kMode_M4, kMode_M8};
141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        mode = kMn_modes[scale_exponent];
142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        if (mode == kMode_MR1) {
143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          // [%r1 + %r1*1] has a smaller encoding than [%r1*2+0]
144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          inputs[(*input_count)++] = UseRegister(index);
145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        }
146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return mode;
149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  AddressingMode GetEffectiveAddressMemoryOperand(Node* operand,
152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                  InstructionOperand inputs[],
153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                  size_t* input_count) {
154f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (selector()->CanAddressRelativeToRootsRegister()) {
155f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      LoadMatcher<ExternalReferenceMatcher> m(operand);
156f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      if (m.index().HasValue() && m.object().HasValue()) {
157f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        Address const kRootsRegisterValue =
158f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch            kRootRegisterBias +
159f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch            reinterpret_cast<Address>(
160f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                selector()->isolate()->heap()->roots_array_start());
161f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        ptrdiff_t const delta =
162f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch            m.index().Value() +
163f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch            (m.object().Value().address() - kRootsRegisterValue);
164f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        if (is_int32(delta)) {
165f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          inputs[(*input_count)++] = TempImmediate(static_cast<int32_t>(delta));
166f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          return kMode_Root;
167f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        }
168f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
169f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    }
170f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    BaseWithIndexAndDisplacement64Matcher m(operand, AddressOption::kAllowAll);
171958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(m.matches());
17262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (m.displacement() == nullptr || CanBeImmediate(m.displacement())) {
173f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return GenerateMemoryOperandInputs(
174f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          m.index(), m.scale(), m.base(), m.displacement(),
175f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          m.displacement_mode(), inputs, input_count);
17662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    } else if (m.base() == nullptr &&
17762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch               m.displacement_mode() == kPositiveDisplacement) {
17862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      // The displacement cannot be an immediate, but we can use the
17962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      // displacement as base instead and still benefit from addressing
18062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      // modes for the scale.
18162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return GenerateMemoryOperandInputs(m.index(), m.scale(), m.displacement(),
18262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                         nullptr, m.displacement_mode(), inputs,
18362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                         input_count);
184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {
185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      inputs[(*input_count)++] = UseRegister(operand->InputAt(0));
186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      inputs[(*input_count)++] = UseRegister(operand->InputAt(1));
187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return kMode_MR1;
188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
189958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
190958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
191958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool CanBeBetterLeftOperand(Node* node) const {
192958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return !selector()->IsLive(node);
193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
196f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochnamespace {
197f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochArchOpcode GetLoadOpcode(LoadRepresentation load_rep) {
198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ArchOpcode opcode = kArchNop;
199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (load_rep.representation()) {
200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kFloat32:
201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      opcode = kX64Movss;
202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kFloat64:
204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      opcode = kX64Movsd;
205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kBit:  // Fall through.
207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord8:
208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      opcode = load_rep.IsSigned() ? kX64Movsxbl : kX64Movzxbl;
209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord16:
211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      opcode = load_rep.IsSigned() ? kX64Movsxwl : kX64Movzxwl;
212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord32:
214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      opcode = kX64Movl;
215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
216f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kTaggedSigned:   // Fall through.
217f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kTaggedPointer:  // Fall through.
218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kTagged:  // Fall through.
219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord64:
220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      opcode = kX64Movq;
221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
222109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case MachineRepresentation::kSimd128:  // Fall through.
22362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kSimd1x4:  // Fall through.
22462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kSimd1x8:  // Fall through.
22562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kSimd1x16:  // Fall through.
226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kNone:
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      UNREACHABLE();
228f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      break;
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
230f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return opcode;
231f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
232f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
23362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochArchOpcode GetStoreOpcode(StoreRepresentation store_rep) {
23462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  switch (store_rep.representation()) {
23562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kFloat32:
23662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return kX64Movss;
23762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      break;
23862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kFloat64:
23962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return kX64Movsd;
24062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      break;
24162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kBit:  // Fall through.
24262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kWord8:
24362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return kX64Movb;
24462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      break;
24562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kWord16:
24662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return kX64Movw;
24762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      break;
24862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kWord32:
24962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return kX64Movl;
25062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      break;
25162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kTaggedSigned:   // Fall through.
25262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kTaggedPointer:  // Fall through.
25362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kTagged:         // Fall through.
25462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kWord64:
25562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return kX64Movq;
25662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      break;
25762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kSimd128:  // Fall through.
25862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kSimd1x4:  // Fall through.
25962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kSimd1x8:  // Fall through.
26062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kSimd1x16:  // Fall through.
26162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kNone:
26262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      UNREACHABLE();
26362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return kArchNop;
26462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
26562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  UNREACHABLE();
26662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return kArchNop;
26762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
26862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
269f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}  // namespace
270958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
271f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid InstructionSelector::VisitLoad(Node* node) {
272f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  LoadRepresentation load_rep = LoadRepresentationOf(node->op());
273f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  X64OperandGenerator g(this);
274f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
275f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ArchOpcode opcode = GetLoadOpcode(load_rep);
276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand outputs[1];
277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  outputs[0] = g.DefineAsRegister(node);
278f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  InstructionOperand inputs[4];
279f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  size_t input_count = 0;
280f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AddressingMode mode =
281f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
282f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  InstructionCode code = opcode | AddressingModeField::encode(mode);
28362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (node->opcode() == IrOpcode::kProtectedLoad) {
28462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    code |= MiscField::encode(X64MemoryProtection::kProtected);
28562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // Add the source position as an input
28662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    inputs[input_count++] = g.UseImmediate(node->InputAt(2));
28762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
288f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Emit(code, 1, outputs, input_count, inputs);
289f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
29162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid InstructionSelector::VisitProtectedLoad(Node* node) { VisitLoad(node); }
29262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitStore(Node* node) {
294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  X64OperandGenerator g(this);
295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* base = node->InputAt(0);
296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* index = node->InputAt(1);
297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Node* value = node->InputAt(2);
298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  StoreRepresentation store_rep = StoreRepresentationOf(node->op());
300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind();
301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (write_barrier_kind != kNoWriteBarrier) {
30362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    DCHECK(CanBeTaggedPointer(store_rep.representation()));
304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AddressingMode addressing_mode;
305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand inputs[3];
306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    size_t input_count = 0;
307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    inputs[input_count++] = g.UseUniqueRegister(base);
308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (g.CanBeImmediate(index)) {
309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      inputs[input_count++] = g.UseImmediate(index);
310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      addressing_mode = kMode_MRI;
311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      inputs[input_count++] = g.UseUniqueRegister(index);
313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      addressing_mode = kMode_MR1;
314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    inputs[input_count++] = g.UseUniqueRegister(value);
316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    RecordWriteMode record_write_mode = RecordWriteMode::kValueIsAny;
317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    switch (write_barrier_kind) {
318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case kNoWriteBarrier:
319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UNREACHABLE();
320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case kMapWriteBarrier:
322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        record_write_mode = RecordWriteMode::kValueIsMap;
323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case kPointerWriteBarrier:
325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        record_write_mode = RecordWriteMode::kValueIsPointer;
326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case kFullWriteBarrier:
328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        record_write_mode = RecordWriteMode::kValueIsAny;
329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()};
332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    size_t const temp_count = arraysize(temps);
333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionCode code = kArchStoreWithWriteBarrier;
334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    code |= AddressingModeField::encode(addressing_mode);
335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    code |= MiscField::encode(static_cast<int>(record_write_mode));
336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Emit(code, 0, nullptr, input_count, inputs, temp_count, temps);
337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
33862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ArchOpcode opcode = GetStoreOpcode(store_rep);
339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand inputs[4];
340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    size_t input_count = 0;
341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AddressingMode addressing_mode =
342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionCode code =
344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        opcode | AddressingModeField::encode(addressing_mode);
34562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if ((ElementSizeLog2Of(store_rep.representation()) < kPointerSizeLog2) &&
34662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        (value->opcode() == IrOpcode::kTruncateInt64ToInt32) &&
34762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        CanCover(node, value)) {
34862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      value = value->InputAt(0);
34962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand value_operand =
351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value);
352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    inputs[input_count++] = value_operand;
353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Emit(code, 0, static_cast<InstructionOperand*>(nullptr), input_count,
354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         inputs);
355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
356958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
357958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
35862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid InstructionSelector::VisitProtectedStore(Node* node) {
35962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  X64OperandGenerator g(this);
36062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* value = node->InputAt(2);
36162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Node* position = node->InputAt(3);
36262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
36362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StoreRepresentation store_rep = StoreRepresentationOf(node->op());
36462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
36562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  ArchOpcode opcode = GetStoreOpcode(store_rep);
36662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  InstructionOperand inputs[5];
36762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  size_t input_count = 0;
36862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  AddressingMode addressing_mode =
36962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
37062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  InstructionCode code = opcode | AddressingModeField::encode(addressing_mode) |
37162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                         MiscField::encode(X64MemoryProtection::kProtected);
37262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  InstructionOperand value_operand =
37362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value);
37462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  inputs[input_count++] = value_operand;
37562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  inputs[input_count++] = g.UseImmediate(position);
37662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Emit(code, 0, static_cast<InstructionOperand*>(nullptr), input_count, inputs);
37762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
37862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
379f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Architecture supports unaligned access, therefore VisitLoad is used instead
380f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InstructionSelector::VisitUnalignedLoad(Node* node) { UNREACHABLE(); }
381f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
382f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Architecture supports unaligned access, therefore VisitStore is used instead
383f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InstructionSelector::VisitUnalignedStore(Node* node) { UNREACHABLE(); }
384958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
385958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitCheckedLoad(Node* node) {
386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op());
387958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  X64OperandGenerator g(this);
388958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Node* const buffer = node->InputAt(0);
389958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Node* const offset = node->InputAt(1);
390958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Node* const length = node->InputAt(2);
391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ArchOpcode opcode = kArchNop;
392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (load_rep.representation()) {
393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord8:
394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      opcode = load_rep.IsSigned() ? kCheckedLoadInt8 : kCheckedLoadUint8;
395958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord16:
397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      opcode = load_rep.IsSigned() ? kCheckedLoadInt16 : kCheckedLoadUint16;
398958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord32:
400958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      opcode = kCheckedLoadWord32;
401958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord64:
403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      opcode = kCheckedLoadWord64;
404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kFloat32:
406958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      opcode = kCheckedLoadFloat32;
407958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kFloat64:
409958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      opcode = kCheckedLoadFloat64;
410958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
411109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case MachineRepresentation::kBit:      // Fall through.
412109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case MachineRepresentation::kSimd128:  // Fall through.
41362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kSimd1x4:  // Fall through.
41462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kSimd1x8:  // Fall through.
41562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kSimd1x16:       // Fall through.
416f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kTaggedSigned:   // Fall through.
417f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kTaggedPointer:  // Fall through.
418109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case MachineRepresentation::kTagged:   // Fall through.
419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kNone:
420958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      UNREACHABLE();
421958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return;
422958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
423958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (offset->opcode() == IrOpcode::kInt32Add && CanCover(node, offset)) {
424958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Int32Matcher mlength(length);
425958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Int32BinopMatcher moffset(offset);
426958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (mlength.HasValue() && moffset.right().HasValue() &&
427958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        moffset.right().Value() >= 0 &&
428958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        mlength.Value() >= moffset.right().Value()) {
429958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      Emit(opcode, g.DefineAsRegister(node), g.UseRegister(buffer),
430958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier           g.UseRegister(moffset.left().node()),
431958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier           g.UseImmediate(moffset.right().node()), g.UseImmediate(length));
432958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return;
433958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
434958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand length_operand =
436958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length);
437958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Emit(opcode, g.DefineAsRegister(node), g.UseRegister(buffer),
438958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier       g.UseRegister(offset), g.TempImmediate(0), length_operand);
439958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
440958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
441958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
442958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitCheckedStore(Node* node) {
443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MachineRepresentation rep = CheckedStoreRepresentationOf(node->op());
444958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  X64OperandGenerator g(this);
445958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Node* const buffer = node->InputAt(0);
446958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Node* const offset = node->InputAt(1);
447958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Node* const length = node->InputAt(2);
448958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Node* const value = node->InputAt(3);
449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ArchOpcode opcode = kArchNop;
450958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  switch (rep) {
451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord8:
452958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      opcode = kCheckedStoreWord8;
453958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord16:
455958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      opcode = kCheckedStoreWord16;
456958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord32:
458958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      opcode = kCheckedStoreWord32;
459958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord64:
461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      opcode = kCheckedStoreWord64;
462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kFloat32:
464958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      opcode = kCheckedStoreFloat32;
465958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kFloat64:
467958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      opcode = kCheckedStoreFloat64;
468958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      break;
469109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case MachineRepresentation::kBit:      // Fall through.
470109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case MachineRepresentation::kSimd128:  // Fall through.
47162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kSimd1x4:  // Fall through.
47262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kSimd1x8:  // Fall through.
47362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kSimd1x16:       // Fall through.
474f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kTaggedSigned:   // Fall through.
475f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kTaggedPointer:  // Fall through.
476109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case MachineRepresentation::kTagged:   // Fall through.
477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kNone:
478958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      UNREACHABLE();
479958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return;
480958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand value_operand =
482958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value);
483958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (offset->opcode() == IrOpcode::kInt32Add && CanCover(node, offset)) {
484958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Int32Matcher mlength(length);
485958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Int32BinopMatcher moffset(offset);
486958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (mlength.HasValue() && moffset.right().HasValue() &&
487958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        moffset.right().Value() >= 0 &&
488958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        mlength.Value() >= moffset.right().Value()) {
489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Emit(opcode, g.NoOutput(), g.UseRegister(buffer),
490958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier           g.UseRegister(moffset.left().node()),
491958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier           g.UseImmediate(moffset.right().node()), g.UseImmediate(length),
492958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier           value_operand);
493958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return;
494958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand length_operand =
497958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length);
498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Emit(opcode, g.NoOutput(), g.UseRegister(buffer), g.UseRegister(offset),
499958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier       g.TempImmediate(0), length_operand, value_operand);
500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Shared routine for multiple binary operations.
504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void VisitBinop(InstructionSelector* selector, Node* node,
505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       InstructionCode opcode, FlagsContinuation* cont) {
506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  X64OperandGenerator g(selector);
507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Int32BinopMatcher m(node);
508958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Node* left = m.left().node();
509958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Node* right = m.right().node();
510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand inputs[4];
511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t input_count = 0;
512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand outputs[2];
513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t output_count = 0;
514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(turbofan): match complex addressing modes.
516958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (left == right) {
517958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // If both inputs refer to the same operand, enforce allocating a register
518958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // for both of them to ensure that we don't end up generating code like
519958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // this:
520958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    //
521958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    //   mov rax, [rbp-0x10]
522958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    //   add rax, [rbp-0x10]
523958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    //   jo label
524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand const input = g.UseRegister(left);
525958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    inputs[input_count++] = input;
526958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    inputs[input_count++] = input;
527958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } else if (g.CanBeImmediate(right)) {
528958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    inputs[input_count++] = g.UseRegister(left);
529958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    inputs[input_count++] = g.UseImmediate(right);
530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
531958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (node->op()->HasProperty(Operator::kCommutative) &&
532958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        g.CanBeBetterLeftOperand(right)) {
533958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      std::swap(left, right);
534958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
535958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    inputs[input_count++] = g.UseRegister(left);
536958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    inputs[input_count++] = g.Use(right);
537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (cont->IsBranch()) {
540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    inputs[input_count++] = g.Label(cont->true_block());
541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    inputs[input_count++] = g.Label(cont->false_block());
542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  outputs[output_count++] = g.DefineSameAsFirst(node);
545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (cont->IsSet()) {
546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    outputs[output_count++] = g.DefineAsRegister(cont->result());
547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_NE(0u, input_count);
550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_NE(0u, output_count);
551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_GE(arraysize(inputs), input_count);
552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_GE(arraysize(outputs), output_count);
553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  opcode = cont->Encode(opcode);
5553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (cont->IsDeoptimize()) {
5563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs,
55762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                             cont->kind(), cont->reason(), cont->frame_state());
5583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  } else {
5593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    selector->Emit(opcode, output_count, outputs, input_count, inputs);
5603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Shared routine for multiple binary operations.
565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void VisitBinop(InstructionSelector* selector, Node* node,
566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       InstructionCode opcode) {
567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FlagsContinuation cont;
568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitBinop(selector, node, opcode, &cont);
569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitWord32And(Node* node) {
573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  X64OperandGenerator g(this);
574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Uint32BinopMatcher m(node);
575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (m.right().Is(0xff)) {
576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Emit(kX64Movzxbl, g.DefineAsRegister(node), g.Use(m.left().node()));
577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (m.right().Is(0xffff)) {
578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Emit(kX64Movzxwl, g.DefineAsRegister(node), g.Use(m.left().node()));
579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    VisitBinop(this, node, kX64And32);
581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitWord64And(Node* node) {
586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitBinop(this, node, kX64And);
587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitWord32Or(Node* node) {
591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitBinop(this, node, kX64Or32);
592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitWord64Or(Node* node) {
596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitBinop(this, node, kX64Or);
597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitWord32Xor(Node* node) {
601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  X64OperandGenerator g(this);
602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Uint32BinopMatcher m(node);
603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (m.right().Is(-1)) {
604958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Emit(kX64Not32, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()));
605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    VisitBinop(this, node, kX64Xor32);
607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitWord64Xor(Node* node) {
612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  X64OperandGenerator g(this);
613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Uint64BinopMatcher m(node);
614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (m.right().Is(-1)) {
615958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Emit(kX64Not, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()));
616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    VisitBinop(this, node, kX64Xor);
618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
622958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace {
623958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Shared routine for multiple 32-bit shift operations.
625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// TODO(bmeurer): Merge this with VisitWord64Shift using template magic?
626958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid VisitWord32Shift(InstructionSelector* selector, Node* node,
627958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                      ArchOpcode opcode) {
628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  X64OperandGenerator g(selector);
629958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Int32BinopMatcher m(node);
630958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Node* left = m.left().node();
631958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Node* right = m.right().node();
632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (g.CanBeImmediate(right)) {
634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left),
635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   g.UseImmediate(right));
636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left),
638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   g.UseFixed(right, rcx));
639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Shared routine for multiple 64-bit shift operations.
644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// TODO(bmeurer): Merge this with VisitWord32Shift using template magic?
645958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid VisitWord64Shift(InstructionSelector* selector, Node* node,
646958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                      ArchOpcode opcode) {
647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  X64OperandGenerator g(selector);
648958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Int64BinopMatcher m(node);
649958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Node* left = m.left().node();
650958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Node* right = m.right().node();
651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (g.CanBeImmediate(right)) {
653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left),
654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   g.UseImmediate(right));
655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (m.right().IsWord64And()) {
657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Int64BinopMatcher mright(right);
658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (mright.right().Is(0x3F)) {
659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        right = mright.left().node();
660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left),
663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   g.UseFixed(right, rcx));
664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
667958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid EmitLea(InstructionSelector* selector, InstructionCode opcode,
668958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier             Node* result, Node* index, int scale, Node* base,
669f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch             Node* displacement, DisplacementMode displacement_mode) {
670958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  X64OperandGenerator g(selector);
671958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand inputs[4];
673958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  size_t input_count = 0;
674f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  AddressingMode mode =
675f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      g.GenerateMemoryOperandInputs(index, scale, base, displacement,
676f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                    displacement_mode, inputs, &input_count);
677958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_NE(0u, input_count);
679958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK_GE(arraysize(inputs), input_count);
680958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand outputs[1];
682958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  outputs[0] = g.DefineAsRegister(result);
683958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
684958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  opcode = AddressingModeField::encode(mode) | opcode;
685958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
686958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  selector->Emit(opcode, 1, outputs, input_count, inputs);
687958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
688958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
689958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}  // namespace
690958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
691958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitWord32Shl(Node* node) {
693958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Int32ScaleMatcher m(node, true);
694958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (m.matches()) {
695958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Node* index = node->InputAt(0);
696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Node* base = m.power_of_two_plus_one() ? index : nullptr;
697f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    EmitLea(this, kX64Lea32, node, index, m.scale(), base, nullptr,
698f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            kPositiveDisplacement);
699958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return;
700958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitWord32Shift(this, node, kX64Shl32);
702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitWord64Shl(Node* node) {
706958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  X64OperandGenerator g(this);
707f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Int64ScaleMatcher m(node, true);
708f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (m.matches()) {
709f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Node* index = node->InputAt(0);
710f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Node* base = m.power_of_two_plus_one() ? index : nullptr;
711f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    EmitLea(this, kX64Lea, node, index, m.scale(), base, nullptr,
712f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            kPositiveDisplacement);
713958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return;
714f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else {
715f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Int64BinopMatcher m(node);
716f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if ((m.left().IsChangeInt32ToInt64() ||
717f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch         m.left().IsChangeUint32ToUint64()) &&
718f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        m.right().IsInRange(32, 63)) {
719f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // There's no need to sign/zero-extend to 64-bit if we shift out the upper
720f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // 32 bits anyway.
721f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Emit(kX64Shl, g.DefineSameAsFirst(node),
722f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch           g.UseRegister(m.left().node()->InputAt(0)),
723f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch           g.UseImmediate(m.right().node()));
724f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return;
725f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
726958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitWord64Shift(this, node, kX64Shl);
728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitWord32Shr(Node* node) {
732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitWord32Shift(this, node, kX64Shr32);
733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
735f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochnamespace {
736f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochbool TryMatchLoadWord64AndShiftRight(InstructionSelector* selector, Node* node,
737f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                     InstructionCode opcode) {
738f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DCHECK(IrOpcode::kWord64Sar == node->opcode() ||
739f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch         IrOpcode::kWord64Shr == node->opcode());
740f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  X64OperandGenerator g(selector);
7413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  Int64BinopMatcher m(node);
742f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (selector->CanCover(m.node(), m.left().node()) && m.left().IsLoad() &&
7433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      m.right().Is(32)) {
7443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // Just load and sign-extend the interesting 4 bytes instead. This happens,
7453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // for example, when we're loading and untagging SMIs.
746f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    BaseWithIndexAndDisplacement64Matcher mleft(m.left().node(),
747f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                                AddressOption::kAllowAll);
7483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (mleft.matches() && (mleft.displacement() == nullptr ||
7493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                            g.CanBeImmediate(mleft.displacement()))) {
7503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      size_t input_count = 0;
7513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      InstructionOperand inputs[3];
7523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      AddressingMode mode = g.GetEffectiveAddressMemoryOperand(
7533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          m.left().node(), inputs, &input_count);
7543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (mleft.displacement() == nullptr) {
7553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // Make sure that the addressing mode indicates the presence of an
7563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // immediate displacement. It seems that we never use M1 and M2, but we
7573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // handle them here anyways.
7583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        switch (mode) {
7593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          case kMode_MR:
7603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            mode = kMode_MRI;
7613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            break;
7623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          case kMode_MR1:
7633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            mode = kMode_MR1I;
7643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            break;
7653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          case kMode_MR2:
7663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            mode = kMode_MR2I;
7673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            break;
7683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          case kMode_MR4:
7693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            mode = kMode_MR4I;
7703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            break;
7713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          case kMode_MR8:
7723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            mode = kMode_MR8I;
7733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            break;
7743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          case kMode_M1:
7753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            mode = kMode_M1I;
7763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            break;
7773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          case kMode_M2:
7783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            mode = kMode_M2I;
7793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            break;
7803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          case kMode_M4:
7813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            mode = kMode_M4I;
7823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            break;
7833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          case kMode_M8:
7843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            mode = kMode_M8I;
7853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            break;
7863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          case kMode_None:
7873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          case kMode_MRI:
7883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          case kMode_MR1I:
7893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          case kMode_MR2I:
7903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          case kMode_MR4I:
7913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          case kMode_MR8I:
7923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          case kMode_M1I:
7933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          case kMode_M2I:
7943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          case kMode_M4I:
7953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          case kMode_M8I:
796f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          case kMode_Root:
7973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch            UNREACHABLE();
7983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        }
7993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        inputs[input_count++] = ImmediateOperand(ImmediateOperand::INLINE, 4);
8003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      } else {
801f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        int32_t displacement = g.GetImmediateIntegerValue(mleft.displacement());
802f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        inputs[input_count - 1] =
803f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            ImmediateOperand(ImmediateOperand::INLINE, displacement + 4);
8043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
8053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      InstructionOperand outputs[] = {g.DefineAsRegister(node)};
806f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      InstructionCode code = opcode | AddressingModeField::encode(mode);
807f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      selector->Emit(code, 1, outputs, input_count, inputs);
808f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return true;
809f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
810f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
811f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return false;
812f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
813f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}  // namespace
814f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
815f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InstructionSelector::VisitWord64Shr(Node* node) {
816f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (TryMatchLoadWord64AndShiftRight(this, node, kX64Movl)) return;
817f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  VisitWord64Shift(this, node, kX64Shr);
818f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
819f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
820f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InstructionSelector::VisitWord32Sar(Node* node) {
821f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  X64OperandGenerator g(this);
822f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Int32BinopMatcher m(node);
823f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (CanCover(m.node(), m.left().node()) && m.left().IsWord32Shl()) {
824f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Int32BinopMatcher mleft(m.left().node());
825f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (mleft.right().Is(16) && m.right().Is(16)) {
826f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Emit(kX64Movsxwl, g.DefineAsRegister(node), g.Use(mleft.left().node()));
827f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return;
828f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    } else if (mleft.right().Is(24) && m.right().Is(24)) {
829f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Emit(kX64Movsxbl, g.DefineAsRegister(node), g.Use(mleft.left().node()));
8303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      return;
8313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
8323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
833f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  VisitWord32Shift(this, node, kX64Sar32);
834f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
835f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
836f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InstructionSelector::VisitWord64Sar(Node* node) {
837f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (TryMatchLoadWord64AndShiftRight(this, node, kX64Movsxlq)) return;
838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitWord64Shift(this, node, kX64Sar);
839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitWord32Ror(Node* node) {
843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitWord32Shift(this, node, kX64Ror32);
844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitWord64Ror(Node* node) {
848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitWord64Shift(this, node, kX64Ror);
849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
851109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid InstructionSelector::VisitWord32ReverseBits(Node* node) { UNREACHABLE(); }
852109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
853109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
854109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid InstructionSelector::VisitWord64ReverseBits(Node* node) { UNREACHABLE(); }
855109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
856f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InstructionSelector::VisitWord64ReverseBytes(Node* node) { UNREACHABLE(); }
857f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
858f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InstructionSelector::VisitWord32ReverseBytes(Node* node) { UNREACHABLE(); }
859109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitInt32Add(Node* node) {
861958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  X64OperandGenerator g(this);
862958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
863958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Try to match the Add to a leal pattern
864958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  BaseWithIndexAndDisplacement32Matcher m(node);
865958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (m.matches() &&
866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      (m.displacement() == nullptr || g.CanBeImmediate(m.displacement()))) {
867958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    EmitLea(this, kX64Lea32, node, m.index(), m.scale(), m.base(),
868f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            m.displacement(), m.displacement_mode());
869958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return;
870958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
871958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
872958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // No leal pattern match, use addl
873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitBinop(this, node, kX64Add32);
874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitInt64Add(Node* node) {
878f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  X64OperandGenerator g(this);
879f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
880f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Try to match the Add to a leaq pattern
881f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  BaseWithIndexAndDisplacement64Matcher m(node);
882f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (m.matches() &&
883f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      (m.displacement() == nullptr || g.CanBeImmediate(m.displacement()))) {
884f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    EmitLea(this, kX64Lea, node, m.index(), m.scale(), m.base(),
885f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            m.displacement(), m.displacement_mode());
886f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return;
887f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
888f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
889f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // No leal pattern match, use addq
890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitBinop(this, node, kX64Add);
891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitInt64AddWithOverflow(Node* node) {
895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
8963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
8973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return VisitBinop(this, node, kX64Add, &cont);
898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FlagsContinuation cont;
900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitBinop(this, node, kX64Add, &cont);
901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitInt32Sub(Node* node) {
905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  X64OperandGenerator g(this);
906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Int32BinopMatcher m(node);
907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (m.left().Is(0)) {
908958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Emit(kX64Neg32, g.DefineSameAsFirst(node), g.UseRegister(m.right().node()));
909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
910958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (m.right().HasValue() && g.CanBeImmediate(m.right().node())) {
911958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // Turn subtractions of constant values into immediate "leal" instructions
912958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // by negating the value.
913958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      Emit(kX64Lea32 | AddressingModeField::encode(kMode_MRI),
914958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier           g.DefineAsRegister(node), g.UseRegister(m.left().node()),
915958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier           g.TempImmediate(-m.right().Value()));
916958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return;
917958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    VisitBinop(this, node, kX64Sub32);
919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitInt64Sub(Node* node) {
924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  X64OperandGenerator g(this);
925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Int64BinopMatcher m(node);
926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (m.left().Is(0)) {
927958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Emit(kX64Neg, g.DefineSameAsFirst(node), g.UseRegister(m.right().node()));
928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
929f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (m.right().HasValue() && g.CanBeImmediate(m.right().node())) {
930f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // Turn subtractions of constant values into immediate "leaq" instructions
931f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // by negating the value.
932f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Emit(kX64Lea | AddressingModeField::encode(kMode_MRI),
933f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch           g.DefineAsRegister(node), g.UseRegister(m.left().node()),
934f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch           g.TempImmediate(-static_cast<int32_t>(m.right().Value())));
935f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return;
936f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    VisitBinop(this, node, kX64Sub);
938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitInt64SubWithOverflow(Node* node) {
943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
9443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return VisitBinop(this, node, kX64Sub, &cont);
946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FlagsContinuation cont;
948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitBinop(this, node, kX64Sub, &cont);
949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
952958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace {
953958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
954958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid VisitMul(InstructionSelector* selector, Node* node, ArchOpcode opcode) {
955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  X64OperandGenerator g(selector);
956958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Int32BinopMatcher m(node);
957958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Node* left = m.left().node();
958958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Node* right = m.right().node();
959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (g.CanBeImmediate(right)) {
960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    selector->Emit(opcode, g.DefineAsRegister(node), g.Use(left),
961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   g.UseImmediate(right));
962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
963958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (g.CanBeBetterLeftOperand(right)) {
964958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      std::swap(left, right);
965958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left),
967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   g.Use(right));
968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
971958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid VisitMulHigh(InstructionSelector* selector, Node* node,
972958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                  ArchOpcode opcode) {
973958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  X64OperandGenerator g(selector);
974958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Node* left = node->InputAt(0);
975958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Node* right = node->InputAt(1);
976958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (selector->IsLive(left) && !selector->IsLive(right)) {
977958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    std::swap(left, right);
978958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
979109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  InstructionOperand temps[] = {g.TempRegister(rax)};
980958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // TODO(turbofan): We use UseUniqueRegister here to improve register
981958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // allocation.
982958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  selector->Emit(opcode, g.DefineAsFixed(node, rdx), g.UseFixed(left, rax),
983109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                 g.UseUniqueRegister(right), arraysize(temps), temps);
984958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
985958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
986958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
987958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid VisitDiv(InstructionSelector* selector, Node* node, ArchOpcode opcode) {
988958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  X64OperandGenerator g(selector);
989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand temps[] = {g.TempRegister(rdx)};
990958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  selector->Emit(
991958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      opcode, g.DefineAsFixed(node, rax), g.UseFixed(node->InputAt(0), rax),
992958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      g.UseUniqueRegister(node->InputAt(1)), arraysize(temps), temps);
993958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
994958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
995958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
996958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid VisitMod(InstructionSelector* selector, Node* node, ArchOpcode opcode) {
997958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  X64OperandGenerator g(selector);
998109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  InstructionOperand temps[] = {g.TempRegister(rax)};
999109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  selector->Emit(
1000109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      opcode, g.DefineAsFixed(node, rdx), g.UseFixed(node->InputAt(0), rax),
1001109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      g.UseUniqueRegister(node->InputAt(1)), arraysize(temps), temps);
1002958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1003958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1004958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}  // namespace
1005958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1006958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitInt32Mul(Node* node) {
1008958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Int32ScaleMatcher m(node, true);
1009958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (m.matches()) {
1010958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Node* index = node->InputAt(0);
1011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Node* base = m.power_of_two_plus_one() ? index : nullptr;
1012f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    EmitLea(this, kX64Lea32, node, index, m.scale(), base, nullptr,
1013f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            kPositiveDisplacement);
1014958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return;
1015958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitMul(this, node, kX64Imul32);
1017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1019f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InstructionSelector::VisitInt32MulWithOverflow(Node* node) {
1020f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // TODO(mvstanton): Use Int32ScaleMatcher somehow.
1021f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
1022f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
1023f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return VisitBinop(this, node, kX64Imul32, &cont);
1024f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1025f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  FlagsContinuation cont;
1026f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  VisitBinop(this, node, kX64Imul32, &cont);
1027f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitInt64Mul(Node* node) {
1030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitMul(this, node, kX64Imul);
1031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1033958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitInt32MulHigh(Node* node) {
1034958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitMulHigh(this, node, kX64ImulHigh32);
1035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitInt32Div(Node* node) {
1039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitDiv(this, node, kX64Idiv32);
1040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitInt64Div(Node* node) {
1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitDiv(this, node, kX64Idiv);
1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1048958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitUint32Div(Node* node) {
1049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitDiv(this, node, kX64Udiv32);
1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1053958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitUint64Div(Node* node) {
1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitDiv(this, node, kX64Udiv);
1055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitInt32Mod(Node* node) {
1059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitMod(this, node, kX64Idiv32);
1060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitInt64Mod(Node* node) {
1064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitMod(this, node, kX64Idiv);
1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1068958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitUint32Mod(Node* node) {
1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitMod(this, node, kX64Udiv32);
1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1073958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitUint64Mod(Node* node) {
1074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitMod(this, node, kX64Udiv);
1075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1078958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitUint32MulHigh(Node* node) {
1079958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitMulHigh(this, node, kX64UmulHigh32);
1080958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1081958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitTryTruncateFloat32ToInt64(Node* node) {
1083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  X64OperandGenerator g(this);
1084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0))};
1085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand outputs[2];
1086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t output_count = 0;
1087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  outputs[output_count++] = g.DefineAsRegister(node);
1088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* success_output = NodeProperties::FindProjection(node, 1);
1090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (success_output) {
1091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    outputs[output_count++] = g.DefineAsRegister(success_output);
1092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Emit(kSSEFloat32ToInt64, output_count, outputs, 1, inputs);
1095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitTryTruncateFloat64ToInt64(Node* node) {
1099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  X64OperandGenerator g(this);
1100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0))};
1101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand outputs[2];
1102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t output_count = 0;
1103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  outputs[output_count++] = g.DefineAsRegister(node);
1104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* success_output = NodeProperties::FindProjection(node, 1);
1106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (success_output) {
1107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    outputs[output_count++] = g.DefineAsRegister(success_output);
1108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Emit(kSSEFloat64ToInt64, output_count, outputs, 1, inputs);
1111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitTryTruncateFloat32ToUint64(Node* node) {
1115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  X64OperandGenerator g(this);
1116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0))};
1117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand outputs[2];
1118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t output_count = 0;
1119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  outputs[output_count++] = g.DefineAsRegister(node);
1120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* success_output = NodeProperties::FindProjection(node, 1);
1122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (success_output) {
1123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    outputs[output_count++] = g.DefineAsRegister(success_output);
1124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Emit(kSSEFloat32ToUint64, output_count, outputs, 1, inputs);
1127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitTryTruncateFloat64ToUint64(Node* node) {
1131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  X64OperandGenerator g(this);
1132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0))};
1133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand outputs[2];
1134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t output_count = 0;
1135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  outputs[output_count++] = g.DefineAsRegister(node);
1136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* success_output = NodeProperties::FindProjection(node, 1);
1138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (success_output) {
1139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    outputs[output_count++] = g.DefineAsRegister(success_output);
1140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Emit(kSSEFloat64ToUint64, output_count, outputs, 1, inputs);
1143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitChangeInt32ToInt64(Node* node) {
1147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  X64OperandGenerator g(this);
1148f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Node* const value = node->InputAt(0);
1149f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (value->opcode() == IrOpcode::kLoad && CanCover(node, value)) {
1150f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    LoadRepresentation load_rep = LoadRepresentationOf(value->op());
1151f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    MachineRepresentation rep = load_rep.representation();
1152f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    InstructionCode opcode = kArchNop;
1153f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    switch (rep) {
1154f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      case MachineRepresentation::kBit:  // Fall through.
1155f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      case MachineRepresentation::kWord8:
1156f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        opcode = load_rep.IsSigned() ? kX64Movsxbq : kX64Movzxbq;
1157f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        break;
1158f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      case MachineRepresentation::kWord16:
1159f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        opcode = load_rep.IsSigned() ? kX64Movsxwq : kX64Movzxwq;
1160f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        break;
1161f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      case MachineRepresentation::kWord32:
1162f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        opcode = load_rep.IsSigned() ? kX64Movsxlq : kX64Movl;
1163f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        break;
1164f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      default:
1165f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        UNREACHABLE();
1166f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        return;
1167f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
1168f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    InstructionOperand outputs[] = {g.DefineAsRegister(node)};
1169f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    size_t input_count = 0;
1170f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    InstructionOperand inputs[3];
1171f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    AddressingMode mode = g.GetEffectiveAddressMemoryOperand(
1172f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        node->InputAt(0), inputs, &input_count);
1173f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    opcode |= AddressingModeField::encode(mode);
1174f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Emit(opcode, 1, outputs, input_count, inputs);
1175f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  } else {
1176f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Emit(kX64Movsxlq, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
1177f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1180f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochnamespace {
1181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1182f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool ZeroExtendsWord32ToWord64(Node* node) {
1183f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  switch (node->opcode()) {
1184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case IrOpcode::kWord32And:
1185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case IrOpcode::kWord32Or:
1186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case IrOpcode::kWord32Xor:
1187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case IrOpcode::kWord32Shl:
1188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case IrOpcode::kWord32Shr:
1189958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case IrOpcode::kWord32Sar:
1190958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case IrOpcode::kWord32Ror:
1191958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case IrOpcode::kWord32Equal:
1192958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case IrOpcode::kInt32Add:
1193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case IrOpcode::kInt32Sub:
1194958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case IrOpcode::kInt32Mul:
1195958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case IrOpcode::kInt32MulHigh:
1196958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case IrOpcode::kInt32Div:
1197958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case IrOpcode::kInt32LessThan:
1198958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case IrOpcode::kInt32LessThanOrEqual:
1199958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case IrOpcode::kInt32Mod:
1200958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case IrOpcode::kUint32Div:
1201958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case IrOpcode::kUint32LessThan:
1202958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case IrOpcode::kUint32LessThanOrEqual:
1203958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    case IrOpcode::kUint32Mod:
1204f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case IrOpcode::kUint32MulHigh:
1205958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // These 32-bit operations implicitly zero-extend to 64-bit on x64, so the
1206958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // zero-extension is a no-op.
1207f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return true;
1208f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    case IrOpcode::kProjection: {
1209f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      Node* const value = node->InputAt(0);
1210f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      switch (value->opcode()) {
1211f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        case IrOpcode::kInt32AddWithOverflow:
1212f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        case IrOpcode::kInt32SubWithOverflow:
1213f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        case IrOpcode::kInt32MulWithOverflow:
1214f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          return true;
1215f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        default:
1216f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          return false;
1217f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      }
1218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1219c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case IrOpcode::kLoad: {
1220c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // The movzxbl/movsxbl/movzxwl/movsxwl operations implicitly zero-extend
1221c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // to 64-bit on x64,
1222c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // so the zero-extension is a no-op.
1223c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      LoadRepresentation load_rep = LoadRepresentationOf(node->op());
1224c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      switch (load_rep.representation()) {
1225c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        case MachineRepresentation::kWord8:
1226c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        case MachineRepresentation::kWord16:
1227c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          return true;
1228c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        default:
1229c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          return false;
1230c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      }
1231c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    }
1232958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    default:
1233f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      return false;
1234f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1235f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
1236f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1237f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}  // namespace
1238f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1239f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid InstructionSelector::VisitChangeUint32ToUint64(Node* node) {
1240f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  X64OperandGenerator g(this);
1241f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Node* value = node->InputAt(0);
1242f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (ZeroExtendsWord32ToWord64(value)) {
1243f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // These 32-bit operations implicitly zero-extend to 64-bit on x64, so the
1244f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // zero-extension is a no-op.
1245f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return EmitIdentity(node);
1246958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1247958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Emit(kX64Movl, g.DefineAsRegister(node), g.Use(value));
1248958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1249958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1250958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace {
1252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid VisitRO(InstructionSelector* selector, Node* node,
1254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             InstructionCode opcode) {
1255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  X64OperandGenerator g(selector);
1256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  selector->Emit(opcode, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
1257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid VisitRR(InstructionSelector* selector, Node* node,
1261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             InstructionCode opcode) {
1262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  X64OperandGenerator g(selector);
1263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  selector->Emit(opcode, g.DefineAsRegister(node),
1264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 g.UseRegister(node->InputAt(0)));
1265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1267f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid VisitRRO(InstructionSelector* selector, Node* node,
1268f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              InstructionCode opcode) {
1269f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  X64OperandGenerator g(selector);
1270f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  selector->Emit(opcode, g.DefineSameAsFirst(node),
1271f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                 g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
1272f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid VisitFloatBinop(InstructionSelector* selector, Node* node,
1275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                     ArchOpcode avx_opcode, ArchOpcode sse_opcode) {
1276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  X64OperandGenerator g(selector);
1277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand operand0 = g.UseRegister(node->InputAt(0));
1278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand operand1 = g.Use(node->InputAt(1));
1279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (selector->IsSupported(AVX)) {
1280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    selector->Emit(avx_opcode, g.DefineAsRegister(node), operand0, operand1);
1281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    selector->Emit(sse_opcode, g.DefineSameAsFirst(node), operand0, operand1);
1283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid VisitFloatUnop(InstructionSelector* selector, Node* node, Node* input,
1288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                    ArchOpcode avx_opcode, ArchOpcode sse_opcode) {
1289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  X64OperandGenerator g(selector);
1290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (selector->IsSupported(AVX)) {
1291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    selector->Emit(avx_opcode, g.DefineAsRegister(node), g.Use(input));
1292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    selector->Emit(sse_opcode, g.DefineSameAsFirst(node), g.UseRegister(input));
1294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace
1298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
129962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#define RO_OP_LIST(V)                                                    \
130062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V(Word64Clz, kX64Lzcnt)                                                \
130162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V(Word32Clz, kX64Lzcnt32)                                              \
130262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V(Word64Ctz, kX64Tzcnt)                                                \
130362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V(Word32Ctz, kX64Tzcnt32)                                              \
130462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V(Word64Popcnt, kX64Popcnt)                                            \
130562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V(Word32Popcnt, kX64Popcnt32)                                          \
130662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V(Float64Sqrt, kSSEFloat64Sqrt)                                        \
130762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V(Float32Sqrt, kSSEFloat32Sqrt)                                        \
130862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V(ChangeFloat64ToInt32, kSSEFloat64ToInt32)                            \
130962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V(ChangeFloat64ToUint32, kSSEFloat64ToUint32 | MiscField::encode(1))   \
131062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V(TruncateFloat64ToUint32, kSSEFloat64ToUint32 | MiscField::encode(0)) \
131162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V(TruncateFloat64ToFloat32, kSSEFloat64ToFloat32)                      \
131262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V(ChangeFloat32ToFloat64, kSSEFloat32ToFloat64)                        \
131362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V(TruncateFloat32ToInt32, kSSEFloat32ToInt32)                          \
131462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V(TruncateFloat32ToUint32, kSSEFloat32ToUint32)                        \
131562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V(ChangeInt32ToFloat64, kSSEInt32ToFloat64)                            \
131662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V(ChangeUint32ToFloat64, kSSEUint32ToFloat64)                          \
131762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V(RoundFloat64ToInt32, kSSEFloat64ToInt32)                             \
131862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V(RoundInt32ToFloat32, kSSEInt32ToFloat32)                             \
131962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V(RoundInt64ToFloat32, kSSEInt64ToFloat32)                             \
132062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V(RoundInt64ToFloat64, kSSEInt64ToFloat64)                             \
132162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V(RoundUint32ToFloat32, kSSEUint32ToFloat32)                           \
132262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V(BitcastFloat32ToInt32, kX64BitcastFI)                                \
132362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V(BitcastFloat64ToInt64, kX64BitcastDL)                                \
132462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V(BitcastInt32ToFloat32, kX64BitcastIF)                                \
132562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V(BitcastInt64ToFloat64, kX64BitcastLD)                                \
132662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V(Float64ExtractLowWord32, kSSEFloat64ExtractLowWord32)                \
132762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V(Float64ExtractHighWord32, kSSEFloat64ExtractHighWord32)
132862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
132962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#define RR_OP_LIST(V)                                                         \
133062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V(Float32RoundDown, kSSEFloat32Round | MiscField::encode(kRoundDown))       \
133162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V(Float64RoundDown, kSSEFloat64Round | MiscField::encode(kRoundDown))       \
133262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V(Float32RoundUp, kSSEFloat32Round | MiscField::encode(kRoundUp))           \
133362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V(Float64RoundUp, kSSEFloat64Round | MiscField::encode(kRoundUp))           \
133462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V(Float32RoundTruncate, kSSEFloat32Round | MiscField::encode(kRoundToZero)) \
133562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V(Float64RoundTruncate, kSSEFloat64Round | MiscField::encode(kRoundToZero)) \
133662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V(Float32RoundTiesEven,                                                     \
133762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    kSSEFloat32Round | MiscField::encode(kRoundToNearest))                    \
133862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  V(Float64RoundTiesEven, kSSEFloat64Round | MiscField::encode(kRoundToNearest))
133962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
134062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#define RO_VISITOR(Name, opcode)                      \
134162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  void InstructionSelector::Visit##Name(Node* node) { \
134262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    VisitRO(this, node, opcode);                      \
134362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
134462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochRO_OP_LIST(RO_VISITOR)
134562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#undef RO_VISITOR
134662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
134762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#define RR_VISITOR(Name, opcode)                      \
134862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  void InstructionSelector::Visit##Name(Node* node) { \
134962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    VisitRR(this, node, opcode);                      \
135062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
135162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochRR_OP_LIST(RR_VISITOR)
135262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#undef RR_VISITOR
1353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1354bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid InstructionSelector::VisitTruncateFloat64ToWord32(Node* node) {
1355bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  VisitRR(this, node, kArchTruncateDoubleToI);
1356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitTruncateInt64ToInt32(Node* node) {
1359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  X64OperandGenerator g(this);
1360958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Node* value = node->InputAt(0);
1361958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (CanCover(node, value)) {
1362958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    switch (value->opcode()) {
1363958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case IrOpcode::kWord64Sar:
1364958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case IrOpcode::kWord64Shr: {
1365958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        Int64BinopMatcher m(value);
1366958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        if (m.right().Is(32)) {
1367f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          if (TryMatchLoadWord64AndShiftRight(this, value, kX64Movl)) {
1368f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch            return EmitIdentity(node);
1369f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          }
1370958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          Emit(kX64Shr, g.DefineSameAsFirst(node),
1371958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier               g.UseRegister(m.left().node()), g.TempImmediate(32));
1372958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          return;
1373958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        }
1374958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        break;
1375958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
1376958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      default:
1377958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        break;
1378958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1379958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1380958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Emit(kX64Movl, g.DefineAsRegister(node), g.Use(value));
1381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitRoundUint64ToFloat32(Node* node) {
1384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  X64OperandGenerator g(this);
1385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand temps[] = {g.TempRegister()};
1386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Emit(kSSEUint64ToFloat32, g.DefineAsRegister(node), g.Use(node->InputAt(0)),
1387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       arraysize(temps), temps);
1388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitRoundUint64ToFloat64(Node* node) {
1392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  X64OperandGenerator g(this);
1393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand temps[] = {g.TempRegister()};
1394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Emit(kSSEUint64ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0)),
1395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       arraysize(temps), temps);
1396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32Add(Node* node) {
1399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitFloatBinop(this, node, kAVXFloat32Add, kSSEFloat32Add);
1400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32Sub(Node* node) {
1404bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  VisitFloatBinop(this, node, kAVXFloat32Sub, kSSEFloat32Sub);
1405bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
1406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32Mul(Node* node) {
1408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitFloatBinop(this, node, kAVXFloat32Mul, kSSEFloat32Mul);
1409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32Div(Node* node) {
1413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitFloatBinop(this, node, kAVXFloat32Div, kSSEFloat32Div);
1414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32Abs(Node* node) {
1418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitFloatUnop(this, node, node->InputAt(0), kAVXFloat32Abs, kSSEFloat32Abs);
1419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1422f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InstructionSelector::VisitFloat32Max(Node* node) {
1423f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  VisitRRO(this, node, kSSEFloat32Max);
1424f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1425f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1426f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InstructionSelector::VisitFloat32Min(Node* node) {
1427f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  VisitRRO(this, node, kSSEFloat32Min);
1428f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
1429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat64Add(Node* node) {
1431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitFloatBinop(this, node, kAVXFloat64Add, kSSEFloat64Add);
1432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitFloat64Sub(Node* node) {
1436bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  VisitFloatBinop(this, node, kAVXFloat64Sub, kSSEFloat64Sub);
1437bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
1438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitFloat64Mul(Node* node) {
1440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitFloatBinop(this, node, kAVXFloat64Mul, kSSEFloat64Mul);
1441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitFloat64Div(Node* node) {
1445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitFloatBinop(this, node, kAVXFloat64Div, kSSEFloat64Div);
1446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InstructionSelector::VisitFloat64Mod(Node* node) {
1450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  X64OperandGenerator g(this);
1451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand temps[] = {g.TempRegister(rax)};
1452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Emit(kSSEFloat64Mod, g.DefineSameAsFirst(node),
1453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)), 1,
1454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       temps);
1455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat64Max(Node* node) {
1459f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  VisitRRO(this, node, kSSEFloat64Max);
1460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat64Min(Node* node) {
1464f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  VisitRRO(this, node, kSSEFloat64Min);
1465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat64Abs(Node* node) {
1469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitFloatUnop(this, node, node->InputAt(0), kAVXFloat64Abs, kSSEFloat64Abs);
1470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1473958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitFloat64RoundTiesAway(Node* node) {
1474958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  UNREACHABLE();
1475958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1476958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1477958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1478f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InstructionSelector::VisitFloat32Neg(Node* node) {
1479f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  VisitFloatUnop(this, node, node->InputAt(0), kAVXFloat32Neg, kSSEFloat32Neg);
1480f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
148113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
1482f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid InstructionSelector::VisitFloat64Neg(Node* node) {
1483f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  VisitFloatUnop(this, node, node->InputAt(0), kAVXFloat64Neg, kSSEFloat64Neg);
1484f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch}
148513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
148613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid InstructionSelector::VisitFloat64Ieee754Binop(Node* node,
148713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                                   InstructionCode opcode) {
148813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  X64OperandGenerator g(this);
148913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Emit(opcode, g.DefineAsFixed(node, xmm0), g.UseFixed(node->InputAt(0), xmm0),
149013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch       g.UseFixed(node->InputAt(1), xmm1))
149113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ->MarkAsCall();
149213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
149313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
149413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid InstructionSelector::VisitFloat64Ieee754Unop(Node* node,
149513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                                  InstructionCode opcode) {
149613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  X64OperandGenerator g(this);
149713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Emit(opcode, g.DefineAsFixed(node, xmm0), g.UseFixed(node->InputAt(0), xmm0))
149813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      ->MarkAsCall();
149913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
1500958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::EmitPrepareArguments(
1502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ZoneVector<PushParameter>* arguments, const CallDescriptor* descriptor,
1503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Node* node) {
1504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  X64OperandGenerator g(this);
1505958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Prepare for C function call.
1507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (descriptor->IsCFunctionCall()) {
1508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Emit(kArchPrepareCallCFunction |
1509f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch             MiscField::encode(static_cast<int>(descriptor->ParameterCount())),
1510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         0, nullptr, 0, nullptr);
1511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Poke any stack arguments.
1513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (size_t n = 0; n < arguments->size(); ++n) {
1514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      PushParameter input = (*arguments)[n];
1515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (input.node()) {
1516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int slot = static_cast<int>(n);
1517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        InstructionOperand value = g.CanBeImmediate(input.node())
1518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       ? g.UseImmediate(input.node())
1519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       : g.UseRegister(input.node());
1520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Emit(kX64Poke | MiscField::encode(slot), g.NoOutput(), value);
1521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Push any stack arguments.
152562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int effect_level = GetEffectLevel(node);
1526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (PushParameter input : base::Reversed(*arguments)) {
152762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      Node* input_node = input.node();
152862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (g.CanBeImmediate(input_node)) {
152962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        Emit(kX64Push, g.NoOutput(), g.UseImmediate(input_node));
153062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      } else if (IsSupported(ATOM) ||
153162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                 sequence()->IsFP(GetVirtualRegister(input_node))) {
153262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        // TODO(titzer): X64Push cannot handle stack->stack double moves
153362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        // because there is no way to encode fixed double slots.
153462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        Emit(kX64Push, g.NoOutput(), g.UseRegister(input_node));
153562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      } else if (g.CanBeMemoryOperand(kX64Push, node, input_node,
153662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                      effect_level)) {
153762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        InstructionOperand outputs[1];
153862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        InstructionOperand inputs[4];
153962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        size_t input_count = 0;
154062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        InstructionCode opcode = kX64Push;
154162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        AddressingMode mode = g.GetEffectiveAddressMemoryOperand(
154262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            input_node, inputs, &input_count);
154362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        opcode |= AddressingModeField::encode(mode);
154462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        Emit(opcode, 0, outputs, input_count, inputs);
154562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      } else {
154662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        Emit(kX64Push, g.NoOutput(), g.Use(input_node));
154762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      }
1548958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1549958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool InstructionSelector::IsTailCallAddressImmediate() { return true; }
1554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
15553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochint InstructionSelector::GetTempsCountForTailCallFromJSFunction() { return 3; }
1556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace {
1558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1559109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid VisitCompareWithMemoryOperand(InstructionSelector* selector,
1560109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                   InstructionCode opcode, Node* left,
1561109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                   InstructionOperand right,
1562109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                   FlagsContinuation* cont) {
1563109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DCHECK(left->opcode() == IrOpcode::kLoad);
1564109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  X64OperandGenerator g(selector);
1565109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  size_t input_count = 0;
1566109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  InstructionOperand inputs[6];
1567109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  AddressingMode addressing_mode =
1568109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      g.GetEffectiveAddressMemoryOperand(left, inputs, &input_count);
1569109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  opcode |= AddressingModeField::encode(addressing_mode);
1570109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  opcode = cont->Encode(opcode);
1571109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  inputs[input_count++] = right;
1572109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1573109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  if (cont->IsBranch()) {
1574109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    inputs[input_count++] = g.Label(cont->true_block());
1575109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    inputs[input_count++] = g.Label(cont->false_block());
1576109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    selector->Emit(opcode, 0, nullptr, input_count, inputs);
15773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  } else if (cont->IsDeoptimize()) {
15783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    selector->EmitDeoptimize(opcode, 0, nullptr, input_count, inputs,
157962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                             cont->kind(), cont->reason(), cont->frame_state());
158062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else if (cont->IsSet()) {
1581109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    InstructionOperand output = g.DefineAsRegister(cont->result());
1582109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    selector->Emit(opcode, 1, &output, input_count, inputs);
158362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else {
158462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    DCHECK(cont->IsTrap());
158562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    inputs[input_count++] = g.UseImmediate(cont->trap_id());
158662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    selector->Emit(opcode, 0, nullptr, input_count, inputs);
1587109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
1588109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
1589109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Shared routine for multiple compare operations.
1591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid VisitCompare(InstructionSelector* selector, InstructionCode opcode,
1592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  InstructionOperand left, InstructionOperand right,
1593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  FlagsContinuation* cont) {
1594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  X64OperandGenerator g(selector);
1595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  opcode = cont->Encode(opcode);
1596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (cont->IsBranch()) {
1597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    selector->Emit(opcode, g.NoOutput(), left, right,
1598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                   g.Label(cont->true_block()), g.Label(cont->false_block()));
15993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  } else if (cont->IsDeoptimize()) {
160062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    selector->EmitDeoptimize(opcode, g.NoOutput(), left, right, cont->kind(),
160162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                             cont->reason(), cont->frame_state());
160262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else if (cont->IsSet()) {
1603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right);
160462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  } else {
160562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    DCHECK(cont->IsTrap());
160662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    selector->Emit(opcode, g.NoOutput(), left, right,
160762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                   g.UseImmediate(cont->trap_id()));
1608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1612958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Shared routine for multiple compare operations.
1613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid VisitCompare(InstructionSelector* selector, InstructionCode opcode,
1614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  Node* left, Node* right, FlagsContinuation* cont,
1615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  bool commutative) {
1616958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  X64OperandGenerator g(selector);
1617958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (commutative && g.CanBeBetterLeftOperand(right)) {
1618958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    std::swap(left, right);
1619958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1620958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitCompare(selector, opcode, g.UseRegister(left), g.Use(right), cont);
1621958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1622958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
162362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochMachineType MachineTypeForNarrow(Node* node, Node* hint_node) {
162462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (hint_node->opcode() == IrOpcode::kLoad) {
162562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    MachineType hint = LoadRepresentationOf(hint_node->op());
162662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (node->opcode() == IrOpcode::kInt32Constant ||
162762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        node->opcode() == IrOpcode::kInt64Constant) {
162862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      int64_t constant = node->opcode() == IrOpcode::kInt32Constant
162962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                             ? OpParameter<int32_t>(node)
163062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                             : OpParameter<int64_t>(node);
163162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (hint == MachineType::Int8()) {
163262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        if (constant >= std::numeric_limits<int8_t>::min() &&
163362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            constant <= std::numeric_limits<int8_t>::max()) {
163462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          return hint;
163562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        }
163662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      } else if (hint == MachineType::Uint8()) {
163762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        if (constant >= std::numeric_limits<uint8_t>::min() &&
163862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            constant <= std::numeric_limits<uint8_t>::max()) {
163962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          return hint;
164062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        }
164162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      } else if (hint == MachineType::Int16()) {
164262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        if (constant >= std::numeric_limits<int16_t>::min() &&
164362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            constant <= std::numeric_limits<int16_t>::max()) {
164462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          return hint;
164562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        }
164662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      } else if (hint == MachineType::Uint16()) {
164762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        if (constant >= std::numeric_limits<uint16_t>::min() &&
164862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch            constant <= std::numeric_limits<uint16_t>::max()) {
164962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch          return hint;
165062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        }
165162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      } else if (hint == MachineType::Int32()) {
165262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        return hint;
165362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      } else if (hint == MachineType::Uint32()) {
165462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        if (constant >= 0) return hint;
165562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      }
165662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
165762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
165862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  return node->opcode() == IrOpcode::kLoad ? LoadRepresentationOf(node->op())
165962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                           : MachineType::None();
166062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
166162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
16623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch// Tries to match the size of the given opcode to that of the operands, if
16633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch// possible.
16643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben MurdochInstructionCode TryNarrowOpcodeSize(InstructionCode opcode, Node* left,
1665f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                    Node* right, FlagsContinuation* cont) {
166662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // TODO(epertoso): we can probably get some size information out phi nodes.
16673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // If the load representations don't match, both operands will be
16683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // zero/sign-extended to 32bit.
166962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  MachineType left_type = MachineTypeForNarrow(left, right);
167062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  MachineType right_type = MachineTypeForNarrow(right, left);
1671f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (left_type == right_type) {
1672f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    switch (left_type.representation()) {
1673f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      case MachineRepresentation::kBit:
1674f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      case MachineRepresentation::kWord8: {
1675f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        if (opcode == kX64Test32) return kX64Test8;
1676f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        if (opcode == kX64Cmp32) {
1677f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          if (left_type.semantic() == MachineSemantic::kUint32) {
1678f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            cont->OverwriteUnsignedIfSigned();
1679f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          } else {
1680f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            CHECK_EQ(MachineSemantic::kInt32, left_type.semantic());
1681f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          }
1682f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          return kX64Cmp8;
1683f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        }
1684f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        break;
1685f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      }
1686f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      case MachineRepresentation::kWord16:
1687f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        if (opcode == kX64Test32) return kX64Test16;
1688f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        if (opcode == kX64Cmp32) {
1689f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          if (left_type.semantic() == MachineSemantic::kUint32) {
1690f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            cont->OverwriteUnsignedIfSigned();
1691f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          } else {
1692f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            CHECK_EQ(MachineSemantic::kInt32, left_type.semantic());
1693f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          }
1694f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch          return kX64Cmp16;
1695f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        }
1696f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        break;
1697f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      default:
1698f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        break;
1699f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
17003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
1701f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return opcode;
17023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
17033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
1704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Shared routine for multiple word compare operations.
1705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid VisitWordCompare(InstructionSelector* selector, Node* node,
1706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                      InstructionCode opcode, FlagsContinuation* cont) {
1707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  X64OperandGenerator g(selector);
1708109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Node* left = node->InputAt(0);
1709109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Node* right = node->InputAt(1);
1710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1711f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  opcode = TryNarrowOpcodeSize(opcode, left, right, cont);
17123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
17133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // If one of the two inputs is an immediate, make sure it's on the right, or
17143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // if one of the two inputs is a memory operand, make sure it's on the left.
1715bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  int effect_level = selector->GetEffectLevel(node);
1716bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (cont->IsBranch()) {
1717bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    effect_level = selector->GetEffectLevel(
1718bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        cont->true_block()->PredecessorAt(0)->control_input());
1719bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
1720bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
17213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if ((!g.CanBeImmediate(right) && g.CanBeImmediate(left)) ||
1722bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      (g.CanBeMemoryOperand(opcode, node, right, effect_level) &&
1723bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch       !g.CanBeMemoryOperand(opcode, node, left, effect_level))) {
1724109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute();
1725109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    std::swap(left, right);
1726109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
1727109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1728109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Match immediates on right side of comparison.
1729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (g.CanBeImmediate(right)) {
1730bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (g.CanBeMemoryOperand(opcode, node, left, effect_level)) {
1731109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return VisitCompareWithMemoryOperand(selector, opcode, left,
1732109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                           g.UseImmediate(right), cont);
1733109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
1734109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return VisitCompare(selector, opcode, g.Use(left), g.UseImmediate(right),
1735109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                        cont);
1736109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
1737109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
17383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Match memory operands on left side of comparison.
1739bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (g.CanBeMemoryOperand(opcode, node, left, effect_level)) {
17403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return VisitCompareWithMemoryOperand(selector, opcode, left,
17413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                         g.UseRegister(right), cont);
17423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
17433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
1744109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return VisitCompare(selector, opcode, left, right, cont,
1745109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                      node->op()->HasProperty(Operator::kCommutative));
1746109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
1747f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch
1748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Shared routine for 64-bit word comparison operations.
1749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid VisitWord64Compare(InstructionSelector* selector, Node* node,
1750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                        FlagsContinuation* cont) {
1751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  X64OperandGenerator g(selector);
1752c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (selector->CanUseRootsRegister()) {
1753c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    Heap* const heap = selector->isolate()->heap();
1754c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    Heap::RootListIndex root_index;
1755c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    HeapObjectBinopMatcher m(node);
1756c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    if (m.right().HasValue() &&
1757c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        heap->IsRootHandle(m.right().Value(), &root_index)) {
1758c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute();
1759c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      InstructionCode opcode =
1760c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          kX64Cmp | AddressingModeField::encode(kMode_Root);
1761c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      return VisitCompare(
1762c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          selector, opcode,
1763c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          g.TempImmediate((root_index * kPointerSize) - kRootRegisterBias),
1764c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          g.UseRegister(m.left().node()), cont);
1765c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    } else if (m.left().HasValue() &&
1766c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch               heap->IsRootHandle(m.left().Value(), &root_index)) {
1767c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      InstructionCode opcode =
1768c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          kX64Cmp | AddressingModeField::encode(kMode_Root);
1769c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      return VisitCompare(
1770c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          selector, opcode,
1771c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          g.TempImmediate((root_index * kPointerSize) - kRootRegisterBias),
1772c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          g.UseRegister(m.right().node()), cont);
1773c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    }
1774c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
1775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Int64BinopMatcher m(node);
1776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (m.left().IsLoad() && m.right().IsLoadStackPointer()) {
1777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LoadMatcher<ExternalReferenceMatcher> mleft(m.left().node());
1778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ExternalReference js_stack_limit =
1779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        ExternalReference::address_of_stack_limit(selector->isolate());
1780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (mleft.object().Is(js_stack_limit) && mleft.index().Is(0)) {
1781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Compare(Load(js_stack_limit), LoadStackPointer)
1782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute();
1783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionCode opcode = cont->Encode(kX64StackCheck);
1784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (cont->IsBranch()) {
1785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        selector->Emit(opcode, g.NoOutput(), g.Label(cont->true_block()),
1786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       g.Label(cont->false_block()));
17873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      } else if (cont->IsDeoptimize()) {
178862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        selector->EmitDeoptimize(opcode, 0, nullptr, 0, nullptr, cont->kind(),
178962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                 cont->reason(), cont->frame_state());
179062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      } else if (cont->IsSet()) {
1791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        selector->Emit(opcode, g.DefineAsRegister(cont->result()));
179262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      } else {
179362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        DCHECK(cont->IsTrap());
179462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        selector->Emit(opcode, g.NoOutput(), g.UseImmediate(cont->trap_id()));
1795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return;
1797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitWordCompare(selector, node, kX64Cmp, cont);
1800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1803958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Shared routine for comparison with zero.
1804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid VisitCompareZero(InstructionSelector* selector, Node* node,
1805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                      InstructionCode opcode, FlagsContinuation* cont) {
1806958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  X64OperandGenerator g(selector);
1807958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitCompare(selector, opcode, g.Use(node), g.TempImmediate(0), cont);
1808958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1809958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1810958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Shared routine for multiple float32 compare operations (inputs commuted).
1812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid VisitFloat32Compare(InstructionSelector* selector, Node* node,
1813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         FlagsContinuation* cont) {
1814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* const left = node->InputAt(0);
1815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* const right = node->InputAt(1);
1816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionCode const opcode =
1817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      selector->IsSupported(AVX) ? kAVXFloat32Cmp : kSSEFloat32Cmp;
1818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitCompare(selector, opcode, right, left, cont, false);
1819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Shared routine for multiple float64 compare operations (inputs commuted).
1823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid VisitFloat64Compare(InstructionSelector* selector, Node* node,
1824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         FlagsContinuation* cont) {
1825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* const left = node->InputAt(0);
1826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* const right = node->InputAt(1);
1827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionCode const opcode =
1828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      selector->IsSupported(AVX) ? kAVXFloat64Cmp : kSSEFloat64Cmp;
1829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitCompare(selector, opcode, right, left, cont, false);
1830958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1831958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
18323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch// Shared routine for word comparison against zero.
18333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid VisitWordCompareZero(InstructionSelector* selector, Node* user,
18343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                          Node* value, FlagsContinuation* cont) {
1835c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // Try to combine with comparisons against 0 by simply inverting the branch.
1836c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  while (value->opcode() == IrOpcode::kWord32Equal &&
1837c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch         selector->CanCover(user, value)) {
1838c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    Int32BinopMatcher m(value);
1839c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    if (!m.right().Is(0)) break;
1840c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
1841c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    user = value;
1842c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    value = m.left().node();
1843c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    cont->Negate();
1844c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
1845c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
1846c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (selector->CanCover(user, value)) {
1847958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    switch (value->opcode()) {
1848c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      case IrOpcode::kWord32Equal:
18493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        cont->OverwriteAndNegateIfEqual(kEqual);
18503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        return VisitWordCompare(selector, value, kX64Cmp32, cont);
1851958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case IrOpcode::kInt32LessThan:
18523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        cont->OverwriteAndNegateIfEqual(kSignedLessThan);
18533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        return VisitWordCompare(selector, value, kX64Cmp32, cont);
1854958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case IrOpcode::kInt32LessThanOrEqual:
18553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
18563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        return VisitWordCompare(selector, value, kX64Cmp32, cont);
1857958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case IrOpcode::kUint32LessThan:
18583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
18593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        return VisitWordCompare(selector, value, kX64Cmp32, cont);
1860958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case IrOpcode::kUint32LessThanOrEqual:
18613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
18623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        return VisitWordCompare(selector, value, kX64Cmp32, cont);
1863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case IrOpcode::kWord64Equal: {
18643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        cont->OverwriteAndNegateIfEqual(kEqual);
1865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Int64BinopMatcher m(value);
1866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (m.right().Is(0)) {
1867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          // Try to combine the branch with a comparison.
1868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Node* const user = m.node();
1869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Node* const value = m.left().node();
18703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          if (selector->CanCover(user, value)) {
1871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            switch (value->opcode()) {
1872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              case IrOpcode::kInt64Sub:
18733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                return VisitWord64Compare(selector, value, cont);
1874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              case IrOpcode::kWord64And:
18753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                return VisitWordCompare(selector, value, kX64Test, cont);
1876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              default:
1877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                break;
1878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            }
1879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
18803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          return VisitCompareZero(selector, value, kX64Cmp, cont);
1881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
18823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        return VisitWord64Compare(selector, value, cont);
1883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1884958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case IrOpcode::kInt64LessThan:
18853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        cont->OverwriteAndNegateIfEqual(kSignedLessThan);
18863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        return VisitWord64Compare(selector, value, cont);
1887958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case IrOpcode::kInt64LessThanOrEqual:
18883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
18893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        return VisitWord64Compare(selector, value, cont);
1890958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case IrOpcode::kUint64LessThan:
18913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
18923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        return VisitWord64Compare(selector, value, cont);
1893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case IrOpcode::kUint64LessThanOrEqual:
18943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
18953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        return VisitWord64Compare(selector, value, cont);
1896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case IrOpcode::kFloat32Equal:
18973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        cont->OverwriteAndNegateIfEqual(kUnorderedEqual);
18983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        return VisitFloat32Compare(selector, value, cont);
1899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case IrOpcode::kFloat32LessThan:
19003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        cont->OverwriteAndNegateIfEqual(kUnsignedGreaterThan);
19013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        return VisitFloat32Compare(selector, value, cont);
1902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case IrOpcode::kFloat32LessThanOrEqual:
19033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        cont->OverwriteAndNegateIfEqual(kUnsignedGreaterThanOrEqual);
19043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        return VisitFloat32Compare(selector, value, cont);
1905958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case IrOpcode::kFloat64Equal:
19063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        cont->OverwriteAndNegateIfEqual(kUnorderedEqual);
19073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        return VisitFloat64Compare(selector, value, cont);
1908c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      case IrOpcode::kFloat64LessThan: {
1909c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        Float64BinopMatcher m(value);
1910c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        if (m.left().Is(0.0) && m.right().IsFloat64Abs()) {
1911c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          // This matches the pattern
1912c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          //
1913c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          //   Float64LessThan(#0.0, Float64Abs(x))
1914c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          //
1915c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          // which TurboFan generates for NumberToBoolean in the general case,
1916c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          // and which evaluates to false if x is 0, -0 or NaN. We can compile
1917c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          // this to a simple (v)ucomisd using not_equal flags condition, which
1918c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          // avoids the costly Float64Abs.
1919c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          cont->OverwriteAndNegateIfEqual(kNotEqual);
1920c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          InstructionCode const opcode =
1921c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch              selector->IsSupported(AVX) ? kAVXFloat64Cmp : kSSEFloat64Cmp;
1922c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          return VisitCompare(selector, opcode, m.left().node(),
1923c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                              m.right().InputAt(0), cont, false);
1924c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        }
19253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        cont->OverwriteAndNegateIfEqual(kUnsignedGreaterThan);
19263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        return VisitFloat64Compare(selector, value, cont);
1927c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      }
1928958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case IrOpcode::kFloat64LessThanOrEqual:
19293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        cont->OverwriteAndNegateIfEqual(kUnsignedGreaterThanOrEqual);
19303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        return VisitFloat64Compare(selector, value, cont);
1931958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case IrOpcode::kProjection:
1932958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        // Check if this is the overflow output projection of an
1933958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        // <Operation>WithOverflow node.
1934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (ProjectionIndexOf(value->op()) == 1u) {
1935958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          // We cannot combine the <Operation>WithOverflow with this branch
1936958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          // unless the 0th projection (the use of the actual value of the
1937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          // <Operation> is either nullptr, which means there's no use of the
1938958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          // actual value, or was already defined, which means it is scheduled
1939958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          // *AFTER* this branch).
1940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Node* const node = value->InputAt(0);
1941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Node* const result = NodeProperties::FindProjection(node, 0);
19423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          if (result == nullptr || selector->IsDefined(result)) {
1943958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            switch (node->opcode()) {
1944958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier              case IrOpcode::kInt32AddWithOverflow:
19453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                cont->OverwriteAndNegateIfEqual(kOverflow);
19463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                return VisitBinop(selector, node, kX64Add32, cont);
1947958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier              case IrOpcode::kInt32SubWithOverflow:
19483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                cont->OverwriteAndNegateIfEqual(kOverflow);
19493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                return VisitBinop(selector, node, kX64Sub32, cont);
1950f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              case IrOpcode::kInt32MulWithOverflow:
1951f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                cont->OverwriteAndNegateIfEqual(kOverflow);
1952f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                return VisitBinop(selector, node, kX64Imul32, cont);
1953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              case IrOpcode::kInt64AddWithOverflow:
19543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                cont->OverwriteAndNegateIfEqual(kOverflow);
19553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                return VisitBinop(selector, node, kX64Add, cont);
1956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              case IrOpcode::kInt64SubWithOverflow:
19573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                cont->OverwriteAndNegateIfEqual(kOverflow);
19583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                return VisitBinop(selector, node, kX64Sub, cont);
1959958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier              default:
1960958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                break;
1961958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            }
1962958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          }
1963958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        }
1964958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        break;
1965958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case IrOpcode::kInt32Sub:
19663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        return VisitWordCompare(selector, value, kX64Cmp32, cont);
1967958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      case IrOpcode::kWord32And:
19683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        return VisitWordCompare(selector, value, kX64Test32, cont);
1969958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      default:
1970958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        break;
1971958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1972958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1973958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1974958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Branch could not be combined with a compare, emit compare against 0.
19753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  VisitCompareZero(selector, value, kX64Cmp32, cont);
1976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
19783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}  // namespace
19793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
19803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
19813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                      BasicBlock* fbranch) {
19823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  FlagsContinuation cont(kNotEqual, tbranch, fbranch);
19833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  VisitWordCompareZero(this, branch, branch->InputAt(0), &cont);
19843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
19853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
19863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid InstructionSelector::VisitDeoptimizeIf(Node* node) {
198762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DeoptimizeParameters p = DeoptimizeParametersOf(node->op());
1988f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  FlagsContinuation cont = FlagsContinuation::ForDeoptimize(
198962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      kNotEqual, p.kind(), p.reason(), node->InputAt(1));
19903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  VisitWordCompareZero(this, node, node->InputAt(0), &cont);
19913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
19923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
19933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochvoid InstructionSelector::VisitDeoptimizeUnless(Node* node) {
199462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DeoptimizeParameters p = DeoptimizeParametersOf(node->op());
1995f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  FlagsContinuation cont = FlagsContinuation::ForDeoptimize(
199662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      kEqual, p.kind(), p.reason(), node->InputAt(1));
199762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  VisitWordCompareZero(this, node, node->InputAt(0), &cont);
199862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
199962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
200062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid InstructionSelector::VisitTrapIf(Node* node, Runtime::FunctionId func_id) {
200162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  FlagsContinuation cont =
200262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      FlagsContinuation::ForTrap(kNotEqual, func_id, node->InputAt(1));
200362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  VisitWordCompareZero(this, node, node->InputAt(0), &cont);
200462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
200562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
200662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid InstructionSelector::VisitTrapUnless(Node* node,
200762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                          Runtime::FunctionId func_id) {
200862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  FlagsContinuation cont =
200962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      FlagsContinuation::ForTrap(kEqual, func_id, node->InputAt(1));
20103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  VisitWordCompareZero(this, node, node->InputAt(0), &cont);
20113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
2012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) {
2014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  X64OperandGenerator g(this);
2015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand value_operand = g.UseRegister(node->InputAt(0));
2016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Emit either ArchTableSwitch or ArchLookupSwitch.
2018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t table_space_cost = 4 + sw.value_range;
2019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t table_time_cost = 3;
2020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t lookup_space_cost = 3 + 2 * sw.case_count;
2021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t lookup_time_cost = sw.case_count;
2022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (sw.case_count > 4 &&
2023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      table_space_cost + 3 * table_time_cost <=
2024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          lookup_space_cost + 3 * lookup_time_cost &&
2025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      sw.min_value > std::numeric_limits<int32_t>::min()) {
2026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand index_operand = g.TempRegister();
2027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (sw.min_value) {
2028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // The leal automatically zero extends, so result is a valid 64-bit index.
2029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Emit(kX64Lea32 | AddressingModeField::encode(kMode_MRI), index_operand,
2030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           value_operand, g.TempImmediate(-sw.min_value));
2031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
2032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Zero extend, because we use it as 64-bit index into the jump table.
2033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Emit(kX64Movl, index_operand, value_operand);
2034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Generate a table lookup.
2036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return EmitTableSwitch(sw, index_operand);
2037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Generate a sequence of conditional jumps.
2040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return EmitLookupSwitch(sw, value_operand);
2041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2044958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitWord32Equal(Node* const node) {
2045958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Node* user = node;
20463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node);
2047958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Int32BinopMatcher m(user);
2048958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (m.right().Is(0)) {
204962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return VisitWordCompareZero(this, m.node(), m.left().node(), &cont);
2050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2051958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitWordCompare(this, node, kX64Cmp32, &cont);
2052958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2054958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2055958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitInt32LessThan(Node* node) {
20563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  FlagsContinuation cont = FlagsContinuation::ForSet(kSignedLessThan, node);
2057958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitWordCompare(this, node, kX64Cmp32, &cont);
2058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2061958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitInt32LessThanOrEqual(Node* node) {
20623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  FlagsContinuation cont =
20633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      FlagsContinuation::ForSet(kSignedLessThanOrEqual, node);
2064958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitWordCompare(this, node, kX64Cmp32, &cont);
2065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2068958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitUint32LessThan(Node* node) {
20693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node);
2070958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitWordCompare(this, node, kX64Cmp32, &cont);
2071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2074958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitUint32LessThanOrEqual(Node* node) {
20753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  FlagsContinuation cont =
20763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node);
2077958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitWordCompare(this, node, kX64Cmp32, &cont);
2078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2081958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitWord64Equal(Node* const node) {
20823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node);
2083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Int64BinopMatcher m(node);
2084958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (m.right().Is(0)) {
2085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Try to combine the equality check with a comparison.
2086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Node* const user = m.node();
2087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Node* const value = m.left().node();
2088958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (CanCover(user, value)) {
2089958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      switch (value->opcode()) {
2090958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        case IrOpcode::kInt64Sub:
2091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          return VisitWord64Compare(this, value, &cont);
2092958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        case IrOpcode::kWord64And:
2093958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          return VisitWordCompare(this, value, kX64Test, &cont);
2094958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        default:
2095958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          break;
2096958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
2097958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitWord64Compare(this, node, &cont);
2100958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2103958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
2104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
21053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
21063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return VisitBinop(this, node, kX64Add32, &cont);
2107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2108958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  FlagsContinuation cont;
2109958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitBinop(this, node, kX64Add32, &cont);
2110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
2114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
21153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
2116958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return VisitBinop(this, node, kX64Sub32, &cont);
2117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2118958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  FlagsContinuation cont;
2119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitBinop(this, node, kX64Sub32, &cont);
2120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitInt64LessThan(Node* node) {
21243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  FlagsContinuation cont = FlagsContinuation::ForSet(kSignedLessThan, node);
2125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitWord64Compare(this, node, &cont);
2126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitInt64LessThanOrEqual(Node* node) {
21303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  FlagsContinuation cont =
21313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      FlagsContinuation::ForSet(kSignedLessThanOrEqual, node);
2132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitWord64Compare(this, node, &cont);
2133958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitUint64LessThan(Node* node) {
21373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node);
2138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitWord64Compare(this, node, &cont);
2139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitUint64LessThanOrEqual(Node* node) {
21433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  FlagsContinuation cont =
21443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node);
2145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitWord64Compare(this, node, &cont);
2146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32Equal(Node* node) {
21503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  FlagsContinuation cont = FlagsContinuation::ForSet(kUnorderedEqual, node);
2151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitFloat32Compare(this, node, &cont);
2152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32LessThan(Node* node) {
21563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  FlagsContinuation cont =
21573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      FlagsContinuation::ForSet(kUnsignedGreaterThan, node);
2158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitFloat32Compare(this, node, &cont);
2159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) {
21633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  FlagsContinuation cont =
21643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      FlagsContinuation::ForSet(kUnsignedGreaterThanOrEqual, node);
2165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VisitFloat32Compare(this, node, &cont);
2166958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2167958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2168958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2169958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitFloat64Equal(Node* node) {
21703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  FlagsContinuation cont = FlagsContinuation::ForSet(kUnorderedEqual, node);
2171958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitFloat64Compare(this, node, &cont);
2172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2173958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2174958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitFloat64LessThan(Node* node) {
2175c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Float64BinopMatcher m(node);
2176c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (m.left().Is(0.0) && m.right().IsFloat64Abs()) {
2177c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // This matches the pattern
2178c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    //
2179c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    //   Float64LessThan(#0.0, Float64Abs(x))
2180c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    //
2181c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // which TurboFan generates for NumberToBoolean in the general case,
2182c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // and which evaluates to false if x is 0, -0 or NaN. We can compile
2183c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // this to a simple (v)ucomisd using not_equal flags condition, which
2184c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // avoids the costly Float64Abs.
2185c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    FlagsContinuation cont = FlagsContinuation::ForSet(kNotEqual, node);
2186c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    InstructionCode const opcode =
2187c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        IsSupported(AVX) ? kAVXFloat64Cmp : kSSEFloat64Cmp;
2188c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return VisitCompare(this, opcode, m.left().node(), m.right().InputAt(0),
2189c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                        &cont, false);
2190c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
21913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  FlagsContinuation cont =
21923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      FlagsContinuation::ForSet(kUnsignedGreaterThan, node);
2193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitFloat64Compare(this, node, &cont);
2194958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2195958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2196958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
21973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  FlagsContinuation cont =
21983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      FlagsContinuation::ForSet(kUnsignedGreaterThanOrEqual, node);
2199958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VisitFloat64Compare(this, node, &cont);
2200958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2201958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat64InsertLowWord32(Node* node) {
2203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  X64OperandGenerator g(this);
2204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* left = node->InputAt(0);
2205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* right = node->InputAt(1);
2206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Float64Matcher mleft(left);
2207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (mleft.HasValue() && (bit_cast<uint64_t>(mleft.Value()) >> 32) == 0u) {
2208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Emit(kSSEFloat64LoadLowWord32, g.DefineAsRegister(node), g.Use(right));
2209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return;
2210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Emit(kSSEFloat64InsertLowWord32, g.DefineSameAsFirst(node),
2212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       g.UseRegister(left), g.Use(right));
2213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid InstructionSelector::VisitFloat64InsertHighWord32(Node* node) {
2217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  X64OperandGenerator g(this);
2218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* left = node->InputAt(0);
2219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Node* right = node->InputAt(1);
2220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Emit(kSSEFloat64InsertHighWord32, g.DefineSameAsFirst(node),
2221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       g.UseRegister(left), g.Use(right));
2222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
222413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid InstructionSelector::VisitFloat64SilenceNaN(Node* node) {
222513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  X64OperandGenerator g(this);
222613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Emit(kSSEFloat64SilenceNaN, g.DefineSameAsFirst(node),
222713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch       g.UseRegister(node->InputAt(0)));
222813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
222913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
2230bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid InstructionSelector::VisitAtomicLoad(Node* node) {
2231bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  LoadRepresentation load_rep = LoadRepresentationOf(node->op());
2232bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK(load_rep.representation() == MachineRepresentation::kWord8 ||
2233bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch         load_rep.representation() == MachineRepresentation::kWord16 ||
2234bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch         load_rep.representation() == MachineRepresentation::kWord32);
2235bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  USE(load_rep);
2236bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  VisitLoad(node);
2237bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
2238bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
2239bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid InstructionSelector::VisitAtomicStore(Node* node) {
2240bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  X64OperandGenerator g(this);
2241bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Node* base = node->InputAt(0);
2242bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Node* index = node->InputAt(1);
2243bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Node* value = node->InputAt(2);
2244bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
2245bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  MachineRepresentation rep = AtomicStoreRepresentationOf(node->op());
2246bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  ArchOpcode opcode = kArchNop;
2247bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  switch (rep) {
2248bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case MachineRepresentation::kWord8:
2249bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      opcode = kX64Xchgb;
2250bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      break;
2251bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case MachineRepresentation::kWord16:
2252bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      opcode = kX64Xchgw;
2253bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      break;
2254bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    case MachineRepresentation::kWord32:
2255bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      opcode = kX64Xchgl;
2256bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      break;
2257bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    default:
2258bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      UNREACHABLE();
2259bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      return;
2260bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
2261bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  AddressingMode addressing_mode;
2262bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  InstructionOperand inputs[4];
2263bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  size_t input_count = 0;
2264bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  inputs[input_count++] = g.UseUniqueRegister(base);
2265bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (g.CanBeImmediate(index)) {
2266bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    inputs[input_count++] = g.UseImmediate(index);
2267bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    addressing_mode = kMode_MRI;
2268bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  } else {
2269bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    inputs[input_count++] = g.UseUniqueRegister(index);
2270bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    addressing_mode = kMode_MR1;
2271bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
2272bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  inputs[input_count++] = g.UseUniqueRegister(value);
2273bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  InstructionCode code = opcode | AddressingModeField::encode(addressing_mode);
2274bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Emit(code, 0, static_cast<InstructionOperand*>(nullptr), input_count, inputs);
2275bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
2276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2277f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid InstructionSelector::VisitCreateInt32x4(Node* node) {
2278f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  X64OperandGenerator g(this);
2279f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Emit(kX64Int32x4Create, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
2280f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
2281f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2282f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid InstructionSelector::VisitInt32x4ExtractLane(Node* node) {
2283f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  X64OperandGenerator g(this);
228462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  int32_t lane = OpParameter<int32_t>(node);
2285f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Emit(kX64Int32x4ExtractLane, g.DefineAsRegister(node),
228662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch       g.UseRegister(node->InputAt(0)), g.UseImmediate(lane));
228762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
228862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
228962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid InstructionSelector::VisitInt32x4ReplaceLane(Node* node) {
229062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  X64OperandGenerator g(this);
229162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  int32_t lane = OpParameter<int32_t>(node);
229262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Emit(kX64Int32x4ReplaceLane, g.DefineSameAsFirst(node),
229362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch       g.UseRegister(node->InputAt(0)), g.UseImmediate(lane),
229462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch       g.Use(node->InputAt(1)));
229562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
229662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
229762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid InstructionSelector::VisitInt32x4Add(Node* node) {
229862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  X64OperandGenerator g(this);
229962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Emit(kX64Int32x4Add, g.DefineSameAsFirst(node),
230062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch       g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)));
230162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch}
230262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
230362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid InstructionSelector::VisitInt32x4Sub(Node* node) {
230462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  X64OperandGenerator g(this);
230562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  Emit(kX64Int32x4Sub, g.DefineSameAsFirst(node),
230662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch       g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)));
2307f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
2308f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2309958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// static
2310958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierMachineOperatorBuilder::Flags
2311958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierInstructionSelector::SupportedMachineOperatorFlags() {
2312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MachineOperatorBuilder::Flags flags =
2313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      MachineOperatorBuilder::kWord32ShiftIsSafe |
2314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      MachineOperatorBuilder::kWord32Ctz | MachineOperatorBuilder::kWord64Ctz;
2315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (CpuFeatures::IsSupported(POPCNT)) {
2316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    flags |= MachineOperatorBuilder::kWord32Popcnt |
2317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             MachineOperatorBuilder::kWord64Popcnt;
2318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2319958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (CpuFeatures::IsSupported(SSE4_1)) {
2320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    flags |= MachineOperatorBuilder::kFloat32RoundDown |
2321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             MachineOperatorBuilder::kFloat64RoundDown |
2322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             MachineOperatorBuilder::kFloat32RoundUp |
2323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             MachineOperatorBuilder::kFloat64RoundUp |
2324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             MachineOperatorBuilder::kFloat32RoundTruncate |
2325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             MachineOperatorBuilder::kFloat64RoundTruncate |
2326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             MachineOperatorBuilder::kFloat32RoundTiesEven |
2327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             MachineOperatorBuilder::kFloat64RoundTiesEven;
2328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return flags;
2330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
233213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch// static
233313e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochMachineOperatorBuilder::AlignmentRequirements
233413e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochInstructionSelector::AlignmentRequirements() {
233513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  return MachineOperatorBuilder::AlignmentRequirements::
233613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      FullUnalignedAccessSupport();
233713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch}
233813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
2339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace compiler
2340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace internal
2341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace v8
2342