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-selector.h" 962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch#include "src/compiler/instruction.h" 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/linkage.h" 11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/schedule.h" 12958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/macro-assembler.h" 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace compiler { 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Helper struct containing data about a table or lookup switch. 19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstruct SwitchInfo { 20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int32_t min_value; // minimum value of {case_values} 21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int32_t max_value; // maximum value of {case_values} 22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t value_range; // |max_value - min_value| + 1 23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch size_t case_count; // number of cases 24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int32_t* case_values; // actual case values, unsorted 25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BasicBlock** case_branches; // basic blocks corresponding to case values 26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BasicBlock* default_branch; // default branch target 27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A helper class for the instruction selector that simplifies construction of 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Operands. This class implements a base for architecture-specific helpers. 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass OperandGenerator { 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit OperandGenerator(InstructionSelector* selector) 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : selector_(selector) {} 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand NoOutput() { 37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return InstructionOperand(); // Generates an invalid operand. 38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand DefineAsRegister(Node* node) { 41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Define(node, 42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, 43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GetVReg(node))); 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 46014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand DefineSameAsFirst(Node* node) { 47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Define(node, 48014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UnallocatedOperand(UnallocatedOperand::SAME_AS_FIRST_INPUT, 49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GetVReg(node))); 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand DefineAsFixed(Node* node, Register reg) { 53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Define(node, UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER, 54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reg.code(), GetVReg(node))); 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch template <typename FPRegType> 5813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch InstructionOperand DefineAsFixed(Node* node, FPRegType reg) { 59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Define(node, 6013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch UnallocatedOperand(UnallocatedOperand::FIXED_FP_REGISTER, 61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reg.code(), GetVReg(node))); 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand DefineAsConstant(Node* node) { 65f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return DefineAsConstant(node, ToConstant(node)); 66f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 67f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 68f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionOperand DefineAsConstant(Node* node, Constant constant) { 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch selector()->MarkAsDefined(node); 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int virtual_register = GetVReg(node); 71f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch sequence()->AddConstant(virtual_register, constant); 72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ConstantOperand(virtual_register); 73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 75f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionOperand DefineAsLocation(Node* node, LinkageLocation location) { 76f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Define(node, ToUnallocatedOperand(location, GetVReg(node))); 77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand DefineAsDualLocation(Node* node, 80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LinkageLocation primary_location, 81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LinkageLocation secondary_location) { 82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Define(node, 83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ToDualLocationUnallocatedOperand( 84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch primary_location, secondary_location, GetVReg(node))); 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand Use(Node* node) { 88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Use(node, UnallocatedOperand(UnallocatedOperand::NONE, 89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UnallocatedOperand::USED_AT_START, 90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GetVReg(node))); 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 93f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch InstructionOperand UseAnyAtEnd(Node* node) { 94f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return Use(node, UnallocatedOperand(UnallocatedOperand::ANY, 95f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch UnallocatedOperand::USED_AT_END, 96f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch GetVReg(node))); 97f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 98f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand UseAny(Node* node) { 100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Use(node, UnallocatedOperand(UnallocatedOperand::ANY, 101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UnallocatedOperand::USED_AT_START, 102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GetVReg(node))); 103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand UseRegister(Node* node) { 106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Use(node, UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, 107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UnallocatedOperand::USED_AT_START, 108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GetVReg(node))); 109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand UseUniqueSlot(Node* node) { 112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Use(node, UnallocatedOperand(UnallocatedOperand::MUST_HAVE_SLOT, 113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GetVReg(node))); 114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Use register or operand for the node. If a register is chosen, it won't 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // alias any temporary or output registers. 118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand UseUnique(Node* node) { 119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Use(node, 120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UnallocatedOperand(UnallocatedOperand::NONE, GetVReg(node))); 121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Use a unique register for the node that does not alias any temporary or 124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // output registers. 125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand UseUniqueRegister(Node* node) { 126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Use(node, UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, 127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GetVReg(node))); 128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand UseFixed(Node* node, Register reg) { 131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Use(node, UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER, 132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reg.code(), GetVReg(node))); 133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 13513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch template <typename FPRegType> 13613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch InstructionOperand UseFixed(Node* node, FPRegType reg) { 13713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return Use(node, UnallocatedOperand(UnallocatedOperand::FIXED_FP_REGISTER, 13813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch reg.code(), GetVReg(node))); 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand UseExplicit(LinkageLocation location) { 142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MachineRepresentation rep = InstructionSequence::DefaultRepresentation(); 143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (location.IsRegister()) { 144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ExplicitOperand(LocationOperand::REGISTER, rep, 145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch location.AsRegister()); 146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return ExplicitOperand(LocationOperand::STACK_SLOT, rep, 148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch location.GetLocation()); 149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 152f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionOperand UseImmediate(int immediate) { 153f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return sequence()->AddImmediate(Constant(immediate)); 154f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 155f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand UseImmediate(Node* node) { 157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return sequence()->AddImmediate(ToConstant(node)); 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 160f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionOperand UseNegatedImmediate(Node* node) { 161f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return sequence()->AddImmediate(ToNegatedConstant(node)); 162f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 163f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 164f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionOperand UseLocation(Node* node, LinkageLocation location) { 165f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Use(node, ToUnallocatedOperand(location, GetVReg(node))); 166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Used to force gap moves from the from_location to the to_location 169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // immediately before an instruction. 170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand UsePointerLocation(LinkageLocation to_location, 171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LinkageLocation from_location) { 172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UnallocatedOperand casted_from_operand = 173f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch UnallocatedOperand::cast(TempLocation(from_location)); 174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch selector_->Emit(kArchNop, casted_from_operand); 175f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return ToUnallocatedOperand(to_location, 176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch casted_from_operand.virtual_register()); 177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand TempRegister() { 180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, 181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UnallocatedOperand::USED_AT_START, 182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch sequence()->NextVirtualRegister()); 183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 18562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int AllocateVirtualRegister() { return sequence()->NextVirtualRegister(); } 18662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 18762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch InstructionOperand DefineSameAsFirstForVreg(int vreg) { 18862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return UnallocatedOperand(UnallocatedOperand::SAME_AS_FIRST_INPUT, vreg); 18962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 19062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 19162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch InstructionOperand DefineAsRegistertForVreg(int vreg) { 19262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg); 19362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 19462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 19562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch InstructionOperand UseRegisterForVreg(int vreg) { 19662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, 19762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch UnallocatedOperand::USED_AT_START, vreg); 19862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 19962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand TempDoubleRegister() { 201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UnallocatedOperand op = UnallocatedOperand( 202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UnallocatedOperand::MUST_HAVE_REGISTER, 203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UnallocatedOperand::USED_AT_START, sequence()->NextVirtualRegister()); 204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch sequence()->MarkAsRepresentation(MachineRepresentation::kFloat64, 205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch op.virtual_register()); 206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return op; 207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand TempRegister(Register reg) { 210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER, reg.code(), 211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand::kInvalidVirtualRegister); 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand TempImmediate(int32_t imm) { 215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return sequence()->AddImmediate(Constant(imm)); 216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 218f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstructionOperand TempLocation(LinkageLocation location) { 219f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return ToUnallocatedOperand(location, sequence()->NextVirtualRegister()); 220958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 221958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InstructionOperand Label(BasicBlock* block) { 223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return sequence()->AddImmediate( 224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Constant(RpoNumber::FromInt(block->rpo_number()))); 225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected: 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionSelector* selector() const { return selector_; } 229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionSequence* sequence() const { return selector()->sequence(); } 230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Zone* zone() const { return selector()->instruction_zone(); } 231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int GetVReg(Node* node) const { return selector_->GetVirtualRegister(node); } 234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static Constant ToConstant(const Node* node) { 236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (node->opcode()) { 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kInt32Constant: 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Constant(OpParameter<int32_t>(node)); 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kInt64Constant: 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Constant(OpParameter<int64_t>(node)); 241958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kFloat32Constant: 242958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Constant(OpParameter<float>(node)); 243bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case IrOpcode::kRelocatableInt32Constant: 244bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch case IrOpcode::kRelocatableInt64Constant: 245bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return Constant(OpParameter<RelocatablePtrConstantInfo>(node)); 246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kFloat64Constant: 247958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case IrOpcode::kNumberConstant: 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Constant(OpParameter<double>(node)); 249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kExternalConstant: 25013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch case IrOpcode::kComment: 251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Constant(OpParameter<ExternalReference>(node)); 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case IrOpcode::kHeapConstant: 253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Constant(OpParameter<Handle<HeapObject>>(node)); 254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Constant(static_cast<int32_t>(0)); 259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 261f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch static Constant ToNegatedConstant(const Node* node) { 262f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch switch (node->opcode()) { 263f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kInt32Constant: 264f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Constant(-OpParameter<int32_t>(node)); 265f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case IrOpcode::kInt64Constant: 266f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Constant(-OpParameter<int64_t>(node)); 267f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch default: 268f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 269f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 270f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch UNREACHABLE(); 271f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return Constant(static_cast<int32_t>(0)); 272f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 273f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UnallocatedOperand Define(Node* node, UnallocatedOperand operand) { 275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NOT_NULL(node); 276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(operand.virtual_register(), GetVReg(node)); 277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch selector()->MarkAsDefined(node); 278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return operand; 279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UnallocatedOperand Use(Node* node, UnallocatedOperand operand) { 282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NOT_NULL(node); 283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(operand.virtual_register(), GetVReg(node)); 284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch selector()->MarkAsUsed(node); 285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return operand; 286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UnallocatedOperand ToDualLocationUnallocatedOperand( 289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LinkageLocation primary_location, LinkageLocation secondary_location, 290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int virtual_register) { 291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // We only support the primary location being a register and the secondary 292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // one a slot. 293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(primary_location.IsRegister() && 294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch secondary_location.IsCalleeFrameSlot()); 295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int reg_id = primary_location.AsRegister(); 296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int slot_id = secondary_location.AsCalleeFrameSlot(); 297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return UnallocatedOperand(reg_id, slot_id, virtual_register); 298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UnallocatedOperand ToUnallocatedOperand(LinkageLocation location, 301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int virtual_register) { 302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (location.IsAnyRegister()) { 303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // any machine register. 304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, 305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch virtual_register); 306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (location.IsCallerFrameSlot()) { 308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // a location on the caller frame. 309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return UnallocatedOperand(UnallocatedOperand::FIXED_SLOT, 310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch location.AsCallerFrameSlot(), virtual_register); 311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (location.IsCalleeFrameSlot()) { 313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // a spill location on this (callee) frame. 314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return UnallocatedOperand(UnallocatedOperand::FIXED_SLOT, 315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch location.AsCalleeFrameSlot(), virtual_register); 316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // a fixed register. 318f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (IsFloatingPoint(location.GetType().representation())) { 31913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch return UnallocatedOperand(UnallocatedOperand::FIXED_FP_REGISTER, 320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch location.AsRegister(), virtual_register); 321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER, 323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch location.AsRegister(), virtual_register); 324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionSelector* selector_; 327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The flags continuation is a way to combine a branch or a materialization 331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// of a boolean value with an instruction that sets the flags register. 332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The whole instruction is treated as a unit by the register allocator, and 333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// thus no spills or moves can be introduced between the flags-setting 334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// instruction and the branch or set it should be combined with. 335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass FlagsContinuation final { 336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FlagsContinuation() : mode_(kFlags_none) {} 338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Creates a new flags continuation from the given condition and true/false 340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // blocks. 341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FlagsContinuation(FlagsCondition condition, BasicBlock* true_block, 342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BasicBlock* false_block) 343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : mode_(kFlags_branch), 344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch condition_(condition), 345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch true_block_(true_block), 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch false_block_(false_block) { 347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NOT_NULL(true_block); 348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NOT_NULL(false_block); 349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Creates a new flags continuation for an eager deoptimization exit. 3523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch static FlagsContinuation ForDeoptimize(FlagsCondition condition, 35362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DeoptimizeKind kind, 354f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DeoptimizeReason reason, 3553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Node* frame_state) { 35662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return FlagsContinuation(condition, kind, reason, frame_state); 3573b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 3583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 3593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Creates a new flags continuation for a boolean value. 3603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch static FlagsContinuation ForSet(FlagsCondition condition, Node* result) { 361f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return FlagsContinuation(condition, result); 362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 36462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Creates a new flags continuation for a wasm trap. 36562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch static FlagsContinuation ForTrap(FlagsCondition condition, 36662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Runtime::FunctionId trap_id, Node* result) { 36762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return FlagsContinuation(condition, trap_id, result); 36862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 36962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool IsNone() const { return mode_ == kFlags_none; } 371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool IsBranch() const { return mode_ == kFlags_branch; } 3723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch bool IsDeoptimize() const { return mode_ == kFlags_deoptimize; } 373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool IsSet() const { return mode_ == kFlags_set; } 37462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool IsTrap() const { return mode_ == kFlags_trap; } 375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FlagsCondition condition() const { 376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!IsNone()); 377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return condition_; 378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 37962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DeoptimizeKind kind() const { 38062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(IsDeoptimize()); 38162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return kind_; 38262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 383f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DeoptimizeReason reason() const { 384f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(IsDeoptimize()); 385f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return reason_; 386f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 3873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Node* frame_state() const { 3883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch DCHECK(IsDeoptimize()); 3893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return frame_state_or_result_; 3903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* result() const { 392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsSet()); 3933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch return frame_state_or_result_; 394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 39562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Runtime::FunctionId trap_id() const { 39662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(IsTrap()); 39762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return trap_id_; 39862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BasicBlock* true_block() const { 400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsBranch()); 401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true_block_; 402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BasicBlock* false_block() const { 404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsBranch()); 405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false_block_; 406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Negate() { 409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!IsNone()); 410958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier condition_ = NegateFlagsCondition(condition_); 411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Commute() { 414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!IsNone()); 415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch condition_ = CommuteFlagsCondition(condition_); 416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 418f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void Overwrite(FlagsCondition condition) { condition_ = condition; } 419f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void OverwriteAndNegateIfEqual(FlagsCondition condition) { 421c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DCHECK(condition_ == kEqual || condition_ == kNotEqual); 422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool negate = condition_ == kEqual; 423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch condition_ = condition; 424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (negate) Negate(); 425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 427f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void OverwriteUnsignedIfSigned() { 428f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch switch (condition_) { 429f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kSignedLessThan: 430f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch condition_ = kUnsignedLessThan; 431f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 432f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kSignedLessThanOrEqual: 433f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch condition_ = kUnsignedLessThanOrEqual; 434f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 435f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kSignedGreaterThan: 436f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch condition_ = kUnsignedGreaterThan; 437f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 438f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch case kSignedGreaterThanOrEqual: 439f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch condition_ = kUnsignedGreaterThanOrEqual; 440f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 441f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch default: 442f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch break; 443f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 444f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 445f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Encodes this flags continuation into the given opcode. 447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionCode Encode(InstructionCode opcode) { 448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch opcode |= FlagsModeField::encode(mode_); 449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mode_ != kFlags_none) { 450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch opcode |= FlagsConditionField::encode(condition_); 451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return opcode; 453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 45662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch FlagsContinuation(FlagsCondition condition, DeoptimizeKind kind, 45762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DeoptimizeReason reason, Node* frame_state) 458f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch : mode_(kFlags_deoptimize), 459f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch condition_(condition), 46062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch kind_(kind), 461f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch reason_(reason), 462f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch frame_state_or_result_(frame_state) { 463f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK_NOT_NULL(frame_state); 464f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 465f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch FlagsContinuation(FlagsCondition condition, Node* result) 466f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch : mode_(kFlags_set), 4673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch condition_(condition), 468f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch frame_state_or_result_(result) { 469f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK_NOT_NULL(result); 4703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch } 4713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 47262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch FlagsContinuation(FlagsCondition condition, Runtime::FunctionId trap_id, 47362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* result) 47462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch : mode_(kFlags_trap), 47562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch condition_(condition), 47662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch frame_state_or_result_(result), 47762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch trap_id_(trap_id) { 47862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK_NOT_NULL(result); 47962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 48062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 4813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch FlagsMode const mode_; 482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FlagsCondition condition_; 48362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DeoptimizeKind kind_; // Only valid if mode_ == kFlags_deoptimize 48462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DeoptimizeReason reason_; // Only valid if mode_ == kFlags_deoptimize 4853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Node* frame_state_or_result_; // Only valid if mode_ == kFlags_deoptimize 4863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // or mode_ == kFlags_set. 4873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch BasicBlock* true_block_; // Only valid if mode_ == kFlags_branch. 4883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch BasicBlock* false_block_; // Only valid if mode_ == kFlags_branch. 48962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Runtime::FunctionId trap_id_; // Only valid if mode_ == kFlags_trap. 490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace compiler 493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace internal 494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace v8 495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // V8_COMPILER_INSTRUCTION_SELECTOR_IMPL_H_ 497