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 #include <type_traits>
7 
8 #include "src/compiler/opcodes.h"
9 #include "src/compiler/operator.h"
10 
11 namespace v8 {
12 namespace internal {
13 namespace compiler {
14 
operator ==(StoreRepresentation lhs,StoreRepresentation rhs)15 bool operator==(StoreRepresentation lhs, StoreRepresentation rhs) {
16   return lhs.representation() == rhs.representation() &&
17          lhs.write_barrier_kind() == rhs.write_barrier_kind();
18 }
19 
20 
operator !=(StoreRepresentation lhs,StoreRepresentation rhs)21 bool operator!=(StoreRepresentation lhs, StoreRepresentation rhs) {
22   return !(lhs == rhs);
23 }
24 
25 
hash_value(StoreRepresentation rep)26 size_t hash_value(StoreRepresentation rep) {
27   return base::hash_combine(rep.representation(), rep.write_barrier_kind());
28 }
29 
30 
operator <<(std::ostream & os,StoreRepresentation rep)31 std::ostream& operator<<(std::ostream& os, StoreRepresentation rep) {
32   return os << rep.representation() << ", " << rep.write_barrier_kind();
33 }
34 
hash_value(MemoryAccessKind kind)35 size_t hash_value(MemoryAccessKind kind) { return static_cast<size_t>(kind); }
36 
operator <<(std::ostream & os,MemoryAccessKind kind)37 std::ostream& operator<<(std::ostream& os, MemoryAccessKind kind) {
38   switch (kind) {
39     case MemoryAccessKind::kNormal:
40       return os << "kNormal";
41     case MemoryAccessKind::kUnaligned:
42       return os << "kUnaligned";
43     case MemoryAccessKind::kProtected:
44       return os << "kProtected";
45   }
46   UNREACHABLE();
47 }
48 
hash_value(LoadTransformation rep)49 size_t hash_value(LoadTransformation rep) { return static_cast<size_t>(rep); }
50 
operator <<(std::ostream & os,LoadTransformation rep)51 std::ostream& operator<<(std::ostream& os, LoadTransformation rep) {
52   switch (rep) {
53     case LoadTransformation::kS128Load8Splat:
54       return os << "kS128Load8Splat";
55     case LoadTransformation::kS128Load16Splat:
56       return os << "kS128Load16Splat";
57     case LoadTransformation::kS128Load32Splat:
58       return os << "kS128Load32Splat";
59     case LoadTransformation::kS128Load64Splat:
60       return os << "kS128Load64Splat";
61     case LoadTransformation::kS128Load8x8S:
62       return os << "kS128Load8x8S";
63     case LoadTransformation::kS128Load8x8U:
64       return os << "kS128Load8x8U";
65     case LoadTransformation::kS128Load16x4S:
66       return os << "kS128Load16x4S";
67     case LoadTransformation::kS128Load16x4U:
68       return os << "kS128Load16x4U";
69     case LoadTransformation::kS128Load32x2S:
70       return os << "kS128Load32x2S";
71     case LoadTransformation::kS128Load32x2U:
72       return os << "kS128Load32x2U";
73     case LoadTransformation::kS128Load32Zero:
74       return os << "kS128Load32Zero";
75     case LoadTransformation::kS128Load64Zero:
76       return os << "kS128Load64Zero";
77   }
78   UNREACHABLE();
79 }
80 
hash_value(LoadTransformParameters params)81 size_t hash_value(LoadTransformParameters params) {
82   return base::hash_combine(params.kind, params.transformation);
83 }
84 
operator <<(std::ostream & os,LoadTransformParameters params)85 std::ostream& operator<<(std::ostream& os, LoadTransformParameters params) {
86   return os << "(" << params.kind << " " << params.transformation << ")";
87 }
88 
LoadTransformParametersOf(Operator const * op)89 LoadTransformParameters const& LoadTransformParametersOf(Operator const* op) {
90   DCHECK_EQ(IrOpcode::kLoadTransform, op->opcode());
91   return OpParameter<LoadTransformParameters>(op);
92 }
93 
operator ==(LoadTransformParameters lhs,LoadTransformParameters rhs)94 bool operator==(LoadTransformParameters lhs, LoadTransformParameters rhs) {
95   return lhs.transformation == rhs.transformation && lhs.kind == rhs.kind;
96 }
97 
operator !=(LoadTransformParameters lhs,LoadTransformParameters rhs)98 bool operator!=(LoadTransformParameters lhs, LoadTransformParameters rhs) {
99   return !(lhs == rhs);
100 }
101 
hash_value(LoadLaneParameters params)102 size_t hash_value(LoadLaneParameters params) {
103   return base::hash_combine(params.kind, params.rep, params.laneidx);
104 }
105 
operator <<(std::ostream & os,LoadLaneParameters params)106 std::ostream& operator<<(std::ostream& os, LoadLaneParameters params) {
107   return os << "(" << params.kind << " " << params.rep << " " << params.laneidx
108             << ")";
109 }
110 
LoadLaneParametersOf(Operator const * op)111 LoadLaneParameters const& LoadLaneParametersOf(Operator const* op) {
112   DCHECK_EQ(IrOpcode::kLoadLane, op->opcode());
113   return OpParameter<LoadLaneParameters>(op);
114 }
115 
operator ==(LoadLaneParameters lhs,LoadLaneParameters rhs)116 bool operator==(LoadLaneParameters lhs, LoadLaneParameters rhs) {
117   return lhs.kind == rhs.kind && lhs.rep == rhs.rep &&
118          lhs.laneidx == rhs.laneidx;
119 }
120 
LoadRepresentationOf(Operator const * op)121 LoadRepresentation LoadRepresentationOf(Operator const* op) {
122   DCHECK(IrOpcode::kLoad == op->opcode() ||
123          IrOpcode::kProtectedLoad == op->opcode() ||
124          IrOpcode::kWord32AtomicLoad == op->opcode() ||
125          IrOpcode::kWord64AtomicLoad == op->opcode() ||
126          IrOpcode::kWord32AtomicPairLoad == op->opcode() ||
127          IrOpcode::kPoisonedLoad == op->opcode() ||
128          IrOpcode::kUnalignedLoad == op->opcode());
129   return OpParameter<LoadRepresentation>(op);
130 }
131 
StoreRepresentationOf(Operator const * op)132 StoreRepresentation const& StoreRepresentationOf(Operator const* op) {
133   DCHECK(IrOpcode::kStore == op->opcode() ||
134          IrOpcode::kProtectedStore == op->opcode());
135   return OpParameter<StoreRepresentation>(op);
136 }
137 
UnalignedStoreRepresentationOf(Operator const * op)138 UnalignedStoreRepresentation const& UnalignedStoreRepresentationOf(
139     Operator const* op) {
140   DCHECK_EQ(IrOpcode::kUnalignedStore, op->opcode());
141   return OpParameter<UnalignedStoreRepresentation>(op);
142 }
143 
hash_value(StoreLaneParameters params)144 size_t hash_value(StoreLaneParameters params) {
145   return base::hash_combine(params.kind, params.rep, params.laneidx);
146 }
147 
operator <<(std::ostream & os,StoreLaneParameters params)148 std::ostream& operator<<(std::ostream& os, StoreLaneParameters params) {
149   return os << "(" << params.kind << " " << params.rep << " " << params.laneidx
150             << ")";
151 }
152 
StoreLaneParametersOf(Operator const * op)153 StoreLaneParameters const& StoreLaneParametersOf(Operator const* op) {
154   DCHECK_EQ(IrOpcode::kStoreLane, op->opcode());
155   return OpParameter<StoreLaneParameters>(op);
156 }
157 
operator ==(StoreLaneParameters lhs,StoreLaneParameters rhs)158 bool operator==(StoreLaneParameters lhs, StoreLaneParameters rhs) {
159   return lhs.kind == rhs.kind && lhs.rep == rhs.rep &&
160          lhs.laneidx == rhs.laneidx;
161 }
162 
operator ==(StackSlotRepresentation lhs,StackSlotRepresentation rhs)163 bool operator==(StackSlotRepresentation lhs, StackSlotRepresentation rhs) {
164   return lhs.size() == rhs.size() && lhs.alignment() == rhs.alignment();
165 }
166 
operator !=(StackSlotRepresentation lhs,StackSlotRepresentation rhs)167 bool operator!=(StackSlotRepresentation lhs, StackSlotRepresentation rhs) {
168   return !(lhs == rhs);
169 }
170 
hash_value(StackSlotRepresentation rep)171 size_t hash_value(StackSlotRepresentation rep) {
172   return base::hash_combine(rep.size(), rep.alignment());
173 }
174 
operator <<(std::ostream & os,StackSlotRepresentation rep)175 std::ostream& operator<<(std::ostream& os, StackSlotRepresentation rep) {
176   return os << rep.size() << ", " << rep.alignment();
177 }
178 
StackSlotRepresentationOf(Operator const * op)179 StackSlotRepresentation const& StackSlotRepresentationOf(Operator const* op) {
180   DCHECK_EQ(IrOpcode::kStackSlot, op->opcode());
181   return OpParameter<StackSlotRepresentation>(op);
182 }
183 
AtomicStoreRepresentationOf(Operator const * op)184 MachineRepresentation AtomicStoreRepresentationOf(Operator const* op) {
185   DCHECK(IrOpcode::kWord32AtomicStore == op->opcode() ||
186          IrOpcode::kWord64AtomicStore == op->opcode());
187   return OpParameter<MachineRepresentation>(op);
188 }
189 
AtomicOpType(Operator const * op)190 MachineType AtomicOpType(Operator const* op) {
191   return OpParameter<MachineType>(op);
192 }
193 
hash_value(ShiftKind kind)194 size_t hash_value(ShiftKind kind) { return static_cast<size_t>(kind); }
operator <<(std::ostream & os,ShiftKind kind)195 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, ShiftKind kind) {
196   switch (kind) {
197     case ShiftKind::kNormal:
198       return os << "Normal";
199     case ShiftKind::kShiftOutZeros:
200       return os << "ShiftOutZeros";
201   }
202 }
203 
ShiftKindOf(Operator const * op)204 ShiftKind ShiftKindOf(Operator const* op) {
205   DCHECK(IrOpcode::kWord32Sar == op->opcode() ||
206          IrOpcode::kWord64Sar == op->opcode());
207   return OpParameter<ShiftKind>(op);
208 }
209 
210 // The format is:
211 // V(Name, properties, value_input_count, control_input_count, output_count)
212 #define PURE_BINARY_OP_LIST_32(V)                                           \
213   V(Word32And, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)    \
214   V(Word32Or, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)     \
215   V(Word32Xor, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)    \
216   V(Word32Shl, Operator::kNoProperties, 2, 0, 1)                            \
217   V(Word32Shr, Operator::kNoProperties, 2, 0, 1)                            \
218   V(Word32Ror, Operator::kNoProperties, 2, 0, 1)                            \
219   V(Word32Equal, Operator::kCommutative, 2, 0, 1)                           \
220   V(Int32Add, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)     \
221   V(Int32Sub, Operator::kNoProperties, 2, 0, 1)                             \
222   V(Int32Mul, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)     \
223   V(Int32MulHigh, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
224   V(Int32Div, Operator::kNoProperties, 2, 1, 1)                             \
225   V(Int32Mod, Operator::kNoProperties, 2, 1, 1)                             \
226   V(Int32LessThan, Operator::kNoProperties, 2, 0, 1)                        \
227   V(Int32LessThanOrEqual, Operator::kNoProperties, 2, 0, 1)                 \
228   V(Uint32Div, Operator::kNoProperties, 2, 1, 1)                            \
229   V(Uint32LessThan, Operator::kNoProperties, 2, 0, 1)                       \
230   V(Uint32LessThanOrEqual, Operator::kNoProperties, 2, 0, 1)                \
231   V(Uint32Mod, Operator::kNoProperties, 2, 1, 1)                            \
232   V(Uint32MulHigh, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)
233 
234 // The format is:
235 // V(Name, properties, value_input_count, control_input_count, output_count)
236 #define PURE_BINARY_OP_LIST_64(V)                                        \
237   V(Word64And, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
238   V(Word64Or, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)  \
239   V(Word64Xor, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
240   V(Word64Shl, Operator::kNoProperties, 2, 0, 1)                         \
241   V(Word64Shr, Operator::kNoProperties, 2, 0, 1)                         \
242   V(Word64Ror, Operator::kNoProperties, 2, 0, 1)                         \
243   V(Word64Equal, Operator::kCommutative, 2, 0, 1)                        \
244   V(Int64Add, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)  \
245   V(Int64Sub, Operator::kNoProperties, 2, 0, 1)                          \
246   V(Int64Mul, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)  \
247   V(Int64Div, Operator::kNoProperties, 2, 1, 1)                          \
248   V(Int64Mod, Operator::kNoProperties, 2, 1, 1)                          \
249   V(Int64LessThan, Operator::kNoProperties, 2, 0, 1)                     \
250   V(Int64LessThanOrEqual, Operator::kNoProperties, 2, 0, 1)              \
251   V(Uint64Div, Operator::kNoProperties, 2, 1, 1)                         \
252   V(Uint64Mod, Operator::kNoProperties, 2, 1, 1)                         \
253   V(Uint64LessThan, Operator::kNoProperties, 2, 0, 1)                    \
254   V(Uint64LessThanOrEqual, Operator::kNoProperties, 2, 0, 1)
255 
256 // The format is:
257 // V(Name, properties, value_input_count, control_input_count, output_count)
258 #define MACHINE_PURE_OP_LIST(V)                                            \
259   PURE_BINARY_OP_LIST_32(V)                                                \
260   PURE_BINARY_OP_LIST_64(V)                                                \
261   V(Word32Clz, Operator::kNoProperties, 1, 0, 1)                           \
262   V(Word64Clz, Operator::kNoProperties, 1, 0, 1)                           \
263   V(Word32ReverseBytes, Operator::kNoProperties, 1, 0, 1)                  \
264   V(Word64ReverseBytes, Operator::kNoProperties, 1, 0, 1)                  \
265   V(Simd128ReverseBytes, Operator::kNoProperties, 1, 0, 1)                 \
266   V(BitcastTaggedToWordForTagAndSmiBits, Operator::kNoProperties, 1, 0, 1) \
267   V(BitcastWordToTaggedSigned, Operator::kNoProperties, 1, 0, 1)           \
268   V(TruncateFloat64ToWord32, Operator::kNoProperties, 1, 0, 1)             \
269   V(ChangeFloat32ToFloat64, Operator::kNoProperties, 1, 0, 1)              \
270   V(ChangeFloat64ToInt32, Operator::kNoProperties, 1, 0, 1)                \
271   V(ChangeFloat64ToInt64, Operator::kNoProperties, 1, 0, 1)                \
272   V(ChangeFloat64ToUint32, Operator::kNoProperties, 1, 0, 1)               \
273   V(ChangeFloat64ToUint64, Operator::kNoProperties, 1, 0, 1)               \
274   V(TruncateFloat64ToInt64, Operator::kNoProperties, 1, 0, 1)              \
275   V(TruncateFloat64ToUint32, Operator::kNoProperties, 1, 0, 1)             \
276   V(TryTruncateFloat32ToInt64, Operator::kNoProperties, 1, 0, 2)           \
277   V(TryTruncateFloat64ToInt64, Operator::kNoProperties, 1, 0, 2)           \
278   V(TryTruncateFloat32ToUint64, Operator::kNoProperties, 1, 0, 2)          \
279   V(TryTruncateFloat64ToUint64, Operator::kNoProperties, 1, 0, 2)          \
280   V(ChangeInt32ToFloat64, Operator::kNoProperties, 1, 0, 1)                \
281   V(ChangeInt64ToFloat64, Operator::kNoProperties, 1, 0, 1)                \
282   V(Float64SilenceNaN, Operator::kNoProperties, 1, 0, 1)                   \
283   V(RoundFloat64ToInt32, Operator::kNoProperties, 1, 0, 1)                 \
284   V(RoundInt32ToFloat32, Operator::kNoProperties, 1, 0, 1)                 \
285   V(RoundInt64ToFloat32, Operator::kNoProperties, 1, 0, 1)                 \
286   V(RoundInt64ToFloat64, Operator::kNoProperties, 1, 0, 1)                 \
287   V(RoundUint32ToFloat32, Operator::kNoProperties, 1, 0, 1)                \
288   V(RoundUint64ToFloat32, Operator::kNoProperties, 1, 0, 1)                \
289   V(RoundUint64ToFloat64, Operator::kNoProperties, 1, 0, 1)                \
290   V(BitcastWord32ToWord64, Operator::kNoProperties, 1, 0, 1)               \
291   V(ChangeInt32ToInt64, Operator::kNoProperties, 1, 0, 1)                  \
292   V(ChangeUint32ToFloat64, Operator::kNoProperties, 1, 0, 1)               \
293   V(ChangeUint32ToUint64, Operator::kNoProperties, 1, 0, 1)                \
294   V(TruncateFloat64ToFloat32, Operator::kNoProperties, 1, 0, 1)            \
295   V(TruncateInt64ToInt32, Operator::kNoProperties, 1, 0, 1)                \
296   V(BitcastFloat32ToInt32, Operator::kNoProperties, 1, 0, 1)               \
297   V(BitcastFloat64ToInt64, Operator::kNoProperties, 1, 0, 1)               \
298   V(BitcastInt32ToFloat32, Operator::kNoProperties, 1, 0, 1)               \
299   V(BitcastInt64ToFloat64, Operator::kNoProperties, 1, 0, 1)               \
300   V(SignExtendWord8ToInt32, Operator::kNoProperties, 1, 0, 1)              \
301   V(SignExtendWord16ToInt32, Operator::kNoProperties, 1, 0, 1)             \
302   V(SignExtendWord8ToInt64, Operator::kNoProperties, 1, 0, 1)              \
303   V(SignExtendWord16ToInt64, Operator::kNoProperties, 1, 0, 1)             \
304   V(SignExtendWord32ToInt64, Operator::kNoProperties, 1, 0, 1)             \
305   V(Float32Abs, Operator::kNoProperties, 1, 0, 1)                          \
306   V(Float32Add, Operator::kCommutative, 2, 0, 1)                           \
307   V(Float32Sub, Operator::kNoProperties, 2, 0, 1)                          \
308   V(Float32Mul, Operator::kCommutative, 2, 0, 1)                           \
309   V(Float32Div, Operator::kNoProperties, 2, 0, 1)                          \
310   V(Float32Neg, Operator::kNoProperties, 1, 0, 1)                          \
311   V(Float32Sqrt, Operator::kNoProperties, 1, 0, 1)                         \
312   V(Float32Max, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)  \
313   V(Float32Min, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)  \
314   V(Float64Abs, Operator::kNoProperties, 1, 0, 1)                          \
315   V(Float64Acos, Operator::kNoProperties, 1, 0, 1)                         \
316   V(Float64Acosh, Operator::kNoProperties, 1, 0, 1)                        \
317   V(Float64Asin, Operator::kNoProperties, 1, 0, 1)                         \
318   V(Float64Asinh, Operator::kNoProperties, 1, 0, 1)                        \
319   V(Float64Atan, Operator::kNoProperties, 1, 0, 1)                         \
320   V(Float64Atan2, Operator::kNoProperties, 2, 0, 1)                        \
321   V(Float64Atanh, Operator::kNoProperties, 1, 0, 1)                        \
322   V(Float64Cbrt, Operator::kNoProperties, 1, 0, 1)                         \
323   V(Float64Cos, Operator::kNoProperties, 1, 0, 1)                          \
324   V(Float64Cosh, Operator::kNoProperties, 1, 0, 1)                         \
325   V(Float64Exp, Operator::kNoProperties, 1, 0, 1)                          \
326   V(Float64Expm1, Operator::kNoProperties, 1, 0, 1)                        \
327   V(Float64Log, Operator::kNoProperties, 1, 0, 1)                          \
328   V(Float64Log1p, Operator::kNoProperties, 1, 0, 1)                        \
329   V(Float64Log2, Operator::kNoProperties, 1, 0, 1)                         \
330   V(Float64Log10, Operator::kNoProperties, 1, 0, 1)                        \
331   V(Float64Max, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)  \
332   V(Float64Min, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)  \
333   V(Float64Neg, Operator::kNoProperties, 1, 0, 1)                          \
334   V(Float64Add, Operator::kCommutative, 2, 0, 1)                           \
335   V(Float64Sub, Operator::kNoProperties, 2, 0, 1)                          \
336   V(Float64Mul, Operator::kCommutative, 2, 0, 1)                           \
337   V(Float64Div, Operator::kNoProperties, 2, 0, 1)                          \
338   V(Float64Mod, Operator::kNoProperties, 2, 0, 1)                          \
339   V(Float64Pow, Operator::kNoProperties, 2, 0, 1)                          \
340   V(Float64Sin, Operator::kNoProperties, 1, 0, 1)                          \
341   V(Float64Sinh, Operator::kNoProperties, 1, 0, 1)                         \
342   V(Float64Sqrt, Operator::kNoProperties, 1, 0, 1)                         \
343   V(Float64Tan, Operator::kNoProperties, 1, 0, 1)                          \
344   V(Float64Tanh, Operator::kNoProperties, 1, 0, 1)                         \
345   V(Float32Equal, Operator::kCommutative, 2, 0, 1)                         \
346   V(Float32LessThan, Operator::kNoProperties, 2, 0, 1)                     \
347   V(Float32LessThanOrEqual, Operator::kNoProperties, 2, 0, 1)              \
348   V(Float64Equal, Operator::kCommutative, 2, 0, 1)                         \
349   V(Float64LessThan, Operator::kNoProperties, 2, 0, 1)                     \
350   V(Float64LessThanOrEqual, Operator::kNoProperties, 2, 0, 1)              \
351   V(Float64ExtractLowWord32, Operator::kNoProperties, 1, 0, 1)             \
352   V(Float64ExtractHighWord32, Operator::kNoProperties, 1, 0, 1)            \
353   V(Float64InsertLowWord32, Operator::kNoProperties, 2, 0, 1)              \
354   V(Float64InsertHighWord32, Operator::kNoProperties, 2, 0, 1)             \
355   V(LoadStackCheckOffset, Operator::kNoProperties, 0, 0, 1)                \
356   V(LoadFramePointer, Operator::kNoProperties, 0, 0, 1)                    \
357   V(LoadParentFramePointer, Operator::kNoProperties, 0, 0, 1)              \
358   V(Int32PairAdd, Operator::kNoProperties, 4, 0, 2)                        \
359   V(Int32PairSub, Operator::kNoProperties, 4, 0, 2)                        \
360   V(Int32PairMul, Operator::kNoProperties, 4, 0, 2)                        \
361   V(Word32PairShl, Operator::kNoProperties, 3, 0, 2)                       \
362   V(Word32PairShr, Operator::kNoProperties, 3, 0, 2)                       \
363   V(Word32PairSar, Operator::kNoProperties, 3, 0, 2)                       \
364   V(F64x2Splat, Operator::kNoProperties, 1, 0, 1)                          \
365   V(F64x2Abs, Operator::kNoProperties, 1, 0, 1)                            \
366   V(F64x2Neg, Operator::kNoProperties, 1, 0, 1)                            \
367   V(F64x2Sqrt, Operator::kNoProperties, 1, 0, 1)                           \
368   V(F64x2Add, Operator::kCommutative, 2, 0, 1)                             \
369   V(F64x2Sub, Operator::kNoProperties, 2, 0, 1)                            \
370   V(F64x2Mul, Operator::kCommutative, 2, 0, 1)                             \
371   V(F64x2Div, Operator::kNoProperties, 2, 0, 1)                            \
372   V(F64x2Min, Operator::kCommutative, 2, 0, 1)                             \
373   V(F64x2Max, Operator::kCommutative, 2, 0, 1)                             \
374   V(F64x2Eq, Operator::kCommutative, 2, 0, 1)                              \
375   V(F64x2Ne, Operator::kCommutative, 2, 0, 1)                              \
376   V(F64x2Lt, Operator::kNoProperties, 2, 0, 1)                             \
377   V(F64x2Le, Operator::kNoProperties, 2, 0, 1)                             \
378   V(F64x2Qfma, Operator::kNoProperties, 3, 0, 1)                           \
379   V(F64x2Qfms, Operator::kNoProperties, 3, 0, 1)                           \
380   V(F64x2Pmin, Operator::kNoProperties, 2, 0, 1)                           \
381   V(F64x2Pmax, Operator::kNoProperties, 2, 0, 1)                           \
382   V(F64x2Ceil, Operator::kNoProperties, 1, 0, 1)                           \
383   V(F64x2Floor, Operator::kNoProperties, 1, 0, 1)                          \
384   V(F64x2Trunc, Operator::kNoProperties, 1, 0, 1)                          \
385   V(F64x2NearestInt, Operator::kNoProperties, 1, 0, 1)                     \
386   V(F32x4Splat, Operator::kNoProperties, 1, 0, 1)                          \
387   V(F32x4SConvertI32x4, Operator::kNoProperties, 1, 0, 1)                  \
388   V(F32x4UConvertI32x4, Operator::kNoProperties, 1, 0, 1)                  \
389   V(F32x4Abs, Operator::kNoProperties, 1, 0, 1)                            \
390   V(F32x4Neg, Operator::kNoProperties, 1, 0, 1)                            \
391   V(F32x4Sqrt, Operator::kNoProperties, 1, 0, 1)                           \
392   V(F32x4RecipApprox, Operator::kNoProperties, 1, 0, 1)                    \
393   V(F32x4RecipSqrtApprox, Operator::kNoProperties, 1, 0, 1)                \
394   V(F32x4Add, Operator::kCommutative, 2, 0, 1)                             \
395   V(F32x4AddHoriz, Operator::kNoProperties, 2, 0, 1)                       \
396   V(F32x4Sub, Operator::kNoProperties, 2, 0, 1)                            \
397   V(F32x4Mul, Operator::kCommutative, 2, 0, 1)                             \
398   V(F32x4Div, Operator::kNoProperties, 2, 0, 1)                            \
399   V(F32x4Min, Operator::kCommutative, 2, 0, 1)                             \
400   V(F32x4Max, Operator::kCommutative, 2, 0, 1)                             \
401   V(F32x4Eq, Operator::kCommutative, 2, 0, 1)                              \
402   V(F32x4Ne, Operator::kCommutative, 2, 0, 1)                              \
403   V(F32x4Lt, Operator::kNoProperties, 2, 0, 1)                             \
404   V(F32x4Le, Operator::kNoProperties, 2, 0, 1)                             \
405   V(F32x4Qfma, Operator::kNoProperties, 3, 0, 1)                           \
406   V(F32x4Qfms, Operator::kNoProperties, 3, 0, 1)                           \
407   V(F32x4Pmin, Operator::kNoProperties, 2, 0, 1)                           \
408   V(F32x4Pmax, Operator::kNoProperties, 2, 0, 1)                           \
409   V(F32x4Ceil, Operator::kNoProperties, 1, 0, 1)                           \
410   V(F32x4Floor, Operator::kNoProperties, 1, 0, 1)                          \
411   V(F32x4Trunc, Operator::kNoProperties, 1, 0, 1)                          \
412   V(F32x4NearestInt, Operator::kNoProperties, 1, 0, 1)                     \
413   V(I64x2Splat, Operator::kNoProperties, 1, 0, 1)                          \
414   V(I64x2SplatI32Pair, Operator::kNoProperties, 2, 0, 1)                   \
415   V(I64x2Neg, Operator::kNoProperties, 1, 0, 1)                            \
416   V(I64x2SConvertI32x4Low, Operator::kNoProperties, 1, 0, 1)               \
417   V(I64x2SConvertI32x4High, Operator::kNoProperties, 1, 0, 1)              \
418   V(I64x2UConvertI32x4Low, Operator::kNoProperties, 1, 0, 1)               \
419   V(I64x2UConvertI32x4High, Operator::kNoProperties, 1, 0, 1)              \
420   V(I64x2BitMask, Operator::kNoProperties, 1, 0, 1)                        \
421   V(I64x2Shl, Operator::kNoProperties, 2, 0, 1)                            \
422   V(I64x2ShrS, Operator::kNoProperties, 2, 0, 1)                           \
423   V(I64x2Add, Operator::kCommutative, 2, 0, 1)                             \
424   V(I64x2Sub, Operator::kNoProperties, 2, 0, 1)                            \
425   V(I64x2Mul, Operator::kCommutative, 2, 0, 1)                             \
426   V(I64x2Eq, Operator::kCommutative, 2, 0, 1)                              \
427   V(I64x2ShrU, Operator::kNoProperties, 2, 0, 1)                           \
428   V(I64x2ExtMulLowI32x4S, Operator::kCommutative, 2, 0, 1)                 \
429   V(I64x2ExtMulHighI32x4S, Operator::kCommutative, 2, 0, 1)                \
430   V(I64x2ExtMulLowI32x4U, Operator::kCommutative, 2, 0, 1)                 \
431   V(I64x2ExtMulHighI32x4U, Operator::kCommutative, 2, 0, 1)                \
432   V(I64x2SignSelect, Operator::kNoProperties, 3, 0, 1)                     \
433   V(I32x4Splat, Operator::kNoProperties, 1, 0, 1)                          \
434   V(I32x4SConvertF32x4, Operator::kNoProperties, 1, 0, 1)                  \
435   V(I32x4SConvertI16x8Low, Operator::kNoProperties, 1, 0, 1)               \
436   V(I32x4SConvertI16x8High, Operator::kNoProperties, 1, 0, 1)              \
437   V(I32x4Neg, Operator::kNoProperties, 1, 0, 1)                            \
438   V(I32x4Shl, Operator::kNoProperties, 2, 0, 1)                            \
439   V(I32x4ShrS, Operator::kNoProperties, 2, 0, 1)                           \
440   V(I32x4Add, Operator::kCommutative, 2, 0, 1)                             \
441   V(I32x4AddHoriz, Operator::kNoProperties, 2, 0, 1)                       \
442   V(I32x4Sub, Operator::kNoProperties, 2, 0, 1)                            \
443   V(I32x4Mul, Operator::kCommutative, 2, 0, 1)                             \
444   V(I32x4MinS, Operator::kCommutative, 2, 0, 1)                            \
445   V(I32x4MaxS, Operator::kCommutative, 2, 0, 1)                            \
446   V(I32x4Eq, Operator::kCommutative, 2, 0, 1)                              \
447   V(I32x4Ne, Operator::kCommutative, 2, 0, 1)                              \
448   V(I32x4GtS, Operator::kNoProperties, 2, 0, 1)                            \
449   V(I32x4GeS, Operator::kNoProperties, 2, 0, 1)                            \
450   V(I32x4UConvertF32x4, Operator::kNoProperties, 1, 0, 1)                  \
451   V(I32x4UConvertI16x8Low, Operator::kNoProperties, 1, 0, 1)               \
452   V(I32x4UConvertI16x8High, Operator::kNoProperties, 1, 0, 1)              \
453   V(I32x4ShrU, Operator::kNoProperties, 2, 0, 1)                           \
454   V(I32x4MinU, Operator::kCommutative, 2, 0, 1)                            \
455   V(I32x4MaxU, Operator::kCommutative, 2, 0, 1)                            \
456   V(I32x4GtU, Operator::kNoProperties, 2, 0, 1)                            \
457   V(I32x4GeU, Operator::kNoProperties, 2, 0, 1)                            \
458   V(I32x4Abs, Operator::kNoProperties, 1, 0, 1)                            \
459   V(I32x4BitMask, Operator::kNoProperties, 1, 0, 1)                        \
460   V(I32x4DotI16x8S, Operator::kCommutative, 2, 0, 1)                       \
461   V(I32x4ExtMulLowI16x8S, Operator::kCommutative, 2, 0, 1)                 \
462   V(I32x4ExtMulHighI16x8S, Operator::kCommutative, 2, 0, 1)                \
463   V(I32x4ExtMulLowI16x8U, Operator::kCommutative, 2, 0, 1)                 \
464   V(I32x4ExtMulHighI16x8U, Operator::kCommutative, 2, 0, 1)                \
465   V(I32x4SignSelect, Operator::kNoProperties, 3, 0, 1)                     \
466   V(I32x4ExtAddPairwiseI16x8S, Operator::kNoProperties, 1, 0, 1)           \
467   V(I32x4ExtAddPairwiseI16x8U, Operator::kNoProperties, 1, 0, 1)           \
468   V(I16x8Splat, Operator::kNoProperties, 1, 0, 1)                          \
469   V(I16x8SConvertI8x16Low, Operator::kNoProperties, 1, 0, 1)               \
470   V(I16x8SConvertI8x16High, Operator::kNoProperties, 1, 0, 1)              \
471   V(I16x8Neg, Operator::kNoProperties, 1, 0, 1)                            \
472   V(I16x8Shl, Operator::kNoProperties, 2, 0, 1)                            \
473   V(I16x8ShrS, Operator::kNoProperties, 2, 0, 1)                           \
474   V(I16x8SConvertI32x4, Operator::kNoProperties, 2, 0, 1)                  \
475   V(I16x8Add, Operator::kCommutative, 2, 0, 1)                             \
476   V(I16x8AddSatS, Operator::kCommutative, 2, 0, 1)                         \
477   V(I16x8AddHoriz, Operator::kNoProperties, 2, 0, 1)                       \
478   V(I16x8Sub, Operator::kNoProperties, 2, 0, 1)                            \
479   V(I16x8SubSatS, Operator::kNoProperties, 2, 0, 1)                        \
480   V(I16x8Mul, Operator::kCommutative, 2, 0, 1)                             \
481   V(I16x8MinS, Operator::kCommutative, 2, 0, 1)                            \
482   V(I16x8MaxS, Operator::kCommutative, 2, 0, 1)                            \
483   V(I16x8Eq, Operator::kCommutative, 2, 0, 1)                              \
484   V(I16x8Ne, Operator::kCommutative, 2, 0, 1)                              \
485   V(I16x8GtS, Operator::kNoProperties, 2, 0, 1)                            \
486   V(I16x8GeS, Operator::kNoProperties, 2, 0, 1)                            \
487   V(I16x8UConvertI8x16Low, Operator::kNoProperties, 1, 0, 1)               \
488   V(I16x8UConvertI8x16High, Operator::kNoProperties, 1, 0, 1)              \
489   V(I16x8ShrU, Operator::kNoProperties, 2, 0, 1)                           \
490   V(I16x8UConvertI32x4, Operator::kNoProperties, 2, 0, 1)                  \
491   V(I16x8AddSatU, Operator::kCommutative, 2, 0, 1)                         \
492   V(I16x8SubSatU, Operator::kNoProperties, 2, 0, 1)                        \
493   V(I16x8MinU, Operator::kCommutative, 2, 0, 1)                            \
494   V(I16x8MaxU, Operator::kCommutative, 2, 0, 1)                            \
495   V(I16x8GtU, Operator::kNoProperties, 2, 0, 1)                            \
496   V(I16x8GeU, Operator::kNoProperties, 2, 0, 1)                            \
497   V(I16x8RoundingAverageU, Operator::kCommutative, 2, 0, 1)                \
498   V(I16x8Q15MulRSatS, Operator::kCommutative, 2, 0, 1)                     \
499   V(I16x8Abs, Operator::kNoProperties, 1, 0, 1)                            \
500   V(I16x8BitMask, Operator::kNoProperties, 1, 0, 1)                        \
501   V(I16x8ExtMulLowI8x16S, Operator::kCommutative, 2, 0, 1)                 \
502   V(I16x8ExtMulHighI8x16S, Operator::kCommutative, 2, 0, 1)                \
503   V(I16x8ExtMulLowI8x16U, Operator::kCommutative, 2, 0, 1)                 \
504   V(I16x8ExtMulHighI8x16U, Operator::kCommutative, 2, 0, 1)                \
505   V(I16x8SignSelect, Operator::kNoProperties, 3, 0, 1)                     \
506   V(I16x8ExtAddPairwiseI8x16S, Operator::kNoProperties, 1, 0, 1)           \
507   V(I16x8ExtAddPairwiseI8x16U, Operator::kNoProperties, 1, 0, 1)           \
508   V(I8x16Splat, Operator::kNoProperties, 1, 0, 1)                          \
509   V(I8x16Neg, Operator::kNoProperties, 1, 0, 1)                            \
510   V(I8x16Shl, Operator::kNoProperties, 2, 0, 1)                            \
511   V(I8x16ShrS, Operator::kNoProperties, 2, 0, 1)                           \
512   V(I8x16SConvertI16x8, Operator::kNoProperties, 2, 0, 1)                  \
513   V(I8x16Add, Operator::kCommutative, 2, 0, 1)                             \
514   V(I8x16AddSatS, Operator::kCommutative, 2, 0, 1)                         \
515   V(I8x16Sub, Operator::kNoProperties, 2, 0, 1)                            \
516   V(I8x16SubSatS, Operator::kNoProperties, 2, 0, 1)                        \
517   V(I8x16Mul, Operator::kCommutative, 2, 0, 1)                             \
518   V(I8x16MinS, Operator::kCommutative, 2, 0, 1)                            \
519   V(I8x16MaxS, Operator::kCommutative, 2, 0, 1)                            \
520   V(I8x16Eq, Operator::kCommutative, 2, 0, 1)                              \
521   V(I8x16Ne, Operator::kCommutative, 2, 0, 1)                              \
522   V(I8x16GtS, Operator::kNoProperties, 2, 0, 1)                            \
523   V(I8x16GeS, Operator::kNoProperties, 2, 0, 1)                            \
524   V(I8x16ShrU, Operator::kNoProperties, 2, 0, 1)                           \
525   V(I8x16UConvertI16x8, Operator::kNoProperties, 2, 0, 1)                  \
526   V(I8x16AddSatU, Operator::kCommutative, 2, 0, 1)                         \
527   V(I8x16SubSatU, Operator::kNoProperties, 2, 0, 1)                        \
528   V(I8x16MinU, Operator::kCommutative, 2, 0, 1)                            \
529   V(I8x16MaxU, Operator::kCommutative, 2, 0, 1)                            \
530   V(I8x16GtU, Operator::kNoProperties, 2, 0, 1)                            \
531   V(I8x16GeU, Operator::kNoProperties, 2, 0, 1)                            \
532   V(I8x16RoundingAverageU, Operator::kCommutative, 2, 0, 1)                \
533   V(I8x16Popcnt, Operator::kNoProperties, 1, 0, 1)                         \
534   V(I8x16Abs, Operator::kNoProperties, 1, 0, 1)                            \
535   V(I8x16BitMask, Operator::kNoProperties, 1, 0, 1)                        \
536   V(I8x16SignSelect, Operator::kNoProperties, 3, 0, 1)                     \
537   V(S128Load, Operator::kNoProperties, 2, 0, 1)                            \
538   V(S128Store, Operator::kNoProperties, 3, 0, 1)                           \
539   V(S128Zero, Operator::kNoProperties, 0, 0, 1)                            \
540   V(S128And, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)     \
541   V(S128Or, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)      \
542   V(S128Xor, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)     \
543   V(S128Not, Operator::kNoProperties, 1, 0, 1)                             \
544   V(S128Select, Operator::kNoProperties, 3, 0, 1)                          \
545   V(S128AndNot, Operator::kNoProperties, 2, 0, 1)                          \
546   V(V32x4AnyTrue, Operator::kNoProperties, 1, 0, 1)                        \
547   V(V32x4AllTrue, Operator::kNoProperties, 1, 0, 1)                        \
548   V(V16x8AnyTrue, Operator::kNoProperties, 1, 0, 1)                        \
549   V(V16x8AllTrue, Operator::kNoProperties, 1, 0, 1)                        \
550   V(V8x16AnyTrue, Operator::kNoProperties, 1, 0, 1)                        \
551   V(V8x16AllTrue, Operator::kNoProperties, 1, 0, 1)                        \
552   V(I8x16Swizzle, Operator::kNoProperties, 2, 0, 1)
553 
554 // The format is:
555 // V(Name, properties, value_input_count, control_input_count, output_count)
556 #define PURE_OPTIONAL_OP_LIST(V)                            \
557   V(Word32Ctz, Operator::kNoProperties, 1, 0, 1)            \
558   V(Word64Ctz, Operator::kNoProperties, 1, 0, 1)            \
559   V(Word32Rol, Operator::kNoProperties, 2, 0, 1)            \
560   V(Word64Rol, Operator::kNoProperties, 2, 0, 1)            \
561   V(Word32ReverseBits, Operator::kNoProperties, 1, 0, 1)    \
562   V(Word64ReverseBits, Operator::kNoProperties, 1, 0, 1)    \
563   V(Int32AbsWithOverflow, Operator::kNoProperties, 1, 0, 2) \
564   V(Int64AbsWithOverflow, Operator::kNoProperties, 1, 0, 2) \
565   V(Word32Popcnt, Operator::kNoProperties, 1, 0, 1)         \
566   V(Word64Popcnt, Operator::kNoProperties, 1, 0, 1)         \
567   V(Float32RoundDown, Operator::kNoProperties, 1, 0, 1)     \
568   V(Float64RoundDown, Operator::kNoProperties, 1, 0, 1)     \
569   V(Float32RoundUp, Operator::kNoProperties, 1, 0, 1)       \
570   V(Float64RoundUp, Operator::kNoProperties, 1, 0, 1)       \
571   V(Float32RoundTruncate, Operator::kNoProperties, 1, 0, 1) \
572   V(Float64RoundTruncate, Operator::kNoProperties, 1, 0, 1) \
573   V(Float64RoundTiesAway, Operator::kNoProperties, 1, 0, 1) \
574   V(Float32RoundTiesEven, Operator::kNoProperties, 1, 0, 1) \
575   V(Float64RoundTiesEven, Operator::kNoProperties, 1, 0, 1)
576 
577 // The format is:
578 // V(Name, properties, value_input_count, control_input_count, output_count)
579 #define OVERFLOW_OP_LIST(V)                                                \
580   V(Int32AddWithOverflow, Operator::kAssociative | Operator::kCommutative) \
581   V(Int32SubWithOverflow, Operator::kNoProperties)                         \
582   V(Int32MulWithOverflow, Operator::kAssociative | Operator::kCommutative) \
583   V(Int64AddWithOverflow, Operator::kAssociative | Operator::kCommutative) \
584   V(Int64SubWithOverflow, Operator::kNoProperties)
585 
586 #define MACHINE_TYPE_LIST(V) \
587   V(Float32)                 \
588   V(Float64)                 \
589   V(Simd128)                 \
590   V(Int8)                    \
591   V(Uint8)                   \
592   V(Int16)                   \
593   V(Uint16)                  \
594   V(Int32)                   \
595   V(Uint32)                  \
596   V(Int64)                   \
597   V(Uint64)                  \
598   V(Pointer)                 \
599   V(TaggedSigned)            \
600   V(TaggedPointer)           \
601   V(AnyTagged)               \
602   V(CompressedPointer)       \
603   V(AnyCompressed)
604 
605 #define MACHINE_REPRESENTATION_LIST(V) \
606   V(kFloat32)                          \
607   V(kFloat64)                          \
608   V(kSimd128)                          \
609   V(kWord8)                            \
610   V(kWord16)                           \
611   V(kWord32)                           \
612   V(kWord64)                           \
613   V(kTaggedSigned)                     \
614   V(kTaggedPointer)                    \
615   V(kTagged)                           \
616   V(kCompressedPointer)                \
617   V(kCompressed)
618 
619 #define LOAD_TRANSFORM_LIST(V) \
620   V(S128Load8Splat)            \
621   V(S128Load16Splat)           \
622   V(S128Load32Splat)           \
623   V(S128Load64Splat)           \
624   V(S128Load8x8S)              \
625   V(S128Load8x8U)              \
626   V(S128Load16x4S)             \
627   V(S128Load16x4U)             \
628   V(S128Load32x2S)             \
629   V(S128Load32x2U)             \
630   V(S128Load32Zero)            \
631   V(S128Load64Zero)
632 
633 #define ATOMIC_U32_TYPE_LIST(V) \
634   V(Uint8)                      \
635   V(Uint16)                     \
636   V(Uint32)
637 
638 #define ATOMIC_TYPE_LIST(V) \
639   ATOMIC_U32_TYPE_LIST(V)   \
640   V(Int8)                   \
641   V(Int16)                  \
642   V(Int32)
643 
644 #define ATOMIC_U64_TYPE_LIST(V) \
645   ATOMIC_U32_TYPE_LIST(V)       \
646   V(Uint64)
647 
648 #define ATOMIC_REPRESENTATION_LIST(V) \
649   V(kWord8)                           \
650   V(kWord16)                          \
651   V(kWord32)
652 
653 #define ATOMIC64_REPRESENTATION_LIST(V) \
654   ATOMIC_REPRESENTATION_LIST(V)         \
655   V(kWord64)
656 
657 #define SIMD_LANE_OP_LIST(V) \
658   V(F64x2, 2)                \
659   V(F32x4, 4)                \
660   V(I64x2, 2)                \
661   V(I32x4, 4)                \
662   V(I16x8, 8)                \
663   V(I8x16, 16)
664 
665 #define SIMD_I64x2_LANES(V) V(0) V(1)
666 
667 #define SIMD_I32x4_LANES(V) SIMD_I64x2_LANES(V) V(2) V(3)
668 
669 #define SIMD_I16x8_LANES(V) SIMD_I32x4_LANES(V) V(4) V(5) V(6) V(7)
670 
671 #define SIMD_I8x16_LANES(V) \
672   SIMD_I16x8_LANES(V) V(8) V(9) V(10) V(11) V(12) V(13) V(14) V(15)
673 
674 #define STACK_SLOT_CACHED_SIZES_ALIGNMENTS_LIST(V) \
675   V(4, 0) V(8, 0) V(16, 0) V(4, 4) V(8, 8) V(16, 16)
676 
677 template <IrOpcode::Value op, int value_input_count, int effect_input_count,
678           int control_input_count, int value_output_count,
679           int effect_output_count, int control_output_count>
680 struct CachedOperator : public Operator {
CachedOperatorv8::internal::compiler::CachedOperator681   CachedOperator(Operator::Properties properties, const char* mnemonic)
682       : Operator(op, properties, mnemonic, value_input_count,
683                  effect_input_count, control_input_count, value_output_count,
684                  effect_output_count, control_output_count) {}
685 };
686 
687 template <IrOpcode::Value op, int value_input_count, int control_input_count,
688           int value_output_count>
689 struct CachedPureOperator : public Operator {
CachedPureOperatorv8::internal::compiler::CachedPureOperator690   CachedPureOperator(Operator::Properties properties, const char* mnemonic)
691       : Operator(op, Operator::kPure | properties, mnemonic, value_input_count,
692                  0, control_input_count, value_output_count, 0, 0) {}
693 };
694 
695 template <class Op>
GetCachedOperator()696 const Operator* GetCachedOperator() {
697   STATIC_ASSERT(std::is_trivially_destructible<Op>::value);
698   static const Op op;
699   return &op;
700 }
701 
702 template <class Op>
GetCachedOperator(Operator::Properties properties,const char * mnemonic)703 const Operator* GetCachedOperator(Operator::Properties properties,
704                                   const char* mnemonic) {
705 #ifdef DEBUG
706   static Operator::Properties const initial_properties = properties;
707   static const char* const initial_mnemonic = mnemonic;
708   DCHECK_EQ(properties, initial_properties);
709   DCHECK_EQ(mnemonic, initial_mnemonic);
710 #endif
711   STATIC_ASSERT(std::is_trivially_destructible<Op>::value);
712   static const Op op(properties, mnemonic);
713   return &op;
714 }
715 
716 struct StackSlotOperator : public Operator1<StackSlotRepresentation> {
StackSlotOperatorv8::internal::compiler::StackSlotOperator717   explicit StackSlotOperator(int size, int alignment)
718       : Operator1(IrOpcode::kStackSlot, Operator::kNoDeopt | Operator::kNoThrow,
719                   "StackSlot", 0, 0, 0, 1, 0, 0,
720                   StackSlotRepresentation(size, alignment)) {}
721 };
722 
723 template <int size, int alignment>
724 struct CachedStackSlotOperator : StackSlotOperator {
CachedStackSlotOperatorv8::internal::compiler::CachedStackSlotOperator725   CachedStackSlotOperator() : StackSlotOperator(size, alignment) {}
726 };
727 
728 #define PURE(Name, properties, value_input_count, control_input_count,         \
729              output_count)                                                     \
730   const OptionalOperator MachineOperatorBuilder::Name() {                      \
731     return OptionalOperator(                                                   \
732         flags_ & k##Name,                                                      \
733         GetCachedOperator<                                                     \
734             CachedPureOperator<IrOpcode::k##Name, value_input_count,           \
735                                control_input_count, output_count>>(properties, \
736                                                                    #Name));    \
737   }
738 PURE_OPTIONAL_OP_LIST(PURE)
739 #undef PURE
740 
741 #define OVERFLOW_OP(Name, properties)                                     \
742   const Operator* MachineOperatorBuilder::Name() {                        \
743     return GetCachedOperator<                                             \
744         CachedOperator<IrOpcode::k##Name, 2, 0, 1, 2, 0, 0>>(             \
745         Operator::kEliminatable | Operator::kNoRead | properties, #Name); \
746   }
747 OVERFLOW_OP_LIST(OVERFLOW_OP)
748 #undef OVERFLOW_OP
749 
750 template <ShiftKind kind>
751 struct Word32SarOperator : Operator1<ShiftKind> {
Word32SarOperatorv8::internal::compiler::Word32SarOperator752   Word32SarOperator()
753       : Operator1(IrOpcode::kWord32Sar, Operator::kPure, "Word32Sar", 2, 0, 0,
754                   1, 0, 0, kind) {}
755 };
756 
Word32Sar(ShiftKind kind)757 const Operator* MachineOperatorBuilder::Word32Sar(ShiftKind kind) {
758   switch (kind) {
759     case ShiftKind::kNormal:
760       return GetCachedOperator<Word32SarOperator<ShiftKind::kNormal>>();
761     case ShiftKind::kShiftOutZeros:
762       return GetCachedOperator<Word32SarOperator<ShiftKind::kShiftOutZeros>>();
763   }
764 }
765 
766 template <ShiftKind kind>
767 struct Word64SarOperator : Operator1<ShiftKind> {
Word64SarOperatorv8::internal::compiler::Word64SarOperator768   Word64SarOperator()
769       : Operator1(IrOpcode::kWord64Sar, Operator::kPure, "Word64Sar", 2, 0, 0,
770                   1, 0, 0, kind) {}
771 };
772 
Word64Sar(ShiftKind kind)773 const Operator* MachineOperatorBuilder::Word64Sar(ShiftKind kind) {
774   switch (kind) {
775     case ShiftKind::kNormal:
776       return GetCachedOperator<Word64SarOperator<ShiftKind::kNormal>>();
777     case ShiftKind::kShiftOutZeros:
778       return GetCachedOperator<Word64SarOperator<ShiftKind::kShiftOutZeros>>();
779   }
780 }
781 
782 template <MachineRepresentation rep, MachineSemantic sem>
783 struct LoadOperator : public Operator1<LoadRepresentation> {
LoadOperatorv8::internal::compiler::LoadOperator784   LoadOperator()
785       : Operator1(IrOpcode::kLoad, Operator::kEliminatable, "Load", 2, 1, 1, 1,
786                   1, 0, LoadRepresentation(rep, sem)) {}
787 };
788 
789 template <MachineRepresentation rep, MachineSemantic sem>
790 struct PoisonedLoadOperator : public Operator1<LoadRepresentation> {
PoisonedLoadOperatorv8::internal::compiler::PoisonedLoadOperator791   PoisonedLoadOperator()
792       : Operator1(IrOpcode::kPoisonedLoad, Operator::kEliminatable,
793                   "PoisonedLoad", 2, 1, 1, 1, 1, 0,
794                   LoadRepresentation(rep, sem)) {}
795 };
796 
797 template <MachineRepresentation rep, MachineSemantic sem>
798 struct UnalignedLoadOperator : public Operator1<LoadRepresentation> {
UnalignedLoadOperatorv8::internal::compiler::UnalignedLoadOperator799   UnalignedLoadOperator()
800       : Operator1(IrOpcode::kUnalignedLoad, Operator::kEliminatable,
801                   "UnalignedLoad", 2, 1, 1, 1, 1, 0,
802                   LoadRepresentation(rep, sem)) {}
803 };
804 
805 template <MachineRepresentation rep, MachineSemantic sem>
806 struct ProtectedLoadOperator : public Operator1<LoadRepresentation> {
ProtectedLoadOperatorv8::internal::compiler::ProtectedLoadOperator807   ProtectedLoadOperator()
808       : Operator1(IrOpcode::kProtectedLoad,
809                   Operator::kNoDeopt | Operator::kNoThrow, "ProtectedLoad", 2,
810                   1, 1, 1, 1, 0, LoadRepresentation(rep, sem)) {}
811 };
812 
813 template <MemoryAccessKind kind, LoadTransformation type>
814 struct LoadTransformOperator : public Operator1<LoadTransformParameters> {
LoadTransformOperatorv8::internal::compiler::LoadTransformOperator815   LoadTransformOperator()
816       : Operator1(IrOpcode::kLoadTransform,
817                   kind == MemoryAccessKind::kProtected
818                       ? Operator::kNoDeopt | Operator::kNoThrow
819                       : Operator::kEliminatable,
820                   "LoadTransform", 2, 1, 1, 1, 1, 0,
821                   LoadTransformParameters{kind, type}) {}
822 };
823 
824 template <MemoryAccessKind kind, MachineRepresentation rep, MachineSemantic sem,
825           uint8_t laneidx>
826 struct LoadLaneOperator : public Operator1<LoadLaneParameters> {
LoadLaneOperatorv8::internal::compiler::LoadLaneOperator827   LoadLaneOperator()
828       : Operator1(
829             IrOpcode::kLoadLane,
830             kind == MemoryAccessKind::kProtected
831                 ? Operator::kNoDeopt | Operator::kNoThrow
832                 : Operator::kEliminatable,
833             "LoadLane", 3, 1, 1, 1, 1, 0,
834             LoadLaneParameters{kind, LoadRepresentation(rep, sem), laneidx}) {}
835 };
836 
837 template <MachineRepresentation rep, WriteBarrierKind write_barrier_kind>
838 struct StoreOperator : public Operator1<StoreRepresentation> {
StoreOperatorv8::internal::compiler::StoreOperator839   StoreOperator()
840       : Operator1(IrOpcode::kStore,
841                   Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow,
842                   "Store", 3, 1, 1, 0, 1, 0,
843                   StoreRepresentation(rep, write_barrier_kind)) {}
844 };
845 
846 template <MachineRepresentation rep>
847 struct UnalignedStoreOperator : public Operator1<UnalignedStoreRepresentation> {
UnalignedStoreOperatorv8::internal::compiler::UnalignedStoreOperator848   UnalignedStoreOperator()
849       : Operator1(IrOpcode::kUnalignedStore,
850                   Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow,
851                   "UnalignedStore", 3, 1, 1, 0, 1, 0, rep) {}
852 };
853 
854 template <MachineRepresentation rep>
855 struct ProtectedStoreOperator : public Operator1<StoreRepresentation> {
ProtectedStoreOperatorv8::internal::compiler::ProtectedStoreOperator856   ProtectedStoreOperator()
857       : Operator1(IrOpcode::kProtectedStore,
858                   Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow,
859                   "Store", 3, 1, 1, 0, 1, 0,
860                   StoreRepresentation(rep, kNoWriteBarrier)) {}
861 };
862 
863 template <MemoryAccessKind kind, MachineRepresentation rep, uint8_t laneidx>
864 struct StoreLaneOperator : public Operator1<StoreLaneParameters> {
StoreLaneOperatorv8::internal::compiler::StoreLaneOperator865   StoreLaneOperator()
866       : Operator1(IrOpcode::kStoreLane,
867                   Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow,
868                   "StoreLane", 3, 1, 1, 0, 1, 0,
869                   StoreLaneParameters{kind, rep, laneidx}) {}
870 };
871 
872 template <MachineRepresentation rep, MachineSemantic sem>
873 struct Word32AtomicLoadOperator : public Operator1<LoadRepresentation> {
Word32AtomicLoadOperatorv8::internal::compiler::Word32AtomicLoadOperator874   Word32AtomicLoadOperator()
875       : Operator1(IrOpcode::kWord32AtomicLoad, Operator::kEliminatable,
876                   "Word32AtomicLoad", 2, 1, 1, 1, 1, 0, MachineType(rep, sem)) {
877   }
878 };
879 
880 template <MachineRepresentation rep, MachineSemantic sem>
881 struct Word64AtomicLoadOperator : public Operator1<LoadRepresentation> {
Word64AtomicLoadOperatorv8::internal::compiler::Word64AtomicLoadOperator882   Word64AtomicLoadOperator()
883       : Operator1(IrOpcode::kWord64AtomicLoad, Operator::kEliminatable,
884                   "Word64AtomicLoad", 2, 1, 1, 1, 1, 0, MachineType(rep, sem)) {
885   }
886 };
887 
888 template <MachineRepresentation rep>
889 struct Word32AtomicStoreOperator : public Operator1<MachineRepresentation> {
Word32AtomicStoreOperatorv8::internal::compiler::Word32AtomicStoreOperator890   Word32AtomicStoreOperator()
891       : Operator1(IrOpcode::kWord32AtomicStore,
892                   Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow,
893                   "Word32AtomicStore", 3, 1, 1, 0, 1, 0, rep) {}
894 };
895 
896 template <MachineRepresentation rep>
897 struct Word64AtomicStoreOperator : public Operator1<MachineRepresentation> {
Word64AtomicStoreOperatorv8::internal::compiler::Word64AtomicStoreOperator898   Word64AtomicStoreOperator()
899       : Operator1(IrOpcode::kWord64AtomicStore,
900                   Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow,
901                   "Word64AtomicStore", 3, 1, 1, 0, 1, 0, rep) {}
902 };
903 
904 #define ATOMIC_OP(op)                                                         \
905   template <MachineRepresentation rep, MachineSemantic sem>                   \
906   struct op##Operator : public Operator1<MachineType> {                       \
907     op##Operator()                                                            \
908         : Operator1(IrOpcode::k##op, Operator::kNoDeopt | Operator::kNoThrow, \
909                     #op, 3, 1, 1, 1, 1, 0, MachineType(rep, sem)) {}          \
910   };
911 ATOMIC_OP(Word32AtomicAdd)
912 ATOMIC_OP(Word32AtomicSub)
913 ATOMIC_OP(Word32AtomicAnd)
914 ATOMIC_OP(Word32AtomicOr)
915 ATOMIC_OP(Word32AtomicXor)
916 ATOMIC_OP(Word32AtomicExchange)
917 ATOMIC_OP(Word64AtomicAdd)
918 ATOMIC_OP(Word64AtomicSub)
919 ATOMIC_OP(Word64AtomicAnd)
920 ATOMIC_OP(Word64AtomicOr)
921 ATOMIC_OP(Word64AtomicXor)
922 ATOMIC_OP(Word64AtomicExchange)
923 #undef ATOMIC_OP
924 
925 template <MachineRepresentation rep, MachineSemantic sem>
926 struct Word32AtomicCompareExchangeOperator : public Operator1<MachineType> {
Word32AtomicCompareExchangeOperatorv8::internal::compiler::Word32AtomicCompareExchangeOperator927   Word32AtomicCompareExchangeOperator()
928       : Operator1(IrOpcode::kWord32AtomicCompareExchange,
929                   Operator::kNoDeopt | Operator::kNoThrow,
930                   "Word32AtomicCompareExchange", 4, 1, 1, 1, 1, 0,
931                   MachineType(rep, sem)) {}
932 };
933 
934 template <MachineRepresentation rep, MachineSemantic sem>
935 struct Word64AtomicCompareExchangeOperator : public Operator1<MachineType> {
Word64AtomicCompareExchangeOperatorv8::internal::compiler::Word64AtomicCompareExchangeOperator936   Word64AtomicCompareExchangeOperator()
937       : Operator1(IrOpcode::kWord64AtomicCompareExchange,
938                   Operator::kNoDeopt | Operator::kNoThrow,
939                   "Word64AtomicCompareExchange", 4, 1, 1, 1, 1, 0,
940                   MachineType(rep, sem)) {}
941 };
942 
943 struct Word32AtomicPairLoadOperator : public Operator {
Word32AtomicPairLoadOperatorv8::internal::compiler::Word32AtomicPairLoadOperator944   Word32AtomicPairLoadOperator()
945       : Operator(IrOpcode::kWord32AtomicPairLoad,
946                  Operator::kNoDeopt | Operator::kNoThrow,
947                  "Word32AtomicPairLoad", 2, 1, 1, 2, 1, 0) {}
948 };
949 
950 struct Word32AtomicPairStoreOperator : public Operator {
Word32AtomicPairStoreOperatorv8::internal::compiler::Word32AtomicPairStoreOperator951   Word32AtomicPairStoreOperator()
952       : Operator(IrOpcode::kWord32AtomicPairStore,
953                  Operator::kNoDeopt | Operator::kNoThrow,
954                  "Word32AtomicPairStore", 4, 1, 1, 0, 1, 0) {}
955 };
956 
957 #define ATOMIC_PAIR_OP(op)                                      \
958   struct Word32AtomicPair##op##Operator : public Operator {     \
959     Word32AtomicPair##op##Operator()                            \
960         : Operator(IrOpcode::kWord32AtomicPair##op,             \
961                    Operator::kNoDeopt | Operator::kNoThrow,     \
962                    "Word32AtomicPair" #op, 4, 1, 1, 2, 1, 0) {} \
963   };
964 ATOMIC_PAIR_OP(Add)
965 ATOMIC_PAIR_OP(Sub)
966 ATOMIC_PAIR_OP(And)
967 ATOMIC_PAIR_OP(Or)
968 ATOMIC_PAIR_OP(Xor)
969 ATOMIC_PAIR_OP(Exchange)
970 #undef ATOMIC_PAIR_OP
971 
972 struct Word32AtomicPairCompareExchangeOperator : public Operator {
Word32AtomicPairCompareExchangeOperatorv8::internal::compiler::Word32AtomicPairCompareExchangeOperator973   Word32AtomicPairCompareExchangeOperator()
974       : Operator(IrOpcode::kWord32AtomicPairCompareExchange,
975                  Operator::kNoDeopt | Operator::kNoThrow,
976                  "Word32AtomicPairCompareExchange", 6, 1, 1, 2, 1, 0) {}
977 };
978 
979 struct MemoryBarrierOperator : public Operator {
MemoryBarrierOperatorv8::internal::compiler::MemoryBarrierOperator980   MemoryBarrierOperator()
981       : Operator(IrOpcode::kMemoryBarrier,
982                  Operator::kNoDeopt | Operator::kNoThrow, "MemoryBarrier", 0, 1,
983                  1, 0, 1, 0) {}
984 };
985 
986 // The {BitcastWordToTagged} operator must not be marked as pure (especially
987 // not idempotent), because otherwise the splitting logic in the Scheduler
988 // might decide to split these operators, thus potentially creating live
989 // ranges of allocation top across calls or other things that might allocate.
990 // See https://bugs.chromium.org/p/v8/issues/detail?id=6059 for more details.
991 struct BitcastWordToTaggedOperator : public Operator {
BitcastWordToTaggedOperatorv8::internal::compiler::BitcastWordToTaggedOperator992   BitcastWordToTaggedOperator()
993       : Operator(IrOpcode::kBitcastWordToTagged,
994                  Operator::kEliminatable | Operator::kNoWrite,
995                  "BitcastWordToTagged", 1, 1, 1, 1, 1, 0) {}
996 };
997 
998 struct BitcastTaggedToWordOperator : public Operator {
BitcastTaggedToWordOperatorv8::internal::compiler::BitcastTaggedToWordOperator999   BitcastTaggedToWordOperator()
1000       : Operator(IrOpcode::kBitcastTaggedToWord,
1001                  Operator::kEliminatable | Operator::kNoWrite,
1002                  "BitcastTaggedToWord", 1, 1, 1, 1, 1, 0) {}
1003 };
1004 
1005 struct BitcastMaybeObjectToWordOperator : public Operator {
BitcastMaybeObjectToWordOperatorv8::internal::compiler::BitcastMaybeObjectToWordOperator1006   BitcastMaybeObjectToWordOperator()
1007       : Operator(IrOpcode::kBitcastTaggedToWord,
1008                  Operator::kEliminatable | Operator::kNoWrite,
1009                  "BitcastMaybeObjectToWord", 1, 1, 1, 1, 1, 0) {}
1010 };
1011 
1012 struct TaggedPoisonOnSpeculationOperator : public Operator {
TaggedPoisonOnSpeculationOperatorv8::internal::compiler::TaggedPoisonOnSpeculationOperator1013   TaggedPoisonOnSpeculationOperator()
1014       : Operator(IrOpcode::kTaggedPoisonOnSpeculation,
1015                  Operator::kEliminatable | Operator::kNoWrite,
1016                  "TaggedPoisonOnSpeculation", 1, 1, 1, 1, 1, 0) {}
1017 };
1018 
1019 struct Word32PoisonOnSpeculationOperator : public Operator {
Word32PoisonOnSpeculationOperatorv8::internal::compiler::Word32PoisonOnSpeculationOperator1020   Word32PoisonOnSpeculationOperator()
1021       : Operator(IrOpcode::kWord32PoisonOnSpeculation,
1022                  Operator::kEliminatable | Operator::kNoWrite,
1023                  "Word32PoisonOnSpeculation", 1, 1, 1, 1, 1, 0) {}
1024 };
1025 
1026 struct Word64PoisonOnSpeculationOperator : public Operator {
Word64PoisonOnSpeculationOperatorv8::internal::compiler::Word64PoisonOnSpeculationOperator1027   Word64PoisonOnSpeculationOperator()
1028       : Operator(IrOpcode::kWord64PoisonOnSpeculation,
1029                  Operator::kEliminatable | Operator::kNoWrite,
1030                  "Word64PoisonOnSpeculation", 1, 1, 1, 1, 1, 0) {}
1031 };
1032 
1033 struct AbortCSAAssertOperator : public Operator {
AbortCSAAssertOperatorv8::internal::compiler::AbortCSAAssertOperator1034   AbortCSAAssertOperator()
1035       : Operator(IrOpcode::kAbortCSAAssert, Operator::kNoThrow,
1036                  "AbortCSAAssert", 1, 1, 1, 0, 1, 0) {}
1037 };
1038 
1039 struct DebugBreakOperator : public Operator {
DebugBreakOperatorv8::internal::compiler::DebugBreakOperator1040   DebugBreakOperator()
1041       : Operator(IrOpcode::kDebugBreak, Operator::kNoThrow, "DebugBreak", 0, 1,
1042                  1, 0, 1, 0) {}
1043 };
1044 
1045 struct UnsafePointerAddOperator : public Operator {
UnsafePointerAddOperatorv8::internal::compiler::UnsafePointerAddOperator1046   UnsafePointerAddOperator()
1047       : Operator(IrOpcode::kUnsafePointerAdd, Operator::kKontrol,
1048                  "UnsafePointerAdd", 2, 1, 1, 1, 1, 0) {}
1049 };
1050 
1051 template <StackCheckKind kind>
1052 struct StackPointerGreaterThanOperator : public Operator1<StackCheckKind> {
StackPointerGreaterThanOperatorv8::internal::compiler::StackPointerGreaterThanOperator1053   StackPointerGreaterThanOperator()
1054       : Operator1(IrOpcode::kStackPointerGreaterThan, Operator::kEliminatable,
1055                   "StackPointerGreaterThan", 1, 1, 0, 1, 1, 0, kind) {}
1056 };
1057 
1058 struct CommentOperator : public Operator1<const char*> {
CommentOperatorv8::internal::compiler::CommentOperator1059   explicit CommentOperator(const char* msg)
1060       : Operator1(IrOpcode::kComment, Operator::kNoThrow | Operator::kNoWrite,
1061                   "Comment", 0, 1, 1, 0, 1, 0, msg) {}
1062 };
1063 
MachineOperatorBuilder(Zone * zone,MachineRepresentation word,Flags flags,AlignmentRequirements alignmentRequirements)1064 MachineOperatorBuilder::MachineOperatorBuilder(
1065     Zone* zone, MachineRepresentation word, Flags flags,
1066     AlignmentRequirements alignmentRequirements)
1067     : zone_(zone),
1068       word_(word),
1069       flags_(flags),
1070       alignment_requirements_(alignmentRequirements) {
1071   DCHECK(word == MachineRepresentation::kWord32 ||
1072          word == MachineRepresentation::kWord64);
1073 }
1074 
UnalignedLoad(LoadRepresentation rep)1075 const Operator* MachineOperatorBuilder::UnalignedLoad(LoadRepresentation rep) {
1076 #define LOAD(Type)                                                  \
1077   if (rep == MachineType::Type()) {                                 \
1078     return GetCachedOperator<                                       \
1079         UnalignedLoadOperator<MachineType::Type().representation(), \
1080                               MachineType::Type().semantic()>>();   \
1081   }
1082   MACHINE_TYPE_LIST(LOAD)
1083 #undef LOAD
1084   UNREACHABLE();
1085 }
1086 
UnalignedStore(UnalignedStoreRepresentation rep)1087 const Operator* MachineOperatorBuilder::UnalignedStore(
1088     UnalignedStoreRepresentation rep) {
1089   switch (rep) {
1090 #define STORE(kRep)                 \
1091   case MachineRepresentation::kRep: \
1092     return GetCachedOperator<       \
1093         UnalignedStoreOperator<MachineRepresentation::kRep>>();
1094     MACHINE_REPRESENTATION_LIST(STORE)
1095 #undef STORE
1096     case MachineRepresentation::kBit:
1097     case MachineRepresentation::kNone:
1098       break;
1099   }
1100   UNREACHABLE();
1101 }
1102 
1103 template <TruncateKind kind>
1104 struct TruncateFloat32ToUint32Operator : Operator1<TruncateKind> {
TruncateFloat32ToUint32Operatorv8::internal::compiler::TruncateFloat32ToUint32Operator1105   TruncateFloat32ToUint32Operator()
1106       : Operator1(IrOpcode::kTruncateFloat32ToUint32, Operator::kPure,
1107                   "TruncateFloat32ToUint32", 1, 0, 0, 1, 0, 0, kind) {}
1108 };
1109 
TruncateFloat32ToUint32(TruncateKind kind)1110 const Operator* MachineOperatorBuilder::TruncateFloat32ToUint32(
1111     TruncateKind kind) {
1112   switch (kind) {
1113     case TruncateKind::kArchitectureDefault:
1114       return GetCachedOperator<TruncateFloat32ToUint32Operator<
1115           TruncateKind::kArchitectureDefault>>();
1116     case TruncateKind::kSetOverflowToMin:
1117       return GetCachedOperator<
1118           TruncateFloat32ToUint32Operator<TruncateKind::kSetOverflowToMin>>();
1119   }
1120 }
1121 
1122 template <TruncateKind kind>
1123 struct TruncateFloat32ToInt32Operator : Operator1<TruncateKind> {
TruncateFloat32ToInt32Operatorv8::internal::compiler::TruncateFloat32ToInt32Operator1124   TruncateFloat32ToInt32Operator()
1125       : Operator1(IrOpcode::kTruncateFloat32ToInt32, Operator::kPure,
1126                   "TruncateFloat32ToInt32", 1, 0, 0, 1, 0, 0, kind) {}
1127 };
1128 
TruncateFloat32ToInt32(TruncateKind kind)1129 const Operator* MachineOperatorBuilder::TruncateFloat32ToInt32(
1130     TruncateKind kind) {
1131   switch (kind) {
1132     case TruncateKind::kArchitectureDefault:
1133       return GetCachedOperator<
1134           TruncateFloat32ToInt32Operator<TruncateKind::kArchitectureDefault>>();
1135     case TruncateKind::kSetOverflowToMin:
1136       return GetCachedOperator<
1137           TruncateFloat32ToInt32Operator<TruncateKind::kSetOverflowToMin>>();
1138   }
1139 }
1140 
hash_value(TruncateKind kind)1141 size_t hash_value(TruncateKind kind) { return static_cast<size_t>(kind); }
1142 
operator <<(std::ostream & os,TruncateKind kind)1143 std::ostream& operator<<(std::ostream& os, TruncateKind kind) {
1144   switch (kind) {
1145     case TruncateKind::kArchitectureDefault:
1146       return os << "kArchitectureDefault";
1147     case TruncateKind::kSetOverflowToMin:
1148       return os << "kSetOverflowToMin";
1149   }
1150 }
1151 
1152 #define PURE(Name, properties, value_input_count, control_input_count,     \
1153              output_count)                                                 \
1154   const Operator* MachineOperatorBuilder::Name() {                         \
1155     return GetCachedOperator<                                              \
1156         CachedPureOperator<IrOpcode::k##Name, value_input_count,           \
1157                            control_input_count, output_count>>(properties, \
1158                                                                #Name);     \
1159   }
MACHINE_PURE_OP_LIST(PURE) const1160 MACHINE_PURE_OP_LIST(PURE)
1161 #undef PURE
1162 
1163 const Operator* MachineOperatorBuilder::Load(LoadRepresentation rep) {
1164 #define LOAD(Type)                                         \
1165   if (rep == MachineType::Type()) {                        \
1166     return GetCachedOperator<                              \
1167         LoadOperator<MachineType::Type().representation(), \
1168                      MachineType::Type().semantic()>>();   \
1169   }
1170   MACHINE_TYPE_LIST(LOAD)
1171 #undef LOAD
1172   UNREACHABLE();
1173 }
1174 
PoisonedLoad(LoadRepresentation rep)1175 const Operator* MachineOperatorBuilder::PoisonedLoad(LoadRepresentation rep) {
1176 #define LOAD(Type)                                                 \
1177   if (rep == MachineType::Type()) {                                \
1178     return GetCachedOperator<                                      \
1179         PoisonedLoadOperator<MachineType::Type().representation(), \
1180                              MachineType::Type().semantic()>>();   \
1181   }
1182   MACHINE_TYPE_LIST(LOAD)
1183 #undef LOAD
1184   UNREACHABLE();
1185 }
1186 
ProtectedLoad(LoadRepresentation rep)1187 const Operator* MachineOperatorBuilder::ProtectedLoad(LoadRepresentation rep) {
1188 #define LOAD(Type)                                                  \
1189   if (rep == MachineType::Type()) {                                 \
1190     return GetCachedOperator<                                       \
1191         ProtectedLoadOperator<MachineType::Type().representation(), \
1192                               MachineType::Type().semantic()>>();   \
1193   }
1194   MACHINE_TYPE_LIST(LOAD)
1195 #undef LOAD
1196   UNREACHABLE();
1197 }
1198 
LoadTransform(MemoryAccessKind kind,LoadTransformation transform)1199 const Operator* MachineOperatorBuilder::LoadTransform(
1200     MemoryAccessKind kind, LoadTransformation transform) {
1201 #define LOAD_TRANSFORM_KIND(TYPE, KIND)                             \
1202   if (kind == MemoryAccessKind::k##KIND &&                          \
1203       transform == LoadTransformation::k##TYPE) {                   \
1204     return GetCachedOperator<LoadTransformOperator<                 \
1205         MemoryAccessKind::k##KIND, LoadTransformation::k##TYPE>>(); \
1206   }
1207 #define LOAD_TRANSFORM(TYPE)           \
1208   LOAD_TRANSFORM_KIND(TYPE, Normal)    \
1209   LOAD_TRANSFORM_KIND(TYPE, Unaligned) \
1210   LOAD_TRANSFORM_KIND(TYPE, Protected)
1211 
1212   LOAD_TRANSFORM_LIST(LOAD_TRANSFORM)
1213 #undef LOAD_TRANSFORM
1214 #undef LOAD_TRANSFORM_KIND
1215   UNREACHABLE();
1216 }
1217 
LoadLane(MemoryAccessKind kind,LoadRepresentation rep,uint8_t laneidx)1218 const Operator* MachineOperatorBuilder::LoadLane(MemoryAccessKind kind,
1219                                                  LoadRepresentation rep,
1220                                                  uint8_t laneidx) {
1221 #define LOAD_LANE_KIND(TYPE, KIND, LANEIDX)                              \
1222   if (kind == MemoryAccessKind::k##KIND && rep == MachineType::TYPE() && \
1223       laneidx == LANEIDX) {                                              \
1224     return GetCachedOperator<LoadLaneOperator<                           \
1225         MemoryAccessKind::k##KIND, MachineType::TYPE().representation(), \
1226         MachineType::TYPE().semantic(), LANEIDX>>();                     \
1227   }
1228 
1229 #define LOAD_LANE_T(T, LANE)         \
1230   LOAD_LANE_KIND(T, Normal, LANE)    \
1231   LOAD_LANE_KIND(T, Unaligned, LANE) \
1232   LOAD_LANE_KIND(T, Protected, LANE)
1233 
1234 #define LOAD_LANE_INT8(LANE) LOAD_LANE_T(Int8, LANE)
1235 #define LOAD_LANE_INT16(LANE) LOAD_LANE_T(Int16, LANE)
1236 #define LOAD_LANE_INT32(LANE) LOAD_LANE_T(Int32, LANE)
1237 #define LOAD_LANE_INT64(LANE) LOAD_LANE_T(Int64, LANE)
1238 
1239   // Semicolons unnecessary, but helps formatting.
1240   SIMD_I8x16_LANES(LOAD_LANE_INT8);
1241   SIMD_I16x8_LANES(LOAD_LANE_INT16);
1242   SIMD_I32x4_LANES(LOAD_LANE_INT32);
1243   SIMD_I64x2_LANES(LOAD_LANE_INT64);
1244 #undef LOAD_LANE_INT8
1245 #undef LOAD_LANE_INT16
1246 #undef LOAD_LANE_INT32
1247 #undef LOAD_LANE_INT64
1248 #undef LOAD_LANE_KIND
1249   UNREACHABLE();
1250 }
1251 
StoreLane(MemoryAccessKind kind,MachineRepresentation rep,uint8_t laneidx)1252 const Operator* MachineOperatorBuilder::StoreLane(MemoryAccessKind kind,
1253                                                   MachineRepresentation rep,
1254                                                   uint8_t laneidx) {
1255 #define STORE_LANE_KIND(REP, KIND, LANEIDX)                                 \
1256   if (kind == MemoryAccessKind::k##KIND &&                                  \
1257       rep == MachineRepresentation::REP && laneidx == LANEIDX) {            \
1258     return GetCachedOperator<StoreLaneOperator<                             \
1259         MemoryAccessKind::k##KIND, MachineRepresentation::REP, LANEIDX>>(); \
1260   }
1261 
1262 #define STORE_LANE_T(T, LANE)         \
1263   STORE_LANE_KIND(T, Normal, LANE)    \
1264   STORE_LANE_KIND(T, Unaligned, LANE) \
1265   STORE_LANE_KIND(T, Protected, LANE)
1266 
1267 #define STORE_LANE_WORD8(LANE) STORE_LANE_T(kWord8, LANE)
1268 #define STORE_LANE_WORD16(LANE) STORE_LANE_T(kWord16, LANE)
1269 #define STORE_LANE_WORD32(LANE) STORE_LANE_T(kWord32, LANE)
1270 #define STORE_LANE_WORD64(LANE) STORE_LANE_T(kWord64, LANE)
1271 
1272   // Semicolons unnecessary, but helps formatting.
1273   SIMD_I8x16_LANES(STORE_LANE_WORD8);
1274   SIMD_I16x8_LANES(STORE_LANE_WORD16);
1275   SIMD_I32x4_LANES(STORE_LANE_WORD32);
1276   SIMD_I64x2_LANES(STORE_LANE_WORD64);
1277 #undef STORE_LANE_WORD8
1278 #undef STORE_LANE_WORD16
1279 #undef STORE_LANE_WORD32
1280 #undef STORE_LANE_WORD64
1281 #undef STORE_LANE_KIND
1282   UNREACHABLE();
1283 }
1284 
StackSlot(int size,int alignment)1285 const Operator* MachineOperatorBuilder::StackSlot(int size, int alignment) {
1286   DCHECK_LE(0, size);
1287   DCHECK(alignment == 0 || alignment == 4 || alignment == 8 || alignment == 16);
1288 #define CASE_CACHED_SIZE(Size, Alignment)                                 \
1289   if (size == Size && alignment == Alignment) {                           \
1290     return GetCachedOperator<CachedStackSlotOperator<Size, Alignment>>(); \
1291   }
1292 
1293   STACK_SLOT_CACHED_SIZES_ALIGNMENTS_LIST(CASE_CACHED_SIZE)
1294 
1295 #undef CASE_CACHED_SIZE
1296   return zone_->New<StackSlotOperator>(size, alignment);
1297 }
1298 
StackSlot(MachineRepresentation rep,int alignment)1299 const Operator* MachineOperatorBuilder::StackSlot(MachineRepresentation rep,
1300                                                   int alignment) {
1301   return StackSlot(1 << ElementSizeLog2Of(rep), alignment);
1302 }
1303 
Store(StoreRepresentation store_rep)1304 const Operator* MachineOperatorBuilder::Store(StoreRepresentation store_rep) {
1305   switch (store_rep.representation()) {
1306 #define STORE(kRep)                                                           \
1307   case MachineRepresentation::kRep:                                           \
1308     switch (store_rep.write_barrier_kind()) {                                 \
1309       case kNoWriteBarrier:                                                   \
1310         return GetCachedOperator<                                             \
1311             StoreOperator<MachineRepresentation::kRep, kNoWriteBarrier>>();   \
1312       case kAssertNoWriteBarrier:                                             \
1313         return GetCachedOperator<StoreOperator<MachineRepresentation::kRep,   \
1314                                                kAssertNoWriteBarrier>>();     \
1315       case kMapWriteBarrier:                                                  \
1316         return GetCachedOperator<                                             \
1317             StoreOperator<MachineRepresentation::kRep, kMapWriteBarrier>>();  \
1318       case kPointerWriteBarrier:                                              \
1319         return GetCachedOperator<StoreOperator<MachineRepresentation::kRep,   \
1320                                                kPointerWriteBarrier>>();      \
1321       case kEphemeronKeyWriteBarrier:                                         \
1322         return GetCachedOperator<StoreOperator<MachineRepresentation::kRep,   \
1323                                                kEphemeronKeyWriteBarrier>>(); \
1324       case kFullWriteBarrier:                                                 \
1325         return GetCachedOperator<                                             \
1326             StoreOperator<MachineRepresentation::kRep, kFullWriteBarrier>>(); \
1327     }                                                                         \
1328     break;
1329     MACHINE_REPRESENTATION_LIST(STORE)
1330 #undef STORE
1331     case MachineRepresentation::kBit:
1332     case MachineRepresentation::kNone:
1333       break;
1334   }
1335   UNREACHABLE();
1336 }
1337 
ProtectedStore(MachineRepresentation rep)1338 const Operator* MachineOperatorBuilder::ProtectedStore(
1339     MachineRepresentation rep) {
1340   switch (rep) {
1341 #define STORE(kRep)                                             \
1342   case MachineRepresentation::kRep:                             \
1343     return GetCachedOperator<                                   \
1344         ProtectedStoreOperator<MachineRepresentation::kRep>>(); \
1345     break;
1346     MACHINE_REPRESENTATION_LIST(STORE)
1347 #undef STORE
1348     case MachineRepresentation::kBit:
1349     case MachineRepresentation::kNone:
1350       break;
1351   }
1352   UNREACHABLE();
1353 }
1354 
UnsafePointerAdd()1355 const Operator* MachineOperatorBuilder::UnsafePointerAdd() {
1356   return GetCachedOperator<UnsafePointerAddOperator>();
1357 }
1358 
StackPointerGreaterThan(StackCheckKind kind)1359 const Operator* MachineOperatorBuilder::StackPointerGreaterThan(
1360     StackCheckKind kind) {
1361   switch (kind) {
1362     case StackCheckKind::kJSFunctionEntry:
1363       return GetCachedOperator<
1364           StackPointerGreaterThanOperator<StackCheckKind::kJSFunctionEntry>>();
1365     case StackCheckKind::kJSIterationBody:
1366       return GetCachedOperator<
1367           StackPointerGreaterThanOperator<StackCheckKind::kJSIterationBody>>();
1368     case StackCheckKind::kCodeStubAssembler:
1369       return GetCachedOperator<StackPointerGreaterThanOperator<
1370           StackCheckKind::kCodeStubAssembler>>();
1371     case StackCheckKind::kWasm:
1372       return GetCachedOperator<
1373           StackPointerGreaterThanOperator<StackCheckKind::kWasm>>();
1374   }
1375   UNREACHABLE();
1376 }
1377 
BitcastWordToTagged()1378 const Operator* MachineOperatorBuilder::BitcastWordToTagged() {
1379   return GetCachedOperator<BitcastWordToTaggedOperator>();
1380 }
1381 
BitcastTaggedToWord()1382 const Operator* MachineOperatorBuilder::BitcastTaggedToWord() {
1383   return GetCachedOperator<BitcastTaggedToWordOperator>();
1384 }
1385 
BitcastMaybeObjectToWord()1386 const Operator* MachineOperatorBuilder::BitcastMaybeObjectToWord() {
1387   return GetCachedOperator<BitcastMaybeObjectToWordOperator>();
1388 }
1389 
AbortCSAAssert()1390 const Operator* MachineOperatorBuilder::AbortCSAAssert() {
1391   return GetCachedOperator<AbortCSAAssertOperator>();
1392 }
1393 
DebugBreak()1394 const Operator* MachineOperatorBuilder::DebugBreak() {
1395   return GetCachedOperator<DebugBreakOperator>();
1396 }
1397 
Comment(const char * msg)1398 const Operator* MachineOperatorBuilder::Comment(const char* msg) {
1399   return zone_->New<CommentOperator>(msg);
1400 }
1401 
MemBarrier()1402 const Operator* MachineOperatorBuilder::MemBarrier() {
1403   return GetCachedOperator<MemoryBarrierOperator>();
1404 }
1405 
Word32AtomicLoad(LoadRepresentation rep)1406 const Operator* MachineOperatorBuilder::Word32AtomicLoad(
1407     LoadRepresentation rep) {
1408 #define LOAD(Type)                                                     \
1409   if (rep == MachineType::Type()) {                                    \
1410     return GetCachedOperator<                                          \
1411         Word32AtomicLoadOperator<MachineType::Type().representation(), \
1412                                  MachineType::Type().semantic()>>();   \
1413   }
1414   ATOMIC_TYPE_LIST(LOAD)
1415 #undef LOAD
1416   UNREACHABLE();
1417 }
1418 
Word32AtomicStore(MachineRepresentation rep)1419 const Operator* MachineOperatorBuilder::Word32AtomicStore(
1420     MachineRepresentation rep) {
1421 #define STORE(kRep)                                                \
1422   if (rep == MachineRepresentation::kRep) {                        \
1423     return GetCachedOperator<                                      \
1424         Word32AtomicStoreOperator<MachineRepresentation::kRep>>(); \
1425   }
1426   ATOMIC_REPRESENTATION_LIST(STORE)
1427 #undef STORE
1428   UNREACHABLE();
1429 }
1430 
Word32AtomicExchange(MachineType type)1431 const Operator* MachineOperatorBuilder::Word32AtomicExchange(MachineType type) {
1432 #define EXCHANGE(Type)                                                     \
1433   if (type == MachineType::Type()) {                                       \
1434     return GetCachedOperator<                                              \
1435         Word32AtomicExchangeOperator<MachineType::Type().representation(), \
1436                                      MachineType::Type().semantic()>>();   \
1437   }
1438   ATOMIC_TYPE_LIST(EXCHANGE)
1439 #undef EXCHANGE
1440   UNREACHABLE();
1441 }
1442 
Word32AtomicCompareExchange(MachineType type)1443 const Operator* MachineOperatorBuilder::Word32AtomicCompareExchange(
1444     MachineType type) {
1445 #define COMPARE_EXCHANGE(Type)                                    \
1446   if (type == MachineType::Type()) {                              \
1447     return GetCachedOperator<Word32AtomicCompareExchangeOperator< \
1448         MachineType::Type().representation(),                     \
1449         MachineType::Type().semantic()>>();                       \
1450   }
1451   ATOMIC_TYPE_LIST(COMPARE_EXCHANGE)
1452 #undef COMPARE_EXCHANGE
1453   UNREACHABLE();
1454 }
1455 
Word32AtomicAdd(MachineType type)1456 const Operator* MachineOperatorBuilder::Word32AtomicAdd(MachineType type) {
1457 #define ADD(Type)                                                     \
1458   if (type == MachineType::Type()) {                                  \
1459     return GetCachedOperator<                                         \
1460         Word32AtomicAddOperator<MachineType::Type().representation(), \
1461                                 MachineType::Type().semantic()>>();   \
1462   }
1463   ATOMIC_TYPE_LIST(ADD)
1464 #undef ADD
1465   UNREACHABLE();
1466 }
1467 
Word32AtomicSub(MachineType type)1468 const Operator* MachineOperatorBuilder::Word32AtomicSub(MachineType type) {
1469 #define SUB(Type)                                                     \
1470   if (type == MachineType::Type()) {                                  \
1471     return GetCachedOperator<                                         \
1472         Word32AtomicSubOperator<MachineType::Type().representation(), \
1473                                 MachineType::Type().semantic()>>();   \
1474   }
1475   ATOMIC_TYPE_LIST(SUB)
1476 #undef SUB
1477   UNREACHABLE();
1478 }
1479 
Word32AtomicAnd(MachineType type)1480 const Operator* MachineOperatorBuilder::Word32AtomicAnd(MachineType type) {
1481 #define AND(Type)                                                     \
1482   if (type == MachineType::Type()) {                                  \
1483     return GetCachedOperator<                                         \
1484         Word32AtomicAndOperator<MachineType::Type().representation(), \
1485                                 MachineType::Type().semantic()>>();   \
1486   }
1487   ATOMIC_TYPE_LIST(AND)
1488 #undef AND
1489   UNREACHABLE();
1490 }
1491 
Word32AtomicOr(MachineType type)1492 const Operator* MachineOperatorBuilder::Word32AtomicOr(MachineType type) {
1493 #define OR(Type)                                                     \
1494   if (type == MachineType::Type()) {                                 \
1495     return GetCachedOperator<                                        \
1496         Word32AtomicOrOperator<MachineType::Type().representation(), \
1497                                MachineType::Type().semantic()>>();   \
1498   }
1499   ATOMIC_TYPE_LIST(OR)
1500 #undef OR
1501   UNREACHABLE();
1502 }
1503 
Word32AtomicXor(MachineType type)1504 const Operator* MachineOperatorBuilder::Word32AtomicXor(MachineType type) {
1505 #define XOR(Type)                                                     \
1506   if (type == MachineType::Type()) {                                  \
1507     return GetCachedOperator<                                         \
1508         Word32AtomicXorOperator<MachineType::Type().representation(), \
1509                                 MachineType::Type().semantic()>>();   \
1510   }
1511   ATOMIC_TYPE_LIST(XOR)
1512 #undef XOR
1513   UNREACHABLE();
1514 }
1515 
Word64AtomicLoad(LoadRepresentation rep)1516 const Operator* MachineOperatorBuilder::Word64AtomicLoad(
1517     LoadRepresentation rep) {
1518 #define LOAD(Type)                                                     \
1519   if (rep == MachineType::Type()) {                                    \
1520     return GetCachedOperator<                                          \
1521         Word64AtomicLoadOperator<MachineType::Type().representation(), \
1522                                  MachineType::Type().semantic()>>();   \
1523   }
1524   ATOMIC_U64_TYPE_LIST(LOAD)
1525 #undef LOAD
1526   UNREACHABLE();
1527 }
1528 
Word64AtomicStore(MachineRepresentation rep)1529 const Operator* MachineOperatorBuilder::Word64AtomicStore(
1530     MachineRepresentation rep) {
1531 #define STORE(kRep)                                                \
1532   if (rep == MachineRepresentation::kRep) {                        \
1533     return GetCachedOperator<                                      \
1534         Word64AtomicStoreOperator<MachineRepresentation::kRep>>(); \
1535   }
1536   ATOMIC64_REPRESENTATION_LIST(STORE)
1537 #undef STORE
1538   UNREACHABLE();
1539 }
1540 
Word64AtomicAdd(MachineType type)1541 const Operator* MachineOperatorBuilder::Word64AtomicAdd(MachineType type) {
1542 #define ADD(Type)                                                     \
1543   if (type == MachineType::Type()) {                                  \
1544     return GetCachedOperator<                                         \
1545         Word64AtomicAddOperator<MachineType::Type().representation(), \
1546                                 MachineType::Type().semantic()>>();   \
1547   }
1548   ATOMIC_U64_TYPE_LIST(ADD)
1549 #undef ADD
1550   UNREACHABLE();
1551 }
1552 
Word64AtomicSub(MachineType type)1553 const Operator* MachineOperatorBuilder::Word64AtomicSub(MachineType type) {
1554 #define SUB(Type)                                                     \
1555   if (type == MachineType::Type()) {                                  \
1556     return GetCachedOperator<                                         \
1557         Word64AtomicSubOperator<MachineType::Type().representation(), \
1558                                 MachineType::Type().semantic()>>();   \
1559   }
1560   ATOMIC_U64_TYPE_LIST(SUB)
1561 #undef SUB
1562   UNREACHABLE();
1563 }
1564 
Word64AtomicAnd(MachineType type)1565 const Operator* MachineOperatorBuilder::Word64AtomicAnd(MachineType type) {
1566 #define AND(Type)                                                     \
1567   if (type == MachineType::Type()) {                                  \
1568     return GetCachedOperator<                                         \
1569         Word64AtomicAndOperator<MachineType::Type().representation(), \
1570                                 MachineType::Type().semantic()>>();   \
1571   }
1572   ATOMIC_U64_TYPE_LIST(AND)
1573 #undef AND
1574   UNREACHABLE();
1575 }
1576 
Word64AtomicOr(MachineType type)1577 const Operator* MachineOperatorBuilder::Word64AtomicOr(MachineType type) {
1578 #define OR(Type)                                                     \
1579   if (type == MachineType::Type()) {                                 \
1580     return GetCachedOperator<                                        \
1581         Word64AtomicOrOperator<MachineType::Type().representation(), \
1582                                MachineType::Type().semantic()>>();   \
1583   }
1584   ATOMIC_U64_TYPE_LIST(OR)
1585 #undef OR
1586   UNREACHABLE();
1587 }
1588 
Word64AtomicXor(MachineType type)1589 const Operator* MachineOperatorBuilder::Word64AtomicXor(MachineType type) {
1590 #define XOR(Type)                                                     \
1591   if (type == MachineType::Type()) {                                  \
1592     return GetCachedOperator<                                         \
1593         Word64AtomicXorOperator<MachineType::Type().representation(), \
1594                                 MachineType::Type().semantic()>>();   \
1595   }
1596   ATOMIC_U64_TYPE_LIST(XOR)
1597 #undef XOR
1598   UNREACHABLE();
1599 }
1600 
Word64AtomicExchange(MachineType type)1601 const Operator* MachineOperatorBuilder::Word64AtomicExchange(MachineType type) {
1602 #define EXCHANGE(Type)                                                     \
1603   if (type == MachineType::Type()) {                                       \
1604     return GetCachedOperator<                                              \
1605         Word64AtomicExchangeOperator<MachineType::Type().representation(), \
1606                                      MachineType::Type().semantic()>>();   \
1607   }
1608   ATOMIC_U64_TYPE_LIST(EXCHANGE)
1609 #undef EXCHANGE
1610   UNREACHABLE();
1611 }
1612 
Word64AtomicCompareExchange(MachineType type)1613 const Operator* MachineOperatorBuilder::Word64AtomicCompareExchange(
1614     MachineType type) {
1615 #define COMPARE_EXCHANGE(Type)                                    \
1616   if (type == MachineType::Type()) {                              \
1617     return GetCachedOperator<Word64AtomicCompareExchangeOperator< \
1618         MachineType::Type().representation(),                     \
1619         MachineType::Type().semantic()>>();                       \
1620   }
1621   ATOMIC_U64_TYPE_LIST(COMPARE_EXCHANGE)
1622 #undef COMPARE_EXCHANGE
1623   UNREACHABLE();
1624 }
1625 
Word32AtomicPairLoad()1626 const Operator* MachineOperatorBuilder::Word32AtomicPairLoad() {
1627   return GetCachedOperator<Word32AtomicPairLoadOperator>();
1628 }
1629 
Word32AtomicPairStore()1630 const Operator* MachineOperatorBuilder::Word32AtomicPairStore() {
1631   return GetCachedOperator<Word32AtomicPairStoreOperator>();
1632 }
1633 
Word32AtomicPairAdd()1634 const Operator* MachineOperatorBuilder::Word32AtomicPairAdd() {
1635   return GetCachedOperator<Word32AtomicPairAddOperator>();
1636 }
1637 
Word32AtomicPairSub()1638 const Operator* MachineOperatorBuilder::Word32AtomicPairSub() {
1639   return GetCachedOperator<Word32AtomicPairSubOperator>();
1640 }
1641 
Word32AtomicPairAnd()1642 const Operator* MachineOperatorBuilder::Word32AtomicPairAnd() {
1643   return GetCachedOperator<Word32AtomicPairAndOperator>();
1644 }
1645 
Word32AtomicPairOr()1646 const Operator* MachineOperatorBuilder::Word32AtomicPairOr() {
1647   return GetCachedOperator<Word32AtomicPairOrOperator>();
1648 }
1649 
Word32AtomicPairXor()1650 const Operator* MachineOperatorBuilder::Word32AtomicPairXor() {
1651   return GetCachedOperator<Word32AtomicPairXorOperator>();
1652 }
1653 
Word32AtomicPairExchange()1654 const Operator* MachineOperatorBuilder::Word32AtomicPairExchange() {
1655   return GetCachedOperator<Word32AtomicPairExchangeOperator>();
1656 }
1657 
Word32AtomicPairCompareExchange()1658 const Operator* MachineOperatorBuilder::Word32AtomicPairCompareExchange() {
1659   return GetCachedOperator<Word32AtomicPairCompareExchangeOperator>();
1660 }
1661 
TaggedPoisonOnSpeculation()1662 const Operator* MachineOperatorBuilder::TaggedPoisonOnSpeculation() {
1663   return GetCachedOperator<TaggedPoisonOnSpeculationOperator>();
1664 }
1665 
Word32PoisonOnSpeculation()1666 const Operator* MachineOperatorBuilder::Word32PoisonOnSpeculation() {
1667   return GetCachedOperator<Word32PoisonOnSpeculationOperator>();
1668 }
1669 
Word64PoisonOnSpeculation()1670 const Operator* MachineOperatorBuilder::Word64PoisonOnSpeculation() {
1671   return GetCachedOperator<Word64PoisonOnSpeculationOperator>();
1672 }
1673 
1674 #define EXTRACT_LANE_OP(Type, Sign, lane_count)                                \
1675   const Operator* MachineOperatorBuilder::Type##ExtractLane##Sign(             \
1676       int32_t lane_index) {                                                    \
1677     DCHECK(0 <= lane_index && lane_index < lane_count);                        \
1678     return zone_->New<Operator1<int32_t>>(                                     \
1679         IrOpcode::k##Type##ExtractLane##Sign, Operator::kPure, "Extract lane", \
1680         1, 0, 0, 1, 0, 0, lane_index);                                         \
1681   }
1682 EXTRACT_LANE_OP(F64x2, , 2)
1683 EXTRACT_LANE_OP(F32x4, , 4)
1684 EXTRACT_LANE_OP(I64x2, , 2)
1685 EXTRACT_LANE_OP(I32x4, , 4)
1686 EXTRACT_LANE_OP(I16x8, U, 8)
1687 EXTRACT_LANE_OP(I16x8, S, 8)
1688 EXTRACT_LANE_OP(I8x16, U, 16)
1689 EXTRACT_LANE_OP(I8x16, S, 16)
1690 #undef EXTRACT_LANE_OP
1691 
1692 #define REPLACE_LANE_OP(Type, lane_count)                                     \
1693   const Operator* MachineOperatorBuilder::Type##ReplaceLane(                  \
1694       int32_t lane_index) {                                                   \
1695     DCHECK(0 <= lane_index && lane_index < lane_count);                       \
1696     return zone_->New<Operator1<int32_t>>(IrOpcode::k##Type##ReplaceLane,     \
1697                                           Operator::kPure, "Replace lane", 2, \
1698                                           0, 0, 1, 0, 0, lane_index);         \
1699   }
SIMD_LANE_OP_LIST(REPLACE_LANE_OP) const1700 SIMD_LANE_OP_LIST(REPLACE_LANE_OP)
1701 #undef REPLACE_LANE_OP
1702 
1703 const Operator* MachineOperatorBuilder::I64x2ReplaceLaneI32Pair(
1704     int32_t lane_index) {
1705   DCHECK(0 <= lane_index && lane_index < 2);
1706   return zone_->New<Operator1<int32_t>>(IrOpcode::kI64x2ReplaceLaneI32Pair,
1707                                         Operator::kPure, "Replace lane", 3, 0,
1708                                         0, 1, 0, 0, lane_index);
1709 }
1710 
operator ==(S128ImmediateParameter const & lhs,S128ImmediateParameter const & rhs)1711 bool operator==(S128ImmediateParameter const& lhs,
1712                 S128ImmediateParameter const& rhs) {
1713   return (lhs.immediate() == rhs.immediate());
1714 }
1715 
operator !=(S128ImmediateParameter const & lhs,S128ImmediateParameter const & rhs)1716 bool operator!=(S128ImmediateParameter const& lhs,
1717                 S128ImmediateParameter const& rhs) {
1718   return !(lhs == rhs);
1719 }
1720 
hash_value(S128ImmediateParameter const & p)1721 size_t hash_value(S128ImmediateParameter const& p) {
1722   return base::hash_range(p.immediate().begin(), p.immediate().end());
1723 }
1724 
operator <<(std::ostream & os,S128ImmediateParameter const & p)1725 std::ostream& operator<<(std::ostream& os, S128ImmediateParameter const& p) {
1726   for (int i = 0; i < 16; i++) {
1727     const char* separator = (i < 15) ? "," : "";
1728     os << static_cast<uint32_t>(p[i]) << separator;
1729   }
1730   return os;
1731 }
1732 
S128ImmediateParameterOf(Operator const * op)1733 S128ImmediateParameter const& S128ImmediateParameterOf(Operator const* op) {
1734   DCHECK(IrOpcode::kI8x16Shuffle == op->opcode() ||
1735          IrOpcode::kS128Const == op->opcode());
1736   return OpParameter<S128ImmediateParameter>(op);
1737 }
1738 
S128Const(const uint8_t value[16])1739 const Operator* MachineOperatorBuilder::S128Const(const uint8_t value[16]) {
1740   return zone_->New<Operator1<S128ImmediateParameter>>(
1741       IrOpcode::kS128Const, Operator::kPure, "Immediate", 0, 0, 0, 1, 0, 0,
1742       S128ImmediateParameter(value));
1743 }
1744 
I8x16Shuffle(const uint8_t shuffle[16])1745 const Operator* MachineOperatorBuilder::I8x16Shuffle(
1746     const uint8_t shuffle[16]) {
1747   return zone_->New<Operator1<S128ImmediateParameter>>(
1748       IrOpcode::kI8x16Shuffle, Operator::kPure, "Shuffle", 2, 0, 0, 1, 0, 0,
1749       S128ImmediateParameter(shuffle));
1750 }
1751 
StackCheckKindOf(Operator const * op)1752 StackCheckKind StackCheckKindOf(Operator const* op) {
1753   DCHECK_EQ(IrOpcode::kStackPointerGreaterThan, op->opcode());
1754   return OpParameter<StackCheckKind>(op);
1755 }
1756 
1757 #undef PURE_BINARY_OP_LIST_32
1758 #undef PURE_BINARY_OP_LIST_64
1759 #undef MACHINE_PURE_OP_LIST
1760 #undef PURE_OPTIONAL_OP_LIST
1761 #undef OVERFLOW_OP_LIST
1762 #undef MACHINE_TYPE_LIST
1763 #undef MACHINE_REPRESENTATION_LIST
1764 #undef ATOMIC_TYPE_LIST
1765 #undef ATOMIC_U64_TYPE_LIST
1766 #undef ATOMIC_U32_TYPE_LIST
1767 #undef ATOMIC_REPRESENTATION_LIST
1768 #undef ATOMIC64_REPRESENTATION_LIST
1769 #undef SIMD_LANE_OP_LIST
1770 #undef STACK_SLOT_CACHED_SIZES_ALIGNMENTS_LIST
1771 #undef LOAD_TRANSFORM_LIST
1772 
1773 }  // namespace compiler
1774 }  // namespace internal
1775 }  // namespace v8
1776