1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2014 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef V8_COMPILER_INSTRUCTION_SELECTOR_IMPL_H_ 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define V8_COMPILER_INSTRUCTION_SELECTOR_IMPL_H_ 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/instruction.h" 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/instruction-selector.h" 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/linkage.h" 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace compiler { 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A helper class for the instruction selector that simplifies construction of 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Operands. This class implements a base for architecture-specific helpers. 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass OperandGenerator { 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit OperandGenerator(InstructionSelector* selector) 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : selector_(selector) {} 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperand* DefineAsRegister(Node* node) { 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Define(node, new (zone()) 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER)); 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperand* DefineSameAsFirst(Node* result) { 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Define(result, new (zone()) 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UnallocatedOperand(UnallocatedOperand::SAME_AS_FIRST_INPUT)); 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperand* DefineAsFixed(Node* node, Register reg) { 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Define(node, new (zone()) 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER, 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register::ToAllocationIndex(reg))); 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperand* DefineAsFixed(Node* node, DoubleRegister reg) { 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Define(node, new (zone()) 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UnallocatedOperand(UnallocatedOperand::FIXED_DOUBLE_REGISTER, 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DoubleRegister::ToAllocationIndex(reg))); 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperand* DefineAsConstant(Node* node) { 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch selector()->MarkAsDefined(node); 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sequence()->AddConstant(node->id(), ToConstant(node)); 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ConstantOperand::Create(node->id(), zone()); 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperand* DefineAsLocation(Node* node, LinkageLocation location, 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MachineType type) { 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Define(node, ToUnallocatedOperand(location, type)); 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperand* Use(Node* node) { 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Use(node, 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new (zone()) UnallocatedOperand( 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UnallocatedOperand::ANY, UnallocatedOperand::USED_AT_START)); 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperand* UseRegister(Node* node) { 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Use(node, new (zone()) 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UnallocatedOperand::USED_AT_START)); 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Use register or operand for the node. If a register is chosen, it won't 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // alias any temporary or output registers. 70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperand* UseUnique(Node* node) { 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Use(node, new (zone()) UnallocatedOperand(UnallocatedOperand::ANY)); 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Use a unique register for the node that does not alias any temporary or 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // output registers. 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperand* UseUniqueRegister(Node* node) { 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Use(node, new (zone()) 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER)); 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperand* UseFixed(Node* node, Register reg) { 82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Use(node, new (zone()) 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER, 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register::ToAllocationIndex(reg))); 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperand* UseFixed(Node* node, DoubleRegister reg) { 88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Use(node, new (zone()) 89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UnallocatedOperand(UnallocatedOperand::FIXED_DOUBLE_REGISTER, 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DoubleRegister::ToAllocationIndex(reg))); 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperand* UseImmediate(Node* node) { 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int index = sequence()->AddImmediate(ToConstant(node)); 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ImmediateOperand::Create(index, zone()); 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperand* UseLocation(Node* node, LinkageLocation location, 99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MachineType type) { 100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Use(node, ToUnallocatedOperand(location, type)); 101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperand* TempRegister() { 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UnallocatedOperand* op = 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new (zone()) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UnallocatedOperand::USED_AT_START); 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch op->set_virtual_register(sequence()->NextVirtualRegister()); 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return op; 109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperand* TempDoubleRegister() { 112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UnallocatedOperand* op = 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new (zone()) UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, 114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UnallocatedOperand::USED_AT_START); 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch op->set_virtual_register(sequence()->NextVirtualRegister()); 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch sequence()->MarkAsDouble(op->virtual_register()); 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return op; 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperand* TempRegister(Register reg) { 121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return new (zone()) UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER, 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register::ToAllocationIndex(reg)); 123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperand* TempImmediate(int32_t imm) { 126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int index = sequence()->AddImmediate(Constant(imm)); 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return ImmediateOperand::Create(index, zone()); 128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperand* Label(BasicBlock* block) { 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(bmeurer): We misuse ImmediateOperand here. 132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return TempImmediate(block->id()); 133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected: 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Graph* graph() const { return selector()->graph(); } 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionSelector* selector() const { return selector_; } 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionSequence* sequence() const { return selector()->sequence(); } 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate() const { return zone()->isolate(); } 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Zone* zone() const { return selector()->instruction_zone(); } 141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static Constant ToConstant(const Node* node) { 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (node->opcode()) { 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kInt32Constant: 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Constant(OpParameter<int32_t>(node)); 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kInt64Constant: 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Constant(OpParameter<int64_t>(node)); 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kNumberConstant: 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kFloat64Constant: 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Constant(OpParameter<double>(node)); 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kExternalConstant: 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Constant(OpParameter<ExternalReference>(node)); 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kHeapConstant: 155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Constant(OpParameter<Unique<HeapObject> >(node).handle()); 156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Constant(static_cast<int32_t>(0)); 161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UnallocatedOperand* Define(Node* node, UnallocatedOperand* operand) { 164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NOT_NULL(node); 165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NOT_NULL(operand); 166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch operand->set_virtual_register(node->id()); 167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch selector()->MarkAsDefined(node); 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return operand; 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UnallocatedOperand* Use(Node* node, UnallocatedOperand* operand) { 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NOT_NULL(node); 173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NOT_NULL(operand); 174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch operand->set_virtual_register(node->id()); 175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch selector()->MarkAsUsed(node); 176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return operand; 177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UnallocatedOperand* ToUnallocatedOperand(LinkageLocation location, 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MachineType type) { 181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (location.location_ == LinkageLocation::ANY_REGISTER) { 182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return new (zone()) 183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER); 184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (location.location_ < 0) { 186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return new (zone()) UnallocatedOperand(UnallocatedOperand::FIXED_SLOT, 187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch location.location_); 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (RepresentationOf(type) == kRepFloat64) { 190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return new (zone()) UnallocatedOperand( 191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UnallocatedOperand::FIXED_DOUBLE_REGISTER, location.location_); 192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return new (zone()) UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER, 194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch location.location_); 195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionSelector* selector_; 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The flags continuation is a way to combine a branch or a materialization 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// of a boolean value with an instruction that sets the flags register. 203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The whole instruction is treated as a unit by the register allocator, and 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// thus no spills or moves can be introduced between the flags-setting 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// instruction and the branch or set it should be combined with. 206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass FlagsContinuation FINAL { 207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FlagsContinuation() : mode_(kFlags_none) {} 209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Creates a new flags continuation from the given condition and true/false 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // blocks. 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FlagsContinuation(FlagsCondition condition, BasicBlock* true_block, 213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BasicBlock* false_block) 214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : mode_(kFlags_branch), 215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch condition_(condition), 216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch true_block_(true_block), 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch false_block_(false_block) { 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NOT_NULL(true_block); 219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NOT_NULL(false_block); 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Creates a new flags continuation from the given condition and result node. 223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FlagsContinuation(FlagsCondition condition, Node* result) 224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : mode_(kFlags_set), condition_(condition), result_(result) { 225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NOT_NULL(result); 226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool IsNone() const { return mode_ == kFlags_none; } 229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool IsBranch() const { return mode_ == kFlags_branch; } 230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool IsSet() const { return mode_ == kFlags_set; } 231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FlagsCondition condition() const { 232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!IsNone()); 233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return condition_; 234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* result() const { 236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsSet()); 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result_; 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BasicBlock* true_block() const { 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsBranch()); 241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true_block_; 242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BasicBlock* false_block() const { 244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsBranch()); 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false_block_; 246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Negate() { 249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!IsNone()); 250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch condition_ = static_cast<FlagsCondition>(condition_ ^ 1); 251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Commute() { 254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!IsNone()); 255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (condition_) { 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kEqual: 257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kNotEqual: 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kOverflow: 259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kNotOverflow: 260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kSignedLessThan: 262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch condition_ = kSignedGreaterThan; 263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kSignedGreaterThanOrEqual: 265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch condition_ = kSignedLessThanOrEqual; 266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kSignedLessThanOrEqual: 268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch condition_ = kSignedGreaterThanOrEqual; 269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kSignedGreaterThan: 271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch condition_ = kSignedLessThan; 272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kUnsignedLessThan: 274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch condition_ = kUnsignedGreaterThan; 275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kUnsignedGreaterThanOrEqual: 277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch condition_ = kUnsignedLessThanOrEqual; 278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kUnsignedLessThanOrEqual: 280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch condition_ = kUnsignedGreaterThanOrEqual; 281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kUnsignedGreaterThan: 283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch condition_ = kUnsignedLessThan; 284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kUnorderedEqual: 286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kUnorderedNotEqual: 287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kUnorderedLessThan: 289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch condition_ = kUnorderedGreaterThan; 290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kUnorderedGreaterThanOrEqual: 292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch condition_ = kUnorderedLessThanOrEqual; 293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kUnorderedLessThanOrEqual: 295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch condition_ = kUnorderedGreaterThanOrEqual; 296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case kUnorderedGreaterThan: 298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch condition_ = kUnorderedLessThan; 299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void OverwriteAndNegateIfEqual(FlagsCondition condition) { 305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool negate = condition_ == kEqual; 306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch condition_ = condition; 307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (negate) Negate(); 308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SwapBlocks() { std::swap(true_block_, false_block_); } 311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Encodes this flags continuation into the given opcode. 313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionCode Encode(InstructionCode opcode) { 314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch opcode |= FlagsModeField::encode(mode_); 315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mode_ != kFlags_none) { 316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch opcode |= FlagsConditionField::encode(condition_); 317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return opcode; 319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FlagsMode mode_; 323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FlagsCondition condition_; 324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* result_; // Only valid if mode_ == kFlags_set. 325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BasicBlock* true_block_; // Only valid if mode_ == kFlags_branch. 326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BasicBlock* false_block_; // Only valid if mode_ == kFlags_branch. 327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// An internal helper class for generating the operands to calls. 331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// TODO(bmeurer): Get rid of the CallBuffer business and make 332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// InstructionSelector::VisitCall platform independent instead. 333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstruct CallBuffer { 334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallBuffer(Zone* zone, CallDescriptor* descriptor, 335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FrameStateDescriptor* frame_state); 336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallDescriptor* descriptor; 338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FrameStateDescriptor* frame_state_descriptor; 339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NodeVector output_nodes; 340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperandVector outputs; 341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperandVector instruction_args; 342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NodeVector pushed_nodes; 343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t input_count() const { return descriptor->InputCount(); } 345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t frame_state_count() const { return descriptor->FrameStateCount(); } 347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch size_t frame_state_value_count() const { 349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return (frame_state_descriptor == NULL) 350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? 0 351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : (frame_state_descriptor->GetTotalSize() + 352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1); // Include deopt id. 353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace compiler 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace internal 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace v8 359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // V8_COMPILER_INSTRUCTION_SELECTOR_IMPL_H_ 361