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