17d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Copyright 2014 the V8 project authors. All rights reserved.
27d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be
37d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// found in the LICENSE file.
47d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
57d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/instruction-selector-impl.h"
67d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/node-matchers.h"
77d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
87d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace v8 {
97d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace internal {
107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace compiler {
117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgenum ImmediateMode {
13e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  kArithmeticImm,  // 12 bit unsigned immediate shifted left 0 or 12 bits
14e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  kShift32Imm,     // 0 - 31
15e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  kShift64Imm,     // 0 - 63
167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  kLogical32Imm,
177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  kLogical64Imm,
18b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  kLoadStoreImm8,   // signed 8 bit or 12 bit unsigned scaled by access size
19b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  kLoadStoreImm16,
20b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  kLoadStoreImm32,
21b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  kLoadStoreImm64,
227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  kNoImmediate
237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org};
247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Adds Arm64-specific methods for generating operands.
27ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.orgclass Arm64OperandGenerator FINAL : public OperandGenerator {
287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org public:
297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  explicit Arm64OperandGenerator(InstructionSelector* selector)
307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      : OperandGenerator(selector) {}
317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  InstructionOperand* UseOperand(Node* node, ImmediateMode mode) {
337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    if (CanBeImmediate(node, mode)) {
347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return UseImmediate(node);
357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return UseRegister(node);
377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  bool CanBeImmediate(Node* node, ImmediateMode mode) {
4006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    int64_t value;
4106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    if (node->opcode() == IrOpcode::kInt32Constant)
4206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org      value = OpParameter<int32_t>(node);
4306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    else if (node->opcode() == IrOpcode::kInt64Constant)
4406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org      value = OpParameter<int64_t>(node);
4506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    else
4606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org      return false;
477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    unsigned ignored;
487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    switch (mode) {
497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      case kLogical32Imm:
507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        // TODO(dcarney): some unencodable values can be handled by
517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        // switching instructions.
527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return Assembler::IsImmLogical(static_cast<uint64_t>(value), 32,
537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                                       &ignored, &ignored, &ignored);
547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      case kLogical64Imm:
557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return Assembler::IsImmLogical(static_cast<uint64_t>(value), 64,
567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                                       &ignored, &ignored, &ignored);
57e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org      case kArithmeticImm:
587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        // TODO(dcarney): -values can be handled by instruction swapping
597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return Assembler::IsImmAddSub(value);
607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      case kShift32Imm:
61e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org        return 0 <= value && value < 32;
627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      case kShift64Imm:
63e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org        return 0 <= value && value < 64;
64b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      case kLoadStoreImm8:
65b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org        return IsLoadStoreImmediate(value, LSByte);
66b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      case kLoadStoreImm16:
67b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org        return IsLoadStoreImmediate(value, LSHalfword);
68b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      case kLoadStoreImm32:
69b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org        return IsLoadStoreImmediate(value, LSWord);
70b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      case kLoadStoreImm64:
71b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org        return IsLoadStoreImmediate(value, LSDoubleWord);
727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      case kNoImmediate:
737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return false;
747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return false;
767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
77b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
78b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org private:
79b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  bool IsLoadStoreImmediate(int64_t value, LSDataSize size) {
80b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    return Assembler::IsImmLSScaled(value, size) ||
81b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org           Assembler::IsImmLSUnscaled(value);
82b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  }
837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org};
847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgstatic void VisitRRR(InstructionSelector* selector, ArchOpcode opcode,
877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                     Node* node) {
887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Arm64OperandGenerator g(selector);
897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  selector->Emit(opcode, g.DefineAsRegister(node),
907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                 g.UseRegister(node->InputAt(0)),
917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                 g.UseRegister(node->InputAt(1)));
927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgstatic void VisitRRRFloat64(InstructionSelector* selector, ArchOpcode opcode,
967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                            Node* node) {
977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Arm64OperandGenerator g(selector);
98fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org  selector->Emit(opcode, g.DefineAsRegister(node),
99fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org                 g.UseRegister(node->InputAt(0)),
100fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org                 g.UseRegister(node->InputAt(1)));
1017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
1027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgstatic void VisitRRO(InstructionSelector* selector, ArchOpcode opcode,
1057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                     Node* node, ImmediateMode operand_mode) {
1067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Arm64OperandGenerator g(selector);
1077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  selector->Emit(opcode, g.DefineAsRegister(node),
1087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                 g.UseRegister(node->InputAt(0)),
1097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                 g.UseOperand(node->InputAt(1), operand_mode));
1107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
1117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Shared routine for multiple binary operations.
11406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.orgtemplate <typename Matcher>
1157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgstatic void VisitBinop(InstructionSelector* selector, Node* node,
116e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org                       InstructionCode opcode, ImmediateMode operand_mode,
117e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org                       FlagsContinuation* cont) {
118aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org  Arm64OperandGenerator g(selector);
11906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  Matcher m(node);
120e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  InstructionOperand* inputs[4];
121aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org  size_t input_count = 0;
122aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org  InstructionOperand* outputs[2];
123aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org  size_t output_count = 0;
124aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org
125aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org  inputs[input_count++] = g.UseRegister(m.left().node());
126e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  inputs[input_count++] = g.UseOperand(m.right().node(), operand_mode);
127aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org
128e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  if (cont->IsBranch()) {
129e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    inputs[input_count++] = g.Label(cont->true_block());
130e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    inputs[input_count++] = g.Label(cont->false_block());
131aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org  }
132e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
133e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  outputs[output_count++] = g.DefineAsRegister(node);
134e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  if (cont->IsSet()) {
135e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    outputs[output_count++] = g.DefineAsRegister(cont->result());
136aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org  }
137aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org
138e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_NE(0, input_count);
139e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_NE(0, output_count);
140fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org  DCHECK_GE(arraysize(inputs), input_count);
141fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org  DCHECK_GE(arraysize(outputs), output_count);
142e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
143e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  Instruction* instr = selector->Emit(cont->Encode(opcode), output_count,
144e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org                                      outputs, input_count, inputs);
145e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  if (cont->IsBranch()) instr->MarkAsControl();
146e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org}
147e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
148aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org
149e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org// Shared routine for multiple binary operations.
15006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.orgtemplate <typename Matcher>
151e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.orgstatic void VisitBinop(InstructionSelector* selector, Node* node,
152e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org                       ArchOpcode opcode, ImmediateMode operand_mode) {
153e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  FlagsContinuation cont;
15406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  VisitBinop<Matcher>(selector, node, opcode, operand_mode, &cont);
155aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org}
156aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org
157aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org
1587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitLoad(Node* node) {
1596313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node));
1606313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node));
1617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Arm64OperandGenerator g(this);
1627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* base = node->InputAt(0);
1637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* index = node->InputAt(1);
1647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  ArchOpcode opcode;
165b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  ImmediateMode immediate_mode = kNoImmediate;
1667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  switch (rep) {
167fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org    case kRepFloat32:
168fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org      opcode = kArm64LdrS;
169b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      immediate_mode = kLoadStoreImm32;
170fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org      break;
1715e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case kRepFloat64:
1726474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      opcode = kArm64LdrD;
173b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      immediate_mode = kLoadStoreImm64;
1747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
1755e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case kRepBit:  // Fall through.
1765e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case kRepWord8:
1776474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      opcode = typ == kTypeInt32 ? kArm64Ldrsb : kArm64Ldrb;
178b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      immediate_mode = kLoadStoreImm8;
1797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
1805e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case kRepWord16:
1816474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      opcode = typ == kTypeInt32 ? kArm64Ldrsh : kArm64Ldrh;
182b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      immediate_mode = kLoadStoreImm16;
1837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
1845e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case kRepWord32:
1856474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      opcode = kArm64LdrW;
186b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      immediate_mode = kLoadStoreImm32;
1877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
1885e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case kRepTagged:  // Fall through.
1895e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case kRepWord64:
1906474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      opcode = kArm64Ldr;
191b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      immediate_mode = kLoadStoreImm64;
1927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
1937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    default:
1947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      UNREACHABLE();
1957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return;
1967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
197b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  if (g.CanBeImmediate(index, immediate_mode)) {
198fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org    Emit(opcode | AddressingModeField::encode(kMode_MRI),
199fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org         g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index));
2007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  } else {
201fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org    Emit(opcode | AddressingModeField::encode(kMode_MRR),
202fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org         g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(index));
2037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
2047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
2057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitStore(Node* node) {
2087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Arm64OperandGenerator g(this);
2097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* base = node->InputAt(0);
2107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* index = node->InputAt(1);
2117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* value = node->InputAt(2);
2127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node);
2146313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  MachineType rep = RepresentationOf(store_rep.machine_type());
2156313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  if (store_rep.write_barrier_kind() == kFullWriteBarrier) {
2165e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    DCHECK(rep == kRepTagged);
2177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    // TODO(dcarney): refactor RecordWrite function to take temp registers
2187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    //                and pass them here instead of using fixed regs
2197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    // TODO(dcarney): handle immediate indices.
2207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    InstructionOperand* temps[] = {g.TempRegister(x11), g.TempRegister(x12)};
2217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    Emit(kArm64StoreWriteBarrier, NULL, g.UseFixed(base, x10),
222fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org         g.UseFixed(index, x11), g.UseFixed(value, x12), arraysize(temps),
2237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org         temps);
2247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return;
2257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
2266313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind());
2277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  ArchOpcode opcode;
228b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  ImmediateMode immediate_mode = kNoImmediate;
2297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  switch (rep) {
230fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org    case kRepFloat32:
231fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org      opcode = kArm64StrS;
232b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      immediate_mode = kLoadStoreImm32;
233fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org      break;
2345e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case kRepFloat64:
2356474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      opcode = kArm64StrD;
236b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      immediate_mode = kLoadStoreImm64;
2377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
2385e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case kRepBit:  // Fall through.
2395e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case kRepWord8:
2406474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      opcode = kArm64Strb;
241b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      immediate_mode = kLoadStoreImm8;
2427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
2435e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case kRepWord16:
2446474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      opcode = kArm64Strh;
245b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      immediate_mode = kLoadStoreImm16;
2467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
2475e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case kRepWord32:
2486474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      opcode = kArm64StrW;
249b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      immediate_mode = kLoadStoreImm32;
2507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
2515e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case kRepTagged:  // Fall through.
2525e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case kRepWord64:
2536474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      opcode = kArm64Str;
254b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      immediate_mode = kLoadStoreImm64;
2557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
2567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    default:
2577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      UNREACHABLE();
2587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return;
2597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
260b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  if (g.CanBeImmediate(index, immediate_mode)) {
2617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    Emit(opcode | AddressingModeField::encode(kMode_MRI), NULL,
262fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org         g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value));
2637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  } else {
2647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    Emit(opcode | AddressingModeField::encode(kMode_MRR), NULL,
265fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org         g.UseRegister(base), g.UseRegister(index), g.UseRegister(value));
2667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
2677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
2687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitWord32And(Node* node) {
27106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  VisitBinop<Int32BinopMatcher>(this, node, kArm64And32, kLogical32Imm);
2727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
2737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitWord64And(Node* node) {
27606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  VisitBinop<Int64BinopMatcher>(this, node, kArm64And, kLogical64Imm);
2777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
2787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitWord32Or(Node* node) {
28106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  VisitBinop<Int32BinopMatcher>(this, node, kArm64Or32, kLogical32Imm);
2827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
2837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitWord64Or(Node* node) {
28606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  VisitBinop<Int64BinopMatcher>(this, node, kArm64Or, kLogical64Imm);
2877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
2887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
290e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.orgvoid InstructionSelector::VisitWord32Xor(Node* node) {
291e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  Arm64OperandGenerator g(this);
292e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  Int32BinopMatcher m(node);
2937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  if (m.right().Is(-1)) {
294e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org    Emit(kArm64Not32, g.DefineAsRegister(node), g.UseRegister(m.left().node()));
2957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  } else {
29606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    VisitBinop<Int32BinopMatcher>(this, node, kArm64Xor32, kLogical32Imm);
2977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
2987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
2997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitWord64Xor(Node* node) {
302e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  Arm64OperandGenerator g(this);
303e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  Int64BinopMatcher m(node);
304e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  if (m.right().Is(-1)) {
305e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org    Emit(kArm64Not, g.DefineAsRegister(node), g.UseRegister(m.left().node()));
306e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  } else {
30706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    VisitBinop<Int64BinopMatcher>(this, node, kArm64Xor, kLogical32Imm);
308e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  }
3097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
3107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitWord32Shl(Node* node) {
3137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitRRO(this, kArm64Shl32, node, kShift32Imm);
3147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
3157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitWord64Shl(Node* node) {
3187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitRRO(this, kArm64Shl, node, kShift64Imm);
3197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
3207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitWord32Shr(Node* node) {
3237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitRRO(this, kArm64Shr32, node, kShift32Imm);
3247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
3257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitWord64Shr(Node* node) {
3287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitRRO(this, kArm64Shr, node, kShift64Imm);
3297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
3307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitWord32Sar(Node* node) {
3337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitRRO(this, kArm64Sar32, node, kShift32Imm);
3347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
3357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitWord64Sar(Node* node) {
3387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitRRO(this, kArm64Sar, node, kShift64Imm);
3397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
3407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3425e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgvoid InstructionSelector::VisitWord32Ror(Node* node) {
3435e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  VisitRRO(this, kArm64Ror32, node, kShift32Imm);
3445e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org}
3455e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
3465e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
3475e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgvoid InstructionSelector::VisitWord64Ror(Node* node) {
3485e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  VisitRRO(this, kArm64Ror, node, kShift64Imm);
3495e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org}
3505e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
3515e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
3527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitInt32Add(Node* node) {
35306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  VisitBinop<Int32BinopMatcher>(this, node, kArm64Add32, kArithmeticImm);
354aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org}
355aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org
356aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org
3577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitInt64Add(Node* node) {
35806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  VisitBinop<Int64BinopMatcher>(this, node, kArm64Add, kArithmeticImm);
3597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
3607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
362e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.orgvoid InstructionSelector::VisitInt32Sub(Node* node) {
363e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  Arm64OperandGenerator g(this);
364e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  Int32BinopMatcher m(node);
3657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  if (m.left().Is(0)) {
366e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org    Emit(kArm64Neg32, g.DefineAsRegister(node),
367e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org         g.UseRegister(m.right().node()));
3687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  } else {
36906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    VisitBinop<Int32BinopMatcher>(this, node, kArm64Sub32, kArithmeticImm);
3707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
3717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
3727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitInt64Sub(Node* node) {
375e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  Arm64OperandGenerator g(this);
376e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  Int64BinopMatcher m(node);
377e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  if (m.left().Is(0)) {
378e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org    Emit(kArm64Neg, g.DefineAsRegister(node), g.UseRegister(m.right().node()));
379e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  } else {
38006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org    VisitBinop<Int64BinopMatcher>(this, node, kArm64Sub, kArithmeticImm);
381e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  }
3827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
3837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitInt32Mul(Node* node) {
3867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitRRR(this, kArm64Mul32, node);
3877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
3887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitInt64Mul(Node* node) {
3917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitRRR(this, kArm64Mul, node);
3927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
3937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitInt32Div(Node* node) {
3967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitRRR(this, kArm64Idiv32, node);
3977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
3987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
4007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitInt64Div(Node* node) {
4017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitRRR(this, kArm64Idiv, node);
4027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
4037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
4047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
4057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitInt32UDiv(Node* node) {
4067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitRRR(this, kArm64Udiv32, node);
4077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
4087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
4097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
4107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitInt64UDiv(Node* node) {
4117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitRRR(this, kArm64Udiv, node);
4127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
4137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
4147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
4157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitInt32Mod(Node* node) {
4167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitRRR(this, kArm64Imod32, node);
4177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
4187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
4197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
4207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitInt64Mod(Node* node) {
4217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitRRR(this, kArm64Imod, node);
4227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
4237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
4247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
4257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitInt32UMod(Node* node) {
4267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitRRR(this, kArm64Umod32, node);
4277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
4287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
4297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
4307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitInt64UMod(Node* node) {
4317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitRRR(this, kArm64Umod, node);
4327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
4337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
4347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
435aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.orgvoid InstructionSelector::VisitChangeInt32ToFloat64(Node* node) {
4367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Arm64OperandGenerator g(this);
437fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org  Emit(kArm64Int32ToFloat64, g.DefineAsRegister(node),
4387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org       g.UseRegister(node->InputAt(0)));
4397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
4407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
4417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
442aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.orgvoid InstructionSelector::VisitChangeUint32ToFloat64(Node* node) {
4437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Arm64OperandGenerator g(this);
444fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org  Emit(kArm64Uint32ToFloat64, g.DefineAsRegister(node),
4457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org       g.UseRegister(node->InputAt(0)));
4467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
4477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
4487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
449aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.orgvoid InstructionSelector::VisitChangeFloat64ToInt32(Node* node) {
4507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Arm64OperandGenerator g(this);
4517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Emit(kArm64Float64ToInt32, g.DefineAsRegister(node),
452fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org       g.UseRegister(node->InputAt(0)));
4537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
4547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
4557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
456aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.orgvoid InstructionSelector::VisitChangeFloat64ToUint32(Node* node) {
4577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Arm64OperandGenerator g(this);
4587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Emit(kArm64Float64ToUint32, g.DefineAsRegister(node),
459fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org       g.UseRegister(node->InputAt(0)));
4607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
4617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
4627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
4635e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgvoid InstructionSelector::VisitChangeInt32ToInt64(Node* node) {
4645e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Arm64OperandGenerator g(this);
4655e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Emit(kArm64Sxtw, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
4665e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org}
4675e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
4685e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
4695e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgvoid InstructionSelector::VisitChangeUint32ToUint64(Node* node) {
4705e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Arm64OperandGenerator g(this);
4715e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Emit(kArm64Mov32, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
4725e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org}
4735e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
4745e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
4755e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgvoid InstructionSelector::VisitTruncateInt64ToInt32(Node* node) {
4765e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Arm64OperandGenerator g(this);
4775e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Emit(kArm64Mov32, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
4785e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org}
4795e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
4805e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
4817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitFloat64Add(Node* node) {
4827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitRRRFloat64(this, kArm64Float64Add, node);
4837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
4847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
4857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
4867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitFloat64Sub(Node* node) {
4877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitRRRFloat64(this, kArm64Float64Sub, node);
4887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
4897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
4907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
4917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitFloat64Mul(Node* node) {
4927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitRRRFloat64(this, kArm64Float64Mul, node);
4937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
4947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
4957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
4967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitFloat64Div(Node* node) {
4977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitRRRFloat64(this, kArm64Float64Div, node);
4987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
4997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
5007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
5017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitFloat64Mod(Node* node) {
5027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Arm64OperandGenerator g(this);
503fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org  Emit(kArm64Float64Mod, g.DefineAsFixed(node, d0),
504fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org       g.UseFixed(node->InputAt(0), d0),
505fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org       g.UseFixed(node->InputAt(1), d1))->MarkAsCall();
5067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
5077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
5087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
509b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.orgvoid InstructionSelector::VisitFloat64Sqrt(Node* node) {
510b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org  Arm64OperandGenerator g(this);
511b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org  Emit(kArm64Float64Sqrt, g.DefineAsRegister(node),
512b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org       g.UseRegister(node->InputAt(0)));
513b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org}
514b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org
515b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org
516e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.orgvoid InstructionSelector::VisitInt32AddWithOverflow(Node* node,
517e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org                                                    FlagsContinuation* cont) {
51806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  VisitBinop<Int32BinopMatcher>(this, node, kArm64Add32, kArithmeticImm, cont);
519e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org}
520e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
521e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
522e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.orgvoid InstructionSelector::VisitInt32SubWithOverflow(Node* node,
523e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org                                                    FlagsContinuation* cont) {
52406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  VisitBinop<Int32BinopMatcher>(this, node, kArm64Sub32, kArithmeticImm, cont);
525e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org}
526e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
527e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
5287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Shared routine for multiple compare operations.
5297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgstatic void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
5307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                         InstructionOperand* left, InstructionOperand* right,
5317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                         FlagsContinuation* cont) {
5327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Arm64OperandGenerator g(selector);
5337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  opcode = cont->Encode(opcode);
5347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  if (cont->IsBranch()) {
5357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    selector->Emit(opcode, NULL, left, right, g.Label(cont->true_block()),
5367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                   g.Label(cont->false_block()))->MarkAsControl();
5377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  } else {
538e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(cont->IsSet());
5397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right);
5407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
5417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
5427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
5437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
5447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// Shared routine for multiple word compare operations.
5457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgstatic void VisitWordCompare(InstructionSelector* selector, Node* node,
5467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                             InstructionCode opcode, FlagsContinuation* cont,
5477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                             bool commutative) {
5487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Arm64OperandGenerator g(selector);
5497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* left = node->InputAt(0);
5507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* right = node->InputAt(1);
5517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
5527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Match immediates on left or right side of comparison.
553e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  if (g.CanBeImmediate(right, kArithmeticImm)) {
5547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    VisitCompare(selector, opcode, g.UseRegister(left), g.UseImmediate(right),
5557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                 cont);
556e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  } else if (g.CanBeImmediate(left, kArithmeticImm)) {
5577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    if (!commutative) cont->Commute();
5587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    VisitCompare(selector, opcode, g.UseRegister(right), g.UseImmediate(left),
5597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                 cont);
5607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  } else {
5617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    VisitCompare(selector, opcode, g.UseRegister(left), g.UseRegister(right),
5627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                 cont);
5637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
5647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
5657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
5667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
5677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitWord32Test(Node* node, FlagsContinuation* cont) {
5687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  switch (node->opcode()) {
5692c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org    case IrOpcode::kInt32Add:
5702c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      return VisitWordCompare(this, node, kArm64Cmn32, cont, true);
5712c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org    case IrOpcode::kInt32Sub:
5722c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      return VisitWordCompare(this, node, kArm64Cmp32, cont, false);
5737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kWord32And:
5747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitWordCompare(this, node, kArm64Tst32, cont, true);
5757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    default:
5767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
5777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
5787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
5797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Arm64OperandGenerator g(this);
5807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitCompare(this, kArm64Tst32, g.UseRegister(node), g.UseRegister(node),
5817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org               cont);
5827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
5837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
5847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
5857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitWord64Test(Node* node, FlagsContinuation* cont) {
5867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  switch (node->opcode()) {
5877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kWord64And:
5887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitWordCompare(this, node, kArm64Tst, cont, true);
5897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    default:
5907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
5917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
5927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
5937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Arm64OperandGenerator g(this);
5947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitCompare(this, kArm64Tst, g.UseRegister(node), g.UseRegister(node), cont);
5957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
5967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
5977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
5987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitWord32Compare(Node* node,
5997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                                             FlagsContinuation* cont) {
6007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitWordCompare(this, node, kArm64Cmp32, cont, false);
6017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
6027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
6037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
6047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitWord64Compare(Node* node,
6057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                                             FlagsContinuation* cont) {
6067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitWordCompare(this, node, kArm64Cmp, cont, false);
6077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
6087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
6097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
6107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitFloat64Compare(Node* node,
6117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                                              FlagsContinuation* cont) {
6127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Arm64OperandGenerator g(this);
6137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* left = node->InputAt(0);
6147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* right = node->InputAt(1);
615fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org  VisitCompare(this, kArm64Float64Cmp, g.UseRegister(left),
616fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org               g.UseRegister(right), cont);
6177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
6187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
6197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
6207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitCall(Node* call, BasicBlock* continuation,
6217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                                    BasicBlock* deoptimization) {
6227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Arm64OperandGenerator g(this);
6237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  CallDescriptor* descriptor = OpParameter<CallDescriptor*>(call);
624a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
625a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  FrameStateDescriptor* frame_state_descriptor = NULL;
626a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  if (descriptor->NeedsFrameState()) {
627a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    frame_state_descriptor =
628a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        GetFrameStateDescriptor(call->InputAt(descriptor->InputCount()));
629a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  }
630a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
631a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  CallBuffer buffer(zone(), descriptor, frame_state_descriptor);
6327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
6337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Compute InstructionOperands for inputs and outputs.
6347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // TODO(turbofan): on ARM64 it's probably better to use the code object in a
6357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // register if there are multiple uses of it. Improve constant pool and the
6367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // heuristics in the register allocator for where to emit constants.
637ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  InitializeCallBuffer(call, &buffer, true, false);
6387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
6397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Push the arguments to the stack.
640a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  bool pushed_count_uneven = buffer.pushed_nodes.size() & 1;
641a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  int aligned_push_count = buffer.pushed_nodes.size();
6427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // TODO(dcarney): claim and poke probably take small immediates,
6437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  //                loop here or whatever.
6447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Bump the stack pointer(s).
6457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  if (aligned_push_count > 0) {
6467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    // TODO(dcarney): it would be better to bump the csp here only
6477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    //                and emit paired stores with increment for non c frames.
6487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    Emit(kArm64Claim | MiscField::encode(aligned_push_count), NULL);
6497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
6507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Move arguments to the stack.
6517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  {
652a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    int slot = buffer.pushed_nodes.size() - 1;
6537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    // Emit the uneven pushes.
6547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    if (pushed_count_uneven) {
6557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      Node* input = buffer.pushed_nodes[slot];
65606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org      Emit(kArm64Poke | MiscField::encode(slot), NULL, g.UseRegister(input));
6577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      slot--;
6587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
6597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    // Now all pushes can be done in pairs.
6607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    for (; slot >= 0; slot -= 2) {
6617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      Emit(kArm64PokePair | MiscField::encode(slot), NULL,
6627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org           g.UseRegister(buffer.pushed_nodes[slot]),
6637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org           g.UseRegister(buffer.pushed_nodes[slot - 1]));
6647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
6657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
6667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
6677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Select the appropriate opcode based on the call type.
6687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  InstructionCode opcode;
6697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  switch (descriptor->kind()) {
6707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case CallDescriptor::kCallCodeObject: {
6717b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org      opcode = kArchCallCodeObject;
6727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
6737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
6747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case CallDescriptor::kCallJSFunction:
6757b6dc58d68c4315b99f5ec3faf6927db3d0db913machenbach@chromium.org      opcode = kArchCallJSFunction;
6767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
6777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    default:
6787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      UNREACHABLE();
6797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return;
6807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
681d4f11c0cf476dd854eaebec1cbacb1afc7bea18emachenbach@chromium.org  opcode |= MiscField::encode(descriptor->flags());
6827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
6837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Emit the call instruction.
6847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Instruction* call_instr =
685a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      Emit(opcode, buffer.outputs.size(), &buffer.outputs.front(),
686a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org           buffer.instruction_args.size(), &buffer.instruction_args.front());
6877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
6887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  call_instr->MarkAsCall();
6897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  if (deoptimization != NULL) {
690e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(continuation != NULL);
6917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    call_instr->MarkAsControl();
6927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
6937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
6947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
6957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}  // namespace compiler
6967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}  // namespace internal
6977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}  // namespace v8
698