1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/compiler/machine-operator.h"
6
7 #include "src/base/lazy-instance.h"
8 #include "src/compiler/opcodes.h"
9 #include "src/compiler/operator.h"
10
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(LoadKind kind)35 size_t hash_value(LoadKind kind) { return static_cast<size_t>(kind); }
36
operator <<(std::ostream & os,LoadKind kind)37 std::ostream& operator<<(std::ostream& os, LoadKind kind) {
38 switch (kind) {
39 case LoadKind::kNormal:
40 return os << "kNormal";
41 case LoadKind::kUnaligned:
42 return os << "kUnaligned";
43 case LoadKind::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::kS8x16LoadSplat:
54 return os << "kS8x16LoadSplat";
55 case LoadTransformation::kS16x8LoadSplat:
56 return os << "kS16x8LoadSplat";
57 case LoadTransformation::kS32x4LoadSplat:
58 return os << "kS32x4LoadSplat";
59 case LoadTransformation::kS64x2LoadSplat:
60 return os << "kS64x2LoadSplat";
61 case LoadTransformation::kI16x8Load8x8S:
62 return os << "kI16x8Load8x8S";
63 case LoadTransformation::kI16x8Load8x8U:
64 return os << "kI16x8Load8x8U";
65 case LoadTransformation::kI32x4Load16x4S:
66 return os << "kI32x4Load16x4S";
67 case LoadTransformation::kI32x4Load16x4U:
68 return os << "kI32x4Load16x4U";
69 case LoadTransformation::kI64x2Load32x2S:
70 return os << "kI64x2Load32x2S";
71 case LoadTransformation::kI64x2Load32x2U:
72 return os << "kI64x2Load32x2U";
73 }
74 UNREACHABLE();
75 }
76
hash_value(LoadTransformParameters params)77 size_t hash_value(LoadTransformParameters params) {
78 return base::hash_combine(params.kind, params.transformation);
79 }
80
operator <<(std::ostream & os,LoadTransformParameters params)81 std::ostream& operator<<(std::ostream& os, LoadTransformParameters params) {
82 return os << "(" << params.kind << " " << params.transformation << ")";
83 }
84
LoadTransformParametersOf(Operator const * op)85 LoadTransformParameters const& LoadTransformParametersOf(Operator const* op) {
86 DCHECK_EQ(IrOpcode::kLoadTransform, op->opcode());
87 return OpParameter<LoadTransformParameters>(op);
88 }
89
operator ==(LoadTransformParameters lhs,LoadTransformParameters rhs)90 bool operator==(LoadTransformParameters lhs, LoadTransformParameters rhs) {
91 return lhs.transformation == rhs.transformation && lhs.kind == rhs.kind;
92 }
93
operator !=(LoadTransformParameters lhs,LoadTransformParameters rhs)94 bool operator!=(LoadTransformParameters lhs, LoadTransformParameters rhs) {
95 return !(lhs == rhs);
96 }
97
LoadRepresentationOf(Operator const * op)98 LoadRepresentation LoadRepresentationOf(Operator const* op) {
99 DCHECK(IrOpcode::kLoad == op->opcode() ||
100 IrOpcode::kProtectedLoad == op->opcode() ||
101 IrOpcode::kWord32AtomicLoad == op->opcode() ||
102 IrOpcode::kWord64AtomicLoad == op->opcode() ||
103 IrOpcode::kWord32AtomicPairLoad == op->opcode() ||
104 IrOpcode::kPoisonedLoad == op->opcode() ||
105 IrOpcode::kUnalignedLoad == op->opcode());
106 return OpParameter<LoadRepresentation>(op);
107 }
108
109
StoreRepresentationOf(Operator const * op)110 StoreRepresentation const& StoreRepresentationOf(Operator const* op) {
111 DCHECK(IrOpcode::kStore == op->opcode() ||
112 IrOpcode::kProtectedStore == op->opcode());
113 return OpParameter<StoreRepresentation>(op);
114 }
115
UnalignedStoreRepresentationOf(Operator const * op)116 UnalignedStoreRepresentation const& UnalignedStoreRepresentationOf(
117 Operator const* op) {
118 DCHECK_EQ(IrOpcode::kUnalignedStore, op->opcode());
119 return OpParameter<UnalignedStoreRepresentation>(op);
120 }
121
operator ==(StackSlotRepresentation lhs,StackSlotRepresentation rhs)122 bool operator==(StackSlotRepresentation lhs, StackSlotRepresentation rhs) {
123 return lhs.size() == rhs.size() && lhs.alignment() == rhs.alignment();
124 }
125
operator !=(StackSlotRepresentation lhs,StackSlotRepresentation rhs)126 bool operator!=(StackSlotRepresentation lhs, StackSlotRepresentation rhs) {
127 return !(lhs == rhs);
128 }
129
hash_value(StackSlotRepresentation rep)130 size_t hash_value(StackSlotRepresentation rep) {
131 return base::hash_combine(rep.size(), rep.alignment());
132 }
133
operator <<(std::ostream & os,StackSlotRepresentation rep)134 std::ostream& operator<<(std::ostream& os, StackSlotRepresentation rep) {
135 return os << rep.size() << ", " << rep.alignment();
136 }
137
StackSlotRepresentationOf(Operator const * op)138 StackSlotRepresentation const& StackSlotRepresentationOf(Operator const* op) {
139 DCHECK_EQ(IrOpcode::kStackSlot, op->opcode());
140 return OpParameter<StackSlotRepresentation>(op);
141 }
142
AtomicStoreRepresentationOf(Operator const * op)143 MachineRepresentation AtomicStoreRepresentationOf(Operator const* op) {
144 DCHECK(IrOpcode::kWord32AtomicStore == op->opcode() ||
145 IrOpcode::kWord64AtomicStore == op->opcode());
146 return OpParameter<MachineRepresentation>(op);
147 }
148
AtomicOpType(Operator const * op)149 MachineType AtomicOpType(Operator const* op) {
150 return OpParameter<MachineType>(op);
151 }
152
153 // The format is:
154 // V(Name, properties, value_input_count, control_input_count, output_count)
155 #define PURE_BINARY_OP_LIST_32(V) \
156 V(Word32And, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
157 V(Word32Or, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
158 V(Word32Xor, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
159 V(Word32Shl, Operator::kNoProperties, 2, 0, 1) \
160 V(Word32Shr, Operator::kNoProperties, 2, 0, 1) \
161 V(Word32Sar, Operator::kNoProperties, 2, 0, 1) \
162 V(Word32Ror, Operator::kNoProperties, 2, 0, 1) \
163 V(Word32Equal, Operator::kCommutative, 2, 0, 1) \
164 V(Int32Add, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
165 V(Int32Sub, Operator::kNoProperties, 2, 0, 1) \
166 V(Int32Mul, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
167 V(Int32MulHigh, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
168 V(Int32Div, Operator::kNoProperties, 2, 1, 1) \
169 V(Int32Mod, Operator::kNoProperties, 2, 1, 1) \
170 V(Int32LessThan, Operator::kNoProperties, 2, 0, 1) \
171 V(Int32LessThanOrEqual, Operator::kNoProperties, 2, 0, 1) \
172 V(Uint32Div, Operator::kNoProperties, 2, 1, 1) \
173 V(Uint32LessThan, Operator::kNoProperties, 2, 0, 1) \
174 V(Uint32LessThanOrEqual, Operator::kNoProperties, 2, 0, 1) \
175 V(Uint32Mod, Operator::kNoProperties, 2, 1, 1) \
176 V(Uint32MulHigh, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)
177
178 // The format is:
179 // V(Name, properties, value_input_count, control_input_count, output_count)
180 #define PURE_BINARY_OP_LIST_64(V) \
181 V(Word64And, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
182 V(Word64Or, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
183 V(Word64Xor, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
184 V(Word64Shl, Operator::kNoProperties, 2, 0, 1) \
185 V(Word64Shr, Operator::kNoProperties, 2, 0, 1) \
186 V(Word64Sar, Operator::kNoProperties, 2, 0, 1) \
187 V(Word64Ror, Operator::kNoProperties, 2, 0, 1) \
188 V(Word64Equal, Operator::kCommutative, 2, 0, 1) \
189 V(Int64Add, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
190 V(Int64Sub, Operator::kNoProperties, 2, 0, 1) \
191 V(Int64Mul, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
192 V(Int64Div, Operator::kNoProperties, 2, 1, 1) \
193 V(Int64Mod, Operator::kNoProperties, 2, 1, 1) \
194 V(Int64LessThan, Operator::kNoProperties, 2, 0, 1) \
195 V(Int64LessThanOrEqual, Operator::kNoProperties, 2, 0, 1) \
196 V(Uint64Div, Operator::kNoProperties, 2, 1, 1) \
197 V(Uint64Mod, Operator::kNoProperties, 2, 1, 1) \
198 V(Uint64LessThan, Operator::kNoProperties, 2, 0, 1) \
199 V(Uint64LessThanOrEqual, Operator::kNoProperties, 2, 0, 1)
200
201 // The format is:
202 // V(Name, properties, value_input_count, control_input_count, output_count)
203 #define MACHINE_PURE_OP_LIST(V) \
204 PURE_BINARY_OP_LIST_32(V) \
205 PURE_BINARY_OP_LIST_64(V) \
206 V(Word32Clz, Operator::kNoProperties, 1, 0, 1) \
207 V(Word64Clz, Operator::kNoProperties, 1, 0, 1) \
208 V(Word32ReverseBytes, Operator::kNoProperties, 1, 0, 1) \
209 V(Word64ReverseBytes, Operator::kNoProperties, 1, 0, 1) \
210 V(Simd128ReverseBytes, Operator::kNoProperties, 1, 0, 1) \
211 V(BitcastTaggedToWordForTagAndSmiBits, Operator::kNoProperties, 1, 0, 1) \
212 V(BitcastWordToTaggedSigned, Operator::kNoProperties, 1, 0, 1) \
213 V(TruncateFloat64ToWord32, Operator::kNoProperties, 1, 0, 1) \
214 V(ChangeFloat32ToFloat64, Operator::kNoProperties, 1, 0, 1) \
215 V(ChangeFloat64ToInt32, Operator::kNoProperties, 1, 0, 1) \
216 V(ChangeFloat64ToInt64, Operator::kNoProperties, 1, 0, 1) \
217 V(ChangeFloat64ToUint32, Operator::kNoProperties, 1, 0, 1) \
218 V(ChangeFloat64ToUint64, Operator::kNoProperties, 1, 0, 1) \
219 V(TruncateFloat64ToInt64, Operator::kNoProperties, 1, 0, 1) \
220 V(TruncateFloat64ToUint32, Operator::kNoProperties, 1, 0, 1) \
221 V(TruncateFloat32ToInt32, Operator::kNoProperties, 1, 0, 1) \
222 V(TruncateFloat32ToUint32, Operator::kNoProperties, 1, 0, 1) \
223 V(TryTruncateFloat32ToInt64, Operator::kNoProperties, 1, 0, 2) \
224 V(TryTruncateFloat64ToInt64, Operator::kNoProperties, 1, 0, 2) \
225 V(TryTruncateFloat32ToUint64, Operator::kNoProperties, 1, 0, 2) \
226 V(TryTruncateFloat64ToUint64, Operator::kNoProperties, 1, 0, 2) \
227 V(ChangeInt32ToFloat64, Operator::kNoProperties, 1, 0, 1) \
228 V(ChangeInt64ToFloat64, Operator::kNoProperties, 1, 0, 1) \
229 V(Float64SilenceNaN, Operator::kNoProperties, 1, 0, 1) \
230 V(RoundFloat64ToInt32, Operator::kNoProperties, 1, 0, 1) \
231 V(RoundInt32ToFloat32, Operator::kNoProperties, 1, 0, 1) \
232 V(RoundInt64ToFloat32, Operator::kNoProperties, 1, 0, 1) \
233 V(RoundInt64ToFloat64, Operator::kNoProperties, 1, 0, 1) \
234 V(RoundUint32ToFloat32, Operator::kNoProperties, 1, 0, 1) \
235 V(RoundUint64ToFloat32, Operator::kNoProperties, 1, 0, 1) \
236 V(RoundUint64ToFloat64, Operator::kNoProperties, 1, 0, 1) \
237 V(BitcastWord32ToWord64, Operator::kNoProperties, 1, 0, 1) \
238 V(ChangeInt32ToInt64, Operator::kNoProperties, 1, 0, 1) \
239 V(ChangeUint32ToFloat64, Operator::kNoProperties, 1, 0, 1) \
240 V(ChangeUint32ToUint64, Operator::kNoProperties, 1, 0, 1) \
241 V(TruncateFloat64ToFloat32, Operator::kNoProperties, 1, 0, 1) \
242 V(TruncateInt64ToInt32, Operator::kNoProperties, 1, 0, 1) \
243 V(BitcastFloat32ToInt32, Operator::kNoProperties, 1, 0, 1) \
244 V(BitcastFloat64ToInt64, Operator::kNoProperties, 1, 0, 1) \
245 V(BitcastInt32ToFloat32, Operator::kNoProperties, 1, 0, 1) \
246 V(BitcastInt64ToFloat64, Operator::kNoProperties, 1, 0, 1) \
247 V(SignExtendWord8ToInt32, Operator::kNoProperties, 1, 0, 1) \
248 V(SignExtendWord16ToInt32, Operator::kNoProperties, 1, 0, 1) \
249 V(SignExtendWord8ToInt64, Operator::kNoProperties, 1, 0, 1) \
250 V(SignExtendWord16ToInt64, Operator::kNoProperties, 1, 0, 1) \
251 V(SignExtendWord32ToInt64, Operator::kNoProperties, 1, 0, 1) \
252 V(Float32Abs, Operator::kNoProperties, 1, 0, 1) \
253 V(Float32Add, Operator::kCommutative, 2, 0, 1) \
254 V(Float32Sub, Operator::kNoProperties, 2, 0, 1) \
255 V(Float32Mul, Operator::kCommutative, 2, 0, 1) \
256 V(Float32Div, Operator::kNoProperties, 2, 0, 1) \
257 V(Float32Neg, Operator::kNoProperties, 1, 0, 1) \
258 V(Float32Sqrt, Operator::kNoProperties, 1, 0, 1) \
259 V(Float32Max, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
260 V(Float32Min, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
261 V(Float64Abs, Operator::kNoProperties, 1, 0, 1) \
262 V(Float64Acos, Operator::kNoProperties, 1, 0, 1) \
263 V(Float64Acosh, Operator::kNoProperties, 1, 0, 1) \
264 V(Float64Asin, Operator::kNoProperties, 1, 0, 1) \
265 V(Float64Asinh, Operator::kNoProperties, 1, 0, 1) \
266 V(Float64Atan, Operator::kNoProperties, 1, 0, 1) \
267 V(Float64Atan2, Operator::kNoProperties, 2, 0, 1) \
268 V(Float64Atanh, Operator::kNoProperties, 1, 0, 1) \
269 V(Float64Cbrt, Operator::kNoProperties, 1, 0, 1) \
270 V(Float64Cos, Operator::kNoProperties, 1, 0, 1) \
271 V(Float64Cosh, Operator::kNoProperties, 1, 0, 1) \
272 V(Float64Exp, Operator::kNoProperties, 1, 0, 1) \
273 V(Float64Expm1, Operator::kNoProperties, 1, 0, 1) \
274 V(Float64Log, Operator::kNoProperties, 1, 0, 1) \
275 V(Float64Log1p, Operator::kNoProperties, 1, 0, 1) \
276 V(Float64Log2, Operator::kNoProperties, 1, 0, 1) \
277 V(Float64Log10, Operator::kNoProperties, 1, 0, 1) \
278 V(Float64Max, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
279 V(Float64Min, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
280 V(Float64Neg, Operator::kNoProperties, 1, 0, 1) \
281 V(Float64Add, Operator::kCommutative, 2, 0, 1) \
282 V(Float64Sub, Operator::kNoProperties, 2, 0, 1) \
283 V(Float64Mul, Operator::kCommutative, 2, 0, 1) \
284 V(Float64Div, Operator::kNoProperties, 2, 0, 1) \
285 V(Float64Mod, Operator::kNoProperties, 2, 0, 1) \
286 V(Float64Pow, Operator::kNoProperties, 2, 0, 1) \
287 V(Float64Sin, Operator::kNoProperties, 1, 0, 1) \
288 V(Float64Sinh, Operator::kNoProperties, 1, 0, 1) \
289 V(Float64Sqrt, Operator::kNoProperties, 1, 0, 1) \
290 V(Float64Tan, Operator::kNoProperties, 1, 0, 1) \
291 V(Float64Tanh, Operator::kNoProperties, 1, 0, 1) \
292 V(Float32Equal, Operator::kCommutative, 2, 0, 1) \
293 V(Float32LessThan, Operator::kNoProperties, 2, 0, 1) \
294 V(Float32LessThanOrEqual, Operator::kNoProperties, 2, 0, 1) \
295 V(Float64Equal, Operator::kCommutative, 2, 0, 1) \
296 V(Float64LessThan, Operator::kNoProperties, 2, 0, 1) \
297 V(Float64LessThanOrEqual, Operator::kNoProperties, 2, 0, 1) \
298 V(Float64ExtractLowWord32, Operator::kNoProperties, 1, 0, 1) \
299 V(Float64ExtractHighWord32, Operator::kNoProperties, 1, 0, 1) \
300 V(Float64InsertLowWord32, Operator::kNoProperties, 2, 0, 1) \
301 V(Float64InsertHighWord32, Operator::kNoProperties, 2, 0, 1) \
302 V(LoadStackCheckOffset, Operator::kNoProperties, 0, 0, 1) \
303 V(LoadFramePointer, Operator::kNoProperties, 0, 0, 1) \
304 V(LoadParentFramePointer, Operator::kNoProperties, 0, 0, 1) \
305 V(Int32PairAdd, Operator::kNoProperties, 4, 0, 2) \
306 V(Int32PairSub, Operator::kNoProperties, 4, 0, 2) \
307 V(Int32PairMul, Operator::kNoProperties, 4, 0, 2) \
308 V(Word32PairShl, Operator::kNoProperties, 3, 0, 2) \
309 V(Word32PairShr, Operator::kNoProperties, 3, 0, 2) \
310 V(Word32PairSar, Operator::kNoProperties, 3, 0, 2) \
311 V(F64x2Splat, Operator::kNoProperties, 1, 0, 1) \
312 V(F64x2Abs, Operator::kNoProperties, 1, 0, 1) \
313 V(F64x2Neg, Operator::kNoProperties, 1, 0, 1) \
314 V(F64x2Sqrt, Operator::kNoProperties, 1, 0, 1) \
315 V(F64x2Add, Operator::kCommutative, 2, 0, 1) \
316 V(F64x2Sub, Operator::kNoProperties, 2, 0, 1) \
317 V(F64x2Mul, Operator::kCommutative, 2, 0, 1) \
318 V(F64x2Div, Operator::kNoProperties, 2, 0, 1) \
319 V(F64x2Min, Operator::kCommutative, 2, 0, 1) \
320 V(F64x2Max, Operator::kCommutative, 2, 0, 1) \
321 V(F64x2Eq, Operator::kCommutative, 2, 0, 1) \
322 V(F64x2Ne, Operator::kCommutative, 2, 0, 1) \
323 V(F64x2Lt, Operator::kNoProperties, 2, 0, 1) \
324 V(F64x2Le, Operator::kNoProperties, 2, 0, 1) \
325 V(F64x2Qfma, Operator::kNoProperties, 3, 0, 1) \
326 V(F64x2Qfms, Operator::kNoProperties, 3, 0, 1) \
327 V(F32x4Splat, Operator::kNoProperties, 1, 0, 1) \
328 V(F32x4SConvertI32x4, Operator::kNoProperties, 1, 0, 1) \
329 V(F32x4UConvertI32x4, Operator::kNoProperties, 1, 0, 1) \
330 V(F32x4Abs, Operator::kNoProperties, 1, 0, 1) \
331 V(F32x4Neg, Operator::kNoProperties, 1, 0, 1) \
332 V(F32x4Sqrt, Operator::kNoProperties, 1, 0, 1) \
333 V(F32x4RecipApprox, Operator::kNoProperties, 1, 0, 1) \
334 V(F32x4RecipSqrtApprox, Operator::kNoProperties, 1, 0, 1) \
335 V(F32x4Add, Operator::kCommutative, 2, 0, 1) \
336 V(F32x4AddHoriz, Operator::kNoProperties, 2, 0, 1) \
337 V(F32x4Sub, Operator::kNoProperties, 2, 0, 1) \
338 V(F32x4Mul, Operator::kCommutative, 2, 0, 1) \
339 V(F32x4Div, Operator::kNoProperties, 2, 0, 1) \
340 V(F32x4Min, Operator::kCommutative, 2, 0, 1) \
341 V(F32x4Max, Operator::kCommutative, 2, 0, 1) \
342 V(F32x4Eq, Operator::kCommutative, 2, 0, 1) \
343 V(F32x4Ne, Operator::kCommutative, 2, 0, 1) \
344 V(F32x4Lt, Operator::kNoProperties, 2, 0, 1) \
345 V(F32x4Le, Operator::kNoProperties, 2, 0, 1) \
346 V(F32x4Qfma, Operator::kNoProperties, 3, 0, 1) \
347 V(F32x4Qfms, Operator::kNoProperties, 3, 0, 1) \
348 V(I64x2Splat, Operator::kNoProperties, 1, 0, 1) \
349 V(I64x2SplatI32Pair, Operator::kNoProperties, 2, 0, 1) \
350 V(I64x2Neg, Operator::kNoProperties, 1, 0, 1) \
351 V(I64x2Shl, Operator::kNoProperties, 2, 0, 1) \
352 V(I64x2ShrS, Operator::kNoProperties, 2, 0, 1) \
353 V(I64x2Add, Operator::kCommutative, 2, 0, 1) \
354 V(I64x2Sub, Operator::kNoProperties, 2, 0, 1) \
355 V(I64x2Mul, Operator::kCommutative, 2, 0, 1) \
356 V(I64x2MinS, Operator::kCommutative, 2, 0, 1) \
357 V(I64x2MaxS, Operator::kCommutative, 2, 0, 1) \
358 V(I64x2Eq, Operator::kCommutative, 2, 0, 1) \
359 V(I64x2Ne, Operator::kCommutative, 2, 0, 1) \
360 V(I64x2GtS, Operator::kNoProperties, 2, 0, 1) \
361 V(I64x2GeS, Operator::kNoProperties, 2, 0, 1) \
362 V(I64x2ShrU, Operator::kNoProperties, 2, 0, 1) \
363 V(I64x2MinU, Operator::kCommutative, 2, 0, 1) \
364 V(I64x2MaxU, Operator::kCommutative, 2, 0, 1) \
365 V(I64x2GtU, Operator::kNoProperties, 2, 0, 1) \
366 V(I64x2GeU, Operator::kNoProperties, 2, 0, 1) \
367 V(I32x4Splat, Operator::kNoProperties, 1, 0, 1) \
368 V(I32x4SConvertF32x4, Operator::kNoProperties, 1, 0, 1) \
369 V(I32x4SConvertI16x8Low, Operator::kNoProperties, 1, 0, 1) \
370 V(I32x4SConvertI16x8High, Operator::kNoProperties, 1, 0, 1) \
371 V(I32x4Neg, Operator::kNoProperties, 1, 0, 1) \
372 V(I32x4Shl, Operator::kNoProperties, 2, 0, 1) \
373 V(I32x4ShrS, Operator::kNoProperties, 2, 0, 1) \
374 V(I32x4Add, Operator::kCommutative, 2, 0, 1) \
375 V(I32x4AddHoriz, Operator::kNoProperties, 2, 0, 1) \
376 V(I32x4Sub, Operator::kNoProperties, 2, 0, 1) \
377 V(I32x4Mul, Operator::kCommutative, 2, 0, 1) \
378 V(I32x4MinS, Operator::kCommutative, 2, 0, 1) \
379 V(I32x4MaxS, Operator::kCommutative, 2, 0, 1) \
380 V(I32x4Eq, Operator::kCommutative, 2, 0, 1) \
381 V(I32x4Ne, Operator::kCommutative, 2, 0, 1) \
382 V(I32x4GtS, Operator::kNoProperties, 2, 0, 1) \
383 V(I32x4GeS, Operator::kNoProperties, 2, 0, 1) \
384 V(I32x4UConvertF32x4, Operator::kNoProperties, 1, 0, 1) \
385 V(I32x4UConvertI16x8Low, Operator::kNoProperties, 1, 0, 1) \
386 V(I32x4UConvertI16x8High, Operator::kNoProperties, 1, 0, 1) \
387 V(I32x4ShrU, Operator::kNoProperties, 2, 0, 1) \
388 V(I32x4MinU, Operator::kCommutative, 2, 0, 1) \
389 V(I32x4MaxU, Operator::kCommutative, 2, 0, 1) \
390 V(I32x4GtU, Operator::kNoProperties, 2, 0, 1) \
391 V(I32x4GeU, Operator::kNoProperties, 2, 0, 1) \
392 V(I32x4Abs, Operator::kNoProperties, 1, 0, 1) \
393 V(I32x4BitMask, Operator::kNoProperties, 1, 0, 1) \
394 V(I16x8Splat, Operator::kNoProperties, 1, 0, 1) \
395 V(I16x8SConvertI8x16Low, Operator::kNoProperties, 1, 0, 1) \
396 V(I16x8SConvertI8x16High, Operator::kNoProperties, 1, 0, 1) \
397 V(I16x8Neg, Operator::kNoProperties, 1, 0, 1) \
398 V(I16x8Shl, Operator::kNoProperties, 2, 0, 1) \
399 V(I16x8ShrS, Operator::kNoProperties, 2, 0, 1) \
400 V(I16x8SConvertI32x4, Operator::kNoProperties, 2, 0, 1) \
401 V(I16x8Add, Operator::kCommutative, 2, 0, 1) \
402 V(I16x8AddSaturateS, Operator::kCommutative, 2, 0, 1) \
403 V(I16x8AddHoriz, Operator::kNoProperties, 2, 0, 1) \
404 V(I16x8Sub, Operator::kNoProperties, 2, 0, 1) \
405 V(I16x8SubSaturateS, Operator::kNoProperties, 2, 0, 1) \
406 V(I16x8Mul, Operator::kCommutative, 2, 0, 1) \
407 V(I16x8MinS, Operator::kCommutative, 2, 0, 1) \
408 V(I16x8MaxS, Operator::kCommutative, 2, 0, 1) \
409 V(I16x8Eq, Operator::kCommutative, 2, 0, 1) \
410 V(I16x8Ne, Operator::kCommutative, 2, 0, 1) \
411 V(I16x8GtS, Operator::kNoProperties, 2, 0, 1) \
412 V(I16x8GeS, Operator::kNoProperties, 2, 0, 1) \
413 V(I16x8UConvertI8x16Low, Operator::kNoProperties, 1, 0, 1) \
414 V(I16x8UConvertI8x16High, Operator::kNoProperties, 1, 0, 1) \
415 V(I16x8ShrU, Operator::kNoProperties, 2, 0, 1) \
416 V(I16x8UConvertI32x4, Operator::kNoProperties, 2, 0, 1) \
417 V(I16x8AddSaturateU, Operator::kCommutative, 2, 0, 1) \
418 V(I16x8SubSaturateU, Operator::kNoProperties, 2, 0, 1) \
419 V(I16x8MinU, Operator::kCommutative, 2, 0, 1) \
420 V(I16x8MaxU, Operator::kCommutative, 2, 0, 1) \
421 V(I16x8GtU, Operator::kNoProperties, 2, 0, 1) \
422 V(I16x8GeU, Operator::kNoProperties, 2, 0, 1) \
423 V(I16x8RoundingAverageU, Operator::kCommutative, 2, 0, 1) \
424 V(I16x8Abs, Operator::kNoProperties, 1, 0, 1) \
425 V(I16x8BitMask, Operator::kNoProperties, 1, 0, 1) \
426 V(I8x16Splat, Operator::kNoProperties, 1, 0, 1) \
427 V(I8x16Neg, Operator::kNoProperties, 1, 0, 1) \
428 V(I8x16Shl, Operator::kNoProperties, 2, 0, 1) \
429 V(I8x16ShrS, Operator::kNoProperties, 2, 0, 1) \
430 V(I8x16SConvertI16x8, Operator::kNoProperties, 2, 0, 1) \
431 V(I8x16Add, Operator::kCommutative, 2, 0, 1) \
432 V(I8x16AddSaturateS, Operator::kCommutative, 2, 0, 1) \
433 V(I8x16Sub, Operator::kNoProperties, 2, 0, 1) \
434 V(I8x16SubSaturateS, Operator::kNoProperties, 2, 0, 1) \
435 V(I8x16Mul, Operator::kCommutative, 2, 0, 1) \
436 V(I8x16MinS, Operator::kCommutative, 2, 0, 1) \
437 V(I8x16MaxS, Operator::kCommutative, 2, 0, 1) \
438 V(I8x16Eq, Operator::kCommutative, 2, 0, 1) \
439 V(I8x16Ne, Operator::kCommutative, 2, 0, 1) \
440 V(I8x16GtS, Operator::kNoProperties, 2, 0, 1) \
441 V(I8x16GeS, Operator::kNoProperties, 2, 0, 1) \
442 V(I8x16ShrU, Operator::kNoProperties, 2, 0, 1) \
443 V(I8x16UConvertI16x8, Operator::kNoProperties, 2, 0, 1) \
444 V(I8x16AddSaturateU, Operator::kCommutative, 2, 0, 1) \
445 V(I8x16SubSaturateU, Operator::kNoProperties, 2, 0, 1) \
446 V(I8x16MinU, Operator::kCommutative, 2, 0, 1) \
447 V(I8x16MaxU, Operator::kCommutative, 2, 0, 1) \
448 V(I8x16GtU, Operator::kNoProperties, 2, 0, 1) \
449 V(I8x16GeU, Operator::kNoProperties, 2, 0, 1) \
450 V(I8x16RoundingAverageU, Operator::kCommutative, 2, 0, 1) \
451 V(I8x16Abs, Operator::kNoProperties, 1, 0, 1) \
452 V(I8x16BitMask, Operator::kNoProperties, 1, 0, 1) \
453 V(S128Load, Operator::kNoProperties, 2, 0, 1) \
454 V(S128Store, Operator::kNoProperties, 3, 0, 1) \
455 V(S128Zero, Operator::kNoProperties, 0, 0, 1) \
456 V(S128And, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
457 V(S128Or, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
458 V(S128Xor, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
459 V(S128Not, Operator::kNoProperties, 1, 0, 1) \
460 V(S128Select, Operator::kNoProperties, 3, 0, 1) \
461 V(S128AndNot, Operator::kNoProperties, 2, 0, 1) \
462 V(S1x2AnyTrue, Operator::kNoProperties, 1, 0, 1) \
463 V(S1x2AllTrue, Operator::kNoProperties, 1, 0, 1) \
464 V(S1x4AnyTrue, Operator::kNoProperties, 1, 0, 1) \
465 V(S1x4AllTrue, Operator::kNoProperties, 1, 0, 1) \
466 V(S1x8AnyTrue, Operator::kNoProperties, 1, 0, 1) \
467 V(S1x8AllTrue, Operator::kNoProperties, 1, 0, 1) \
468 V(S1x16AnyTrue, Operator::kNoProperties, 1, 0, 1) \
469 V(S1x16AllTrue, Operator::kNoProperties, 1, 0, 1) \
470 V(S8x16Swizzle, Operator::kNoProperties, 2, 0, 1)
471
472 // The format is:
473 // V(Name, properties, value_input_count, control_input_count, output_count)
474 #define PURE_OPTIONAL_OP_LIST(V) \
475 V(Word32Ctz, Operator::kNoProperties, 1, 0, 1) \
476 V(Word64Ctz, Operator::kNoProperties, 1, 0, 1) \
477 V(Word32ReverseBits, Operator::kNoProperties, 1, 0, 1) \
478 V(Word64ReverseBits, Operator::kNoProperties, 1, 0, 1) \
479 V(Int32AbsWithOverflow, Operator::kNoProperties, 1, 0, 2) \
480 V(Int64AbsWithOverflow, Operator::kNoProperties, 1, 0, 2) \
481 V(Word32Popcnt, Operator::kNoProperties, 1, 0, 1) \
482 V(Word64Popcnt, Operator::kNoProperties, 1, 0, 1) \
483 V(Float32RoundDown, Operator::kNoProperties, 1, 0, 1) \
484 V(Float64RoundDown, Operator::kNoProperties, 1, 0, 1) \
485 V(Float32RoundUp, Operator::kNoProperties, 1, 0, 1) \
486 V(Float64RoundUp, Operator::kNoProperties, 1, 0, 1) \
487 V(Float32RoundTruncate, Operator::kNoProperties, 1, 0, 1) \
488 V(Float64RoundTruncate, Operator::kNoProperties, 1, 0, 1) \
489 V(Float64RoundTiesAway, Operator::kNoProperties, 1, 0, 1) \
490 V(Float32RoundTiesEven, Operator::kNoProperties, 1, 0, 1) \
491 V(Float64RoundTiesEven, Operator::kNoProperties, 1, 0, 1)
492
493 // The format is:
494 // V(Name, properties, value_input_count, control_input_count, output_count)
495 #define OVERFLOW_OP_LIST(V) \
496 V(Int32AddWithOverflow, Operator::kAssociative | Operator::kCommutative) \
497 V(Int32SubWithOverflow, Operator::kNoProperties) \
498 V(Int32MulWithOverflow, Operator::kAssociative | Operator::kCommutative) \
499 V(Int64AddWithOverflow, Operator::kAssociative | Operator::kCommutative) \
500 V(Int64SubWithOverflow, Operator::kNoProperties)
501
502 #define MACHINE_TYPE_LIST(V) \
503 V(Float32) \
504 V(Float64) \
505 V(Simd128) \
506 V(Int8) \
507 V(Uint8) \
508 V(Int16) \
509 V(Uint16) \
510 V(Int32) \
511 V(Uint32) \
512 V(Int64) \
513 V(Uint64) \
514 V(Pointer) \
515 V(TaggedSigned) \
516 V(TaggedPointer) \
517 V(AnyTagged) \
518 V(CompressedPointer) \
519 V(AnyCompressed)
520
521 #define MACHINE_REPRESENTATION_LIST(V) \
522 V(kFloat32) \
523 V(kFloat64) \
524 V(kSimd128) \
525 V(kWord8) \
526 V(kWord16) \
527 V(kWord32) \
528 V(kWord64) \
529 V(kTaggedSigned) \
530 V(kTaggedPointer) \
531 V(kTagged) \
532 V(kCompressedPointer) \
533 V(kCompressed)
534
535 #define LOAD_TRANSFORM_LIST(V) \
536 V(S8x16LoadSplat) \
537 V(S16x8LoadSplat) \
538 V(S32x4LoadSplat) \
539 V(S64x2LoadSplat) \
540 V(I16x8Load8x8S) \
541 V(I16x8Load8x8U) \
542 V(I32x4Load16x4S) \
543 V(I32x4Load16x4U) \
544 V(I64x2Load32x2S) \
545 V(I64x2Load32x2U)
546
547 #define ATOMIC_U32_TYPE_LIST(V) \
548 V(Uint8) \
549 V(Uint16) \
550 V(Uint32)
551
552 #define ATOMIC_TYPE_LIST(V) \
553 ATOMIC_U32_TYPE_LIST(V) \
554 V(Int8) \
555 V(Int16) \
556 V(Int32)
557
558 #define ATOMIC_U64_TYPE_LIST(V) \
559 ATOMIC_U32_TYPE_LIST(V) \
560 V(Uint64)
561
562 #define ATOMIC_REPRESENTATION_LIST(V) \
563 V(kWord8) \
564 V(kWord16) \
565 V(kWord32)
566
567 #define ATOMIC64_REPRESENTATION_LIST(V) \
568 ATOMIC_REPRESENTATION_LIST(V) \
569 V(kWord64)
570
571 #define ATOMIC_PAIR_BINOP_LIST(V) \
572 V(Add) \
573 V(Sub) \
574 V(And) \
575 V(Or) \
576 V(Xor) \
577 V(Exchange)
578
579 #define SIMD_LANE_OP_LIST(V) \
580 V(F64x2, 2) \
581 V(F32x4, 4) \
582 V(I64x2, 2) \
583 V(I32x4, 4) \
584 V(I16x8, 8) \
585 V(I8x16, 16)
586
587 #define STACK_SLOT_CACHED_SIZES_ALIGNMENTS_LIST(V) \
588 V(4, 0) V(8, 0) V(16, 0) V(4, 4) V(8, 8) V(16, 16)
589
590 struct StackSlotOperator : public Operator1<StackSlotRepresentation> {
StackSlotOperatorv8::internal::compiler::StackSlotOperator591 explicit StackSlotOperator(int size, int alignment)
592 : Operator1<StackSlotRepresentation>(
593 IrOpcode::kStackSlot, Operator::kNoDeopt | Operator::kNoThrow,
594 "StackSlot", 0, 0, 0, 1, 0, 0,
595 StackSlotRepresentation(size, alignment)) {}
596 };
597
598 struct MachineOperatorGlobalCache {
599 #define PURE(Name, properties, value_input_count, control_input_count, \
600 output_count) \
601 struct Name##Operator final : public Operator { \
602 Name##Operator() \
603 : Operator(IrOpcode::k##Name, Operator::kPure | properties, #Name, \
604 value_input_count, 0, control_input_count, output_count, 0, \
605 0) {} \
606 }; \
607 Name##Operator k##Name;
608 MACHINE_PURE_OP_LIST(PURE)
609 PURE_OPTIONAL_OP_LIST(PURE)
610 #undef PURE
611
612 #define OVERFLOW_OP(Name, properties) \
613 struct Name##Operator final : public Operator { \
614 Name##Operator() \
615 : Operator(IrOpcode::k##Name, \
616 Operator::kEliminatable | Operator::kNoRead | properties, \
617 #Name, 2, 0, 1, 2, 0, 0) {} \
618 }; \
619 Name##Operator k##Name;
620 OVERFLOW_OP_LIST(OVERFLOW_OP)
621 #undef OVERFLOW_OP
622
623 #define LOAD(Type) \
624 struct Load##Type##Operator final : public Operator1<LoadRepresentation> { \
625 Load##Type##Operator() \
626 : Operator1<LoadRepresentation>(IrOpcode::kLoad, \
627 Operator::kEliminatable, "Load", 2, 1, \
628 1, 1, 1, 0, MachineType::Type()) {} \
629 }; \
630 struct PoisonedLoad##Type##Operator final \
631 : public Operator1<LoadRepresentation> { \
632 PoisonedLoad##Type##Operator() \
633 : Operator1<LoadRepresentation>( \
634 IrOpcode::kPoisonedLoad, Operator::kEliminatable, \
635 "PoisonedLoad", 2, 1, 1, 1, 1, 0, MachineType::Type()) {} \
636 }; \
637 struct UnalignedLoad##Type##Operator final \
638 : public Operator1<LoadRepresentation> { \
639 UnalignedLoad##Type##Operator() \
640 : Operator1<LoadRepresentation>( \
641 IrOpcode::kUnalignedLoad, Operator::kEliminatable, \
642 "UnalignedLoad", 2, 1, 1, 1, 1, 0, MachineType::Type()) {} \
643 }; \
644 struct ProtectedLoad##Type##Operator final \
645 : public Operator1<LoadRepresentation> { \
646 ProtectedLoad##Type##Operator() \
647 : Operator1<LoadRepresentation>( \
648 IrOpcode::kProtectedLoad, \
649 Operator::kNoDeopt | Operator::kNoThrow, "ProtectedLoad", 2, 1, \
650 1, 1, 1, 0, MachineType::Type()) {} \
651 }; \
652 Load##Type##Operator kLoad##Type; \
653 PoisonedLoad##Type##Operator kPoisonedLoad##Type; \
654 UnalignedLoad##Type##Operator kUnalignedLoad##Type; \
655 ProtectedLoad##Type##Operator kProtectedLoad##Type;
656 MACHINE_TYPE_LIST(LOAD)
657 #undef LOAD
658
659 #define LOAD_TRANSFORM_KIND(TYPE, KIND) \
660 struct KIND##LoadTransform##TYPE##Operator final \
661 : public Operator1<LoadTransformParameters> { \
662 KIND##LoadTransform##TYPE##Operator() \
663 : Operator1<LoadTransformParameters>( \
664 IrOpcode::kLoadTransform, Operator::kEliminatable, \
665 #KIND "LoadTransform", 2, 1, 1, 1, 1, 0, \
666 LoadTransformParameters{LoadKind::k##KIND, \
667 LoadTransformation::k##TYPE}) {} \
668 }; \
669 KIND##LoadTransform##TYPE##Operator k##KIND##LoadTransform##TYPE;
670
671 #define LOAD_TRANSFORM(TYPE) \
672 LOAD_TRANSFORM_KIND(TYPE, Normal) \
673 LOAD_TRANSFORM_KIND(TYPE, Unaligned) \
674 LOAD_TRANSFORM_KIND(TYPE, Protected)
675
676 LOAD_TRANSFORM_LIST(LOAD_TRANSFORM)
677 #undef LOAD_TRANSFORM
678 #undef LOAD_TRANSFORM_KIND
679
680 #define STACKSLOT(Size, Alignment) \
681 struct StackSlotOfSize##Size##OfAlignment##Alignment##Operator final \
682 : public StackSlotOperator { \
683 StackSlotOfSize##Size##OfAlignment##Alignment##Operator() \
684 : StackSlotOperator(Size, Alignment) {} \
685 }; \
686 StackSlotOfSize##Size##OfAlignment##Alignment##Operator \
687 kStackSlotOfSize##Size##OfAlignment##Alignment;
688 STACK_SLOT_CACHED_SIZES_ALIGNMENTS_LIST(STACKSLOT)
689 #undef STACKSLOT
690
691 #define STORE(Type) \
692 struct Store##Type##Operator : public Operator1<StoreRepresentation> { \
693 explicit Store##Type##Operator(WriteBarrierKind write_barrier_kind) \
694 : Operator1<StoreRepresentation>( \
695 IrOpcode::kStore, \
696 Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow, \
697 "Store", 3, 1, 1, 0, 1, 0, \
698 StoreRepresentation(MachineRepresentation::Type, \
699 write_barrier_kind)) {} \
700 }; \
701 struct Store##Type##NoWriteBarrier##Operator final \
702 : public Store##Type##Operator { \
703 Store##Type##NoWriteBarrier##Operator() \
704 : Store##Type##Operator(kNoWriteBarrier) {} \
705 }; \
706 struct Store##Type##AssertNoWriteBarrier##Operator final \
707 : public Store##Type##Operator { \
708 Store##Type##AssertNoWriteBarrier##Operator() \
709 : Store##Type##Operator(kAssertNoWriteBarrier) {} \
710 }; \
711 struct Store##Type##MapWriteBarrier##Operator final \
712 : public Store##Type##Operator { \
713 Store##Type##MapWriteBarrier##Operator() \
714 : Store##Type##Operator(kMapWriteBarrier) {} \
715 }; \
716 struct Store##Type##PointerWriteBarrier##Operator final \
717 : public Store##Type##Operator { \
718 Store##Type##PointerWriteBarrier##Operator() \
719 : Store##Type##Operator(kPointerWriteBarrier) {} \
720 }; \
721 struct Store##Type##EphemeronKeyWriteBarrier##Operator final \
722 : public Store##Type##Operator { \
723 Store##Type##EphemeronKeyWriteBarrier##Operator() \
724 : Store##Type##Operator(kEphemeronKeyWriteBarrier) {} \
725 }; \
726 struct Store##Type##FullWriteBarrier##Operator final \
727 : public Store##Type##Operator { \
728 Store##Type##FullWriteBarrier##Operator() \
729 : Store##Type##Operator(kFullWriteBarrier) {} \
730 }; \
731 struct UnalignedStore##Type##Operator final \
732 : public Operator1<UnalignedStoreRepresentation> { \
733 UnalignedStore##Type##Operator() \
734 : Operator1<UnalignedStoreRepresentation>( \
735 IrOpcode::kUnalignedStore, \
736 Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow, \
737 "UnalignedStore", 3, 1, 1, 0, 1, 0, \
738 MachineRepresentation::Type) {} \
739 }; \
740 struct ProtectedStore##Type##Operator \
741 : public Operator1<StoreRepresentation> { \
742 explicit ProtectedStore##Type##Operator() \
743 : Operator1<StoreRepresentation>( \
744 IrOpcode::kProtectedStore, \
745 Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow, \
746 "Store", 3, 1, 1, 0, 1, 0, \
747 StoreRepresentation(MachineRepresentation::Type, \
748 kNoWriteBarrier)) {} \
749 }; \
750 Store##Type##NoWriteBarrier##Operator kStore##Type##NoWriteBarrier; \
751 Store##Type##AssertNoWriteBarrier##Operator \
752 kStore##Type##AssertNoWriteBarrier; \
753 Store##Type##MapWriteBarrier##Operator kStore##Type##MapWriteBarrier; \
754 Store##Type##PointerWriteBarrier##Operator \
755 kStore##Type##PointerWriteBarrier; \
756 Store##Type##EphemeronKeyWriteBarrier##Operator \
757 kStore##Type##EphemeronKeyWriteBarrier; \
758 Store##Type##FullWriteBarrier##Operator kStore##Type##FullWriteBarrier; \
759 UnalignedStore##Type##Operator kUnalignedStore##Type; \
760 ProtectedStore##Type##Operator kProtectedStore##Type;
761 MACHINE_REPRESENTATION_LIST(STORE)
762 #undef STORE
763
764 #define ATOMIC_LOAD(Type) \
765 struct Word32AtomicLoad##Type##Operator final \
766 : public Operator1<LoadRepresentation> { \
767 Word32AtomicLoad##Type##Operator() \
768 : Operator1<LoadRepresentation>( \
769 IrOpcode::kWord32AtomicLoad, Operator::kEliminatable, \
770 "Word32AtomicLoad", 2, 1, 1, 1, 1, 0, MachineType::Type()) {} \
771 }; \
772 Word32AtomicLoad##Type##Operator kWord32AtomicLoad##Type;
773 ATOMIC_TYPE_LIST(ATOMIC_LOAD)
774 #undef ATOMIC_LOAD
775
776 #define ATOMIC_LOAD(Type) \
777 struct Word64AtomicLoad##Type##Operator final \
778 : public Operator1<LoadRepresentation> { \
779 Word64AtomicLoad##Type##Operator() \
780 : Operator1<LoadRepresentation>( \
781 IrOpcode::kWord64AtomicLoad, Operator::kEliminatable, \
782 "Word64AtomicLoad", 2, 1, 1, 1, 1, 0, MachineType::Type()) {} \
783 }; \
784 Word64AtomicLoad##Type##Operator kWord64AtomicLoad##Type;
785 ATOMIC_U64_TYPE_LIST(ATOMIC_LOAD)
786 #undef ATOMIC_LOAD
787
788 #define ATOMIC_STORE(Type) \
789 struct Word32AtomicStore##Type##Operator \
790 : public Operator1<MachineRepresentation> { \
791 Word32AtomicStore##Type##Operator() \
792 : Operator1<MachineRepresentation>( \
793 IrOpcode::kWord32AtomicStore, \
794 Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow, \
795 "Word32AtomicStore", 3, 1, 1, 0, 1, 0, \
796 MachineRepresentation::Type) {} \
797 }; \
798 Word32AtomicStore##Type##Operator kWord32AtomicStore##Type;
799 ATOMIC_REPRESENTATION_LIST(ATOMIC_STORE)
800 #undef ATOMIC_STORE
801
802 #define ATOMIC_STORE(Type) \
803 struct Word64AtomicStore##Type##Operator \
804 : public Operator1<MachineRepresentation> { \
805 Word64AtomicStore##Type##Operator() \
806 : Operator1<MachineRepresentation>( \
807 IrOpcode::kWord64AtomicStore, \
808 Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow, \
809 "Word64AtomicStore", 3, 1, 1, 0, 1, 0, \
810 MachineRepresentation::Type) {} \
811 }; \
812 Word64AtomicStore##Type##Operator kWord64AtomicStore##Type;
813 ATOMIC64_REPRESENTATION_LIST(ATOMIC_STORE)
814 #undef ATOMIC_STORE
815
816 #define ATOMIC_OP(op, type) \
817 struct op##type##Operator : public Operator1<MachineType> { \
818 op##type##Operator() \
819 : Operator1<MachineType>(IrOpcode::k##op, \
820 Operator::kNoDeopt | Operator::kNoThrow, #op, \
821 3, 1, 1, 1, 1, 0, MachineType::type()) {} \
822 }; \
823 op##type##Operator k##op##type;
824 #define ATOMIC_OP_LIST(type) \
825 ATOMIC_OP(Word32AtomicAdd, type) \
826 ATOMIC_OP(Word32AtomicSub, type) \
827 ATOMIC_OP(Word32AtomicAnd, type) \
828 ATOMIC_OP(Word32AtomicOr, type) \
829 ATOMIC_OP(Word32AtomicXor, type) \
830 ATOMIC_OP(Word32AtomicExchange, type)
831 ATOMIC_TYPE_LIST(ATOMIC_OP_LIST)
832 #undef ATOMIC_OP_LIST
833 #define ATOMIC64_OP_LIST(type) \
834 ATOMIC_OP(Word64AtomicAdd, type) \
835 ATOMIC_OP(Word64AtomicSub, type) \
836 ATOMIC_OP(Word64AtomicAnd, type) \
837 ATOMIC_OP(Word64AtomicOr, type) \
838 ATOMIC_OP(Word64AtomicXor, type) \
839 ATOMIC_OP(Word64AtomicExchange, type)
840 ATOMIC_U64_TYPE_LIST(ATOMIC64_OP_LIST)
841 #undef ATOMIC64_OP_LIST
842 #undef ATOMIC_OP
843
844 #define ATOMIC_COMPARE_EXCHANGE(Type) \
845 struct Word32AtomicCompareExchange##Type##Operator \
846 : public Operator1<MachineType> { \
847 Word32AtomicCompareExchange##Type##Operator() \
848 : Operator1<MachineType>(IrOpcode::kWord32AtomicCompareExchange, \
849 Operator::kNoDeopt | Operator::kNoThrow, \
850 "Word32AtomicCompareExchange", 4, 1, 1, 1, 1, \
851 0, MachineType::Type()) {} \
852 }; \
853 Word32AtomicCompareExchange##Type##Operator \
854 kWord32AtomicCompareExchange##Type;
855 ATOMIC_TYPE_LIST(ATOMIC_COMPARE_EXCHANGE)
856 #undef ATOMIC_COMPARE_EXCHANGE
857
858 #define ATOMIC_COMPARE_EXCHANGE(Type) \
859 struct Word64AtomicCompareExchange##Type##Operator \
860 : public Operator1<MachineType> { \
861 Word64AtomicCompareExchange##Type##Operator() \
862 : Operator1<MachineType>(IrOpcode::kWord64AtomicCompareExchange, \
863 Operator::kNoDeopt | Operator::kNoThrow, \
864 "Word64AtomicCompareExchange", 4, 1, 1, 1, 1, \
865 0, MachineType::Type()) {} \
866 }; \
867 Word64AtomicCompareExchange##Type##Operator \
868 kWord64AtomicCompareExchange##Type;
869 ATOMIC_U64_TYPE_LIST(ATOMIC_COMPARE_EXCHANGE)
870 #undef ATOMIC_COMPARE_EXCHANGE
871
872 struct Word32AtomicPairLoadOperator : public Operator {
Word32AtomicPairLoadOperatorv8::internal::compiler::MachineOperatorGlobalCache::Word32AtomicPairLoadOperator873 Word32AtomicPairLoadOperator()
874 : Operator(IrOpcode::kWord32AtomicPairLoad,
875 Operator::kNoDeopt | Operator::kNoThrow,
876 "Word32AtomicPairLoad", 2, 1, 1, 2, 1, 0) {}
877 };
878 Word32AtomicPairLoadOperator kWord32AtomicPairLoad;
879
880 struct Word32AtomicPairStoreOperator : public Operator {
Word32AtomicPairStoreOperatorv8::internal::compiler::MachineOperatorGlobalCache::Word32AtomicPairStoreOperator881 Word32AtomicPairStoreOperator()
882 : Operator(IrOpcode::kWord32AtomicPairStore,
883 Operator::kNoDeopt | Operator::kNoThrow,
884 "Word32AtomicPairStore", 4, 1, 1, 0, 1, 0) {}
885 };
886 Word32AtomicPairStoreOperator kWord32AtomicPairStore;
887
888 #define ATOMIC_PAIR_OP(op) \
889 struct Word32AtomicPair##op##Operator : public Operator { \
890 Word32AtomicPair##op##Operator() \
891 : Operator(IrOpcode::kWord32AtomicPair##op, \
892 Operator::kNoDeopt | Operator::kNoThrow, \
893 "Word32AtomicPair##op", 4, 1, 1, 2, 1, 0) {} \
894 }; \
895 Word32AtomicPair##op##Operator kWord32AtomicPair##op;
896 ATOMIC_PAIR_BINOP_LIST(ATOMIC_PAIR_OP)
897 #undef ATOMIC_PAIR_OP
898 #undef ATOMIC_PAIR_BINOP_LIST
899
900 struct Word32AtomicPairCompareExchangeOperator : public Operator {
Word32AtomicPairCompareExchangeOperatorv8::internal::compiler::MachineOperatorGlobalCache::Word32AtomicPairCompareExchangeOperator901 Word32AtomicPairCompareExchangeOperator()
902 : Operator(IrOpcode::kWord32AtomicPairCompareExchange,
903 Operator::kNoDeopt | Operator::kNoThrow,
904 "Word32AtomicPairCompareExchange", 6, 1, 1, 2, 1, 0) {}
905 };
906 Word32AtomicPairCompareExchangeOperator kWord32AtomicPairCompareExchange;
907
908 struct MemoryBarrierOperator : public Operator {
MemoryBarrierOperatorv8::internal::compiler::MachineOperatorGlobalCache::MemoryBarrierOperator909 MemoryBarrierOperator()
910 : Operator(IrOpcode::kMemoryBarrier,
911 Operator::kNoDeopt | Operator::kNoThrow, "MemoryBarrier", 0,
912 1, 1, 0, 1, 0) {}
913 };
914 MemoryBarrierOperator kMemoryBarrier;
915
916 // The {BitcastWordToTagged} operator must not be marked as pure (especially
917 // not idempotent), because otherwise the splitting logic in the Scheduler
918 // might decide to split these operators, thus potentially creating live
919 // ranges of allocation top across calls or other things that might allocate.
920 // See https://bugs.chromium.org/p/v8/issues/detail?id=6059 for more details.
921 struct BitcastWordToTaggedOperator : public Operator {
BitcastWordToTaggedOperatorv8::internal::compiler::MachineOperatorGlobalCache::BitcastWordToTaggedOperator922 BitcastWordToTaggedOperator()
923 : Operator(IrOpcode::kBitcastWordToTagged,
924 Operator::kEliminatable | Operator::kNoWrite,
925 "BitcastWordToTagged", 1, 1, 1, 1, 1, 0) {}
926 };
927 BitcastWordToTaggedOperator kBitcastWordToTagged;
928
929 struct BitcastTaggedToWordOperator : public Operator {
BitcastTaggedToWordOperatorv8::internal::compiler::MachineOperatorGlobalCache::BitcastTaggedToWordOperator930 BitcastTaggedToWordOperator()
931 : Operator(IrOpcode::kBitcastTaggedToWord,
932 Operator::kEliminatable | Operator::kNoWrite,
933 "BitcastTaggedToWord", 1, 1, 1, 1, 1, 0) {}
934 };
935 BitcastTaggedToWordOperator kBitcastTaggedToWord;
936
937 struct BitcastMaybeObjectToWordOperator : public Operator {
BitcastMaybeObjectToWordOperatorv8::internal::compiler::MachineOperatorGlobalCache::BitcastMaybeObjectToWordOperator938 BitcastMaybeObjectToWordOperator()
939 : Operator(IrOpcode::kBitcastTaggedToWord,
940 Operator::kEliminatable | Operator::kNoWrite,
941 "BitcastMaybeObjectToWord", 1, 1, 1, 1, 1, 0) {}
942 };
943 BitcastMaybeObjectToWordOperator kBitcastMaybeObjectToWord;
944
945 struct TaggedPoisonOnSpeculation : public Operator {
TaggedPoisonOnSpeculationv8::internal::compiler::MachineOperatorGlobalCache::TaggedPoisonOnSpeculation946 TaggedPoisonOnSpeculation()
947 : Operator(IrOpcode::kTaggedPoisonOnSpeculation,
948 Operator::kEliminatable | Operator::kNoWrite,
949 "TaggedPoisonOnSpeculation", 1, 1, 1, 1, 1, 0) {}
950 };
951 TaggedPoisonOnSpeculation kTaggedPoisonOnSpeculation;
952
953 struct Word32PoisonOnSpeculation : public Operator {
Word32PoisonOnSpeculationv8::internal::compiler::MachineOperatorGlobalCache::Word32PoisonOnSpeculation954 Word32PoisonOnSpeculation()
955 : Operator(IrOpcode::kWord32PoisonOnSpeculation,
956 Operator::kEliminatable | Operator::kNoWrite,
957 "Word32PoisonOnSpeculation", 1, 1, 1, 1, 1, 0) {}
958 };
959 Word32PoisonOnSpeculation kWord32PoisonOnSpeculation;
960
961 struct Word64PoisonOnSpeculation : public Operator {
Word64PoisonOnSpeculationv8::internal::compiler::MachineOperatorGlobalCache::Word64PoisonOnSpeculation962 Word64PoisonOnSpeculation()
963 : Operator(IrOpcode::kWord64PoisonOnSpeculation,
964 Operator::kEliminatable | Operator::kNoWrite,
965 "Word64PoisonOnSpeculation", 1, 1, 1, 1, 1, 0) {}
966 };
967 Word64PoisonOnSpeculation kWord64PoisonOnSpeculation;
968
969 struct AbortCSAAssertOperator : public Operator {
AbortCSAAssertOperatorv8::internal::compiler::MachineOperatorGlobalCache::AbortCSAAssertOperator970 AbortCSAAssertOperator()
971 : Operator(IrOpcode::kAbortCSAAssert, Operator::kNoThrow,
972 "AbortCSAAssert", 1, 1, 1, 0, 1, 0) {}
973 };
974 AbortCSAAssertOperator kAbortCSAAssert;
975
976 struct DebugBreakOperator : public Operator {
DebugBreakOperatorv8::internal::compiler::MachineOperatorGlobalCache::DebugBreakOperator977 DebugBreakOperator()
978 : Operator(IrOpcode::kDebugBreak, Operator::kNoThrow, "DebugBreak", 0,
979 1, 1, 0, 1, 0) {}
980 };
981 DebugBreakOperator kDebugBreak;
982
983 struct UnsafePointerAddOperator final : public Operator {
UnsafePointerAddOperatorv8::internal::compiler::MachineOperatorGlobalCache::UnsafePointerAddOperator984 UnsafePointerAddOperator()
985 : Operator(IrOpcode::kUnsafePointerAdd, Operator::kKontrol,
986 "UnsafePointerAdd", 2, 1, 1, 1, 1, 0) {}
987 };
988 UnsafePointerAddOperator kUnsafePointerAdd;
989
990 struct StackPointerGreaterThanOperator : public Operator1<StackCheckKind> {
StackPointerGreaterThanOperatorv8::internal::compiler::MachineOperatorGlobalCache::StackPointerGreaterThanOperator991 explicit StackPointerGreaterThanOperator(StackCheckKind kind)
992 : Operator1<StackCheckKind>(
993 IrOpcode::kStackPointerGreaterThan, Operator::kEliminatable,
994 "StackPointerGreaterThan", 1, 1, 0, 1, 1, 0, kind) {}
995 };
996 #define STACK_POINTER_GREATER_THAN(Kind) \
997 struct StackPointerGreaterThan##Kind##Operator final \
998 : public StackPointerGreaterThanOperator { \
999 StackPointerGreaterThan##Kind##Operator() \
1000 : StackPointerGreaterThanOperator(StackCheckKind::k##Kind) {} \
1001 }; \
1002 StackPointerGreaterThan##Kind##Operator kStackPointerGreaterThan##Kind;
1003
1004 STACK_POINTER_GREATER_THAN(JSFunctionEntry)
1005 STACK_POINTER_GREATER_THAN(JSIterationBody)
1006 STACK_POINTER_GREATER_THAN(CodeStubAssembler)
1007 STACK_POINTER_GREATER_THAN(Wasm)
1008 #undef STACK_POINTER_GREATER_THAN
1009 };
1010
1011 struct CommentOperator : public Operator1<const char*> {
CommentOperatorv8::internal::compiler::CommentOperator1012 explicit CommentOperator(const char* msg)
1013 : Operator1<const char*>(IrOpcode::kComment, Operator::kNoThrow,
1014 "Comment", 0, 1, 1, 0, 1, 0, msg) {}
1015 };
1016
1017 namespace {
1018 DEFINE_LAZY_LEAKY_OBJECT_GETTER(MachineOperatorGlobalCache,
1019 GetMachineOperatorGlobalCache)
1020 }
1021
MachineOperatorBuilder(Zone * zone,MachineRepresentation word,Flags flags,AlignmentRequirements alignmentRequirements)1022 MachineOperatorBuilder::MachineOperatorBuilder(
1023 Zone* zone, MachineRepresentation word, Flags flags,
1024 AlignmentRequirements alignmentRequirements)
1025 : zone_(zone),
1026 cache_(*GetMachineOperatorGlobalCache()),
1027 word_(word),
1028 flags_(flags),
1029 alignment_requirements_(alignmentRequirements) {
1030 DCHECK(word == MachineRepresentation::kWord32 ||
1031 word == MachineRepresentation::kWord64);
1032 }
1033
UnalignedLoad(LoadRepresentation rep)1034 const Operator* MachineOperatorBuilder::UnalignedLoad(LoadRepresentation rep) {
1035 #define LOAD(Type) \
1036 if (rep == MachineType::Type()) { \
1037 return &cache_.kUnalignedLoad##Type; \
1038 }
1039 MACHINE_TYPE_LIST(LOAD)
1040 #undef LOAD
1041 UNREACHABLE();
1042 }
1043
UnalignedStore(UnalignedStoreRepresentation rep)1044 const Operator* MachineOperatorBuilder::UnalignedStore(
1045 UnalignedStoreRepresentation rep) {
1046 switch (rep) {
1047 #define STORE(kRep) \
1048 case MachineRepresentation::kRep: \
1049 return &cache_.kUnalignedStore##kRep;
1050 MACHINE_REPRESENTATION_LIST(STORE)
1051 #undef STORE
1052 case MachineRepresentation::kBit:
1053 case MachineRepresentation::kNone:
1054 break;
1055 }
1056 UNREACHABLE();
1057 }
1058
1059 #define PURE(Name, properties, value_input_count, control_input_count, \
1060 output_count) \
1061 const Operator* MachineOperatorBuilder::Name() { return &cache_.k##Name; }
1062 MACHINE_PURE_OP_LIST(PURE)
1063 #undef PURE
1064
1065 #define PURE(Name, properties, value_input_count, control_input_count, \
1066 output_count) \
1067 const OptionalOperator MachineOperatorBuilder::Name() { \
1068 return OptionalOperator(flags_ & k##Name, &cache_.k##Name); \
1069 }
PURE_OPTIONAL_OP_LIST(PURE)1070 PURE_OPTIONAL_OP_LIST(PURE)
1071 #undef PURE
1072
1073 #define OVERFLOW_OP(Name, properties) \
1074 const Operator* MachineOperatorBuilder::Name() { return &cache_.k##Name; }
1075 OVERFLOW_OP_LIST(OVERFLOW_OP)
1076 #undef OVERFLOW_OP
1077
1078 const Operator* MachineOperatorBuilder::Load(LoadRepresentation rep) {
1079 #define LOAD(Type) \
1080 if (rep == MachineType::Type()) { \
1081 return &cache_.kLoad##Type; \
1082 }
1083 MACHINE_TYPE_LIST(LOAD)
1084 #undef LOAD
1085 UNREACHABLE();
1086 }
1087
PoisonedLoad(LoadRepresentation rep)1088 const Operator* MachineOperatorBuilder::PoisonedLoad(LoadRepresentation rep) {
1089 #define LOAD(Type) \
1090 if (rep == MachineType::Type()) { \
1091 return &cache_.kPoisonedLoad##Type; \
1092 }
1093 MACHINE_TYPE_LIST(LOAD)
1094 #undef LOAD
1095 UNREACHABLE();
1096 }
1097
ProtectedLoad(LoadRepresentation rep)1098 const Operator* MachineOperatorBuilder::ProtectedLoad(LoadRepresentation rep) {
1099 #define LOAD(Type) \
1100 if (rep == MachineType::Type()) { \
1101 return &cache_.kProtectedLoad##Type; \
1102 }
1103 MACHINE_TYPE_LIST(LOAD)
1104 #undef LOAD
1105 UNREACHABLE();
1106 }
1107
LoadTransform(LoadKind kind,LoadTransformation transform)1108 const Operator* MachineOperatorBuilder::LoadTransform(
1109 LoadKind kind, LoadTransformation transform) {
1110 #define LOAD_TRANSFORM_KIND(TYPE, KIND) \
1111 if (kind == LoadKind::k##KIND && transform == LoadTransformation::k##TYPE) { \
1112 return &cache_.k##KIND##LoadTransform##TYPE; \
1113 }
1114 #define LOAD_TRANSFORM(TYPE) \
1115 LOAD_TRANSFORM_KIND(TYPE, Normal) \
1116 LOAD_TRANSFORM_KIND(TYPE, Unaligned) \
1117 LOAD_TRANSFORM_KIND(TYPE, Protected)
1118
1119 LOAD_TRANSFORM_LIST(LOAD_TRANSFORM)
1120 #undef LOAD_TRANSFORM
1121 #undef LOAD_TRANSFORM_KIND
1122 UNREACHABLE();
1123 }
1124
StackSlot(int size,int alignment)1125 const Operator* MachineOperatorBuilder::StackSlot(int size, int alignment) {
1126 DCHECK_LE(0, size);
1127 DCHECK(alignment == 0 || alignment == 4 || alignment == 8 || alignment == 16);
1128 #define CASE_CACHED_SIZE(Size, Alignment) \
1129 if (size == Size && alignment == Alignment) { \
1130 return &cache_.kStackSlotOfSize##Size##OfAlignment##Alignment; \
1131 }
1132
1133 STACK_SLOT_CACHED_SIZES_ALIGNMENTS_LIST(CASE_CACHED_SIZE)
1134
1135 #undef CASE_CACHED_SIZE
1136 return new (zone_) StackSlotOperator(size, alignment);
1137 }
1138
StackSlot(MachineRepresentation rep,int alignment)1139 const Operator* MachineOperatorBuilder::StackSlot(MachineRepresentation rep,
1140 int alignment) {
1141 return StackSlot(1 << ElementSizeLog2Of(rep), alignment);
1142 }
1143
Store(StoreRepresentation store_rep)1144 const Operator* MachineOperatorBuilder::Store(StoreRepresentation store_rep) {
1145 switch (store_rep.representation()) {
1146 #define STORE(kRep) \
1147 case MachineRepresentation::kRep: \
1148 switch (store_rep.write_barrier_kind()) { \
1149 case kNoWriteBarrier: \
1150 return &cache_.k##Store##kRep##NoWriteBarrier; \
1151 case kAssertNoWriteBarrier: \
1152 return &cache_.k##Store##kRep##AssertNoWriteBarrier; \
1153 case kMapWriteBarrier: \
1154 return &cache_.k##Store##kRep##MapWriteBarrier; \
1155 case kPointerWriteBarrier: \
1156 return &cache_.k##Store##kRep##PointerWriteBarrier; \
1157 case kEphemeronKeyWriteBarrier: \
1158 return &cache_.k##Store##kRep##EphemeronKeyWriteBarrier; \
1159 case kFullWriteBarrier: \
1160 return &cache_.k##Store##kRep##FullWriteBarrier; \
1161 } \
1162 break;
1163 MACHINE_REPRESENTATION_LIST(STORE)
1164 #undef STORE
1165 case MachineRepresentation::kBit:
1166 case MachineRepresentation::kNone:
1167 break;
1168 }
1169 UNREACHABLE();
1170 }
1171
ProtectedStore(MachineRepresentation rep)1172 const Operator* MachineOperatorBuilder::ProtectedStore(
1173 MachineRepresentation rep) {
1174 switch (rep) {
1175 #define STORE(kRep) \
1176 case MachineRepresentation::kRep: \
1177 return &cache_.kProtectedStore##kRep; \
1178 break;
1179 MACHINE_REPRESENTATION_LIST(STORE)
1180 #undef STORE
1181 case MachineRepresentation::kBit:
1182 case MachineRepresentation::kNone:
1183 break;
1184 }
1185 UNREACHABLE();
1186 }
1187
UnsafePointerAdd()1188 const Operator* MachineOperatorBuilder::UnsafePointerAdd() {
1189 return &cache_.kUnsafePointerAdd;
1190 }
1191
StackPointerGreaterThan(StackCheckKind kind)1192 const Operator* MachineOperatorBuilder::StackPointerGreaterThan(
1193 StackCheckKind kind) {
1194 switch (kind) {
1195 case StackCheckKind::kJSFunctionEntry:
1196 return &cache_.kStackPointerGreaterThanJSFunctionEntry;
1197 case StackCheckKind::kJSIterationBody:
1198 return &cache_.kStackPointerGreaterThanJSIterationBody;
1199 case StackCheckKind::kCodeStubAssembler:
1200 return &cache_.kStackPointerGreaterThanCodeStubAssembler;
1201 case StackCheckKind::kWasm:
1202 return &cache_.kStackPointerGreaterThanWasm;
1203 }
1204 UNREACHABLE();
1205 }
1206
BitcastWordToTagged()1207 const Operator* MachineOperatorBuilder::BitcastWordToTagged() {
1208 return &cache_.kBitcastWordToTagged;
1209 }
1210
BitcastTaggedToWord()1211 const Operator* MachineOperatorBuilder::BitcastTaggedToWord() {
1212 return &cache_.kBitcastTaggedToWord;
1213 }
1214
BitcastMaybeObjectToWord()1215 const Operator* MachineOperatorBuilder::BitcastMaybeObjectToWord() {
1216 return &cache_.kBitcastMaybeObjectToWord;
1217 }
1218
AbortCSAAssert()1219 const Operator* MachineOperatorBuilder::AbortCSAAssert() {
1220 return &cache_.kAbortCSAAssert;
1221 }
1222
DebugBreak()1223 const Operator* MachineOperatorBuilder::DebugBreak() {
1224 return &cache_.kDebugBreak;
1225 }
1226
Comment(const char * msg)1227 const Operator* MachineOperatorBuilder::Comment(const char* msg) {
1228 return new (zone_) CommentOperator(msg);
1229 }
1230
MemBarrier()1231 const Operator* MachineOperatorBuilder::MemBarrier() {
1232 return &cache_.kMemoryBarrier;
1233 }
1234
Word32AtomicLoad(LoadRepresentation rep)1235 const Operator* MachineOperatorBuilder::Word32AtomicLoad(
1236 LoadRepresentation rep) {
1237 #define LOAD(Type) \
1238 if (rep == MachineType::Type()) { \
1239 return &cache_.kWord32AtomicLoad##Type; \
1240 }
1241 ATOMIC_TYPE_LIST(LOAD)
1242 #undef LOAD
1243 UNREACHABLE();
1244 }
1245
Word32AtomicStore(MachineRepresentation rep)1246 const Operator* MachineOperatorBuilder::Word32AtomicStore(
1247 MachineRepresentation rep) {
1248 #define STORE(kRep) \
1249 if (rep == MachineRepresentation::kRep) { \
1250 return &cache_.kWord32AtomicStore##kRep; \
1251 }
1252 ATOMIC_REPRESENTATION_LIST(STORE)
1253 #undef STORE
1254 UNREACHABLE();
1255 }
1256
Word32AtomicExchange(MachineType type)1257 const Operator* MachineOperatorBuilder::Word32AtomicExchange(MachineType type) {
1258 #define EXCHANGE(kType) \
1259 if (type == MachineType::kType()) { \
1260 return &cache_.kWord32AtomicExchange##kType; \
1261 }
1262 ATOMIC_TYPE_LIST(EXCHANGE)
1263 #undef EXCHANGE
1264 UNREACHABLE();
1265 }
1266
Word32AtomicCompareExchange(MachineType type)1267 const Operator* MachineOperatorBuilder::Word32AtomicCompareExchange(
1268 MachineType type) {
1269 #define COMPARE_EXCHANGE(kType) \
1270 if (type == MachineType::kType()) { \
1271 return &cache_.kWord32AtomicCompareExchange##kType; \
1272 }
1273 ATOMIC_TYPE_LIST(COMPARE_EXCHANGE)
1274 #undef COMPARE_EXCHANGE
1275 UNREACHABLE();
1276 }
1277
Word32AtomicAdd(MachineType type)1278 const Operator* MachineOperatorBuilder::Word32AtomicAdd(MachineType type) {
1279 #define ADD(kType) \
1280 if (type == MachineType::kType()) { \
1281 return &cache_.kWord32AtomicAdd##kType; \
1282 }
1283 ATOMIC_TYPE_LIST(ADD)
1284 #undef ADD
1285 UNREACHABLE();
1286 }
1287
Word32AtomicSub(MachineType type)1288 const Operator* MachineOperatorBuilder::Word32AtomicSub(MachineType type) {
1289 #define SUB(kType) \
1290 if (type == MachineType::kType()) { \
1291 return &cache_.kWord32AtomicSub##kType; \
1292 }
1293 ATOMIC_TYPE_LIST(SUB)
1294 #undef SUB
1295 UNREACHABLE();
1296 }
1297
Word32AtomicAnd(MachineType type)1298 const Operator* MachineOperatorBuilder::Word32AtomicAnd(MachineType type) {
1299 #define AND(kType) \
1300 if (type == MachineType::kType()) { \
1301 return &cache_.kWord32AtomicAnd##kType; \
1302 }
1303 ATOMIC_TYPE_LIST(AND)
1304 #undef AND
1305 UNREACHABLE();
1306 }
1307
Word32AtomicOr(MachineType type)1308 const Operator* MachineOperatorBuilder::Word32AtomicOr(MachineType type) {
1309 #define OR(kType) \
1310 if (type == MachineType::kType()) { \
1311 return &cache_.kWord32AtomicOr##kType; \
1312 }
1313 ATOMIC_TYPE_LIST(OR)
1314 #undef OR
1315 UNREACHABLE();
1316 }
1317
Word32AtomicXor(MachineType type)1318 const Operator* MachineOperatorBuilder::Word32AtomicXor(MachineType type) {
1319 #define XOR(kType) \
1320 if (type == MachineType::kType()) { \
1321 return &cache_.kWord32AtomicXor##kType; \
1322 }
1323 ATOMIC_TYPE_LIST(XOR)
1324 #undef XOR
1325 UNREACHABLE();
1326 }
1327
Word64AtomicLoad(LoadRepresentation rep)1328 const Operator* MachineOperatorBuilder::Word64AtomicLoad(
1329 LoadRepresentation rep) {
1330 #define LOAD(Type) \
1331 if (rep == MachineType::Type()) { \
1332 return &cache_.kWord64AtomicLoad##Type; \
1333 }
1334 ATOMIC_U64_TYPE_LIST(LOAD)
1335 #undef LOAD
1336 UNREACHABLE();
1337 }
1338
Word64AtomicStore(MachineRepresentation rep)1339 const Operator* MachineOperatorBuilder::Word64AtomicStore(
1340 MachineRepresentation rep) {
1341 #define STORE(kRep) \
1342 if (rep == MachineRepresentation::kRep) { \
1343 return &cache_.kWord64AtomicStore##kRep; \
1344 }
1345 ATOMIC64_REPRESENTATION_LIST(STORE)
1346 #undef STORE
1347 UNREACHABLE();
1348 }
1349
Word64AtomicAdd(MachineType type)1350 const Operator* MachineOperatorBuilder::Word64AtomicAdd(MachineType type) {
1351 #define ADD(kType) \
1352 if (type == MachineType::kType()) { \
1353 return &cache_.kWord64AtomicAdd##kType; \
1354 }
1355 ATOMIC_U64_TYPE_LIST(ADD)
1356 #undef ADD
1357 UNREACHABLE();
1358 }
1359
Word64AtomicSub(MachineType type)1360 const Operator* MachineOperatorBuilder::Word64AtomicSub(MachineType type) {
1361 #define SUB(kType) \
1362 if (type == MachineType::kType()) { \
1363 return &cache_.kWord64AtomicSub##kType; \
1364 }
1365 ATOMIC_U64_TYPE_LIST(SUB)
1366 #undef SUB
1367 UNREACHABLE();
1368 }
1369
Word64AtomicAnd(MachineType type)1370 const Operator* MachineOperatorBuilder::Word64AtomicAnd(MachineType type) {
1371 #define AND(kType) \
1372 if (type == MachineType::kType()) { \
1373 return &cache_.kWord64AtomicAnd##kType; \
1374 }
1375 ATOMIC_U64_TYPE_LIST(AND)
1376 #undef AND
1377 UNREACHABLE();
1378 }
1379
Word64AtomicOr(MachineType type)1380 const Operator* MachineOperatorBuilder::Word64AtomicOr(MachineType type) {
1381 #define OR(kType) \
1382 if (type == MachineType::kType()) { \
1383 return &cache_.kWord64AtomicOr##kType; \
1384 }
1385 ATOMIC_U64_TYPE_LIST(OR)
1386 #undef OR
1387 UNREACHABLE();
1388 }
1389
Word64AtomicXor(MachineType type)1390 const Operator* MachineOperatorBuilder::Word64AtomicXor(MachineType type) {
1391 #define XOR(kType) \
1392 if (type == MachineType::kType()) { \
1393 return &cache_.kWord64AtomicXor##kType; \
1394 }
1395 ATOMIC_U64_TYPE_LIST(XOR)
1396 #undef XOR
1397 UNREACHABLE();
1398 }
1399
Word64AtomicExchange(MachineType type)1400 const Operator* MachineOperatorBuilder::Word64AtomicExchange(MachineType type) {
1401 #define EXCHANGE(kType) \
1402 if (type == MachineType::kType()) { \
1403 return &cache_.kWord64AtomicExchange##kType; \
1404 }
1405 ATOMIC_U64_TYPE_LIST(EXCHANGE)
1406 #undef EXCHANGE
1407 UNREACHABLE();
1408 }
1409
Word64AtomicCompareExchange(MachineType type)1410 const Operator* MachineOperatorBuilder::Word64AtomicCompareExchange(
1411 MachineType type) {
1412 #define COMPARE_EXCHANGE(kType) \
1413 if (type == MachineType::kType()) { \
1414 return &cache_.kWord64AtomicCompareExchange##kType; \
1415 }
1416 ATOMIC_U64_TYPE_LIST(COMPARE_EXCHANGE)
1417 #undef COMPARE_EXCHANGE
1418 UNREACHABLE();
1419 }
1420
Word32AtomicPairLoad()1421 const Operator* MachineOperatorBuilder::Word32AtomicPairLoad() {
1422 return &cache_.kWord32AtomicPairLoad;
1423 }
1424
Word32AtomicPairStore()1425 const Operator* MachineOperatorBuilder::Word32AtomicPairStore() {
1426 return &cache_.kWord32AtomicPairStore;
1427 }
1428
Word32AtomicPairAdd()1429 const Operator* MachineOperatorBuilder::Word32AtomicPairAdd() {
1430 return &cache_.kWord32AtomicPairAdd;
1431 }
1432
Word32AtomicPairSub()1433 const Operator* MachineOperatorBuilder::Word32AtomicPairSub() {
1434 return &cache_.kWord32AtomicPairSub;
1435 }
1436
Word32AtomicPairAnd()1437 const Operator* MachineOperatorBuilder::Word32AtomicPairAnd() {
1438 return &cache_.kWord32AtomicPairAnd;
1439 }
1440
Word32AtomicPairOr()1441 const Operator* MachineOperatorBuilder::Word32AtomicPairOr() {
1442 return &cache_.kWord32AtomicPairOr;
1443 }
1444
Word32AtomicPairXor()1445 const Operator* MachineOperatorBuilder::Word32AtomicPairXor() {
1446 return &cache_.kWord32AtomicPairXor;
1447 }
1448
Word32AtomicPairExchange()1449 const Operator* MachineOperatorBuilder::Word32AtomicPairExchange() {
1450 return &cache_.kWord32AtomicPairExchange;
1451 }
1452
Word32AtomicPairCompareExchange()1453 const Operator* MachineOperatorBuilder::Word32AtomicPairCompareExchange() {
1454 return &cache_.kWord32AtomicPairCompareExchange;
1455 }
1456
TaggedPoisonOnSpeculation()1457 const Operator* MachineOperatorBuilder::TaggedPoisonOnSpeculation() {
1458 return &cache_.kTaggedPoisonOnSpeculation;
1459 }
1460
Word32PoisonOnSpeculation()1461 const Operator* MachineOperatorBuilder::Word32PoisonOnSpeculation() {
1462 return &cache_.kWord32PoisonOnSpeculation;
1463 }
1464
Word64PoisonOnSpeculation()1465 const Operator* MachineOperatorBuilder::Word64PoisonOnSpeculation() {
1466 return &cache_.kWord64PoisonOnSpeculation;
1467 }
1468
1469 #define EXTRACT_LANE_OP(Type, Sign, lane_count) \
1470 const Operator* MachineOperatorBuilder::Type##ExtractLane##Sign( \
1471 int32_t lane_index) { \
1472 DCHECK(0 <= lane_index && lane_index < lane_count); \
1473 return new (zone_) Operator1<int32_t>( \
1474 IrOpcode::k##Type##ExtractLane##Sign, Operator::kPure, "Extract lane", \
1475 1, 0, 0, 1, 0, 0, lane_index); \
1476 }
1477 EXTRACT_LANE_OP(F64x2, , 2)
1478 EXTRACT_LANE_OP(F32x4, , 4)
1479 EXTRACT_LANE_OP(I64x2, , 2)
1480 EXTRACT_LANE_OP(I32x4, , 4)
1481 EXTRACT_LANE_OP(I16x8, U, 8)
1482 EXTRACT_LANE_OP(I16x8, S, 8)
1483 EXTRACT_LANE_OP(I8x16, U, 16)
1484 EXTRACT_LANE_OP(I8x16, S, 16)
1485 #undef EXTRACT_LANE_OP
1486
1487 #define REPLACE_LANE_OP(Type, lane_count) \
1488 const Operator* MachineOperatorBuilder::Type##ReplaceLane( \
1489 int32_t lane_index) { \
1490 DCHECK(0 <= lane_index && lane_index < lane_count); \
1491 return new (zone_) \
1492 Operator1<int32_t>(IrOpcode::k##Type##ReplaceLane, Operator::kPure, \
1493 "Replace lane", 2, 0, 0, 1, 0, 0, lane_index); \
1494 }
SIMD_LANE_OP_LIST(REPLACE_LANE_OP) const1495 SIMD_LANE_OP_LIST(REPLACE_LANE_OP)
1496 #undef REPLACE_LANE_OP
1497
1498 const Operator* MachineOperatorBuilder::I64x2ReplaceLaneI32Pair(
1499 int32_t lane_index) {
1500 DCHECK(0 <= lane_index && lane_index < 2);
1501 return new (zone_)
1502 Operator1<int32_t>(IrOpcode::kI64x2ReplaceLaneI32Pair, Operator::kPure,
1503 "Replace lane", 3, 0, 0, 1, 0, 0, lane_index);
1504 }
1505
operator ==(S8x16ShuffleParameter const & lhs,S8x16ShuffleParameter const & rhs)1506 bool operator==(S8x16ShuffleParameter const& lhs,
1507 S8x16ShuffleParameter const& rhs) {
1508 return (lhs.shuffle() == rhs.shuffle());
1509 }
1510
operator !=(S8x16ShuffleParameter const & lhs,S8x16ShuffleParameter const & rhs)1511 bool operator!=(S8x16ShuffleParameter const& lhs,
1512 S8x16ShuffleParameter const& rhs) {
1513 return !(lhs == rhs);
1514 }
1515
hash_value(S8x16ShuffleParameter const & p)1516 size_t hash_value(S8x16ShuffleParameter const& p) {
1517 return base::hash_range(p.shuffle().begin(), p.shuffle().end());
1518 }
1519
operator <<(std::ostream & os,S8x16ShuffleParameter const & p)1520 std::ostream& operator<<(std::ostream& os, S8x16ShuffleParameter const& p) {
1521 for (int i = 0; i < 16; i++) {
1522 const char* separator = (i < 15) ? "," : "";
1523 os << static_cast<uint32_t>(p[i]) << separator;
1524 }
1525 return os;
1526 }
1527
S8x16ShuffleParameterOf(Operator const * op)1528 S8x16ShuffleParameter const& S8x16ShuffleParameterOf(Operator const* op) {
1529 DCHECK_EQ(IrOpcode::kS8x16Shuffle, op->opcode());
1530 return OpParameter<S8x16ShuffleParameter>(op);
1531 }
1532
S8x16Shuffle(const uint8_t shuffle[16])1533 const Operator* MachineOperatorBuilder::S8x16Shuffle(
1534 const uint8_t shuffle[16]) {
1535 return new (zone_) Operator1<S8x16ShuffleParameter>(
1536 IrOpcode::kS8x16Shuffle, Operator::kPure, "Shuffle", 2, 0, 0, 1, 0, 0,
1537 S8x16ShuffleParameter(shuffle));
1538 }
1539
StackCheckKindOf(Operator const * op)1540 StackCheckKind StackCheckKindOf(Operator const* op) {
1541 DCHECK_EQ(IrOpcode::kStackPointerGreaterThan, op->opcode());
1542 return OpParameter<StackCheckKind>(op);
1543 }
1544
1545 #undef PURE_BINARY_OP_LIST_32
1546 #undef PURE_BINARY_OP_LIST_64
1547 #undef MACHINE_PURE_OP_LIST
1548 #undef PURE_OPTIONAL_OP_LIST
1549 #undef OVERFLOW_OP_LIST
1550 #undef MACHINE_TYPE_LIST
1551 #undef MACHINE_REPRESENTATION_LIST
1552 #undef ATOMIC_TYPE_LIST
1553 #undef ATOMIC_U64_TYPE_LIST
1554 #undef ATOMIC_U32_TYPE_LIST
1555 #undef ATOMIC_REPRESENTATION_LIST
1556 #undef ATOMIC64_REPRESENTATION_LIST
1557 #undef SIMD_LANE_OP_LIST
1558 #undef STACK_SLOT_CACHED_SIZES_ALIGNMENTS_LIST
1559 #undef LOAD_TRANSFORM_LIST
1560
1561 } // namespace compiler
1562 } // namespace internal
1563 } // namespace v8
1564