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.h"
67d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
77d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/instruction-selector-impl.h"
87d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/node-matchers.h"
97d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/node-properties-inl.h"
107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "src/compiler/pipeline.h"
117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace v8 {
137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace internal {
147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgnamespace compiler {
157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgInstructionSelector::InstructionSelector(InstructionSequence* sequence,
173e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                         SourcePositionTable* source_positions,
183e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                                         Features features)
197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    : zone_(sequence->isolate()),
207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      sequence_(sequence),
217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      source_positions_(source_positions),
223e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      features_(features),
237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      current_block_(NULL),
24fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org      instructions_(zone()),
25fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org      defined_(graph()->NodeCount(), false, zone()),
26fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org      used_(graph()->NodeCount(), false, zone()) {}
277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::SelectInstructions() {
307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Mark the inputs of all phis in loop headers as used.
317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  BasicBlockVector* blocks = schedule()->rpo_order();
327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  for (BasicBlockVectorIter i = blocks->begin(); i != blocks->end(); ++i) {
337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    BasicBlock* block = *i;
347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    if (!block->IsLoopHeader()) continue;
35e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK_NE(0, block->PredecessorCount());
36e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK_NE(1, block->PredecessorCount());
377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    for (BasicBlock::const_iterator j = block->begin(); j != block->end();
387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org         ++j) {
397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      Node* phi = *j;
407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (phi->opcode() != IrOpcode::kPhi) continue;
417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      // Mark all inputs as used.
437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      Node::Inputs inputs = phi->inputs();
447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      for (InputIter k = inputs.begin(); k != inputs.end(); ++k) {
457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        MarkAsUsed(*k);
467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Visit each basic block in post order.
517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  for (BasicBlockVectorRIter i = blocks->rbegin(); i != blocks->rend(); ++i) {
527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    VisitBlock(*i);
537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Schedule the selected instructions.
567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  for (BasicBlockVectorIter i = blocks->begin(); i != blocks->end(); ++i) {
577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    BasicBlock* block = *i;
587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    size_t end = block->code_end_;
597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    size_t start = block->code_start_;
607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    sequence()->StartBlock(block);
617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    while (start-- > end) {
627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      sequence()->AddInstruction(instructions_[start], block);
637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    sequence()->EndBlock(block);
657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgInstruction* InstructionSelector::Emit(InstructionCode opcode,
707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                                       InstructionOperand* output,
717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                                       size_t temp_count,
727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                                       InstructionOperand** temps) {
737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  size_t output_count = output == NULL ? 0 : 1;
747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  return Emit(opcode, output_count, &output, 0, NULL, temp_count, temps);
757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgInstruction* InstructionSelector::Emit(InstructionCode opcode,
797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                                       InstructionOperand* output,
807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                                       InstructionOperand* a, size_t temp_count,
817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                                       InstructionOperand** temps) {
827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  size_t output_count = output == NULL ? 0 : 1;
837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  return Emit(opcode, output_count, &output, 1, &a, temp_count, temps);
847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgInstruction* InstructionSelector::Emit(InstructionCode opcode,
887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                                       InstructionOperand* output,
897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                                       InstructionOperand* a,
907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                                       InstructionOperand* b, size_t temp_count,
917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                                       InstructionOperand** temps) {
927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  size_t output_count = output == NULL ? 0 : 1;
937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  InstructionOperand* inputs[] = {a, b};
94fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org  size_t input_count = arraysize(inputs);
957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org              temps);
977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgInstruction* InstructionSelector::Emit(InstructionCode opcode,
1017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                                       InstructionOperand* output,
1027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                                       InstructionOperand* a,
1037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                                       InstructionOperand* b,
1047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                                       InstructionOperand* c, size_t temp_count,
1057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                                       InstructionOperand** temps) {
1067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  size_t output_count = output == NULL ? 0 : 1;
1077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  InstructionOperand* inputs[] = {a, b, c};
108fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org  size_t input_count = arraysize(inputs);
1097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
1107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org              temps);
1117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
1127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgInstruction* InstructionSelector::Emit(
1157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    InstructionCode opcode, InstructionOperand* output, InstructionOperand* a,
1167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    InstructionOperand* b, InstructionOperand* c, InstructionOperand* d,
1177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    size_t temp_count, InstructionOperand** temps) {
1187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  size_t output_count = output == NULL ? 0 : 1;
1197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  InstructionOperand* inputs[] = {a, b, c, d};
120fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org  size_t input_count = arraysize(inputs);
1217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
1227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org              temps);
1237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
1247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgInstruction* InstructionSelector::Emit(
1277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    InstructionCode opcode, size_t output_count, InstructionOperand** outputs,
1287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    size_t input_count, InstructionOperand** inputs, size_t temp_count,
1297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    InstructionOperand** temps) {
1307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Instruction* instr =
1317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      Instruction::New(instruction_zone(), opcode, output_count, outputs,
1327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                       input_count, inputs, temp_count, temps);
1337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  return Emit(instr);
1347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
1357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgInstruction* InstructionSelector::Emit(Instruction* instr) {
1387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  instructions_.push_back(instr);
1397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  return instr;
1407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
1417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgbool InstructionSelector::IsNextInAssemblyOrder(const BasicBlock* block) const {
1447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  return block->rpo_number_ == (current_block_->rpo_number_ + 1) &&
1457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org         block->deferred_ == current_block_->deferred_;
1467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
1477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgbool InstructionSelector::CanCover(Node* user, Node* node) const {
1507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  return node->OwnedBy(user) &&
1517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org         schedule()->block(node) == schedule()->block(user);
1527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
1537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
155e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.orgbool InstructionSelector::IsDefined(Node* node) const {
156e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_NOT_NULL(node);
157e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  NodeId id = node->id();
158e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(id >= 0);
159e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(id < static_cast<NodeId>(defined_.size()));
160e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  return defined_[id];
161e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org}
162e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
163e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
164e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.orgvoid InstructionSelector::MarkAsDefined(Node* node) {
165e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_NOT_NULL(node);
166e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  NodeId id = node->id();
167e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(id >= 0);
168e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(id < static_cast<NodeId>(defined_.size()));
169e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  defined_[id] = true;
170e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org}
171e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
172e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
1737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgbool InstructionSelector::IsUsed(Node* node) const {
1747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  if (!node->op()->HasProperty(Operator::kEliminatable)) return true;
1757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  NodeId id = node->id();
176e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(id >= 0);
177e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(id < static_cast<NodeId>(used_.size()));
1787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  return used_[id];
1797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
1807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::MarkAsUsed(Node* node) {
183e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_NOT_NULL(node);
1847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  NodeId id = node->id();
185e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(id >= 0);
186e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(id < static_cast<NodeId>(used_.size()));
1877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  used_[id] = true;
1887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
1897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgbool InstructionSelector::IsDouble(const Node* node) const {
192e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_NOT_NULL(node);
1937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  return sequence()->IsDouble(node->id());
1947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
1957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::MarkAsDouble(Node* node) {
198e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_NOT_NULL(node);
199e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!IsReference(node));
2007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  sequence()->MarkAsDouble(node->id());
2017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
2027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgbool InstructionSelector::IsReference(const Node* node) const {
205e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_NOT_NULL(node);
2067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  return sequence()->IsReference(node->id());
2077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
2087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::MarkAsReference(Node* node) {
211e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_NOT_NULL(node);
212e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!IsDouble(node));
2137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  sequence()->MarkAsReference(node->id());
2147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
2157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
21731c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.orgvoid InstructionSelector::MarkAsRepresentation(MachineType rep, Node* node) {
218e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_NOT_NULL(node);
219fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org  switch (RepresentationOf(rep)) {
220fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org    case kRepFloat32:
221fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org    case kRepFloat64:
222fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org      MarkAsDouble(node);
223fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org      break;
224fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org    case kRepTagged:
225fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org      MarkAsReference(node);
226fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org      break;
227fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org    default:
228fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org      break;
229fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org  }
2307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
2317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// TODO(bmeurer): Get rid of the CallBuffer business and make
2347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// InstructionSelector::VisitCall platform independent instead.
235a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgCallBuffer::CallBuffer(Zone* zone, CallDescriptor* d,
236a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org                       FrameStateDescriptor* frame_desc)
237a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    : descriptor(d),
238a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      frame_state_descriptor(frame_desc),
239fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org      output_nodes(zone),
240fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org      outputs(zone),
241fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org      instruction_args(zone),
242fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org      pushed_nodes(zone) {
243a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  output_nodes.reserve(d->ReturnCount());
244a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  outputs.reserve(d->ReturnCount());
245a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  pushed_nodes.reserve(input_count());
246ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  instruction_args.reserve(input_count() + frame_state_value_count());
2477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
2487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// TODO(bmeurer): Get rid of the CallBuffer business and make
2517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// InstructionSelector::VisitCall platform independent instead.
2527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer,
2537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                                               bool call_code_immediate,
254ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org                                               bool call_address_immediate) {
2557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  OperandGenerator g(this);
256e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_EQ(call->op()->OutputCount(), buffer->descriptor->ReturnCount());
2578640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org  DCHECK_EQ(OperatorProperties::GetValueInputCount(call->op()),
258a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org            buffer->input_count() + buffer->frame_state_count());
2597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  if (buffer->descriptor->ReturnCount() > 0) {
2617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    // Collect the projections that represent multiple outputs from this call.
2627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    if (buffer->descriptor->ReturnCount() == 1) {
263a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      buffer->output_nodes.push_back(call);
2647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    } else {
2656474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      buffer->output_nodes.resize(buffer->descriptor->ReturnCount(), NULL);
266a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      call->CollectProjections(&buffer->output_nodes);
2677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
2687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    // Filter out the outputs that aren't live because no projection uses them.
270a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    for (size_t i = 0; i < buffer->output_nodes.size(); i++) {
2717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (buffer->output_nodes[i] != NULL) {
2727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        Node* output = buffer->output_nodes[i];
2739aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org        MachineType type =
2749aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org            buffer->descriptor->GetReturnType(static_cast<int>(i));
275a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        LinkageLocation location =
276a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org            buffer->descriptor->GetReturnLocation(static_cast<int>(i));
2779aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org        MarkAsRepresentation(type, output);
2789aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org        buffer->outputs.push_back(g.DefineAsLocation(output, location, type));
2797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
2807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
2817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
2827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
283a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  // The first argument is always the callee code.
2847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* callee = call->InputAt(0);
2857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  switch (buffer->descriptor->kind()) {
2867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case CallDescriptor::kCallCodeObject:
287a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      buffer->instruction_args.push_back(
2887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org          (call_code_immediate && callee->opcode() == IrOpcode::kHeapConstant)
2897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org              ? g.UseImmediate(callee)
290a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org              : g.UseRegister(callee));
2917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
2927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case CallDescriptor::kCallAddress:
293a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      buffer->instruction_args.push_back(
2947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org          (call_address_immediate &&
2957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org           (callee->opcode() == IrOpcode::kInt32Constant ||
2967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org            callee->opcode() == IrOpcode::kInt64Constant))
2977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org              ? g.UseImmediate(callee)
298a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org              : g.UseRegister(callee));
2997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
3007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case CallDescriptor::kCallJSFunction:
301a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      buffer->instruction_args.push_back(
3029aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org          g.UseLocation(callee, buffer->descriptor->GetInputLocation(0),
3039aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org                        buffer->descriptor->GetInputType(0)));
3047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
3057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
306a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  DCHECK_EQ(1, buffer->instruction_args.size());
307a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
308a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  // If the call needs a frame state, we insert the state information as
309a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  // follows (n is the number of value inputs to the frame state):
310a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  // arg 1               : deoptimization id.
311a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  // arg 2 - arg (n + 1) : value inputs to the frame state.
312a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  if (buffer->frame_state_descriptor != NULL) {
313ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    InstructionSequence::StateId state_id =
314ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org        sequence()->AddFrameStateDescriptor(buffer->frame_state_descriptor);
315ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    buffer->instruction_args.push_back(g.TempImmediate(state_id.ToInt()));
316a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
3179aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org    Node* frame_state =
3189aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org        call->InputAt(static_cast<int>(buffer->descriptor->InputCount()));
319a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    AddFrameStateInputs(frame_state, &buffer->instruction_args,
320a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org                        buffer->frame_state_descriptor);
321a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  }
3229aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  DCHECK(1 + buffer->frame_state_value_count() ==
3239aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org         buffer->instruction_args.size());
3247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3259aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  size_t input_count = static_cast<size_t>(buffer->input_count());
3267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
327a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  // Split the arguments into pushed_nodes and instruction_args. Pushed
328a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  // arguments require an explicit push instruction before the call and do
329a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  // not appear as arguments to the call. Everything else ends up
330a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  // as an InstructionOperand argument to the call.
3317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  InputIter iter(call->inputs().begin());
332a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  int pushed_count = 0;
3339aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  for (size_t index = 0; index < input_count; ++iter, ++index) {
334e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(iter != call->inputs().end());
3359aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org    DCHECK(index == static_cast<size_t>(iter.index()));
336a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    DCHECK((*iter)->op()->opcode() != IrOpcode::kFrameState);
3377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    if (index == 0) continue;  // The first argument (callee) is already done.
3387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    InstructionOperand* op =
3399aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org        g.UseLocation(*iter, buffer->descriptor->GetInputLocation(index),
3409aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org                      buffer->descriptor->GetInputType(index));
3417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    if (UnallocatedOperand::cast(op)->HasFixedSlotPolicy()) {
3427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      int stack_index = -UnallocatedOperand::cast(op)->fixed_slot_index() - 1;
343a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      if (static_cast<size_t>(stack_index) >= buffer->pushed_nodes.size()) {
344a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        buffer->pushed_nodes.resize(stack_index + 1, NULL);
345a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      }
346a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      DCHECK_EQ(NULL, buffer->pushed_nodes[stack_index]);
3477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      buffer->pushed_nodes[stack_index] = *iter;
348a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      pushed_count++;
3497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    } else {
350a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      buffer->instruction_args.push_back(op);
3517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
3527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
353a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  CHECK_EQ(pushed_count, static_cast<int>(buffer->pushed_nodes.size()));
354a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  DCHECK(static_cast<size_t>(input_count) ==
355ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org         (buffer->instruction_args.size() + buffer->pushed_nodes.size() -
356ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org          buffer->frame_state_value_count()));
3577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
3587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitBlock(BasicBlock* block) {
361e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_EQ(NULL, current_block_);
3627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  current_block_ = block;
3637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  int current_block_end = static_cast<int>(instructions_.size());
3647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Generate code for the block control "top down", but schedule the code
3667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // "bottom up".
3677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitControl(block);
3687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  std::reverse(instructions_.begin() + current_block_end, instructions_.end());
3697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Visit code in reverse control flow order, because architecture-specific
3717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // matching may cover more than one node at a time.
3727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  for (BasicBlock::reverse_iterator i = block->rbegin(); i != block->rend();
3737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org       ++i) {
3747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    Node* node = *i;
375e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    // Skip nodes that are unused or already defined.
376e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    if (!IsUsed(node) || IsDefined(node)) continue;
3777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    // Generate code for this node "top down", but schedule the code "bottom
3787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    // up".
3797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    size_t current_node_end = instructions_.size();
3807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    VisitNode(node);
3817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    std::reverse(instructions_.begin() + current_node_end, instructions_.end());
3827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
3837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // We're done with the block.
3857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // TODO(bmeurer): We should not mutate the schedule.
3867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  block->code_end_ = current_block_end;
3877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  block->code_start_ = static_cast<int>(instructions_.size());
3887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  current_block_ = NULL;
3907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
3917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
3937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgstatic inline void CheckNoPhis(const BasicBlock* block) {
3947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#ifdef DEBUG
3957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Branch targets should not have phis.
3967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  for (BasicBlock::const_iterator i = block->begin(); i != block->end(); ++i) {
3977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    const Node* node = *i;
3987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    CHECK_NE(IrOpcode::kPhi, node->opcode());
3997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
4007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#endif
4017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
4027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
4037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
4047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitControl(BasicBlock* block) {
4057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* input = block->control_input_;
4067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  switch (block->control_) {
4077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case BasicBlockData::kGoto:
4087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitGoto(block->SuccessorAt(0));
4097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case BasicBlockData::kBranch: {
410e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK_EQ(IrOpcode::kBranch, input->opcode());
4117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      BasicBlock* tbranch = block->SuccessorAt(0);
4127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      BasicBlock* fbranch = block->SuccessorAt(1);
4137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      // SSA deconstruction requires targets of branches not to have phis.
4147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      // Edge split form guarantees this property, but is more strict.
4157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      CheckNoPhis(tbranch);
4167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      CheckNoPhis(fbranch);
4177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (tbranch == fbranch) return VisitGoto(tbranch);
4187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitBranch(input, tbranch, fbranch);
4197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
4207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case BasicBlockData::kReturn: {
4217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      // If the result itself is a return, return its input.
4227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      Node* value = (input != NULL && input->opcode() == IrOpcode::kReturn)
4237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                        ? input->InputAt(0)
4247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                        : input;
4257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitReturn(value);
4267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
4277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case BasicBlockData::kThrow:
4287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitThrow(input);
4297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case BasicBlockData::kNone: {
4307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      // TODO(titzer): exit block doesn't have control.
431e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(input == NULL);
4327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
4337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
4347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    default:
4357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      UNREACHABLE();
4367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
4377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
4387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
4397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
4407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
4417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitNode(Node* node) {
442e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_NOT_NULL(schedule()->block(node));  // should only use scheduled nodes.
4437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  SourcePosition source_position = source_positions_->GetSourcePosition(node);
4447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  if (!source_position.IsUnknown()) {
445e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!source_position.IsInvalid());
4467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    if (FLAG_turbo_source_positions || node->opcode() == IrOpcode::kCall) {
4477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      Emit(SourcePositionInstruction::New(instruction_zone(), source_position));
4487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
4497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
4507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  switch (node->opcode()) {
4517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kStart:
4527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kLoop:
4537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kEnd:
4547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kBranch:
4557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kIfTrue:
4567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kIfFalse:
4577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kEffectPhi:
4587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kMerge:
4597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      // No code needed for these graph artifacts.
4607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return;
461e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    case IrOpcode::kFinish:
4629aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org      return MarkAsReference(node), VisitFinish(node);
4637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kParameter: {
4649aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org      MachineType type = linkage()->GetParameterType(OpParameter<int>(node));
4659aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org      MarkAsRepresentation(type, node);
4667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitParameter(node);
4677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
46842ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org    case IrOpcode::kPhi: {
46942ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org      MachineType type = OpParameter<MachineType>(node);
47042ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org      MarkAsRepresentation(type, node);
471aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org      return VisitPhi(node);
47242ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org    }
473aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org    case IrOpcode::kProjection:
474aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org      return VisitProjection(node);
4757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kInt32Constant:
4767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kInt64Constant:
4777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kExternalConstant:
4787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitConstant(node);
4797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kFloat64Constant:
4807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return MarkAsDouble(node), VisitConstant(node);
4817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kHeapConstant:
4827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kNumberConstant:
4837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      // TODO(turbofan): only mark non-smis as references.
4847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return MarkAsReference(node), VisitConstant(node);
4857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kCall:
4867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitCall(node, NULL, NULL);
4877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kFrameState:
4889d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    case IrOpcode::kStateValues:
4897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return;
4907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kLoad: {
4916313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org      LoadRepresentation rep = OpParameter<LoadRepresentation>(node);
4926313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org      MarkAsRepresentation(rep, node);
4937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitLoad(node);
4947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
4957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kStore:
4967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitStore(node);
4977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kWord32And:
4987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitWord32And(node);
4997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kWord32Or:
5007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitWord32Or(node);
5017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kWord32Xor:
5027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitWord32Xor(node);
5037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kWord32Shl:
5047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitWord32Shl(node);
5057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kWord32Shr:
5067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitWord32Shr(node);
5077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kWord32Sar:
5087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitWord32Sar(node);
5095e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case IrOpcode::kWord32Ror:
5105e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      return VisitWord32Ror(node);
5117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kWord32Equal:
5127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitWord32Equal(node);
5137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kWord64And:
5147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitWord64And(node);
5157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kWord64Or:
5167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitWord64Or(node);
5177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kWord64Xor:
5187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitWord64Xor(node);
5197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kWord64Shl:
5207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitWord64Shl(node);
5217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kWord64Shr:
5227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitWord64Shr(node);
5237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kWord64Sar:
5247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitWord64Sar(node);
5255e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case IrOpcode::kWord64Ror:
5265e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      return VisitWord64Ror(node);
5277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kWord64Equal:
5287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitWord64Equal(node);
5297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kInt32Add:
5307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitInt32Add(node);
531aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org    case IrOpcode::kInt32AddWithOverflow:
532aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org      return VisitInt32AddWithOverflow(node);
5337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kInt32Sub:
5347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitInt32Sub(node);
535aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org    case IrOpcode::kInt32SubWithOverflow:
536aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org      return VisitInt32SubWithOverflow(node);
5377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kInt32Mul:
5387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitInt32Mul(node);
5397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kInt32Div:
5407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitInt32Div(node);
5417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kInt32UDiv:
5427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitInt32UDiv(node);
5437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kInt32Mod:
5447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitInt32Mod(node);
5457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kInt32UMod:
5467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitInt32UMod(node);
5477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kInt32LessThan:
5487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitInt32LessThan(node);
5497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kInt32LessThanOrEqual:
5507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitInt32LessThanOrEqual(node);
5517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kUint32LessThan:
5527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitUint32LessThan(node);
5537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kUint32LessThanOrEqual:
5547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitUint32LessThanOrEqual(node);
5557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kInt64Add:
5567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitInt64Add(node);
5577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kInt64Sub:
5587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitInt64Sub(node);
5597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kInt64Mul:
5607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitInt64Mul(node);
5617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kInt64Div:
5627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitInt64Div(node);
5637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kInt64UDiv:
5647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitInt64UDiv(node);
5657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kInt64Mod:
5667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitInt64Mod(node);
5677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kInt64UMod:
5687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitInt64UMod(node);
5697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kInt64LessThan:
5707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitInt64LessThan(node);
5717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kInt64LessThanOrEqual:
5727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitInt64LessThanOrEqual(node);
573aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org    case IrOpcode::kChangeInt32ToFloat64:
574aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org      return MarkAsDouble(node), VisitChangeInt32ToFloat64(node);
575aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org    case IrOpcode::kChangeUint32ToFloat64:
576aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org      return MarkAsDouble(node), VisitChangeUint32ToFloat64(node);
577aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org    case IrOpcode::kChangeFloat64ToInt32:
578aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org      return VisitChangeFloat64ToInt32(node);
579aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org    case IrOpcode::kChangeFloat64ToUint32:
580aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org      return VisitChangeFloat64ToUint32(node);
5815e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case IrOpcode::kChangeInt32ToInt64:
5825e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      return VisitChangeInt32ToInt64(node);
5835e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case IrOpcode::kChangeUint32ToUint64:
5845e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      return VisitChangeUint32ToUint64(node);
5857dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org    case IrOpcode::kTruncateFloat64ToInt32:
5867dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org      return VisitTruncateFloat64ToInt32(node);
5875e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    case IrOpcode::kTruncateInt64ToInt32:
5885e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      return VisitTruncateInt64ToInt32(node);
5897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kFloat64Add:
5907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return MarkAsDouble(node), VisitFloat64Add(node);
5917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kFloat64Sub:
5927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return MarkAsDouble(node), VisitFloat64Sub(node);
5937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kFloat64Mul:
5947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return MarkAsDouble(node), VisitFloat64Mul(node);
5957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kFloat64Div:
5967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return MarkAsDouble(node), VisitFloat64Div(node);
5977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kFloat64Mod:
5987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return MarkAsDouble(node), VisitFloat64Mod(node);
599b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org    case IrOpcode::kFloat64Sqrt:
600b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org      return MarkAsDouble(node), VisitFloat64Sqrt(node);
6017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kFloat64Equal:
6027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitFloat64Equal(node);
6037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kFloat64LessThan:
6047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitFloat64LessThan(node);
6057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    case IrOpcode::kFloat64LessThanOrEqual:
6067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      return VisitFloat64LessThanOrEqual(node);
6077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    default:
6087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      V8_Fatal(__FILE__, __LINE__, "Unexpected operator #%d:%s @ node #%d",
6097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org               node->opcode(), node->op()->mnemonic(), node->id());
6107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
6117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
6127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
6137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
6143e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#if V8_TURBOFAN_BACKEND
6157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
6167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitWord32Equal(Node* node) {
6177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  FlagsContinuation cont(kEqual, node);
6187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Int32BinopMatcher m(node);
6197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  if (m.right().Is(0)) {
6207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return VisitWord32Test(m.left().node(), &cont);
6217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
6227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitWord32Compare(node, &cont);
6237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
6247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
6257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
6267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitInt32LessThan(Node* node) {
6277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  FlagsContinuation cont(kSignedLessThan, node);
6287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitWord32Compare(node, &cont);
6297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
6307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
6317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
6327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitInt32LessThanOrEqual(Node* node) {
6337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  FlagsContinuation cont(kSignedLessThanOrEqual, node);
6347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitWord32Compare(node, &cont);
6357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
6367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
6377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
6387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitUint32LessThan(Node* node) {
6397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  FlagsContinuation cont(kUnsignedLessThan, node);
6407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitWord32Compare(node, &cont);
6417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
6427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
6437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
6447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitUint32LessThanOrEqual(Node* node) {
6457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
6467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitWord32Compare(node, &cont);
6477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
6487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
6497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
6507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitWord64Equal(Node* node) {
6517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  FlagsContinuation cont(kEqual, node);
6527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Int64BinopMatcher m(node);
6537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  if (m.right().Is(0)) {
6547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    return VisitWord64Test(m.left().node(), &cont);
6557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
6567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitWord64Compare(node, &cont);
6577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
6587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
6597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
660e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.orgvoid InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
661e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  if (Node* ovf = node->FindProjection(1)) {
662e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    FlagsContinuation cont(kOverflow, ovf);
663e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    return VisitInt32AddWithOverflow(node, &cont);
664e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  }
665e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  FlagsContinuation cont;
666e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  VisitInt32AddWithOverflow(node, &cont);
667e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org}
668e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
669e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
670e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.orgvoid InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
671e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  if (Node* ovf = node->FindProjection(1)) {
672e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    FlagsContinuation cont(kOverflow, ovf);
673e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    return VisitInt32SubWithOverflow(node, &cont);
674e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  }
675e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  FlagsContinuation cont;
676e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  VisitInt32SubWithOverflow(node, &cont);
677e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org}
678e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
679e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
6807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitInt64LessThan(Node* node) {
6817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  FlagsContinuation cont(kSignedLessThan, node);
6827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitWord64Compare(node, &cont);
6837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
6847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
6857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
6867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitInt64LessThanOrEqual(Node* node) {
6877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  FlagsContinuation cont(kSignedLessThanOrEqual, node);
6887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitWord64Compare(node, &cont);
6897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
6907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
6917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
6927dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.orgvoid InstructionSelector::VisitTruncateFloat64ToInt32(Node* node) {
6937dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org  OperandGenerator g(this);
6947dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org  Emit(kArchTruncateDoubleToI, g.DefineAsRegister(node),
695fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org       g.UseRegister(node->InputAt(0)));
6967dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org}
6977dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org
6987dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org
6997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitFloat64Equal(Node* node) {
7007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  FlagsContinuation cont(kUnorderedEqual, node);
7017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitFloat64Compare(node, &cont);
7027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
7037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitFloat64LessThan(Node* node) {
7067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  FlagsContinuation cont(kUnorderedLessThan, node);
7077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitFloat64Compare(node, &cont);
7087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
7097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
7127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  FlagsContinuation cont(kUnorderedLessThanOrEqual, node);
7137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitFloat64Compare(node, &cont);
7147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
7157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7163e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#endif  // V8_TURBOFAN_BACKEND
7177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// 32 bit targets do not implement the following instructions.
7193e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#if V8_TARGET_ARCH_32_BIT && V8_TURBOFAN_BACKEND
7207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitWord64And(Node* node) { UNIMPLEMENTED(); }
7227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitWord64Or(Node* node) { UNIMPLEMENTED(); }
7257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitWord64Xor(Node* node) { UNIMPLEMENTED(); }
7287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitWord64Shl(Node* node) { UNIMPLEMENTED(); }
7317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitWord64Shr(Node* node) { UNIMPLEMENTED(); }
7347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitWord64Sar(Node* node) { UNIMPLEMENTED(); }
7377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7395e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgvoid InstructionSelector::VisitWord64Ror(Node* node) { UNIMPLEMENTED(); }
7405e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
7415e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
7427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitInt64Add(Node* node) { UNIMPLEMENTED(); }
7437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitInt64Sub(Node* node) { UNIMPLEMENTED(); }
7467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitInt64Mul(Node* node) { UNIMPLEMENTED(); }
7497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitInt64Div(Node* node) { UNIMPLEMENTED(); }
7527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitInt64UDiv(Node* node) { UNIMPLEMENTED(); }
7557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitInt64Mod(Node* node) { UNIMPLEMENTED(); }
7587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitInt64UMod(Node* node) { UNIMPLEMENTED(); }
7617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7635e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgvoid InstructionSelector::VisitChangeInt32ToInt64(Node* node) {
7645e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  UNIMPLEMENTED();
7655e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org}
7665e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
7675e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
7685e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgvoid InstructionSelector::VisitChangeUint32ToUint64(Node* node) {
7697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  UNIMPLEMENTED();
7707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
7717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7735e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgvoid InstructionSelector::VisitTruncateInt64ToInt32(Node* node) {
7747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  UNIMPLEMENTED();
7757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
7767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7773e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#endif  // V8_TARGET_ARCH_32_BIT && V8_TURBOFAN_BACKEND
7787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// 32-bit targets and unsupported architectures need dummy implementations of
7817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org// selected 64-bit ops.
7823e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#if V8_TARGET_ARCH_32_BIT || !V8_TURBOFAN_BACKEND
7837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitWord64Test(Node* node, FlagsContinuation* cont) {
7857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  UNIMPLEMENTED();
7867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
7877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitWord64Compare(Node* node,
7907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                                             FlagsContinuation* cont) {
7917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  UNIMPLEMENTED();
7927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
7937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7943e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#endif  // V8_TARGET_ARCH_32_BIT || !V8_TURBOFAN_BACKEND
7957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
797e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.orgvoid InstructionSelector::VisitFinish(Node* node) {
798e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  OperandGenerator g(this);
799e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Node* value = node->InputAt(0);
800e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value));
801e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org}
802e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
803e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
804aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.orgvoid InstructionSelector::VisitParameter(Node* node) {
805aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org  OperandGenerator g(this);
8069aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  int index = OpParameter<int>(node);
8079aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  Emit(kArchNop,
8089aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org       g.DefineAsLocation(node, linkage()->GetParameterLocation(index),
8099aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org                          linkage()->GetParameterType(index)));
810aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org}
811aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org
812aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org
8137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitPhi(Node* node) {
8147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // TODO(bmeurer): Emit a PhiInstruction here.
8157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  for (InputIter i = node->inputs().begin(); i != node->inputs().end(); ++i) {
8167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    MarkAsUsed(*i);
8177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
8187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
8197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
8207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
821aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.orgvoid InstructionSelector::VisitProjection(Node* node) {
822e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  OperandGenerator g(this);
823e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  Node* value = node->InputAt(0);
824e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  switch (value->opcode()) {
825e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    case IrOpcode::kInt32AddWithOverflow:
826e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    case IrOpcode::kInt32SubWithOverflow:
827e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org      if (OpParameter<size_t>(node) == 0) {
828e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value));
829e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      } else {
830e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org        DCHECK(OpParameter<size_t>(node) == 1u);
831e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        MarkAsUsed(value);
832e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      }
833e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      break;
834e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    default:
835e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      break;
836aca8beeda619beb0f9758b04d1eaebdea5538a44machenbach@chromium.org  }
8377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
8387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
8397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
8407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitConstant(Node* node) {
8417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // We must emit a NOP here because every live range needs a defining
8427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // instruction in the register allocator.
8437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  OperandGenerator g(this);
8447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Emit(kArchNop, g.DefineAsConstant(node));
8457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
8467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
8477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
8487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitGoto(BasicBlock* target) {
8497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  if (IsNextInAssemblyOrder(target)) {
8507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    // fall through to the next block.
8517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    Emit(kArchNop, NULL)->MarkAsControl();
8527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  } else {
8537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    // jump to the next block.
8547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    OperandGenerator g(this);
8557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    Emit(kArchJmp, NULL, g.Label(target))->MarkAsControl();
8567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
8577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
8587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
8597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
8607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
8617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                                      BasicBlock* fbranch) {
8627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  OperandGenerator g(this);
8637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* user = branch;
8647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  Node* value = branch->InputAt(0);
8657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
8667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  FlagsContinuation cont(kNotEqual, tbranch, fbranch);
8677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
8687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // If we can fall through to the true block, invert the branch.
8697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  if (IsNextInAssemblyOrder(tbranch)) {
8707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    cont.Negate();
8717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    cont.SwapBlocks();
8727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
8737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
8747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Try to combine with comparisons against 0 by simply inverting the branch.
8757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  while (CanCover(user, value)) {
8767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    if (value->opcode() == IrOpcode::kWord32Equal) {
8777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      Int32BinopMatcher m(value);
8787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.right().Is(0)) {
8797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        user = value;
8807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        value = m.left().node();
8817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        cont.Negate();
8827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      } else {
8837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        break;
8847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
8857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    } else if (value->opcode() == IrOpcode::kWord64Equal) {
8867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      Int64BinopMatcher m(value);
8877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      if (m.right().Is(0)) {
8887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        user = value;
8897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        value = m.left().node();
8907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        cont.Negate();
8917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      } else {
8927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        break;
8937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      }
8947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    } else {
8957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      break;
8967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
8977d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
8987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
8997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Try to combine the branch with a comparison.
9007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  if (CanCover(user, value)) {
9017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    switch (value->opcode()) {
9027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      case IrOpcode::kWord32Equal:
9037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        cont.OverwriteAndNegateIfEqual(kEqual);
9047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return VisitWord32Compare(value, &cont);
9057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      case IrOpcode::kInt32LessThan:
9067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        cont.OverwriteAndNegateIfEqual(kSignedLessThan);
9077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return VisitWord32Compare(value, &cont);
9087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      case IrOpcode::kInt32LessThanOrEqual:
9097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        cont.OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
9107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return VisitWord32Compare(value, &cont);
9117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      case IrOpcode::kUint32LessThan:
9127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        cont.OverwriteAndNegateIfEqual(kUnsignedLessThan);
9137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return VisitWord32Compare(value, &cont);
9147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      case IrOpcode::kUint32LessThanOrEqual:
9157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        cont.OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
9167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return VisitWord32Compare(value, &cont);
9177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      case IrOpcode::kWord64Equal:
9187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        cont.OverwriteAndNegateIfEqual(kEqual);
9197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return VisitWord64Compare(value, &cont);
9207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      case IrOpcode::kInt64LessThan:
9217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        cont.OverwriteAndNegateIfEqual(kSignedLessThan);
9227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return VisitWord64Compare(value, &cont);
9237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      case IrOpcode::kInt64LessThanOrEqual:
9247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        cont.OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
9257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return VisitWord64Compare(value, &cont);
9267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      case IrOpcode::kFloat64Equal:
9277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        cont.OverwriteAndNegateIfEqual(kUnorderedEqual);
9287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return VisitFloat64Compare(value, &cont);
9297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      case IrOpcode::kFloat64LessThan:
9307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        cont.OverwriteAndNegateIfEqual(kUnorderedLessThan);
9317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return VisitFloat64Compare(value, &cont);
9327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      case IrOpcode::kFloat64LessThanOrEqual:
9337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        cont.OverwriteAndNegateIfEqual(kUnorderedLessThanOrEqual);
9347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        return VisitFloat64Compare(value, &cont);
935e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      case IrOpcode::kProjection:
936e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        // Check if this is the overflow output projection of an
937e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        // <Operation>WithOverflow node.
938e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org        if (OpParameter<size_t>(value) == 1u) {
939e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org          // We cannot combine the <Operation>WithOverflow with this branch
940e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org          // unless the 0th projection (the use of the actual value of the
941e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org          // <Operation> is either NULL, which means there's no use of the
942e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org          // actual value, or was already defined, which means it is scheduled
943e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org          // *AFTER* this branch).
944e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org          Node* node = value->InputAt(0);
945e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org          Node* result = node->FindProjection(0);
946e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org          if (result == NULL || IsDefined(result)) {
947e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org            switch (node->opcode()) {
948e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org              case IrOpcode::kInt32AddWithOverflow:
949e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org                cont.OverwriteAndNegateIfEqual(kOverflow);
950e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org                return VisitInt32AddWithOverflow(node, &cont);
951e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org              case IrOpcode::kInt32SubWithOverflow:
952e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org                cont.OverwriteAndNegateIfEqual(kOverflow);
953e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org                return VisitInt32SubWithOverflow(node, &cont);
954e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org              default:
955e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org                break;
956e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org            }
957e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org          }
958e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        }
959e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        break;
9607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org      default:
9617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org        break;
9627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    }
9637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
9647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
9657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  // Branch could not be combined with a compare, emit compare against 0.
9667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  VisitWord32Test(value, &cont);
9677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
9687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
9697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
9707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitReturn(Node* value) {
9717d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  OperandGenerator g(this);
9727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  if (value != NULL) {
9739aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org    Emit(kArchRet, NULL, g.UseLocation(value, linkage()->GetReturnLocation(),
9749aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org                                       linkage()->GetReturnType()));
9757d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  } else {
9767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org    Emit(kArchRet, NULL);
9777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
9787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
9797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
9807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
9817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitThrow(Node* value) {
9827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  UNIMPLEMENTED();  // TODO(titzer)
9837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
9847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
9857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
986a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgFrameStateDescriptor* InstructionSelector::GetFrameStateDescriptor(
987a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    Node* state) {
9889aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  DCHECK(state->opcode() == IrOpcode::kFrameState);
9899aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  DCHECK_EQ(5, state->InputCount());
990ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  FrameStateCallInfo state_info = OpParameter<FrameStateCallInfo>(state);
9919aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  int parameters = OpParameter<int>(state->InputAt(0));
9929aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  int locals = OpParameter<int>(state->InputAt(1));
9939aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  int stack = OpParameter<int>(state->InputAt(2));
9949aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org
9959aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  FrameStateDescriptor* outer_state = NULL;
9969aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  Node* outer_node = state->InputAt(4);
9979aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  if (outer_node->opcode() == IrOpcode::kFrameState) {
9989aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org    outer_state = GetFrameStateDescriptor(outer_node);
9999aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  }
1000a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
1001a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  return new (instruction_zone())
10029aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org      FrameStateDescriptor(state_info, parameters, locals, stack, outer_state);
1003a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org}
1004a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
1005a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
10069d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.orgstatic InstructionOperand* UseOrImmediate(OperandGenerator* g, Node* input) {
10079d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  switch (input->opcode()) {
10089d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    case IrOpcode::kInt32Constant:
10099d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    case IrOpcode::kNumberConstant:
10109d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    case IrOpcode::kFloat64Constant:
10119d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    case IrOpcode::kHeapConstant:
10129d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      return g->UseImmediate(input);
10139d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    default:
10146474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      return g->UseUnique(input);
10159d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  }
10169d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org}
10179d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
10189d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
1019a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgvoid InstructionSelector::AddFrameStateInputs(
1020a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    Node* state, InstructionOperandVector* inputs,
1021a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    FrameStateDescriptor* descriptor) {
1022a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  DCHECK_EQ(IrOpcode::kFrameState, state->op()->opcode());
10239d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
10249aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  if (descriptor->outer_state() != NULL) {
10259aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org    AddFrameStateInputs(state->InputAt(4), inputs, descriptor->outer_state());
10269aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  }
10279aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org
10289d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  Node* parameters = state->InputAt(0);
10299d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  Node* locals = state->InputAt(1);
10309d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  Node* stack = state->InputAt(2);
1031ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  Node* context = state->InputAt(3);
1032ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org
1033ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  DCHECK_EQ(IrOpcode::kStateValues, parameters->op()->opcode());
1034ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  DCHECK_EQ(IrOpcode::kStateValues, locals->op()->opcode());
1035ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  DCHECK_EQ(IrOpcode::kStateValues, stack->op()->opcode());
1036a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
1037a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  DCHECK_EQ(descriptor->parameters_count(), parameters->InputCount());
1038a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  DCHECK_EQ(descriptor->locals_count(), locals->InputCount());
1039a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  DCHECK_EQ(descriptor->stack_count(), stack->InputCount());
10409d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org
10419d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  OperandGenerator g(this);
1042a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  for (int i = 0; i < static_cast<int>(descriptor->parameters_count()); i++) {
1043a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    inputs->push_back(UseOrImmediate(&g, parameters->InputAt(i)));
10449d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  }
1045a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  if (descriptor->HasContext()) {
1046a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org    inputs->push_back(UseOrImmediate(&g, context));
1047a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  }
1048a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  for (int i = 0; i < static_cast<int>(descriptor->locals_count()); i++) {
1049a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    inputs->push_back(UseOrImmediate(&g, locals->InputAt(i)));
10509d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  }
1051a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  for (int i = 0; i < static_cast<int>(descriptor->stack_count()); i++) {
1052a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    inputs->push_back(UseOrImmediate(&g, stack->InputAt(i)));
10539d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  }
1054a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org}
1055a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
1056a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org
10573e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#if !V8_TURBOFAN_BACKEND
10587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
10597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#define DECLARE_UNIMPLEMENTED_SELECTOR(x) \
10607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  void InstructionSelector::Visit##x(Node* node) { UNIMPLEMENTED(); }
10617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgMACHINE_OP_LIST(DECLARE_UNIMPLEMENTED_SELECTOR)
10627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#undef DECLARE_UNIMPLEMENTED_SELECTOR
10637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
10647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1065e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.orgvoid InstructionSelector::VisitInt32AddWithOverflow(Node* node,
1066e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org                                                    FlagsContinuation* cont) {
1067e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  UNIMPLEMENTED();
1068e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org}
1069e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
1070e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
1071e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.orgvoid InstructionSelector::VisitInt32SubWithOverflow(Node* node,
1072e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org                                                    FlagsContinuation* cont) {
1073e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  UNIMPLEMENTED();
1074e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org}
1075e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
1076e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
10777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitWord32Test(Node* node, FlagsContinuation* cont) {
10787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  UNIMPLEMENTED();
10797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
10807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
10817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
10827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitWord32Compare(Node* node,
10837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                                             FlagsContinuation* cont) {
10847d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  UNIMPLEMENTED();
10857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
10867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
10877d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
10887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitFloat64Compare(Node* node,
10897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                                              FlagsContinuation* cont) {
10907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  UNIMPLEMENTED();
10917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
10927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
10937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
10947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgvoid InstructionSelector::VisitCall(Node* call, BasicBlock* continuation,
10957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org                                    BasicBlock* deoptimization) {}
10967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
10973e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#endif  // !V8_TURBOFAN_BACKEND
10987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
10997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}  // namespace compiler
11007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}  // namespace internal
11017d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}  // namespace v8
1102