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_H_
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define V8_COMPILER_INSTRUCTION_H_
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <deque>
9958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include <iosfwd>
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <map>
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <set>
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
13c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#include "src/base/compiler-specific.h"
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/common-operator.h"
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/frame.h"
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/instruction-codes.h"
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/opcodes.h"
18c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#include "src/globals.h"
19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/macro-assembler.h"
20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/register-configuration.h"
21f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/zone/zone-allocator.h"
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
25c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
26c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochclass SourcePosition;
27c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace compiler {
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass Schedule;
31c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochclass SourcePositionTable;
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
33c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochclass V8_EXPORT_PRIVATE InstructionOperand {
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static const int kInvalidVirtualRegister = -1;
36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // TODO(dcarney): recover bit. INVALID can be represented as UNALLOCATED with
38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // kInvalidVirtualRegister and some DCHECKS.
39f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  enum Kind {
40f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    INVALID,
41f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    UNALLOCATED,
42f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    CONSTANT,
43f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    IMMEDIATE,
44f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // Location operand kinds.
45f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    EXPLICIT,
46f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ALLOCATED,
47f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    FIRST_LOCATION_OPERAND_KIND = EXPLICIT
48f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // Location operand kinds must be last.
49f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  };
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand() : InstructionOperand(INVALID) {}
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Kind kind() const { return KindField::decode(value_); }
54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define INSTRUCTION_OPERAND_PREDICATE(name, type) \
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool Is##name() const { return kind() == type; }
57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  INSTRUCTION_OPERAND_PREDICATE(Invalid, INVALID)
58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // UnallocatedOperands are place-holder operands created before register
59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // allocation. They later are assigned registers and become AllocatedOperands.
60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  INSTRUCTION_OPERAND_PREDICATE(Unallocated, UNALLOCATED)
61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Constant operands participate in register allocation. They are allocated to
62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // registers but have a special "spilling" behavior. When a ConstantOperand
63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // value must be rematerialized, it is loaded from an immediate constant
64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // rather from an unspilled slot.
65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  INSTRUCTION_OPERAND_PREDICATE(Constant, CONSTANT)
66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // ImmediateOperands do not participate in register allocation and are only
67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // embedded directly in instructions, e.g. small integers and on some
68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // platforms Objects.
69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  INSTRUCTION_OPERAND_PREDICATE(Immediate, IMMEDIATE)
70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // ExplicitOperands do not participate in register allocation. They are
71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // created by the instruction selector for direct access to registers and
72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // stack slots, completely bypassing the register allocator. They are never
73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // associated with a virtual register
74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  INSTRUCTION_OPERAND_PREDICATE(Explicit, EXPLICIT)
75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // AllocatedOperands are registers or stack slots that are assigned by the
76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // register allocator and are always associated with a virtual register.
77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  INSTRUCTION_OPERAND_PREDICATE(Allocated, ALLOCATED)
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef INSTRUCTION_OPERAND_PREDICATE
79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
80f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  inline bool IsAnyLocationOperand() const;
81f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  inline bool IsLocationOperand() const;
82f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  inline bool IsFPLocationOperand() const;
83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  inline bool IsAnyRegister() const;
84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  inline bool IsRegister() const;
85bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  inline bool IsFPRegister() const;
86bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  inline bool IsFloatRegister() const;
87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  inline bool IsDoubleRegister() const;
88109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  inline bool IsSimd128Register() const;
89f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  inline bool IsAnyStackSlot() const;
90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  inline bool IsStackSlot() const;
91bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  inline bool IsFPStackSlot() const;
92bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  inline bool IsFloatStackSlot() const;
93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  inline bool IsDoubleStackSlot() const;
94109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  inline bool IsSimd128StackSlot() const;
95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  template <typename SubKindOperand>
97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static SubKindOperand* New(Zone* zone, const SubKindOperand& op) {
98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    void* buffer = zone->New(sizeof(op));
99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return new (buffer) SubKindOperand(op);
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static void ReplaceWith(InstructionOperand* dest,
103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                          const InstructionOperand* src) {
104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    *dest = *src;
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool Equals(const InstructionOperand& that) const {
108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return this->value_ == that.value_;
109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool Compare(const InstructionOperand& that) const {
112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return this->value_ < that.value_;
113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool EqualsCanonicalized(const InstructionOperand& that) const {
116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return this->GetCanonicalizedValue() == that.GetCanonicalizedValue();
117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool CompareCanonicalized(const InstructionOperand& that) const {
120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return this->GetCanonicalizedValue() < that.GetCanonicalizedValue();
121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
123c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  bool InterferesWith(const InstructionOperand& other) const;
12413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
125f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // APIs to aid debugging. For general-stream APIs, use operator<<
126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Print(const RegisterConfiguration* config) const;
127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Print() const;
128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  explicit InstructionOperand(Kind kind) : value_(KindField::encode(kind)) {}
131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  inline uint64_t GetCanonicalizedValue() const;
133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  class KindField : public BitField64<Kind, 0, 3> {};
135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  uint64_t value_;
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtypedef ZoneVector<InstructionOperand> InstructionOperandVector;
141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstruct PrintableInstructionOperand {
144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const RegisterConfiguration* register_configuration_;
145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand op_;
146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier};
147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstd::ostream& operator<<(std::ostream& os,
150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                         const PrintableInstructionOperand& op);
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define INSTRUCTION_OPERAND_CASTS(OperandType, OperandKind)      \
154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                                 \
155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static OperandType* cast(InstructionOperand* op) {             \
156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_EQ(OperandKind, op->kind());                          \
157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return static_cast<OperandType*>(op);                        \
158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }                                                              \
159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                                 \
160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static const OperandType* cast(const InstructionOperand* op) { \
161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_EQ(OperandKind, op->kind());                          \
162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return static_cast<const OperandType*>(op);                  \
163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }                                                              \
164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                                 \
165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static OperandType cast(const InstructionOperand& op) {        \
166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_EQ(OperandKind, op.kind());                           \
167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return *static_cast<const OperandType*>(&op);                \
168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass UnallocatedOperand : public InstructionOperand {
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  enum BasicPolicy { FIXED_SLOT, EXTENDED_POLICY };
173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  enum ExtendedPolicy {
175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    NONE,
176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ANY,
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FIXED_REGISTER,
17813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    FIXED_FP_REGISTER,
179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MUST_HAVE_REGISTER,
180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MUST_HAVE_SLOT,
181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SAME_AS_FIRST_INPUT
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Lifetime of operand inside the instruction.
185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  enum Lifetime {
186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // USED_AT_START operand is guaranteed to be live only at
187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // instruction start. Register allocator is free to assign the same register
188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // to some other operand used inside instruction (i.e. temporary or
189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // output).
190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    USED_AT_START,
191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // USED_AT_END operand is treated as live until the end of
193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // instruction. This means that register allocator will not reuse it's
194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // register for any other operand inside instruction.
195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    USED_AT_END
196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UnallocatedOperand(ExtendedPolicy policy, int virtual_register)
199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : UnallocatedOperand(virtual_register) {
200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value_ |= BasicPolicyField::encode(EXTENDED_POLICY);
201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value_ |= ExtendedPolicyField::encode(policy);
202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value_ |= LifetimeField::encode(USED_AT_END);
203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UnallocatedOperand(BasicPolicy policy, int index, int virtual_register)
206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : UnallocatedOperand(virtual_register) {
207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(policy == FIXED_SLOT);
208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value_ |= BasicPolicyField::encode(policy);
209958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    value_ |= static_cast<int64_t>(index) << FixedSlotIndexField::kShift;
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(this->fixed_slot_index() == index);
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UnallocatedOperand(ExtendedPolicy policy, int index, int virtual_register)
214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : UnallocatedOperand(virtual_register) {
21513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    DCHECK(policy == FIXED_REGISTER || policy == FIXED_FP_REGISTER);
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value_ |= BasicPolicyField::encode(EXTENDED_POLICY);
217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value_ |= ExtendedPolicyField::encode(policy);
218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value_ |= LifetimeField::encode(USED_AT_END);
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value_ |= FixedRegisterField::encode(index);
220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UnallocatedOperand(ExtendedPolicy policy, Lifetime lifetime,
223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                     int virtual_register)
224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : UnallocatedOperand(virtual_register) {
225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value_ |= BasicPolicyField::encode(EXTENDED_POLICY);
226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value_ |= ExtendedPolicyField::encode(policy);
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value_ |= LifetimeField::encode(lifetime);
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UnallocatedOperand(int reg_id, int slot_id, int virtual_register)
231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : UnallocatedOperand(FIXED_REGISTER, reg_id, virtual_register) {
232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value_ |= HasSecondaryStorageField::encode(true);
233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value_ |= SecondaryStorageField::encode(slot_id);
234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Predicates for the operand policy.
237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool HasAnyPolicy() const {
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return basic_policy() == EXTENDED_POLICY && extended_policy() == ANY;
239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool HasFixedPolicy() const {
241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return basic_policy() == FIXED_SLOT ||
242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           extended_policy() == FIXED_REGISTER ||
24313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch           extended_policy() == FIXED_FP_REGISTER;
244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool HasRegisterPolicy() const {
246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return basic_policy() == EXTENDED_POLICY &&
247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           extended_policy() == MUST_HAVE_REGISTER;
248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool HasSlotPolicy() const {
250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return basic_policy() == EXTENDED_POLICY &&
251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           extended_policy() == MUST_HAVE_SLOT;
252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool HasSameAsInputPolicy() const {
254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return basic_policy() == EXTENDED_POLICY &&
255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           extended_policy() == SAME_AS_FIRST_INPUT;
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool HasFixedSlotPolicy() const { return basic_policy() == FIXED_SLOT; }
258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool HasFixedRegisterPolicy() const {
259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return basic_policy() == EXTENDED_POLICY &&
260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           extended_policy() == FIXED_REGISTER;
261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
26213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  bool HasFixedFPRegisterPolicy() const {
263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return basic_policy() == EXTENDED_POLICY &&
26413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch           extended_policy() == FIXED_FP_REGISTER;
265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool HasSecondaryStorage() const {
267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return basic_policy() == EXTENDED_POLICY &&
268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           extended_policy() == FIXED_REGISTER &&
269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           HasSecondaryStorageField::decode(value_);
270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int GetSecondaryStorage() const {
272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(HasSecondaryStorage());
273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return SecondaryStorageField::decode(value_);
274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // [basic_policy]: Distinguish between FIXED_SLOT and all other policies.
277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BasicPolicy basic_policy() const {
278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_EQ(UNALLOCATED, kind());
279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return BasicPolicyField::decode(value_);
280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // [extended_policy]: Only for non-FIXED_SLOT. The finer-grained policy.
283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ExtendedPolicy extended_policy() const {
284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(basic_policy() == EXTENDED_POLICY);
285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return ExtendedPolicyField::decode(value_);
286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // [fixed_slot_index]: Only for FIXED_SLOT.
289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int fixed_slot_index() const {
290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(HasFixedSlotPolicy());
291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return static_cast<int>(static_cast<int64_t>(value_) >>
292958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                            FixedSlotIndexField::kShift);
293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
29513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  // [fixed_register_index]: Only for FIXED_REGISTER or FIXED_FP_REGISTER.
296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int fixed_register_index() const {
29713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    DCHECK(HasFixedRegisterPolicy() || HasFixedFPRegisterPolicy());
298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return FixedRegisterField::decode(value_);
299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // [virtual_register]: The virtual register ID for this operand.
302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int32_t virtual_register() const {
303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_EQ(UNALLOCATED, kind());
304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return static_cast<int32_t>(VirtualRegisterField::decode(value_));
305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // TODO(dcarney): remove this.
308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_virtual_register(int32_t id) {
309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_EQ(UNALLOCATED, kind());
310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value_ = VirtualRegisterField::update(value_, static_cast<uint32_t>(id));
311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // [lifetime]: Only for non-FIXED_SLOT.
314958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool IsUsedAtStart() const {
315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(basic_policy() == EXTENDED_POLICY);
316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return LifetimeField::decode(value_) == USED_AT_START;
317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  INSTRUCTION_OPERAND_CASTS(UnallocatedOperand, UNALLOCATED);
320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The encoding used for UnallocatedOperand operands depends on the policy
322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // that is
323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // stored within the operand. The FIXED_SLOT policy uses a compact encoding
324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // because it accommodates a larger pay-load.
325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //
326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // For FIXED_SLOT policy:
327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //     +------------------------------------------------+
328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //     |      slot_index   | 0 | virtual_register | 001 |
329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //     +------------------------------------------------+
330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //
331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // For all other (extended) policies:
332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //     +-----------------------------------------------------+
333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //     |  reg_index  | L | PPP |  1 | virtual_register | 001 |
334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //     +-----------------------------------------------------+
335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //     L ... Lifetime
336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //     P ... Policy
337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  //
338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The slot index is a signed value which requires us to decode it manually
339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // instead of using the BitField utility class.
340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  STATIC_ASSERT(KindField::kSize == 3);
342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  class VirtualRegisterField : public BitField64<uint32_t, 3, 32> {};
344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // BitFields for all unallocated operands.
346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  class BasicPolicyField : public BitField64<BasicPolicy, 35, 1> {};
347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // BitFields specific to BasicPolicy::FIXED_SLOT.
349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  class FixedSlotIndexField : public BitField64<int, 36, 28> {};
350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // BitFields specific to BasicPolicy::EXTENDED_POLICY.
352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  class ExtendedPolicyField : public BitField64<ExtendedPolicy, 36, 3> {};
353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  class LifetimeField : public BitField64<Lifetime, 39, 1> {};
354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  class HasSecondaryStorageField : public BitField64<bool, 40, 1> {};
355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  class FixedRegisterField : public BitField64<int, 41, 6> {};
356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  class SecondaryStorageField : public BitField64<int, 47, 3> {};
357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  explicit UnallocatedOperand(int virtual_register)
360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : InstructionOperand(UNALLOCATED) {
361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value_ |=
362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        VirtualRegisterField::encode(static_cast<uint32_t>(virtual_register));
363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass ConstantOperand : public InstructionOperand {
368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  explicit ConstantOperand(int virtual_register)
370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : InstructionOperand(CONSTANT) {
371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value_ |=
372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        VirtualRegisterField::encode(static_cast<uint32_t>(virtual_register));
373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int32_t virtual_register() const {
376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return static_cast<int32_t>(VirtualRegisterField::decode(value_));
377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static ConstantOperand* New(Zone* zone, int virtual_register) {
380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return InstructionOperand::New(zone, ConstantOperand(virtual_register));
381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  INSTRUCTION_OPERAND_CASTS(ConstantOperand, CONSTANT);
384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  STATIC_ASSERT(KindField::kSize == 3);
386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  class VirtualRegisterField : public BitField64<uint32_t, 3, 32> {};
387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass ImmediateOperand : public InstructionOperand {
391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  enum ImmediateType { INLINE, INDEXED };
393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  explicit ImmediateOperand(ImmediateType type, int32_t value)
395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : InstructionOperand(IMMEDIATE) {
396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value_ |= TypeField::encode(type);
397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value_ |= static_cast<int64_t>(value) << ValueField::kShift;
398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ImmediateType type() const { return TypeField::decode(value_); }
401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int32_t inline_value() const {
403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_EQ(INLINE, type());
404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return static_cast<int64_t>(value_) >> ValueField::kShift;
405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int32_t indexed_value() const {
408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_EQ(INDEXED, type());
409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return static_cast<int64_t>(value_) >> ValueField::kShift;
410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static ImmediateOperand* New(Zone* zone, ImmediateType type, int32_t value) {
413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return InstructionOperand::New(zone, ImmediateOperand(type, value));
414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  INSTRUCTION_OPERAND_CASTS(ImmediateOperand, IMMEDIATE);
417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  STATIC_ASSERT(KindField::kSize == 3);
419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  class TypeField : public BitField64<ImmediateType, 3, 1> {};
420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  class ValueField : public BitField64<int32_t, 32, 32> {};
421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
423958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass LocationOperand : public InstructionOperand {
425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  enum LocationKind { REGISTER, STACK_SLOT };
427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LocationOperand(InstructionOperand::Kind operand_kind,
429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  LocationOperand::LocationKind location_kind,
430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  MachineRepresentation rep, int index)
431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : InstructionOperand(operand_kind) {
432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_IMPLIES(location_kind == REGISTER, index >= 0);
433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(IsSupportedRepresentation(rep));
434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value_ |= LocationKindField::encode(location_kind);
435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value_ |= RepresentationField::encode(rep);
436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    value_ |= static_cast<int64_t>(index) << IndexField::kShift;
437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int index() const {
440bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    DCHECK(IsStackSlot() || IsFPStackSlot());
441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return static_cast<int64_t>(value_) >> IndexField::kShift;
442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
44413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  int register_code() const {
44513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    DCHECK(IsRegister() || IsFPRegister());
44613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    return static_cast<int64_t>(value_) >> IndexField::kShift;
44713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
44813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Register GetRegister() const {
450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(IsRegister());
45113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    return Register::from_code(register_code());
452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
454bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  FloatRegister GetFloatRegister() const {
455bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    DCHECK(IsFloatRegister());
45613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    return FloatRegister::from_code(register_code());
457bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
458bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DoubleRegister GetDoubleRegister() const {
46013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    // On platforms where FloatRegister, DoubleRegister, and Simd128Register
46113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    // are all the same type, it's convenient to treat everything as a
46213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    // DoubleRegister, so be lax about type checking here.
463bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    DCHECK(IsFPRegister());
46413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    return DoubleRegister::from_code(register_code());
465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
467109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Simd128Register GetSimd128Register() const {
468109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    DCHECK(IsSimd128Register());
46913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    return Simd128Register::from_code(register_code());
470109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
471109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LocationKind location_kind() const {
473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return LocationKindField::decode(value_);
474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MachineRepresentation representation() const {
477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return RepresentationField::decode(value_);
478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static bool IsSupportedRepresentation(MachineRepresentation rep) {
481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    switch (rep) {
482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case MachineRepresentation::kWord32:
483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case MachineRepresentation::kWord64:
484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case MachineRepresentation::kFloat32:
485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case MachineRepresentation::kFloat64:
486109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      case MachineRepresentation::kSimd128:
48762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      case MachineRepresentation::kSimd1x4:
48862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      case MachineRepresentation::kSimd1x8:
48962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      case MachineRepresentation::kSimd1x16:
490f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      case MachineRepresentation::kTaggedSigned:
491f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      case MachineRepresentation::kTaggedPointer:
492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case MachineRepresentation::kTagged:
493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return true;
494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case MachineRepresentation::kBit:
495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case MachineRepresentation::kWord8:
496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case MachineRepresentation::kWord16:
497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case MachineRepresentation::kNone:
498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return false;
499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UNREACHABLE();
501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return false;
502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static LocationOperand* cast(InstructionOperand* op) {
505f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    DCHECK(op->IsAnyLocationOperand());
506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return static_cast<LocationOperand*>(op);
507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static const LocationOperand* cast(const InstructionOperand* op) {
510f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    DCHECK(op->IsAnyLocationOperand());
511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return static_cast<const LocationOperand*>(op);
512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static LocationOperand cast(const InstructionOperand& op) {
515f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    DCHECK(op.IsAnyLocationOperand());
516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return *static_cast<const LocationOperand*>(&op);
517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  STATIC_ASSERT(KindField::kSize == 3);
520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  class LocationKindField : public BitField64<LocationKind, 3, 2> {};
521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  class RepresentationField : public BitField64<MachineRepresentation, 5, 8> {};
522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  class IndexField : public BitField64<int32_t, 35, 29> {};
523958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier};
524958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
525c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochclass V8_EXPORT_PRIVATE ExplicitOperand
526c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    : public NON_EXPORTED_BASE(LocationOperand) {
527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ExplicitOperand(LocationKind kind, MachineRepresentation rep, int index);
529958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static ExplicitOperand* New(Zone* zone, LocationKind kind,
531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              MachineRepresentation rep, int index) {
532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return InstructionOperand::New(zone, ExplicitOperand(kind, rep, index));
533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  INSTRUCTION_OPERAND_CASTS(ExplicitOperand, EXPLICIT);
536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass AllocatedOperand : public LocationOperand {
540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AllocatedOperand(LocationKind kind, MachineRepresentation rep, int index)
542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : LocationOperand(ALLOCATED, kind, rep, index) {}
543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static AllocatedOperand* New(Zone* zone, LocationKind kind,
545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                               MachineRepresentation rep, int index) {
546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return InstructionOperand::New(zone, AllocatedOperand(kind, rep, index));
547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  INSTRUCTION_OPERAND_CASTS(AllocatedOperand, ALLOCATED);
550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef INSTRUCTION_OPERAND_CASTS
554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
555f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool InstructionOperand::IsAnyLocationOperand() const {
556f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return this->kind() >= FIRST_LOCATION_OPERAND_KIND;
557f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
558f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
559f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool InstructionOperand::IsLocationOperand() const {
560f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return IsAnyLocationOperand() &&
561f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch         !IsFloatingPoint(LocationOperand::cast(this)->representation());
562f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
563f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
564f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool InstructionOperand::IsFPLocationOperand() const {
565f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return IsAnyLocationOperand() &&
566f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch         IsFloatingPoint(LocationOperand::cast(this)->representation());
567f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool InstructionOperand::IsAnyRegister() const {
570f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return IsAnyLocationOperand() &&
571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         LocationOperand::cast(this)->location_kind() ==
572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             LocationOperand::REGISTER;
573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool InstructionOperand::IsRegister() const {
577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return IsAnyRegister() &&
578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         !IsFloatingPoint(LocationOperand::cast(this)->representation());
579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
581bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochbool InstructionOperand::IsFPRegister() const {
582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return IsAnyRegister() &&
583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         IsFloatingPoint(LocationOperand::cast(this)->representation());
584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
586bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochbool InstructionOperand::IsFloatRegister() const {
587bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return IsAnyRegister() &&
588bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch         LocationOperand::cast(this)->representation() ==
589bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch             MachineRepresentation::kFloat32;
590bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
591bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
592bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochbool InstructionOperand::IsDoubleRegister() const {
593bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return IsAnyRegister() &&
594bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch         LocationOperand::cast(this)->representation() ==
595bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch             MachineRepresentation::kFloat64;
596bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
597bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
598109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochbool InstructionOperand::IsSimd128Register() const {
599109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return IsAnyRegister() &&
600109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch         LocationOperand::cast(this)->representation() ==
601109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch             MachineRepresentation::kSimd128;
602109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
603109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
604f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool InstructionOperand::IsAnyStackSlot() const {
605f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return IsAnyLocationOperand() &&
606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         LocationOperand::cast(this)->location_kind() ==
607f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch             LocationOperand::STACK_SLOT;
608f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch}
609f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
610f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool InstructionOperand::IsStackSlot() const {
611f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return IsAnyStackSlot() &&
612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         !IsFloatingPoint(LocationOperand::cast(this)->representation());
613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
615bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochbool InstructionOperand::IsFPStackSlot() const {
616f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return IsAnyStackSlot() &&
617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         IsFloatingPoint(LocationOperand::cast(this)->representation());
618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
620bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochbool InstructionOperand::IsFloatStackSlot() const {
621f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return IsAnyLocationOperand() &&
622bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch         LocationOperand::cast(this)->location_kind() ==
623bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch             LocationOperand::STACK_SLOT &&
624bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch         LocationOperand::cast(this)->representation() ==
625bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch             MachineRepresentation::kFloat32;
626bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
627bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
628bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochbool InstructionOperand::IsDoubleStackSlot() const {
629f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return IsAnyLocationOperand() &&
630bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch         LocationOperand::cast(this)->location_kind() ==
631bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch             LocationOperand::STACK_SLOT &&
632bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch         LocationOperand::cast(this)->representation() ==
633bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch             MachineRepresentation::kFloat64;
634bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch}
635bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
636109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochbool InstructionOperand::IsSimd128StackSlot() const {
637f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  return IsAnyLocationOperand() &&
638109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch         LocationOperand::cast(this)->location_kind() ==
639109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch             LocationOperand::STACK_SLOT &&
640109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch         LocationOperand::cast(this)->representation() ==
641109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch             MachineRepresentation::kSimd128;
642109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
643109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochuint64_t InstructionOperand::GetCanonicalizedValue() const {
645f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  if (IsAnyLocationOperand()) {
64613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    MachineRepresentation canonical = MachineRepresentation::kNone;
647f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (IsFPRegister()) {
648c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (kSimpleFPAliasing) {
649c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        // We treat all FP register operands the same for simple aliasing.
650c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        canonical = MachineRepresentation::kFloat64;
651c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      } else {
652c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        // We need to distinguish FP register operands of different reps when
653c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        // aliasing is not simple (e.g. ARM).
654c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        canonical = LocationOperand::cast(this)->representation();
655c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      }
65613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return InstructionOperand::KindField::update(
65813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        LocationOperand::RepresentationField::update(this->value_, canonical),
659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        LocationOperand::EXPLICIT);
660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return this->value_;
662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
664014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Required for maps that don't care about machine type.
665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstruct CompareOperandModuloType {
666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool operator()(const InstructionOperand& a,
667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  const InstructionOperand& b) const {
668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return a.CompareCanonicalized(b);
669958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
671958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
672c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochclass V8_EXPORT_PRIVATE MoveOperands final
673c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    : public NON_EXPORTED_BASE(ZoneObject) {
674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MoveOperands(const InstructionOperand& source,
676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               const InstructionOperand& destination)
677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : source_(source), destination_(destination) {
678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!source.IsInvalid() && !destination.IsInvalid());
679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const InstructionOperand& source() const { return source_; }
682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand& source() { return source_; }
683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_source(const InstructionOperand& operand) { source_ = operand; }
684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const InstructionOperand& destination() const { return destination_; }
686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand& destination() { return destination_; }
687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_destination(const InstructionOperand& operand) {
688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    destination_ = operand;
689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The gap resolver marks moves as "in-progress" by clearing the
692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // destination (but not the source).
693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsPending() const {
694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return destination_.IsInvalid() && !source_.IsInvalid();
695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void SetPending() { destination_ = InstructionOperand(); }
697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // A move is redundant if it's been eliminated or if its source and
699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // destination are the same.
700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsRedundant() const {
701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_IMPLIES(!destination_.IsInvalid(), !destination_.IsConstant());
702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return IsEliminated() || source_.EqualsCanonicalized(destination_);
703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // We clear both operands to indicate move that's been eliminated.
706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Eliminate() { source_ = destination_ = InstructionOperand(); }
707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsEliminated() const {
708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_IMPLIES(source_.IsInvalid(), destination_.IsInvalid());
709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return source_.IsInvalid();
710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
712f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // APIs to aid debugging. For general-stream APIs, use operator<<
713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Print(const RegisterConfiguration* config) const;
714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Print() const;
715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand source_;
718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand destination_;
719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(MoveOperands);
721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstruct PrintableMoveOperands {
725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const RegisterConfiguration* register_configuration_;
726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const MoveOperands* move_operands_;
727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstd::ostream& operator<<(std::ostream& os, const PrintableMoveOperands& mo);
731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
732c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochclass V8_EXPORT_PRIVATE ParallelMove final
733c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    : public NON_EXPORTED_BASE(ZoneVector<MoveOperands *>),
734c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      public NON_EXPORTED_BASE(ZoneObject) {
735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  explicit ParallelMove(Zone* zone) : ZoneVector<MoveOperands*>(zone) {
737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    reserve(4);
738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
740014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MoveOperands* AddMove(const InstructionOperand& from,
741014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                        const InstructionOperand& to) {
742109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    Zone* zone = get_allocator().zone();
743109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return AddMove(from, to, zone);
744109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
745109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
746109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  MoveOperands* AddMove(const InstructionOperand& from,
747109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                        const InstructionOperand& to,
748109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                        Zone* operand_allocation_zone) {
749109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    MoveOperands* move = new (operand_allocation_zone) MoveOperands(from, to);
750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    push_back(move);
751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return move;
752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsRedundant() const;
755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Prepare this ParallelMove to insert move as if it happened in a subsequent
757c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // ParallelMove.  move->source() may be changed.  Any MoveOperands added to
758c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // to_eliminate must be Eliminated.
759c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  void PrepareInsertAfter(MoveOperands* move,
760c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                          ZoneVector<MoveOperands*>* to_eliminate) const;
761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(ParallelMove);
764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
766958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
767958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstruct PrintableParallelMove {
768958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const RegisterConfiguration* register_configuration_;
769958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const ParallelMove* parallel_move_;
770958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier};
771958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
772958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
773958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstd::ostream& operator<<(std::ostream& os, const PrintableParallelMove& pm);
774958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass ReferenceMap final : public ZoneObject {
777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  explicit ReferenceMap(Zone* zone)
779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : reference_operands_(8, zone), instruction_position_(-1) {}
780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const ZoneVector<InstructionOperand>& reference_operands() const {
782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return reference_operands_;
783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int instruction_position() const { return instruction_position_; }
785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_instruction_position(int pos) {
787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(instruction_position_ == -1);
788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    instruction_position_ = pos;
789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void RecordReference(const AllocatedOperand& op);
792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  friend std::ostream& operator<<(std::ostream& os, const ReferenceMap& pm);
795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ZoneVector<InstructionOperand> reference_operands_;
797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int instruction_position_;
798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstd::ostream& operator<<(std::ostream& os, const ReferenceMap& pm);
801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
802bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochclass InstructionBlock;
803bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
804c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochclass V8_EXPORT_PRIVATE Instruction final {
805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t OutputCount() const { return OutputCountField::decode(bit_field_); }
807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const InstructionOperand* OutputAt(size_t i) const {
808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(i < OutputCount());
809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return &operands_[i];
810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand* OutputAt(size_t i) {
812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(i < OutputCount());
813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return &operands_[i];
814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool HasOutput() const { return OutputCount() == 1; }
817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const InstructionOperand* Output() const { return OutputAt(0); }
818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand* Output() { return OutputAt(0); }
819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t InputCount() const { return InputCountField::decode(bit_field_); }
821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const InstructionOperand* InputAt(size_t i) const {
822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(i < InputCount());
823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return &operands_[OutputCount() + i];
824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand* InputAt(size_t i) {
826958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(i < InputCount());
827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return &operands_[OutputCount() + i];
828958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t TempCount() const { return TempCountField::decode(bit_field_); }
831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const InstructionOperand* TempAt(size_t i) const {
832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(i < TempCount());
833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return &operands_[OutputCount() + InputCount() + i];
834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand* TempAt(size_t i) {
836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(i < TempCount());
837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return &operands_[OutputCount() + InputCount() + i];
838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  InstructionCode opcode() const { return opcode_; }
841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ArchOpcode arch_opcode() const { return ArchOpcodeField::decode(opcode()); }
842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AddressingMode addressing_mode() const {
843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return AddressingModeField::decode(opcode());
844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FlagsMode flags_mode() const { return FlagsModeField::decode(opcode()); }
846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FlagsCondition flags_condition() const {
847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return FlagsConditionField::decode(opcode());
848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Instruction* New(Zone* zone, InstructionCode opcode) {
851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return New(zone, opcode, 0, nullptr, 0, nullptr, 0, nullptr);
852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Instruction* New(Zone* zone, InstructionCode opcode,
855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                          size_t output_count, InstructionOperand* outputs,
856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                          size_t input_count, InstructionOperand* inputs,
857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                          size_t temp_count, InstructionOperand* temps) {
858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(opcode >= 0);
859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(output_count == 0 || outputs != nullptr);
860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(input_count == 0 || inputs != nullptr);
861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(temp_count == 0 || temps != nullptr);
8623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    // TODO(jarin/mstarzinger): Handle this gracefully. See crbug.com/582702.
8633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    CHECK(InputCountField::is_valid(input_count));
8643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    size_t total_extra_ops = output_count + input_count + temp_count;
866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (total_extra_ops != 0) total_extra_ops--;
867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int size = static_cast<int>(
868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        RoundUp(sizeof(Instruction), sizeof(InstructionOperand)) +
869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        total_extra_ops * sizeof(InstructionOperand));
870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return new (zone->New(size)) Instruction(
871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        opcode, output_count, outputs, input_count, inputs, temp_count, temps);
872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instruction* MarkAsCall() {
875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bit_field_ = IsCallField::update(bit_field_, true);
876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return this;
877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsCall() const { return IsCallField::decode(bit_field_); }
879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool NeedsReferenceMap() const { return IsCall(); }
880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool HasReferenceMap() const { return reference_map_ != nullptr; }
881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool ClobbersRegisters() const { return IsCall(); }
883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool ClobbersTemps() const { return IsCall(); }
884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool ClobbersDoubleRegisters() const { return IsCall(); }
885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ReferenceMap* reference_map() const { return reference_map_; }
886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_reference_map(ReferenceMap* map) {
888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(NeedsReferenceMap());
889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!reference_map_);
890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    reference_map_ = map;
891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
893958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void OverwriteWithNop() {
894958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    opcode_ = ArchOpcodeField::encode(kArchNop);
895958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    bit_field_ = 0;
896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    reference_map_ = nullptr;
897958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
898958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
899f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool IsNop() const { return arch_opcode() == kArchNop; }
900958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
9013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  bool IsDeoptimizeCall() const {
9023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return arch_opcode() == ArchOpcode::kArchDeoptimize ||
9033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch           FlagsModeField::decode(opcode()) == kFlags_deoptimize;
9043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
9053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
9063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  bool IsJump() const { return arch_opcode() == ArchOpcode::kArchJmp; }
9073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  bool IsRet() const { return arch_opcode() == ArchOpcode::kArchRet; }
9083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  bool IsTailCall() const {
9093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return arch_opcode() == ArchOpcode::kArchTailCallCodeObject ||
9103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch           arch_opcode() == ArchOpcode::kArchTailCallCodeObjectFromJSFunction ||
911bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch           arch_opcode() == ArchOpcode::kArchTailCallJSFunctionFromJSFunction ||
912bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch           arch_opcode() == ArchOpcode::kArchTailCallAddress;
9133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
9143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  bool IsThrow() const {
9153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    return arch_opcode() == ArchOpcode::kArchThrowTerminator;
9163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
9173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  enum GapPosition {
919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    START,
920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    END,
921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FIRST_GAP_POSITION = START,
922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LAST_GAP_POSITION = END
923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ParallelMove* GetOrCreateParallelMove(GapPosition pos, Zone* zone) {
926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (parallel_moves_[pos] == nullptr) {
927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      parallel_moves_[pos] = new (zone) ParallelMove(zone);
928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return parallel_moves_[pos];
930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ParallelMove* GetParallelMove(GapPosition pos) {
933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return parallel_moves_[pos];
934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const ParallelMove* GetParallelMove(GapPosition pos) const {
937958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return parallel_moves_[pos];
938958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
939958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool AreMovesRedundant() const;
941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ParallelMove* const* parallel_moves() const { return &parallel_moves_[0]; }
943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ParallelMove** parallel_moves() { return &parallel_moves_[0]; }
944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
945bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // The block_id may be invalidated in JumpThreading. It is only important for
946bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // register allocation, to avoid searching for blocks from instruction
947bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // indexes.
948bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  InstructionBlock* block() const { return block_; }
949bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  void set_block(InstructionBlock* block) {
950bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    DCHECK_NOT_NULL(block);
951bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    block_ = block;
952bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
953bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
954f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // APIs to aid debugging. For general-stream APIs, use operator<<
955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Print(const RegisterConfiguration* config) const;
956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Print() const;
957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
958f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  typedef BitField<size_t, 0, 8> OutputCountField;
959f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  typedef BitField<size_t, 8, 16> InputCountField;
960f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  typedef BitField<size_t, 24, 6> TempCountField;
961f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
962f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  static const size_t kMaxOutputCount = OutputCountField::kMax;
963f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  static const size_t kMaxInputCount = InputCountField::kMax;
964f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  static const size_t kMaxTempCount = TempCountField::kMax;
965f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  explicit Instruction(InstructionCode opcode);
968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Instruction(InstructionCode opcode, size_t output_count,
970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              InstructionOperand* outputs, size_t input_count,
971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              InstructionOperand* inputs, size_t temp_count,
972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              InstructionOperand* temps);
973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  typedef BitField<bool, 30, 1> IsCallField;
975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionCode opcode_;
977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint32_t bit_field_;
978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ParallelMove* parallel_moves_[2];
979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ReferenceMap* reference_map_;
980bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  InstructionBlock* block_;
981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand operands_[1];
982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(Instruction);
984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstruct PrintableInstruction {
988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const RegisterConfiguration* register_configuration_;
989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const Instruction* instr_;
990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstd::ostream& operator<<(std::ostream& os, const PrintableInstruction& instr);
992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass RpoNumber final {
995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static const int kInvalidRpoNumber = -1;
997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int ToInt() const {
998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(IsValid());
999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return index_;
1000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t ToSize() const {
1002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(IsValid());
1003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return static_cast<size_t>(index_);
1004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsValid() const { return index_ >= 0; }
1006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static RpoNumber FromInt(int index) { return RpoNumber(index); }
1007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static RpoNumber Invalid() { return RpoNumber(kInvalidRpoNumber); }
1008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsNext(const RpoNumber other) const {
1010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(IsValid());
1011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return other.index_ == this->index_ + 1;
1012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Comparison operators.
1015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool operator==(RpoNumber other) const { return index_ == other.index_; }
1016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool operator!=(RpoNumber other) const { return index_ != other.index_; }
1017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool operator>(RpoNumber other) const { return index_ > other.index_; }
1018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool operator<(RpoNumber other) const { return index_ < other.index_; }
1019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool operator<=(RpoNumber other) const { return index_ <= other.index_; }
1020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool operator>=(RpoNumber other) const { return index_ >= other.index_; }
1021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
1023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  explicit RpoNumber(int32_t index) : index_(index) {}
1024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int32_t index_;
1025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
1026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstd::ostream& operator<<(std::ostream&, const RpoNumber&);
1029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1030c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochclass V8_EXPORT_PRIVATE Constant final {
1031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
1032958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  enum Type {
1033958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    kInt32,
1034958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    kInt64,
1035958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    kFloat32,
1036958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    kFloat64,
1037958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    kExternalReference,
1038958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    kHeapObject,
1039958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    kRpoNumber
1040958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  };
1041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  explicit Constant(int32_t v);
1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit Constant(int64_t v) : type_(kInt64), value_(v) {}
1044958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  explicit Constant(float v) : type_(kFloat32), value_(bit_cast<int32_t>(v)) {}
1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit Constant(double v) : type_(kFloat64), value_(bit_cast<int64_t>(v)) {}
1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit Constant(ExternalReference ref)
1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : type_(kExternalReference), value_(bit_cast<intptr_t>(ref)) {}
1048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit Constant(Handle<HeapObject> obj)
1049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : type_(kHeapObject), value_(bit_cast<intptr_t>(obj)) {}
1050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  explicit Constant(RpoNumber rpo) : type_(kRpoNumber), value_(rpo.ToInt()) {}
1051bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  explicit Constant(RelocatablePtrConstantInfo info);
1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Type type() const { return type_; }
1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1055bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  RelocInfo::Mode rmode() const { return rmode_; }
1056bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
1057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int32_t ToInt32() const {
1058958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(type() == kInt32 || type() == kInt64);
1059958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    const int32_t value = static_cast<int32_t>(value_);
1060958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK_EQ(value_, static_cast<int64_t>(value));
1061958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return value;
1062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int64_t ToInt64() const {
1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (type() == kInt32) return ToInt32();
1066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK_EQ(kInt64, type());
1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return value_;
1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1070958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  float ToFloat32() const {
107162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // TODO(ahaas): We should remove this function. If value_ has the bit
107262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // representation of a signalling NaN, then returning it as float can cause
107362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // the signalling bit to flip, and value_ is returned as a quiet NaN.
1074958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK_EQ(kFloat32, type());
1075958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return bit_cast<float>(static_cast<int32_t>(value_));
1076958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1077958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
107862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  uint32_t ToFloat32AsInt() const {
107962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    DCHECK_EQ(kFloat32, type());
108062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return bit_cast<uint32_t>(static_cast<int32_t>(value_));
108162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
108262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
1083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  double ToFloat64() const {
108462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // TODO(ahaas): We should remove this function. If value_ has the bit
108562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // representation of a signalling NaN, then returning it as float can cause
108662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // the signalling bit to flip, and value_ is returned as a quiet NaN.
1087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (type() == kInt32) return ToInt32();
1088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK_EQ(kFloat64, type());
1089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return bit_cast<double>(value_);
1090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
109262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  uint64_t ToFloat64AsInt() const {
109362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (type() == kInt32) return ToInt32();
109462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    DCHECK_EQ(kFloat64, type());
109562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return bit_cast<uint64_t>(value_);
109662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
109762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
1098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ExternalReference ToExternalReference() const {
1099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK_EQ(kExternalReference, type());
1100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return bit_cast<ExternalReference>(static_cast<intptr_t>(value_));
1101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RpoNumber ToRpoNumber() const {
1104958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK_EQ(kRpoNumber, type());
1105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return RpoNumber::FromInt(static_cast<int>(value_));
1106958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1107958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1108bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Handle<HeapObject> ToHeapObject() const;
1109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
1111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Type type_;
1112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int64_t value_;
1113bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#if V8_TARGET_ARCH_32_BIT
1114bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  RelocInfo::Mode rmode_ = RelocInfo::NONE32;
1115bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#else
1116bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  RelocInfo::Mode rmode_ = RelocInfo::NONE64;
1117bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch#endif
1118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
1119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstd::ostream& operator<<(std::ostream& os, const Constant& constant);
1122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Forward declarations.
1125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass FrameStateDescriptor;
1126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
112762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochenum class StateValueKind : uint8_t {
112862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  kArguments,
112962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  kPlain,
113062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  kOptimizedOut,
113162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  kNested,
113262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  kDuplicate
113362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch};
1134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass StateValueDescriptor {
1136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
113762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StateValueDescriptor()
1138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : kind_(StateValueKind::kPlain),
1139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        type_(MachineType::AnyTagged()),
114062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        id_(0) {}
1141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
114262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  static StateValueDescriptor Arguments() {
114362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return StateValueDescriptor(StateValueKind::kArguments,
114462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                MachineType::AnyTagged(), 0);
114562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
114662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  static StateValueDescriptor Plain(MachineType type) {
114762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return StateValueDescriptor(StateValueKind::kPlain, type, 0);
1148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
114962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  static StateValueDescriptor OptimizedOut() {
115062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return StateValueDescriptor(StateValueKind::kOptimizedOut,
115162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                                MachineType::AnyTagged(), 0);
115262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
115362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  static StateValueDescriptor Recursive(size_t id) {
115462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return StateValueDescriptor(StateValueKind::kNested,
1155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                MachineType::AnyTagged(), id);
1156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
115762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  static StateValueDescriptor Duplicate(size_t id) {
115862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return StateValueDescriptor(StateValueKind::kDuplicate,
1159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                MachineType::AnyTagged(), id);
1160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
116262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  bool IsArguments() const { return kind_ == StateValueKind::kArguments; }
116362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  bool IsPlain() const { return kind_ == StateValueKind::kPlain; }
116462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  bool IsOptimizedOut() const { return kind_ == StateValueKind::kOptimizedOut; }
116562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  bool IsNested() const { return kind_ == StateValueKind::kNested; }
116662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  bool IsDuplicate() const { return kind_ == StateValueKind::kDuplicate; }
1167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MachineType type() const { return type_; }
1168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t id() const { return id_; }
1169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
117162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StateValueDescriptor(StateValueKind kind, MachineType type, size_t id)
117262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      : kind_(kind), type_(type), id_(id) {}
1173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  StateValueKind kind_;
1175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MachineType type_;
1176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t id_;
1177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
1178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
117962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochclass StateValueList {
118062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch public:
118162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  explicit StateValueList(Zone* zone) : fields_(zone), nested_(zone) {}
118262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
118362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  size_t size() { return fields_.size(); }
118462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
118562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  struct Value {
118662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    StateValueDescriptor* desc;
118762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    StateValueList* nested;
118862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
118962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Value(StateValueDescriptor* desc, StateValueList* nested)
119062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        : desc(desc), nested(nested) {}
119162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  };
119262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
119362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  class iterator {
119462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch   public:
119562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // Bare minimum of operators needed for range iteration.
119662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    bool operator!=(const iterator& other) const {
119762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return field_iterator != other.field_iterator;
119862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
119962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    bool operator==(const iterator& other) const {
120062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return field_iterator == other.field_iterator;
120162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
120262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    iterator& operator++() {
120362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (field_iterator->IsNested()) {
120462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        nested_iterator++;
120562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      }
120662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      ++field_iterator;
120762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return *this;
120862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
120962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    Value operator*() {
121062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      StateValueDescriptor* desc = &(*field_iterator);
121162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      StateValueList* nested = desc->IsNested() ? *nested_iterator : nullptr;
121262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return Value(desc, nested);
121362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
121462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
121562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch   private:
121662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    friend class StateValueList;
121762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
121862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    iterator(ZoneVector<StateValueDescriptor>::iterator it,
121962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch             ZoneVector<StateValueList*>::iterator nested)
122062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        : field_iterator(it), nested_iterator(nested) {}
122162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
122262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ZoneVector<StateValueDescriptor>::iterator field_iterator;
122362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    ZoneVector<StateValueList*>::iterator nested_iterator;
122462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  };
122562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
122662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  void ReserveSize(size_t size) { fields_.reserve(size); }
122762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
122862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StateValueList* PushRecursiveField(Zone* zone, size_t id) {
122962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    fields_.push_back(StateValueDescriptor::Recursive(id));
123062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    StateValueList* nested =
123162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        new (zone->New(sizeof(StateValueList))) StateValueList(zone);
123262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    nested_.push_back(nested);
123362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    return nested;
123462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
123562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  void PushArguments() { fields_.push_back(StateValueDescriptor::Arguments()); }
123662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  void PushDuplicate(size_t id) {
123762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    fields_.push_back(StateValueDescriptor::Duplicate(id));
123862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
123962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  void PushPlain(MachineType type) {
124062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    fields_.push_back(StateValueDescriptor::Plain(type));
124162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
124262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  void PushOptimizedOut() {
124362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    fields_.push_back(StateValueDescriptor::OptimizedOut());
124462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
124562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
124662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  iterator begin() { return iterator(fields_.begin(), nested_.begin()); }
124762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  iterator end() { return iterator(fields_.end(), nested_.end()); }
124862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
124962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch private:
125062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  ZoneVector<StateValueDescriptor> fields_;
125162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  ZoneVector<StateValueList*> nested_;
125262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch};
1253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass FrameStateDescriptor : public ZoneObject {
1255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
1256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FrameStateDescriptor(Zone* zone, FrameStateType type, BailoutId bailout_id,
1257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       OutputFrameStateCombine state_combine,
1258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       size_t parameters_count, size_t locals_count,
1259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       size_t stack_count,
1260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       MaybeHandle<SharedFunctionInfo> shared_info,
1261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                       FrameStateDescriptor* outer_state = nullptr);
1262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FrameStateType type() const { return type_; }
1264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BailoutId bailout_id() const { return bailout_id_; }
1265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  OutputFrameStateCombine state_combine() const { return frame_state_combine_; }
1266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t parameters_count() const { return parameters_count_; }
1267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t locals_count() const { return locals_count_; }
1268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t stack_count() const { return stack_count_; }
1269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MaybeHandle<SharedFunctionInfo> shared_info() const { return shared_info_; }
1270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FrameStateDescriptor* outer_state() const { return outer_state_; }
1271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool HasContext() const {
1272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return FrameStateFunctionInfo::IsJSFunctionType(type_);
1273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1275958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  size_t GetSize(OutputFrameStateCombine combine =
1276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                     OutputFrameStateCombine::Ignore()) const;
1277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  size_t GetTotalSize() const;
1278958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  size_t GetFrameCount() const;
1279958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  size_t GetJSFrameCount() const;
1280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
128162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StateValueList* GetStateValueDescriptors() { return &values_; }
1282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1283f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static const int kImpossibleValue = 0xdead;
1284f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
1286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FrameStateType type_;
1287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BailoutId bailout_id_;
1288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  OutputFrameStateCombine frame_state_combine_;
1289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t parameters_count_;
1290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t locals_count_;
1291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t stack_count_;
129262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  StateValueList values_;
1293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MaybeHandle<SharedFunctionInfo> const shared_info_;
1294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FrameStateDescriptor* outer_state_;
1295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
1296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1297f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// A deoptimization entry is a pair of the reason why we deoptimize and the
1298f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// frame state descriptor that we have to go back to.
1299f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass DeoptimizationEntry final {
1300f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public:
1301f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DeoptimizationEntry() {}
130262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DeoptimizationEntry(FrameStateDescriptor* descriptor, DeoptimizeKind kind,
130362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                      DeoptimizeReason reason)
130462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      : descriptor_(descriptor), kind_(kind), reason_(reason) {}
1305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1306f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  FrameStateDescriptor* descriptor() const { return descriptor_; }
130762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DeoptimizeKind kind() const { return kind_; }
1308f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DeoptimizeReason reason() const { return reason_; }
1309958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1310f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
1311f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  FrameStateDescriptor* descriptor_ = nullptr;
131262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  DeoptimizeKind kind_ = DeoptimizeKind::kEager;
1313f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DeoptimizeReason reason_ = DeoptimizeReason::kNoReason;
1314f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
1315f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1316f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtypedef ZoneVector<DeoptimizationEntry> DeoptimizationVector;
1317958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1318c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochclass V8_EXPORT_PRIVATE PhiInstruction final
1319c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    : public NON_EXPORTED_BASE(ZoneObject) {
1320958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public:
1321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  typedef ZoneVector<InstructionOperand> Inputs;
1322958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  PhiInstruction(Zone* zone, int virtual_register, size_t input_count);
1324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void SetInput(size_t offset, int virtual_register);
1326f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void RenameInput(size_t offset, int virtual_register);
1327958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1328958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int virtual_register() const { return virtual_register_; }
1329958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const IntVector& operands() const { return operands_; }
1330958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // TODO(dcarney): this has no real business being here, since it's internal to
1332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // the register allocator, but putting it here was convenient.
1333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const InstructionOperand& output() const { return output_; }
1334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand& output() { return output_; }
1335958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1336958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private:
1337958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const int virtual_register_;
1338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand output_;
1339958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  IntVector operands_;
1340958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier};
1341958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1342958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1343958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Analogue of BasicBlock for Instructions instead of Nodes.
1344c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochclass V8_EXPORT_PRIVATE InstructionBlock final
1345c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    : public NON_EXPORTED_BASE(ZoneObject) {
1346958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public:
1347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionBlock(Zone* zone, RpoNumber rpo_number, RpoNumber loop_header,
1348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                   RpoNumber loop_end, bool deferred, bool handler);
1349958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1350958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Instruction indexes (used by the register allocator).
1351958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int first_instruction_index() const {
1352958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(code_start_ >= 0);
1353958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(code_end_ > 0);
1354958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(code_end_ >= code_start_);
1355958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return code_start_;
1356958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1357958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int last_instruction_index() const {
1358958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(code_start_ >= 0);
1359958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(code_end_ > 0);
1360958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(code_end_ >= code_start_);
1361958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return code_end_ - 1;
1362958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1363958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1364958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int32_t code_start() const { return code_start_; }
1365958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void set_code_start(int32_t start) { code_start_ = start; }
1366958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1367958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int32_t code_end() const { return code_end_; }
1368958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void set_code_end(int32_t end) { code_end_ = end; }
1369958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1370958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool IsDeferred() const { return deferred_; }
1371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsHandler() const { return handler_; }
1372958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RpoNumber ao_number() const { return ao_number_; }
1374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RpoNumber rpo_number() const { return rpo_number_; }
1375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RpoNumber loop_header() const { return loop_header_; }
1376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RpoNumber loop_end() const {
1377958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(IsLoopHeader());
1378958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return loop_end_;
1379958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1380958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  inline bool IsLoopHeader() const { return loop_end_.IsValid(); }
1381958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  typedef ZoneVector<RpoNumber> Predecessors;
1383958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Predecessors& predecessors() { return predecessors_; }
1384958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const Predecessors& predecessors() const { return predecessors_; }
1385958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  size_t PredecessorCount() const { return predecessors_.size(); }
1386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t PredecessorIndexOf(RpoNumber rpo_number) const;
1387958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  typedef ZoneVector<RpoNumber> Successors;
1389958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Successors& successors() { return successors_; }
1390958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const Successors& successors() const { return successors_; }
1391958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  size_t SuccessorCount() const { return successors_.size(); }
1392958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1393958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  typedef ZoneVector<PhiInstruction*> PhiInstructions;
1394958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const PhiInstructions& phis() const { return phis_; }
1395f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  PhiInstruction* PhiAt(size_t i) const { return phis_[i]; }
1396958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void AddPhi(PhiInstruction* phi) { phis_.push_back(phi); }
1397958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_ao_number(RpoNumber ao_number) { ao_number_ = ao_number; }
1399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool needs_frame() const { return needs_frame_; }
1401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void mark_needs_frame() { needs_frame_ = true; }
1402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool must_construct_frame() const { return must_construct_frame_; }
1404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void mark_must_construct_frame() { must_construct_frame_ = true; }
1405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool must_deconstruct_frame() const { return must_deconstruct_frame_; }
1407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void mark_must_deconstruct_frame() { must_deconstruct_frame_ = true; }
1408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1409958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private:
1410958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Successors successors_;
1411958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Predecessors predecessors_;
1412958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  PhiInstructions phis_;
1413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RpoNumber ao_number_;  // Assembly order number.
1414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const RpoNumber rpo_number_;
1415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const RpoNumber loop_header_;
1416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const RpoNumber loop_end_;
1417958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int32_t code_start_;   // start index of arch-specific code.
1418958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int32_t code_end_;     // end index of arch-specific code.
1419958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const bool deferred_;  // Block contains deferred code.
1420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const bool handler_;   // Block is a handler entry point.
1421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool needs_frame_;
1422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool must_construct_frame_;
1423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool must_deconstruct_frame_;
1424958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier};
1425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1426f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochclass InstructionSequence;
1427f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1428f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochstruct PrintableInstructionBlock {
1429f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  const RegisterConfiguration* register_configuration_;
1430f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  const InstructionBlock* block_;
1431f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  const InstructionSequence* code_;
1432f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch};
1433f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1434f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochstd::ostream& operator<<(std::ostream& os,
1435f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                         const PrintableInstructionBlock& printable_block);
1436f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtypedef ZoneDeque<Constant> ConstantDeque;
1438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtypedef std::map<int, Constant, std::less<int>,
1439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                 zone_allocator<std::pair<const int, Constant> > > ConstantMap;
1440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtypedef ZoneDeque<Instruction*> InstructionDeque;
1442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochtypedef ZoneDeque<ReferenceMap*> ReferenceMapDeque;
1443958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertypedef ZoneVector<InstructionBlock*> InstructionBlocks;
1444958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Forward declarations.
1447958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstruct PrintableInstructionSequence;
1448958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Represents architecture-specific generated code before, during, and after
1451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// register allocation.
1452c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochclass V8_EXPORT_PRIVATE InstructionSequence final
1453c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    : public NON_EXPORTED_BASE(ZoneObject) {
1454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
1455958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static InstructionBlocks* InstructionBlocksFor(Zone* zone,
1456958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                 const Schedule* schedule);
1457958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Puts the deferred blocks last.
1458958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static void ComputeAssemblyOrder(InstructionBlocks* blocks);
1459958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionSequence(Isolate* isolate, Zone* zone,
1461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                      InstructionBlocks* instruction_blocks);
1462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int NextVirtualRegister();
1464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int VirtualRegisterCount() const { return next_virtual_register_; }
1465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1466958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const InstructionBlocks& instruction_blocks() const {
1467958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return *instruction_blocks_;
1468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1470958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int InstructionBlockCount() const {
1471958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return static_cast<int>(instruction_blocks_->size());
1472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionBlock* InstructionBlockAt(RpoNumber rpo_number) {
1475958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return instruction_blocks_->at(rpo_number.ToSize());
1476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1478958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int LastLoopInstructionIndex(const InstructionBlock* block) {
1479958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return instruction_blocks_->at(block->loop_end().ToSize() - 1)
1480958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        ->last_instruction_index();
1481958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const InstructionBlock* InstructionBlockAt(RpoNumber rpo_number) const {
1484958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return instruction_blocks_->at(rpo_number.ToSize());
1485958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionBlock* GetInstructionBlock(int instruction_index) const;
1488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static MachineRepresentation DefaultRepresentation() {
1490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return MachineType::PointerRepresentation();
1491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MachineRepresentation GetRepresentation(int virtual_register) const;
1493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void MarkAsRepresentation(MachineRepresentation rep, int virtual_register);
1494c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  int representation_mask() const { return representation_mask_; }
1495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsReference(int virtual_register) const {
1497f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return CanBeTaggedPointer(GetRepresentation(virtual_register));
1498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
149913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  bool IsFP(int virtual_register) const {
1500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return IsFloatingPoint(GetRepresentation(virtual_register));
1501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Instruction* GetBlockStart(RpoNumber rpo) const;
1504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  typedef InstructionDeque::const_iterator const_iterator;
1506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const_iterator begin() const { return instructions_.begin(); }
1507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const_iterator end() const { return instructions_.end(); }
1508958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const InstructionDeque& instructions() const { return instructions_; }
1509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int LastInstructionIndex() const {
1510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return static_cast<int>(instructions().size()) - 1;
1511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Instruction* InstructionAt(int index) const {
1514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(index >= 0);
1515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(index < static_cast<int>(instructions_.size()));
1516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return instructions_[index];
1517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Isolate* isolate() const { return isolate_; }
1520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const ReferenceMapDeque* reference_maps() const { return &reference_maps_; }
1521958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Zone* zone() const { return zone_; }
1522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1523958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Used by the instruction selector while adding instructions.
1524958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int AddInstruction(Instruction* instr);
1525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void StartBlock(RpoNumber rpo);
1526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void EndBlock(RpoNumber rpo);
1527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1528958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int AddConstant(int virtual_register, Constant constant) {
1529958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // TODO(titzer): allow RPO numbers as constants?
1530958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(constant.type() != Constant::kRpoNumber);
1531958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(virtual_register >= 0 && virtual_register < next_virtual_register_);
1532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(constants_.find(virtual_register) == constants_.end());
1533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    constants_.insert(std::make_pair(virtual_register, constant));
1534958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return virtual_register;
1535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Constant GetConstant(int virtual_register) const {
1537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ConstantMap::const_iterator it = constants_.find(virtual_register);
1538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(it != constants_.end());
1539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK_EQ(virtual_register, it->first);
1540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return it->second;
1541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1543958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  typedef ZoneVector<Constant> Immediates;
1544958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Immediates& immediates() { return immediates_; }
1545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ImmediateOperand AddImmediate(const Constant& constant) {
1547bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (constant.type() == Constant::kInt32 &&
1548bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        RelocInfo::IsNone(constant.rmode())) {
1549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return ImmediateOperand(ImmediateOperand::INLINE, constant.ToInt32());
1550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int index = static_cast<int>(immediates_.size());
1552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    immediates_.push_back(constant);
1553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return ImmediateOperand(ImmediateOperand::INDEXED, index);
1554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Constant GetImmediate(const ImmediateOperand* op) const {
1557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    switch (op->type()) {
1558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case ImmediateOperand::INLINE:
1559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return Constant(op->inline_value());
1560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case ImmediateOperand::INDEXED: {
1561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int index = op->indexed_value();
1562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(index >= 0);
1563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(index < static_cast<int>(immediates_.size()));
1564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return immediates_[index];
1565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UNREACHABLE();
1568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return Constant(static_cast<int32_t>(0));
1569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1571f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int AddDeoptimizationEntry(FrameStateDescriptor* descriptor,
157262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                             DeoptimizeKind kind, DeoptimizeReason reason);
1573f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DeoptimizationEntry const& GetDeoptimizationEntry(int deoptimization_id);
1574f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int GetDeoptimizationEntryCount() const {
1575f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return static_cast<int>(deoptimization_entries_.size());
1576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RpoNumber InputRpo(Instruction* instr, size_t index);
1579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool GetSourcePosition(const Instruction* instr,
1581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         SourcePosition* result) const;
1582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void SetSourcePosition(const Instruction* instr, SourcePosition value);
1583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool ContainsCall() const {
1585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (Instruction* instr : instructions_) {
1586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->IsCall()) return true;
1587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return false;
1589958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1590f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1591f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // APIs to aid debugging. For general-stream APIs, use operator<<
1592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Print(const RegisterConfiguration* config) const;
1593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Print() const;
1594958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1595109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  void PrintBlock(const RegisterConfiguration* config, int block_id) const;
1596109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  void PrintBlock(int block_id) const;
1597109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1598bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  void ValidateEdgeSplitForm() const;
1599bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  void ValidateDeferredBlockExitPaths() const;
1600bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  void ValidateDeferredBlockEntryPaths() const;
1601bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  void ValidateSSA() const;
1602109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
160362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  static void SetRegisterConfigurationForTesting(
160462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      const RegisterConfiguration* regConfig);
160562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  static void ClearRegisterConfigurationForTesting();
1606c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
1607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
1608c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  friend V8_EXPORT_PRIVATE std::ostream& operator<<(
1609c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      std::ostream& os, const PrintableInstructionSequence& code);
1610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  typedef ZoneMap<const Instruction*, SourcePosition> SourcePositionMap;
1612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
161362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  static const RegisterConfiguration* RegisterConfigurationForTesting();
161462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  static const RegisterConfiguration* registerConfigurationForTesting_;
161562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
1616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Isolate* isolate_;
1617958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Zone* const zone_;
1618958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  InstructionBlocks* const instruction_blocks_;
1619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SourcePositionMap source_positions_;
1620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ConstantMap constants_;
1621958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Immediates immediates_;
1622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  InstructionDeque instructions_;
1623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int next_virtual_register_;
1624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ReferenceMapDeque reference_maps_;
1625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ZoneVector<MachineRepresentation> representations_;
1626c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  int representation_mask_;
1627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DeoptimizationVector deoptimization_entries_;
1628958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1629bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  // Used at construction time
1630bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  InstructionBlock* current_block_;
1631bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
1632958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DISALLOW_COPY_AND_ASSIGN(InstructionSequence);
1633958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier};
1634958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1635958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1636958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstruct PrintableInstructionSequence {
1637958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const RegisterConfiguration* register_configuration_;
1638958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const InstructionSequence* sequence_;
1639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
1640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1641c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochV8_EXPORT_PRIVATE std::ostream& operator<<(
1642c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    std::ostream& os, const PrintableInstructionSequence& code);
1643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace compiler
1645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace internal
1646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace v8
1647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // V8_COMPILER_INSTRUCTION_H_
1649