1// Copyright 2014 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "src/compiler/machine-operator.h"
6
7#include "src/base/lazy-instance.h"
8#include "src/compiler/opcodes.h"
9#include "src/compiler/operator.h"
10
11namespace v8 {
12namespace internal {
13namespace compiler {
14
15bool operator==(StoreRepresentation lhs, StoreRepresentation rhs) {
16  return lhs.representation() == rhs.representation() &&
17         lhs.write_barrier_kind() == rhs.write_barrier_kind();
18}
19
20
21bool operator!=(StoreRepresentation lhs, StoreRepresentation rhs) {
22  return !(lhs == rhs);
23}
24
25
26size_t hash_value(StoreRepresentation rep) {
27  return base::hash_combine(rep.representation(), rep.write_barrier_kind());
28}
29
30
31std::ostream& operator<<(std::ostream& os, StoreRepresentation rep) {
32  return os << "(" << rep.representation() << " : " << rep.write_barrier_kind()
33            << ")";
34}
35
36
37LoadRepresentation LoadRepresentationOf(Operator const* op) {
38  DCHECK(IrOpcode::kLoad == op->opcode() ||
39         IrOpcode::kAtomicLoad == op->opcode());
40  return OpParameter<LoadRepresentation>(op);
41}
42
43
44StoreRepresentation const& StoreRepresentationOf(Operator const* op) {
45  DCHECK_EQ(IrOpcode::kStore, op->opcode());
46  return OpParameter<StoreRepresentation>(op);
47}
48
49
50CheckedLoadRepresentation CheckedLoadRepresentationOf(Operator const* op) {
51  DCHECK_EQ(IrOpcode::kCheckedLoad, op->opcode());
52  return OpParameter<CheckedLoadRepresentation>(op);
53}
54
55
56CheckedStoreRepresentation CheckedStoreRepresentationOf(Operator const* op) {
57  DCHECK_EQ(IrOpcode::kCheckedStore, op->opcode());
58  return OpParameter<CheckedStoreRepresentation>(op);
59}
60
61MachineRepresentation StackSlotRepresentationOf(Operator const* op) {
62  DCHECK_EQ(IrOpcode::kStackSlot, op->opcode());
63  return OpParameter<MachineRepresentation>(op);
64}
65
66MachineRepresentation AtomicStoreRepresentationOf(Operator const* op) {
67  DCHECK_EQ(IrOpcode::kAtomicStore, op->opcode());
68  return OpParameter<MachineRepresentation>(op);
69}
70
71#define PURE_OP_LIST(V)                                                       \
72  V(Word32And, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)      \
73  V(Word32Or, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)       \
74  V(Word32Xor, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)      \
75  V(Word32Shl, Operator::kNoProperties, 2, 0, 1)                              \
76  V(Word32Shr, Operator::kNoProperties, 2, 0, 1)                              \
77  V(Word32Sar, Operator::kNoProperties, 2, 0, 1)                              \
78  V(Word32Ror, Operator::kNoProperties, 2, 0, 1)                              \
79  V(Word32Equal, Operator::kCommutative, 2, 0, 1)                             \
80  V(Word32Clz, Operator::kNoProperties, 1, 0, 1)                              \
81  V(Word64And, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)      \
82  V(Word64Or, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)       \
83  V(Word64Xor, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)      \
84  V(Word64Shl, Operator::kNoProperties, 2, 0, 1)                              \
85  V(Word64Shr, Operator::kNoProperties, 2, 0, 1)                              \
86  V(Word64Sar, Operator::kNoProperties, 2, 0, 1)                              \
87  V(Word64Ror, Operator::kNoProperties, 2, 0, 1)                              \
88  V(Word64Clz, Operator::kNoProperties, 1, 0, 1)                              \
89  V(Word64Equal, Operator::kCommutative, 2, 0, 1)                             \
90  V(Int32Add, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)       \
91  V(Int32Sub, Operator::kNoProperties, 2, 0, 1)                               \
92  V(Int32Mul, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)       \
93  V(Int32MulHigh, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)   \
94  V(Int32Div, Operator::kNoProperties, 2, 1, 1)                               \
95  V(Int32Mod, Operator::kNoProperties, 2, 1, 1)                               \
96  V(Int32LessThan, Operator::kNoProperties, 2, 0, 1)                          \
97  V(Int32LessThanOrEqual, Operator::kNoProperties, 2, 0, 1)                   \
98  V(Uint32Div, Operator::kNoProperties, 2, 1, 1)                              \
99  V(Uint32LessThan, Operator::kNoProperties, 2, 0, 1)                         \
100  V(Uint32LessThanOrEqual, Operator::kNoProperties, 2, 0, 1)                  \
101  V(Uint32Mod, Operator::kNoProperties, 2, 1, 1)                              \
102  V(Uint32MulHigh, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)  \
103  V(Int64Add, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)       \
104  V(Int64Sub, Operator::kNoProperties, 2, 0, 1)                               \
105  V(Int64Mul, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)       \
106  V(Int64Div, Operator::kNoProperties, 2, 1, 1)                               \
107  V(Int64Mod, Operator::kNoProperties, 2, 1, 1)                               \
108  V(Int64LessThan, Operator::kNoProperties, 2, 0, 1)                          \
109  V(Int64LessThanOrEqual, Operator::kNoProperties, 2, 0, 1)                   \
110  V(Uint64Div, Operator::kNoProperties, 2, 1, 1)                              \
111  V(Uint64Mod, Operator::kNoProperties, 2, 1, 1)                              \
112  V(Uint64LessThan, Operator::kNoProperties, 2, 0, 1)                         \
113  V(Uint64LessThanOrEqual, Operator::kNoProperties, 2, 0, 1)                  \
114  V(BitcastWordToTagged, Operator::kNoProperties, 1, 0, 1)                    \
115  V(TruncateFloat64ToWord32, Operator::kNoProperties, 1, 0, 1)                \
116  V(ChangeFloat32ToFloat64, Operator::kNoProperties, 1, 0, 1)                 \
117  V(ChangeFloat64ToInt32, Operator::kNoProperties, 1, 0, 1)                   \
118  V(ChangeFloat64ToUint32, Operator::kNoProperties, 1, 0, 1)                  \
119  V(TruncateFloat64ToUint32, Operator::kNoProperties, 1, 0, 1)                \
120  V(TruncateFloat32ToInt32, Operator::kNoProperties, 1, 0, 1)                 \
121  V(TruncateFloat32ToUint32, Operator::kNoProperties, 1, 0, 1)                \
122  V(TryTruncateFloat32ToInt64, Operator::kNoProperties, 1, 0, 2)              \
123  V(TryTruncateFloat64ToInt64, Operator::kNoProperties, 1, 0, 2)              \
124  V(TryTruncateFloat32ToUint64, Operator::kNoProperties, 1, 0, 2)             \
125  V(TryTruncateFloat64ToUint64, Operator::kNoProperties, 1, 0, 2)             \
126  V(ChangeInt32ToFloat64, Operator::kNoProperties, 1, 0, 1)                   \
127  V(Float64SilenceNaN, Operator::kNoProperties, 1, 0, 1)                      \
128  V(RoundFloat64ToInt32, Operator::kNoProperties, 1, 0, 1)                    \
129  V(RoundInt32ToFloat32, Operator::kNoProperties, 1, 0, 1)                    \
130  V(RoundInt64ToFloat32, Operator::kNoProperties, 1, 0, 1)                    \
131  V(RoundInt64ToFloat64, Operator::kNoProperties, 1, 0, 1)                    \
132  V(RoundUint32ToFloat32, Operator::kNoProperties, 1, 0, 1)                   \
133  V(RoundUint64ToFloat32, Operator::kNoProperties, 1, 0, 1)                   \
134  V(RoundUint64ToFloat64, Operator::kNoProperties, 1, 0, 1)                   \
135  V(ChangeInt32ToInt64, Operator::kNoProperties, 1, 0, 1)                     \
136  V(ChangeUint32ToFloat64, Operator::kNoProperties, 1, 0, 1)                  \
137  V(ChangeUint32ToUint64, Operator::kNoProperties, 1, 0, 1)                   \
138  V(TruncateFloat64ToFloat32, Operator::kNoProperties, 1, 0, 1)               \
139  V(TruncateInt64ToInt32, Operator::kNoProperties, 1, 0, 1)                   \
140  V(BitcastFloat32ToInt32, Operator::kNoProperties, 1, 0, 1)                  \
141  V(BitcastFloat64ToInt64, Operator::kNoProperties, 1, 0, 1)                  \
142  V(BitcastInt32ToFloat32, Operator::kNoProperties, 1, 0, 1)                  \
143  V(BitcastInt64ToFloat64, Operator::kNoProperties, 1, 0, 1)                  \
144  V(Float32Abs, Operator::kNoProperties, 1, 0, 1)                             \
145  V(Float32Add, Operator::kCommutative, 2, 0, 1)                              \
146  V(Float32Sub, Operator::kNoProperties, 2, 0, 1)                             \
147  V(Float32SubPreserveNan, Operator::kNoProperties, 2, 0, 1)                  \
148  V(Float32Mul, Operator::kCommutative, 2, 0, 1)                              \
149  V(Float32Div, Operator::kNoProperties, 2, 0, 1)                             \
150  V(Float32Sqrt, Operator::kNoProperties, 1, 0, 1)                            \
151  V(Float64Abs, Operator::kNoProperties, 1, 0, 1)                             \
152  V(Float64Atan, Operator::kNoProperties, 1, 0, 1)                            \
153  V(Float64Atan2, Operator::kNoProperties, 2, 0, 1)                           \
154  V(Float64Atanh, Operator::kNoProperties, 1, 0, 1)                           \
155  V(Float64Cbrt, Operator::kNoProperties, 1, 0, 1)                            \
156  V(Float64Cos, Operator::kNoProperties, 1, 0, 1)                             \
157  V(Float64Exp, Operator::kNoProperties, 1, 0, 1)                             \
158  V(Float64Expm1, Operator::kNoProperties, 1, 0, 1)                           \
159  V(Float64Log, Operator::kNoProperties, 1, 0, 1)                             \
160  V(Float64Log1p, Operator::kNoProperties, 1, 0, 1)                           \
161  V(Float64Log2, Operator::kNoProperties, 1, 0, 1)                            \
162  V(Float64Log10, Operator::kNoProperties, 1, 0, 1)                           \
163  V(Float64Add, Operator::kCommutative, 2, 0, 1)                              \
164  V(Float64Sub, Operator::kNoProperties, 2, 0, 1)                             \
165  V(Float64SubPreserveNan, Operator::kNoProperties, 2, 0, 1)                  \
166  V(Float64Mul, Operator::kCommutative, 2, 0, 1)                              \
167  V(Float64Div, Operator::kNoProperties, 2, 0, 1)                             \
168  V(Float64Mod, Operator::kNoProperties, 2, 0, 1)                             \
169  V(Float64Sin, Operator::kNoProperties, 1, 0, 1)                             \
170  V(Float64Sqrt, Operator::kNoProperties, 1, 0, 1)                            \
171  V(Float64Tan, Operator::kNoProperties, 1, 0, 1)                             \
172  V(Float32Equal, Operator::kCommutative, 2, 0, 1)                            \
173  V(Float32LessThan, Operator::kNoProperties, 2, 0, 1)                        \
174  V(Float32LessThanOrEqual, Operator::kNoProperties, 2, 0, 1)                 \
175  V(Float64Equal, Operator::kCommutative, 2, 0, 1)                            \
176  V(Float64LessThan, Operator::kNoProperties, 2, 0, 1)                        \
177  V(Float64LessThanOrEqual, Operator::kNoProperties, 2, 0, 1)                 \
178  V(Float64ExtractLowWord32, Operator::kNoProperties, 1, 0, 1)                \
179  V(Float64ExtractHighWord32, Operator::kNoProperties, 1, 0, 1)               \
180  V(Float64InsertLowWord32, Operator::kNoProperties, 2, 0, 1)                 \
181  V(Float64InsertHighWord32, Operator::kNoProperties, 2, 0, 1)                \
182  V(LoadStackPointer, Operator::kNoProperties, 0, 0, 1)                       \
183  V(LoadFramePointer, Operator::kNoProperties, 0, 0, 1)                       \
184  V(LoadParentFramePointer, Operator::kNoProperties, 0, 0, 1)                 \
185  V(Int32PairAdd, Operator::kNoProperties, 4, 0, 2)                           \
186  V(Int32PairSub, Operator::kNoProperties, 4, 0, 2)                           \
187  V(Int32PairMul, Operator::kNoProperties, 4, 0, 2)                           \
188  V(Word32PairShl, Operator::kNoProperties, 3, 0, 2)                          \
189  V(Word32PairShr, Operator::kNoProperties, 3, 0, 2)                          \
190  V(Word32PairSar, Operator::kNoProperties, 3, 0, 2)                          \
191  V(CreateFloat32x4, Operator::kNoProperties, 4, 0, 1)                        \
192  V(Float32x4ExtractLane, Operator::kNoProperties, 2, 0, 1)                   \
193  V(Float32x4ReplaceLane, Operator::kNoProperties, 3, 0, 1)                   \
194  V(Float32x4Abs, Operator::kNoProperties, 1, 0, 1)                           \
195  V(Float32x4Neg, Operator::kNoProperties, 1, 0, 1)                           \
196  V(Float32x4Sqrt, Operator::kNoProperties, 1, 0, 1)                          \
197  V(Float32x4RecipApprox, Operator::kNoProperties, 1, 0, 1)                   \
198  V(Float32x4RecipSqrtApprox, Operator::kNoProperties, 1, 0, 1)               \
199  V(Float32x4Add, Operator::kCommutative, 2, 0, 1)                            \
200  V(Float32x4Sub, Operator::kNoProperties, 2, 0, 1)                           \
201  V(Float32x4Mul, Operator::kCommutative, 2, 0, 1)                            \
202  V(Float32x4Div, Operator::kNoProperties, 2, 0, 1)                           \
203  V(Float32x4Min, Operator::kCommutative, 2, 0, 1)                            \
204  V(Float32x4Max, Operator::kCommutative, 2, 0, 1)                            \
205  V(Float32x4MinNum, Operator::kCommutative, 2, 0, 1)                         \
206  V(Float32x4MaxNum, Operator::kCommutative, 2, 0, 1)                         \
207  V(Float32x4Equal, Operator::kCommutative, 2, 0, 1)                          \
208  V(Float32x4NotEqual, Operator::kCommutative, 2, 0, 1)                       \
209  V(Float32x4LessThan, Operator::kNoProperties, 2, 0, 1)                      \
210  V(Float32x4LessThanOrEqual, Operator::kNoProperties, 2, 0, 1)               \
211  V(Float32x4GreaterThan, Operator::kNoProperties, 2, 0, 1)                   \
212  V(Float32x4GreaterThanOrEqual, Operator::kNoProperties, 2, 0, 1)            \
213  V(Float32x4Select, Operator::kNoProperties, 3, 0, 1)                        \
214  V(Float32x4Swizzle, Operator::kNoProperties, 5, 0, 1)                       \
215  V(Float32x4Shuffle, Operator::kNoProperties, 6, 0, 1)                       \
216  V(Float32x4FromInt32x4, Operator::kNoProperties, 1, 0, 1)                   \
217  V(Float32x4FromUint32x4, Operator::kNoProperties, 1, 0, 1)                  \
218  V(CreateInt32x4, Operator::kNoProperties, 4, 0, 1)                          \
219  V(Int32x4ExtractLane, Operator::kNoProperties, 2, 0, 1)                     \
220  V(Int32x4ReplaceLane, Operator::kNoProperties, 3, 0, 1)                     \
221  V(Int32x4Neg, Operator::kNoProperties, 1, 0, 1)                             \
222  V(Int32x4Add, Operator::kCommutative, 2, 0, 1)                              \
223  V(Int32x4Sub, Operator::kNoProperties, 2, 0, 1)                             \
224  V(Int32x4Mul, Operator::kCommutative, 2, 0, 1)                              \
225  V(Int32x4Min, Operator::kCommutative, 2, 0, 1)                              \
226  V(Int32x4Max, Operator::kCommutative, 2, 0, 1)                              \
227  V(Int32x4ShiftLeftByScalar, Operator::kNoProperties, 2, 0, 1)               \
228  V(Int32x4ShiftRightByScalar, Operator::kNoProperties, 2, 0, 1)              \
229  V(Int32x4Equal, Operator::kCommutative, 2, 0, 1)                            \
230  V(Int32x4NotEqual, Operator::kCommutative, 2, 0, 1)                         \
231  V(Int32x4LessThan, Operator::kNoProperties, 2, 0, 1)                        \
232  V(Int32x4LessThanOrEqual, Operator::kNoProperties, 2, 0, 1)                 \
233  V(Int32x4GreaterThan, Operator::kNoProperties, 2, 0, 1)                     \
234  V(Int32x4GreaterThanOrEqual, Operator::kNoProperties, 2, 0, 1)              \
235  V(Int32x4Select, Operator::kNoProperties, 3, 0, 1)                          \
236  V(Int32x4Swizzle, Operator::kNoProperties, 5, 0, 1)                         \
237  V(Int32x4Shuffle, Operator::kNoProperties, 6, 0, 1)                         \
238  V(Int32x4FromFloat32x4, Operator::kNoProperties, 1, 0, 1)                   \
239  V(Uint32x4Min, Operator::kCommutative, 2, 0, 1)                             \
240  V(Uint32x4Max, Operator::kCommutative, 2, 0, 1)                             \
241  V(Uint32x4ShiftLeftByScalar, Operator::kNoProperties, 2, 0, 1)              \
242  V(Uint32x4ShiftRightByScalar, Operator::kNoProperties, 2, 0, 1)             \
243  V(Uint32x4LessThan, Operator::kNoProperties, 2, 0, 1)                       \
244  V(Uint32x4LessThanOrEqual, Operator::kNoProperties, 2, 0, 1)                \
245  V(Uint32x4GreaterThan, Operator::kNoProperties, 2, 0, 1)                    \
246  V(Uint32x4GreaterThanOrEqual, Operator::kNoProperties, 2, 0, 1)             \
247  V(Uint32x4FromFloat32x4, Operator::kNoProperties, 1, 0, 1)                  \
248  V(CreateBool32x4, Operator::kNoProperties, 4, 0, 1)                         \
249  V(Bool32x4ExtractLane, Operator::kNoProperties, 2, 0, 1)                    \
250  V(Bool32x4ReplaceLane, Operator::kNoProperties, 3, 0, 1)                    \
251  V(Bool32x4And, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)    \
252  V(Bool32x4Or, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)     \
253  V(Bool32x4Xor, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)    \
254  V(Bool32x4Not, Operator::kNoProperties, 1, 0, 1)                            \
255  V(Bool32x4AnyTrue, Operator::kNoProperties, 1, 0, 1)                        \
256  V(Bool32x4AllTrue, Operator::kNoProperties, 1, 0, 1)                        \
257  V(Bool32x4Swizzle, Operator::kNoProperties, 5, 0, 1)                        \
258  V(Bool32x4Shuffle, Operator::kNoProperties, 6, 0, 1)                        \
259  V(Bool32x4Equal, Operator::kCommutative, 2, 0, 1)                           \
260  V(Bool32x4NotEqual, Operator::kCommutative, 2, 0, 1)                        \
261  V(CreateInt16x8, Operator::kNoProperties, 8, 0, 1)                          \
262  V(Int16x8ExtractLane, Operator::kNoProperties, 2, 0, 1)                     \
263  V(Int16x8ReplaceLane, Operator::kNoProperties, 3, 0, 1)                     \
264  V(Int16x8Neg, Operator::kNoProperties, 1, 0, 1)                             \
265  V(Int16x8Add, Operator::kCommutative, 2, 0, 1)                              \
266  V(Int16x8AddSaturate, Operator::kCommutative, 2, 0, 1)                      \
267  V(Int16x8Sub, Operator::kNoProperties, 2, 0, 1)                             \
268  V(Int16x8SubSaturate, Operator::kNoProperties, 2, 0, 1)                     \
269  V(Int16x8Mul, Operator::kCommutative, 2, 0, 1)                              \
270  V(Int16x8Min, Operator::kCommutative, 2, 0, 1)                              \
271  V(Int16x8Max, Operator::kCommutative, 2, 0, 1)                              \
272  V(Int16x8ShiftLeftByScalar, Operator::kNoProperties, 2, 0, 1)               \
273  V(Int16x8ShiftRightByScalar, Operator::kNoProperties, 2, 0, 1)              \
274  V(Int16x8Equal, Operator::kCommutative, 2, 0, 1)                            \
275  V(Int16x8NotEqual, Operator::kCommutative, 2, 0, 1)                         \
276  V(Int16x8LessThan, Operator::kNoProperties, 2, 0, 1)                        \
277  V(Int16x8LessThanOrEqual, Operator::kNoProperties, 2, 0, 1)                 \
278  V(Int16x8GreaterThan, Operator::kNoProperties, 2, 0, 1)                     \
279  V(Int16x8GreaterThanOrEqual, Operator::kNoProperties, 2, 0, 1)              \
280  V(Int16x8Select, Operator::kNoProperties, 3, 0, 1)                          \
281  V(Int16x8Swizzle, Operator::kNoProperties, 9, 0, 1)                         \
282  V(Int16x8Shuffle, Operator::kNoProperties, 10, 0, 1)                        \
283  V(Uint16x8AddSaturate, Operator::kCommutative, 2, 0, 1)                     \
284  V(Uint16x8SubSaturate, Operator::kNoProperties, 2, 0, 1)                    \
285  V(Uint16x8Min, Operator::kCommutative, 2, 0, 1)                             \
286  V(Uint16x8Max, Operator::kCommutative, 2, 0, 1)                             \
287  V(Uint16x8ShiftLeftByScalar, Operator::kNoProperties, 2, 0, 1)              \
288  V(Uint16x8ShiftRightByScalar, Operator::kNoProperties, 2, 0, 1)             \
289  V(Uint16x8LessThan, Operator::kNoProperties, 2, 0, 1)                       \
290  V(Uint16x8LessThanOrEqual, Operator::kNoProperties, 2, 0, 1)                \
291  V(Uint16x8GreaterThan, Operator::kNoProperties, 2, 0, 1)                    \
292  V(Uint16x8GreaterThanOrEqual, Operator::kNoProperties, 2, 0, 1)             \
293  V(CreateBool16x8, Operator::kNoProperties, 8, 0, 1)                         \
294  V(Bool16x8ExtractLane, Operator::kNoProperties, 2, 0, 1)                    \
295  V(Bool16x8ReplaceLane, Operator::kNoProperties, 3, 0, 1)                    \
296  V(Bool16x8And, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)    \
297  V(Bool16x8Or, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)     \
298  V(Bool16x8Xor, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)    \
299  V(Bool16x8Not, Operator::kNoProperties, 1, 0, 1)                            \
300  V(Bool16x8AnyTrue, Operator::kNoProperties, 1, 0, 1)                        \
301  V(Bool16x8AllTrue, Operator::kNoProperties, 1, 0, 1)                        \
302  V(Bool16x8Swizzle, Operator::kNoProperties, 9, 0, 1)                        \
303  V(Bool16x8Shuffle, Operator::kNoProperties, 10, 0, 1)                       \
304  V(Bool16x8Equal, Operator::kCommutative, 2, 0, 1)                           \
305  V(Bool16x8NotEqual, Operator::kCommutative, 2, 0, 1)                        \
306  V(CreateInt8x16, Operator::kNoProperties, 16, 0, 1)                         \
307  V(Int8x16ExtractLane, Operator::kNoProperties, 2, 0, 1)                     \
308  V(Int8x16ReplaceLane, Operator::kNoProperties, 3, 0, 1)                     \
309  V(Int8x16Neg, Operator::kNoProperties, 1, 0, 1)                             \
310  V(Int8x16Add, Operator::kCommutative, 2, 0, 1)                              \
311  V(Int8x16AddSaturate, Operator::kCommutative, 2, 0, 1)                      \
312  V(Int8x16Sub, Operator::kNoProperties, 2, 0, 1)                             \
313  V(Int8x16SubSaturate, Operator::kNoProperties, 2, 0, 1)                     \
314  V(Int8x16Mul, Operator::kCommutative, 2, 0, 1)                              \
315  V(Int8x16Min, Operator::kCommutative, 2, 0, 1)                              \
316  V(Int8x16Max, Operator::kCommutative, 2, 0, 1)                              \
317  V(Int8x16ShiftLeftByScalar, Operator::kNoProperties, 2, 0, 1)               \
318  V(Int8x16ShiftRightByScalar, Operator::kNoProperties, 2, 0, 1)              \
319  V(Int8x16Equal, Operator::kCommutative, 2, 0, 1)                            \
320  V(Int8x16NotEqual, Operator::kCommutative, 2, 0, 1)                         \
321  V(Int8x16LessThan, Operator::kNoProperties, 2, 0, 1)                        \
322  V(Int8x16LessThanOrEqual, Operator::kNoProperties, 2, 0, 1)                 \
323  V(Int8x16GreaterThan, Operator::kNoProperties, 2, 0, 1)                     \
324  V(Int8x16GreaterThanOrEqual, Operator::kNoProperties, 2, 0, 1)              \
325  V(Int8x16Select, Operator::kNoProperties, 3, 0, 1)                          \
326  V(Int8x16Swizzle, Operator::kNoProperties, 17, 0, 1)                        \
327  V(Int8x16Shuffle, Operator::kNoProperties, 18, 0, 1)                        \
328  V(Uint8x16AddSaturate, Operator::kCommutative, 2, 0, 1)                     \
329  V(Uint8x16SubSaturate, Operator::kNoProperties, 2, 0, 1)                    \
330  V(Uint8x16Min, Operator::kCommutative, 2, 0, 1)                             \
331  V(Uint8x16Max, Operator::kCommutative, 2, 0, 1)                             \
332  V(Uint8x16ShiftLeftByScalar, Operator::kNoProperties, 2, 0, 1)              \
333  V(Uint8x16ShiftRightByScalar, Operator::kNoProperties, 2, 0, 1)             \
334  V(Uint8x16LessThan, Operator::kNoProperties, 2, 0, 1)                       \
335  V(Uint8x16LessThanOrEqual, Operator::kNoProperties, 2, 0, 1)                \
336  V(Uint8x16GreaterThan, Operator::kNoProperties, 2, 0, 1)                    \
337  V(Uint8x16GreaterThanOrEqual, Operator::kNoProperties, 2, 0, 1)             \
338  V(CreateBool8x16, Operator::kNoProperties, 16, 0, 1)                        \
339  V(Bool8x16ExtractLane, Operator::kNoProperties, 2, 0, 1)                    \
340  V(Bool8x16ReplaceLane, Operator::kNoProperties, 3, 0, 1)                    \
341  V(Bool8x16And, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)    \
342  V(Bool8x16Or, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)     \
343  V(Bool8x16Xor, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)    \
344  V(Bool8x16Not, Operator::kNoProperties, 1, 0, 1)                            \
345  V(Bool8x16AnyTrue, Operator::kNoProperties, 1, 0, 1)                        \
346  V(Bool8x16AllTrue, Operator::kNoProperties, 1, 0, 1)                        \
347  V(Bool8x16Swizzle, Operator::kNoProperties, 17, 0, 1)                       \
348  V(Bool8x16Shuffle, Operator::kNoProperties, 18, 0, 1)                       \
349  V(Bool8x16Equal, Operator::kCommutative, 2, 0, 1)                           \
350  V(Bool8x16NotEqual, Operator::kCommutative, 2, 0, 1)                        \
351  V(Simd128Load, Operator::kNoProperties, 2, 0, 1)                            \
352  V(Simd128Load1, Operator::kNoProperties, 2, 0, 1)                           \
353  V(Simd128Load2, Operator::kNoProperties, 2, 0, 1)                           \
354  V(Simd128Load3, Operator::kNoProperties, 2, 0, 1)                           \
355  V(Simd128Store, Operator::kNoProperties, 3, 0, 1)                           \
356  V(Simd128Store1, Operator::kNoProperties, 3, 0, 1)                          \
357  V(Simd128Store2, Operator::kNoProperties, 3, 0, 1)                          \
358  V(Simd128Store3, Operator::kNoProperties, 3, 0, 1)                          \
359  V(Simd128And, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)     \
360  V(Simd128Or, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)      \
361  V(Simd128Xor, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)     \
362  V(Simd128Not, Operator::kNoProperties, 1, 0, 1)
363
364#define PURE_OPTIONAL_OP_LIST(V)                            \
365  V(Word32Ctz, Operator::kNoProperties, 1, 0, 1)            \
366  V(Word64Ctz, Operator::kNoProperties, 1, 0, 1)            \
367  V(Word32ReverseBits, Operator::kNoProperties, 1, 0, 1)    \
368  V(Word64ReverseBits, Operator::kNoProperties, 1, 0, 1)    \
369  V(Word32Popcnt, Operator::kNoProperties, 1, 0, 1)         \
370  V(Word64Popcnt, Operator::kNoProperties, 1, 0, 1)         \
371  V(Float32Max, Operator::kNoProperties, 2, 0, 1)           \
372  V(Float32Min, Operator::kNoProperties, 2, 0, 1)           \
373  V(Float64Max, Operator::kNoProperties, 2, 0, 1)           \
374  V(Float64Min, Operator::kNoProperties, 2, 0, 1)           \
375  V(Float32RoundDown, Operator::kNoProperties, 1, 0, 1)     \
376  V(Float64RoundDown, Operator::kNoProperties, 1, 0, 1)     \
377  V(Float32RoundUp, Operator::kNoProperties, 1, 0, 1)       \
378  V(Float64RoundUp, Operator::kNoProperties, 1, 0, 1)       \
379  V(Float32RoundTruncate, Operator::kNoProperties, 1, 0, 1) \
380  V(Float64RoundTruncate, Operator::kNoProperties, 1, 0, 1) \
381  V(Float64RoundTiesAway, Operator::kNoProperties, 1, 0, 1) \
382  V(Float32RoundTiesEven, Operator::kNoProperties, 1, 0, 1) \
383  V(Float64RoundTiesEven, Operator::kNoProperties, 1, 0, 1) \
384  V(Float32Neg, Operator::kNoProperties, 1, 0, 1)           \
385  V(Float64Neg, Operator::kNoProperties, 1, 0, 1)
386
387#define OVERFLOW_OP_LIST(V)                                                \
388  V(Int32AddWithOverflow, Operator::kAssociative | Operator::kCommutative) \
389  V(Int32SubWithOverflow, Operator::kNoProperties)                         \
390  V(Int64AddWithOverflow, Operator::kAssociative | Operator::kCommutative) \
391  V(Int64SubWithOverflow, Operator::kNoProperties)
392
393#define MACHINE_TYPE_LIST(V) \
394  V(Float32)                 \
395  V(Float64)                 \
396  V(Simd128)                 \
397  V(Int8)                    \
398  V(Uint8)                   \
399  V(Int16)                   \
400  V(Uint16)                  \
401  V(Int32)                   \
402  V(Uint32)                  \
403  V(Int64)                   \
404  V(Uint64)                  \
405  V(Pointer)                 \
406  V(AnyTagged)
407
408#define MACHINE_REPRESENTATION_LIST(V) \
409  V(kFloat32)                          \
410  V(kFloat64)                          \
411  V(kSimd128)                          \
412  V(kWord8)                            \
413  V(kWord16)                           \
414  V(kWord32)                           \
415  V(kWord64)                           \
416  V(kTagged)
417
418#define ATOMIC_TYPE_LIST(V) \
419  V(Int8)                   \
420  V(Uint8)                  \
421  V(Int16)                  \
422  V(Uint16)                 \
423  V(Int32)                  \
424  V(Uint32)
425
426#define ATOMIC_REPRESENTATION_LIST(V) \
427  V(kWord8)                           \
428  V(kWord16)                          \
429  V(kWord32)
430
431struct MachineOperatorGlobalCache {
432#define PURE(Name, properties, value_input_count, control_input_count,         \
433             output_count)                                                     \
434  struct Name##Operator final : public Operator {                              \
435    Name##Operator()                                                           \
436        : Operator(IrOpcode::k##Name, Operator::kPure | properties, #Name,     \
437                   value_input_count, 0, control_input_count, output_count, 0, \
438                   0) {}                                                       \
439  };                                                                           \
440  Name##Operator k##Name;
441  PURE_OP_LIST(PURE)
442  PURE_OPTIONAL_OP_LIST(PURE)
443#undef PURE
444
445#define OVERFLOW_OP(Name, properties)                                        \
446  struct Name##Operator final : public Operator {                            \
447    Name##Operator()                                                         \
448        : Operator(IrOpcode::k##Name,                                        \
449                   Operator::kEliminatable | Operator::kNoRead | properties, \
450                   #Name, 2, 0, 1, 2, 0, 0) {}                               \
451  };                                                                         \
452  Name##Operator k##Name;
453  OVERFLOW_OP_LIST(OVERFLOW_OP)
454#undef OVERFLOW_OP
455
456#define LOAD(Type)                                                           \
457  struct Load##Type##Operator final : public Operator1<LoadRepresentation> { \
458    Load##Type##Operator()                                                   \
459        : Operator1<LoadRepresentation>(                                     \
460              IrOpcode::kLoad,                                               \
461              Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite,  \
462              "Load", 2, 1, 1, 1, 1, 0, MachineType::Type()) {}              \
463  };                                                                         \
464  struct CheckedLoad##Type##Operator final                                   \
465      : public Operator1<CheckedLoadRepresentation> {                        \
466    CheckedLoad##Type##Operator()                                            \
467        : Operator1<CheckedLoadRepresentation>(                              \
468              IrOpcode::kCheckedLoad,                                        \
469              Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite,  \
470              "CheckedLoad", 3, 1, 1, 1, 1, 0, MachineType::Type()) {}       \
471  };                                                                         \
472  Load##Type##Operator kLoad##Type;                                          \
473  CheckedLoad##Type##Operator kCheckedLoad##Type;
474  MACHINE_TYPE_LIST(LOAD)
475#undef LOAD
476
477#define STACKSLOT(Type)                                                      \
478  struct StackSlot##Type##Operator final                                     \
479      : public Operator1<MachineRepresentation> {                            \
480    StackSlot##Type##Operator()                                              \
481        : Operator1<MachineRepresentation>(                                  \
482              IrOpcode::kStackSlot, Operator::kNoDeopt | Operator::kNoThrow, \
483              "StackSlot", 0, 0, 0, 1, 0, 0,                                 \
484              MachineType::Type().representation()) {}                       \
485  };                                                                         \
486  StackSlot##Type##Operator kStackSlot##Type;
487  MACHINE_TYPE_LIST(STACKSLOT)
488#undef STACKSLOT
489
490#define STORE(Type)                                                            \
491  struct Store##Type##Operator : public Operator1<StoreRepresentation> {       \
492    explicit Store##Type##Operator(WriteBarrierKind write_barrier_kind)        \
493        : Operator1<StoreRepresentation>(                                      \
494              IrOpcode::kStore,                                                \
495              Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow,     \
496              "Store", 3, 1, 1, 0, 1, 0,                                       \
497              StoreRepresentation(MachineRepresentation::Type,                 \
498                                  write_barrier_kind)) {}                      \
499  };                                                                           \
500  struct Store##Type##NoWriteBarrier##Operator final                           \
501      : public Store##Type##Operator {                                         \
502    Store##Type##NoWriteBarrier##Operator()                                    \
503        : Store##Type##Operator(kNoWriteBarrier) {}                            \
504  };                                                                           \
505  struct Store##Type##MapWriteBarrier##Operator final                          \
506      : public Store##Type##Operator {                                         \
507    Store##Type##MapWriteBarrier##Operator()                                   \
508        : Store##Type##Operator(kMapWriteBarrier) {}                           \
509  };                                                                           \
510  struct Store##Type##PointerWriteBarrier##Operator final                      \
511      : public Store##Type##Operator {                                         \
512    Store##Type##PointerWriteBarrier##Operator()                               \
513        : Store##Type##Operator(kPointerWriteBarrier) {}                       \
514  };                                                                           \
515  struct Store##Type##FullWriteBarrier##Operator final                         \
516      : public Store##Type##Operator {                                         \
517    Store##Type##FullWriteBarrier##Operator()                                  \
518        : Store##Type##Operator(kFullWriteBarrier) {}                          \
519  };                                                                           \
520  struct CheckedStore##Type##Operator final                                    \
521      : public Operator1<CheckedStoreRepresentation> {                         \
522    CheckedStore##Type##Operator()                                             \
523        : Operator1<CheckedStoreRepresentation>(                               \
524              IrOpcode::kCheckedStore,                                         \
525              Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow,     \
526              "CheckedStore", 4, 1, 1, 0, 1, 0, MachineRepresentation::Type) { \
527    }                                                                          \
528  };                                                                           \
529  Store##Type##NoWriteBarrier##Operator kStore##Type##NoWriteBarrier;          \
530  Store##Type##MapWriteBarrier##Operator kStore##Type##MapWriteBarrier;        \
531  Store##Type##PointerWriteBarrier##Operator                                   \
532      kStore##Type##PointerWriteBarrier;                                       \
533  Store##Type##FullWriteBarrier##Operator kStore##Type##FullWriteBarrier;      \
534  CheckedStore##Type##Operator kCheckedStore##Type;
535  MACHINE_REPRESENTATION_LIST(STORE)
536#undef STORE
537
538#define ATOMIC_LOAD(Type)                                                   \
539  struct AtomicLoad##Type##Operator final                                   \
540      : public Operator1<LoadRepresentation> {                              \
541    AtomicLoad##Type##Operator()                                            \
542        : Operator1<LoadRepresentation>(                                    \
543              IrOpcode::kAtomicLoad,                                        \
544              Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite, \
545              "AtomicLoad", 2, 1, 1, 1, 1, 0, MachineType::Type()) {}       \
546  };                                                                        \
547  AtomicLoad##Type##Operator kAtomicLoad##Type;
548  ATOMIC_TYPE_LIST(ATOMIC_LOAD)
549#undef ATOMIC_LOAD
550
551#define ATOMIC_STORE(Type)                                                     \
552  struct AtomicStore##Type##Operator                                           \
553      : public Operator1<MachineRepresentation> {                              \
554    AtomicStore##Type##Operator()                                              \
555        : Operator1<MachineRepresentation>(                                    \
556              IrOpcode::kAtomicStore,                                          \
557              Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow,     \
558              "AtomicStore", 3, 1, 1, 0, 1, 0, MachineRepresentation::Type) {} \
559  };                                                                           \
560  AtomicStore##Type##Operator kAtomicStore##Type;
561  ATOMIC_REPRESENTATION_LIST(ATOMIC_STORE)
562#undef STORE
563
564  struct DebugBreakOperator : public Operator {
565    DebugBreakOperator()
566        : Operator(IrOpcode::kDebugBreak, Operator::kNoThrow, "DebugBreak", 0,
567                   0, 0, 0, 0, 0) {}
568  };
569  DebugBreakOperator kDebugBreak;
570};
571
572struct CommentOperator : public Operator1<const char*> {
573  explicit CommentOperator(const char* msg)
574      : Operator1<const char*>(IrOpcode::kComment, Operator::kNoThrow,
575                               "Comment", 0, 0, 0, 0, 0, 0, msg) {}
576};
577
578static base::LazyInstance<MachineOperatorGlobalCache>::type kCache =
579    LAZY_INSTANCE_INITIALIZER;
580
581MachineOperatorBuilder::MachineOperatorBuilder(
582    Zone* zone, MachineRepresentation word, Flags flags,
583    AlignmentRequirements alignmentRequirements)
584    : zone_(zone),
585      cache_(kCache.Get()),
586      word_(word),
587      flags_(flags),
588      alignment_requirements_(alignmentRequirements) {
589  DCHECK(word == MachineRepresentation::kWord32 ||
590         word == MachineRepresentation::kWord64);
591}
592
593
594#define PURE(Name, properties, value_input_count, control_input_count, \
595             output_count)                                             \
596  const Operator* MachineOperatorBuilder::Name() { return &cache_.k##Name; }
597PURE_OP_LIST(PURE)
598#undef PURE
599
600#define PURE(Name, properties, value_input_count, control_input_count,     \
601             output_count)                                                 \
602  const OptionalOperator MachineOperatorBuilder::Name() {                  \
603    return OptionalOperator(flags_ & k##Name ? &cache_.k##Name : nullptr); \
604  }
605PURE_OPTIONAL_OP_LIST(PURE)
606#undef PURE
607
608#define OVERFLOW_OP(Name, properties) \
609  const Operator* MachineOperatorBuilder::Name() { return &cache_.k##Name; }
610OVERFLOW_OP_LIST(OVERFLOW_OP)
611#undef OVERFLOW_OP
612
613const Operator* MachineOperatorBuilder::Load(LoadRepresentation rep) {
614#define LOAD(Type)                  \
615  if (rep == MachineType::Type()) { \
616    return &cache_.kLoad##Type;     \
617  }
618    MACHINE_TYPE_LIST(LOAD)
619#undef LOAD
620  UNREACHABLE();
621  return nullptr;
622}
623
624const Operator* MachineOperatorBuilder::StackSlot(MachineRepresentation rep) {
625#define STACKSLOT(Type)                              \
626  if (rep == MachineType::Type().representation()) { \
627    return &cache_.kStackSlot##Type;                 \
628  }
629  MACHINE_TYPE_LIST(STACKSLOT)
630#undef STACKSLOT
631  UNREACHABLE();
632  return nullptr;
633}
634
635const Operator* MachineOperatorBuilder::Store(StoreRepresentation store_rep) {
636  switch (store_rep.representation()) {
637#define STORE(kRep)                                         \
638  case MachineRepresentation::kRep:                         \
639    switch (store_rep.write_barrier_kind()) {               \
640      case kNoWriteBarrier:                                 \
641        return &cache_.k##Store##kRep##NoWriteBarrier;      \
642      case kMapWriteBarrier:                                \
643        return &cache_.k##Store##kRep##MapWriteBarrier;     \
644      case kPointerWriteBarrier:                            \
645        return &cache_.k##Store##kRep##PointerWriteBarrier; \
646      case kFullWriteBarrier:                               \
647        return &cache_.k##Store##kRep##FullWriteBarrier;    \
648    }                                                       \
649    break;
650    MACHINE_REPRESENTATION_LIST(STORE)
651#undef STORE
652    case MachineRepresentation::kBit:
653    case MachineRepresentation::kNone:
654      break;
655  }
656  UNREACHABLE();
657  return nullptr;
658}
659
660const Operator* MachineOperatorBuilder::DebugBreak() {
661  return &cache_.kDebugBreak;
662}
663
664const Operator* MachineOperatorBuilder::Comment(const char* msg) {
665  return new (zone_) CommentOperator(msg);
666}
667
668const Operator* MachineOperatorBuilder::CheckedLoad(
669    CheckedLoadRepresentation rep) {
670#define LOAD(Type)                     \
671  if (rep == MachineType::Type()) {    \
672    return &cache_.kCheckedLoad##Type; \
673  }
674    MACHINE_TYPE_LIST(LOAD)
675#undef LOAD
676  UNREACHABLE();
677  return nullptr;
678}
679
680
681const Operator* MachineOperatorBuilder::CheckedStore(
682    CheckedStoreRepresentation rep) {
683  switch (rep) {
684#define STORE(kRep)                 \
685  case MachineRepresentation::kRep: \
686    return &cache_.kCheckedStore##kRep;
687    MACHINE_REPRESENTATION_LIST(STORE)
688#undef STORE
689    case MachineRepresentation::kBit:
690    case MachineRepresentation::kNone:
691      break;
692  }
693  UNREACHABLE();
694  return nullptr;
695}
696
697// On 32 bit platforms we need to get a reference to optional operators of
698// 64-bit instructions for later Int64Lowering, even though 32 bit platforms
699// don't support the original 64-bit instruction.
700const Operator* MachineOperatorBuilder::Word64PopcntPlaceholder() {
701  return &cache_.kWord64Popcnt;
702}
703
704// On 32 bit platforms we need to get a reference to optional operators of
705// 64-bit instructions for later Int64Lowering, even though 32 bit platforms
706// don't support the original 64-bit instruction.
707const Operator* MachineOperatorBuilder::Word64CtzPlaceholder() {
708  return &cache_.kWord64Ctz;
709}
710
711const Operator* MachineOperatorBuilder::AtomicLoad(LoadRepresentation rep) {
712#define LOAD(Type)                    \
713  if (rep == MachineType::Type()) {   \
714    return &cache_.kAtomicLoad##Type; \
715  }
716  ATOMIC_TYPE_LIST(LOAD)
717#undef LOAD
718  UNREACHABLE();
719  return nullptr;
720}
721
722const Operator* MachineOperatorBuilder::AtomicStore(MachineRepresentation rep) {
723#define STORE(kRep)                         \
724  if (rep == MachineRepresentation::kRep) { \
725    return &cache_.kAtomicStore##kRep;      \
726  }
727  ATOMIC_REPRESENTATION_LIST(STORE)
728#undef STORE
729  UNREACHABLE();
730  return nullptr;
731}
732
733}  // namespace compiler
734}  // namespace internal
735}  // namespace v8
736