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