Line data Source code
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 :
15 343 : bool operator==(StoreRepresentation lhs, StoreRepresentation rhs) {
16 686 : return lhs.representation() == rhs.representation() &&
17 686 : lhs.write_barrier_kind() == rhs.write_barrier_kind();
18 : }
19 :
20 :
21 0 : bool operator!=(StoreRepresentation lhs, StoreRepresentation rhs) {
22 0 : return !(lhs == rhs);
23 : }
24 :
25 :
26 0 : size_t hash_value(StoreRepresentation rep) {
27 0 : return base::hash_combine(rep.representation(), rep.write_barrier_kind());
28 : }
29 :
30 :
31 0 : std::ostream& operator<<(std::ostream& os, StoreRepresentation rep) {
32 0 : return os << "(" << rep.representation() << " : " << rep.write_barrier_kind()
33 0 : << ")";
34 : }
35 :
36 :
37 9517729 : LoadRepresentation LoadRepresentationOf(Operator const* op) {
38 : DCHECK(IrOpcode::kLoad == op->opcode() ||
39 : IrOpcode::kProtectedLoad == op->opcode() ||
40 : IrOpcode::kAtomicLoad == op->opcode());
41 9517729 : return OpParameter<LoadRepresentation>(op);
42 : }
43 :
44 :
45 3665224 : StoreRepresentation const& StoreRepresentationOf(Operator const* op) {
46 : DCHECK(IrOpcode::kStore == op->opcode() ||
47 : IrOpcode::kProtectedStore == op->opcode());
48 3665224 : return OpParameter<StoreRepresentation>(op);
49 : }
50 :
51 1 : UnalignedLoadRepresentation UnalignedLoadRepresentationOf(Operator const* op) {
52 : DCHECK_EQ(IrOpcode::kUnalignedLoad, op->opcode());
53 1 : return OpParameter<UnalignedLoadRepresentation>(op);
54 : }
55 :
56 1 : UnalignedStoreRepresentation const& UnalignedStoreRepresentationOf(
57 : Operator const* op) {
58 : DCHECK_EQ(IrOpcode::kUnalignedStore, op->opcode());
59 1 : return OpParameter<UnalignedStoreRepresentation>(op);
60 : }
61 :
62 152428 : CheckedLoadRepresentation CheckedLoadRepresentationOf(Operator const* op) {
63 : DCHECK_EQ(IrOpcode::kCheckedLoad, op->opcode());
64 152428 : return OpParameter<CheckedLoadRepresentation>(op);
65 : }
66 :
67 :
68 109202 : CheckedStoreRepresentation CheckedStoreRepresentationOf(Operator const* op) {
69 : DCHECK_EQ(IrOpcode::kCheckedStore, op->opcode());
70 109202 : return OpParameter<CheckedStoreRepresentation>(op);
71 : }
72 :
73 7 : bool operator==(StackSlotRepresentation lhs, StackSlotRepresentation rhs) {
74 7 : return lhs.size() == rhs.size() && lhs.alignment() == rhs.alignment();
75 : }
76 :
77 0 : bool operator!=(StackSlotRepresentation lhs, StackSlotRepresentation rhs) {
78 0 : return !(lhs == rhs);
79 : }
80 :
81 0 : size_t hash_value(StackSlotRepresentation rep) {
82 0 : return base::hash_combine(rep.size(), rep.alignment());
83 : }
84 :
85 0 : std::ostream& operator<<(std::ostream& os, StackSlotRepresentation rep) {
86 0 : return os << "(" << rep.size() << " : " << rep.alignment() << ")";
87 : }
88 :
89 1177 : StackSlotRepresentation const& StackSlotRepresentationOf(Operator const* op) {
90 : DCHECK_EQ(IrOpcode::kStackSlot, op->opcode());
91 1177 : return OpParameter<StackSlotRepresentation>(op);
92 : }
93 :
94 270 : MachineRepresentation AtomicStoreRepresentationOf(Operator const* op) {
95 : DCHECK_EQ(IrOpcode::kAtomicStore, op->opcode());
96 270 : return OpParameter<MachineRepresentation>(op);
97 : }
98 :
99 5880 : MachineType AtomicOpRepresentationOf(Operator const* op) {
100 5880 : return OpParameter<MachineType>(op);
101 : }
102 :
103 : #define PURE_BINARY_OP_LIST_32(V) \
104 : V(Word32And, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
105 : V(Word32Or, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
106 : V(Word32Xor, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
107 : V(Word32Shl, Operator::kNoProperties, 2, 0, 1) \
108 : V(Word32Shr, Operator::kNoProperties, 2, 0, 1) \
109 : V(Word32Sar, Operator::kNoProperties, 2, 0, 1) \
110 : V(Word32Ror, Operator::kNoProperties, 2, 0, 1) \
111 : V(Word32Equal, Operator::kCommutative, 2, 0, 1) \
112 : V(Int32Add, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
113 : V(Int32Sub, Operator::kNoProperties, 2, 0, 1) \
114 : V(Int32Mul, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
115 : V(Int32MulHigh, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
116 : V(Int32Div, Operator::kNoProperties, 2, 1, 1) \
117 : V(Int32Mod, Operator::kNoProperties, 2, 1, 1) \
118 : V(Int32LessThan, Operator::kNoProperties, 2, 0, 1) \
119 : V(Int32LessThanOrEqual, Operator::kNoProperties, 2, 0, 1) \
120 : V(Uint32Div, Operator::kNoProperties, 2, 1, 1) \
121 : V(Uint32LessThan, Operator::kNoProperties, 2, 0, 1) \
122 : V(Uint32LessThanOrEqual, Operator::kNoProperties, 2, 0, 1) \
123 : V(Uint32Mod, Operator::kNoProperties, 2, 1, 1) \
124 : V(Uint32MulHigh, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)
125 :
126 : #define PURE_BINARY_OP_LIST_64(V) \
127 : V(Word64And, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
128 : V(Word64Or, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
129 : V(Word64Xor, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
130 : V(Word64Shl, Operator::kNoProperties, 2, 0, 1) \
131 : V(Word64Shr, Operator::kNoProperties, 2, 0, 1) \
132 : V(Word64Sar, Operator::kNoProperties, 2, 0, 1) \
133 : V(Word64Ror, Operator::kNoProperties, 2, 0, 1) \
134 : V(Word64Equal, Operator::kCommutative, 2, 0, 1) \
135 : V(Int64Add, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
136 : V(Int64Sub, Operator::kNoProperties, 2, 0, 1) \
137 : V(Int64Mul, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
138 : V(Int64Div, Operator::kNoProperties, 2, 1, 1) \
139 : V(Int64Mod, Operator::kNoProperties, 2, 1, 1) \
140 : V(Int64LessThan, Operator::kNoProperties, 2, 0, 1) \
141 : V(Int64LessThanOrEqual, Operator::kNoProperties, 2, 0, 1) \
142 : V(Uint64Div, Operator::kNoProperties, 2, 1, 1) \
143 : V(Uint64Mod, Operator::kNoProperties, 2, 1, 1) \
144 : V(Uint64LessThan, Operator::kNoProperties, 2, 0, 1) \
145 : V(Uint64LessThanOrEqual, Operator::kNoProperties, 2, 0, 1)
146 :
147 : #define MACHINE_PURE_OP_LIST(V) \
148 : PURE_BINARY_OP_LIST_32(V) \
149 : PURE_BINARY_OP_LIST_64(V) \
150 : V(Word32Clz, Operator::kNoProperties, 1, 0, 1) \
151 : V(Word64Clz, Operator::kNoProperties, 1, 0, 1) \
152 : V(BitcastTaggedToWord, Operator::kNoProperties, 1, 0, 1) \
153 : V(BitcastWordToTaggedSigned, Operator::kNoProperties, 1, 0, 1) \
154 : V(TruncateFloat64ToWord32, Operator::kNoProperties, 1, 0, 1) \
155 : V(ChangeFloat32ToFloat64, Operator::kNoProperties, 1, 0, 1) \
156 : V(ChangeFloat64ToInt32, Operator::kNoProperties, 1, 0, 1) \
157 : V(ChangeFloat64ToUint32, Operator::kNoProperties, 1, 0, 1) \
158 : V(ChangeFloat64ToUint64, Operator::kNoProperties, 1, 0, 1) \
159 : V(TruncateFloat64ToUint32, Operator::kNoProperties, 1, 0, 1) \
160 : V(TruncateFloat32ToInt32, Operator::kNoProperties, 1, 0, 1) \
161 : V(TruncateFloat32ToUint32, Operator::kNoProperties, 1, 0, 1) \
162 : V(TryTruncateFloat32ToInt64, Operator::kNoProperties, 1, 0, 2) \
163 : V(TryTruncateFloat64ToInt64, Operator::kNoProperties, 1, 0, 2) \
164 : V(TryTruncateFloat32ToUint64, Operator::kNoProperties, 1, 0, 2) \
165 : V(TryTruncateFloat64ToUint64, Operator::kNoProperties, 1, 0, 2) \
166 : V(ChangeInt32ToFloat64, Operator::kNoProperties, 1, 0, 1) \
167 : V(Float64SilenceNaN, Operator::kNoProperties, 1, 0, 1) \
168 : V(RoundFloat64ToInt32, Operator::kNoProperties, 1, 0, 1) \
169 : V(RoundInt32ToFloat32, Operator::kNoProperties, 1, 0, 1) \
170 : V(RoundInt64ToFloat32, Operator::kNoProperties, 1, 0, 1) \
171 : V(RoundInt64ToFloat64, Operator::kNoProperties, 1, 0, 1) \
172 : V(RoundUint32ToFloat32, Operator::kNoProperties, 1, 0, 1) \
173 : V(RoundUint64ToFloat32, Operator::kNoProperties, 1, 0, 1) \
174 : V(RoundUint64ToFloat64, Operator::kNoProperties, 1, 0, 1) \
175 : V(ChangeInt32ToInt64, Operator::kNoProperties, 1, 0, 1) \
176 : V(ChangeUint32ToFloat64, Operator::kNoProperties, 1, 0, 1) \
177 : V(ChangeUint32ToUint64, Operator::kNoProperties, 1, 0, 1) \
178 : V(TruncateFloat64ToFloat32, Operator::kNoProperties, 1, 0, 1) \
179 : V(TruncateInt64ToInt32, Operator::kNoProperties, 1, 0, 1) \
180 : V(BitcastFloat32ToInt32, Operator::kNoProperties, 1, 0, 1) \
181 : V(BitcastFloat64ToInt64, Operator::kNoProperties, 1, 0, 1) \
182 : V(BitcastInt32ToFloat32, Operator::kNoProperties, 1, 0, 1) \
183 : V(BitcastInt64ToFloat64, Operator::kNoProperties, 1, 0, 1) \
184 : V(Float32Abs, Operator::kNoProperties, 1, 0, 1) \
185 : V(Float32Add, Operator::kCommutative, 2, 0, 1) \
186 : V(Float32Sub, Operator::kNoProperties, 2, 0, 1) \
187 : V(Float32Mul, Operator::kCommutative, 2, 0, 1) \
188 : V(Float32Div, Operator::kNoProperties, 2, 0, 1) \
189 : V(Float32Neg, Operator::kNoProperties, 1, 0, 1) \
190 : V(Float32Sqrt, Operator::kNoProperties, 1, 0, 1) \
191 : V(Float32Max, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
192 : V(Float32Min, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
193 : V(Float64Abs, Operator::kNoProperties, 1, 0, 1) \
194 : V(Float64Acos, Operator::kNoProperties, 1, 0, 1) \
195 : V(Float64Acosh, Operator::kNoProperties, 1, 0, 1) \
196 : V(Float64Asin, Operator::kNoProperties, 1, 0, 1) \
197 : V(Float64Asinh, Operator::kNoProperties, 1, 0, 1) \
198 : V(Float64Atan, Operator::kNoProperties, 1, 0, 1) \
199 : V(Float64Atan2, Operator::kNoProperties, 2, 0, 1) \
200 : V(Float64Atanh, Operator::kNoProperties, 1, 0, 1) \
201 : V(Float64Cbrt, Operator::kNoProperties, 1, 0, 1) \
202 : V(Float64Cos, Operator::kNoProperties, 1, 0, 1) \
203 : V(Float64Cosh, Operator::kNoProperties, 1, 0, 1) \
204 : V(Float64Exp, Operator::kNoProperties, 1, 0, 1) \
205 : V(Float64Expm1, Operator::kNoProperties, 1, 0, 1) \
206 : V(Float64Log, Operator::kNoProperties, 1, 0, 1) \
207 : V(Float64Log1p, Operator::kNoProperties, 1, 0, 1) \
208 : V(Float64Log2, Operator::kNoProperties, 1, 0, 1) \
209 : V(Float64Log10, Operator::kNoProperties, 1, 0, 1) \
210 : V(Float64Max, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
211 : V(Float64Min, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
212 : V(Float64Neg, Operator::kNoProperties, 1, 0, 1) \
213 : V(Float64Add, Operator::kCommutative, 2, 0, 1) \
214 : V(Float64Sub, Operator::kNoProperties, 2, 0, 1) \
215 : V(Float64Mul, Operator::kCommutative, 2, 0, 1) \
216 : V(Float64Div, Operator::kNoProperties, 2, 0, 1) \
217 : V(Float64Mod, Operator::kNoProperties, 2, 0, 1) \
218 : V(Float64Pow, Operator::kNoProperties, 2, 0, 1) \
219 : V(Float64Sin, Operator::kNoProperties, 1, 0, 1) \
220 : V(Float64Sinh, Operator::kNoProperties, 1, 0, 1) \
221 : V(Float64Sqrt, Operator::kNoProperties, 1, 0, 1) \
222 : V(Float64Tan, Operator::kNoProperties, 1, 0, 1) \
223 : V(Float64Tanh, Operator::kNoProperties, 1, 0, 1) \
224 : V(Float32Equal, Operator::kCommutative, 2, 0, 1) \
225 : V(Float32LessThan, Operator::kNoProperties, 2, 0, 1) \
226 : V(Float32LessThanOrEqual, Operator::kNoProperties, 2, 0, 1) \
227 : V(Float64Equal, Operator::kCommutative, 2, 0, 1) \
228 : V(Float64LessThan, Operator::kNoProperties, 2, 0, 1) \
229 : V(Float64LessThanOrEqual, Operator::kNoProperties, 2, 0, 1) \
230 : V(Float64ExtractLowWord32, Operator::kNoProperties, 1, 0, 1) \
231 : V(Float64ExtractHighWord32, Operator::kNoProperties, 1, 0, 1) \
232 : V(Float64InsertLowWord32, Operator::kNoProperties, 2, 0, 1) \
233 : V(Float64InsertHighWord32, Operator::kNoProperties, 2, 0, 1) \
234 : V(LoadStackPointer, Operator::kNoProperties, 0, 0, 1) \
235 : V(LoadFramePointer, Operator::kNoProperties, 0, 0, 1) \
236 : V(LoadParentFramePointer, Operator::kNoProperties, 0, 0, 1) \
237 : V(Int32PairAdd, Operator::kNoProperties, 4, 0, 2) \
238 : V(Int32PairSub, Operator::kNoProperties, 4, 0, 2) \
239 : V(Int32PairMul, Operator::kNoProperties, 4, 0, 2) \
240 : V(Word32PairShl, Operator::kNoProperties, 3, 0, 2) \
241 : V(Word32PairShr, Operator::kNoProperties, 3, 0, 2) \
242 : V(Word32PairSar, Operator::kNoProperties, 3, 0, 2) \
243 : V(F32x4Splat, Operator::kNoProperties, 1, 0, 1) \
244 : V(F32x4SConvertI32x4, Operator::kNoProperties, 1, 0, 1) \
245 : V(F32x4UConvertI32x4, Operator::kNoProperties, 1, 0, 1) \
246 : V(F32x4Abs, Operator::kNoProperties, 1, 0, 1) \
247 : V(F32x4Neg, Operator::kNoProperties, 1, 0, 1) \
248 : V(F32x4RecipApprox, Operator::kNoProperties, 1, 0, 1) \
249 : V(F32x4RecipSqrtApprox, Operator::kNoProperties, 1, 0, 1) \
250 : V(F32x4Add, Operator::kCommutative, 2, 0, 1) \
251 : V(F32x4AddHoriz, Operator::kNoProperties, 2, 0, 1) \
252 : V(F32x4Sub, Operator::kNoProperties, 2, 0, 1) \
253 : V(F32x4Mul, Operator::kCommutative, 2, 0, 1) \
254 : V(F32x4Min, Operator::kCommutative, 2, 0, 1) \
255 : V(F32x4Max, Operator::kCommutative, 2, 0, 1) \
256 : V(F32x4Eq, Operator::kCommutative, 2, 0, 1) \
257 : V(F32x4Ne, Operator::kCommutative, 2, 0, 1) \
258 : V(F32x4Lt, Operator::kNoProperties, 2, 0, 1) \
259 : V(F32x4Le, Operator::kNoProperties, 2, 0, 1) \
260 : V(I32x4Splat, Operator::kNoProperties, 1, 0, 1) \
261 : V(I32x4SConvertF32x4, Operator::kNoProperties, 1, 0, 1) \
262 : V(I32x4SConvertI16x8Low, Operator::kNoProperties, 1, 0, 1) \
263 : V(I32x4SConvertI16x8High, Operator::kNoProperties, 1, 0, 1) \
264 : V(I32x4Neg, Operator::kNoProperties, 1, 0, 1) \
265 : V(I32x4Add, Operator::kCommutative, 2, 0, 1) \
266 : V(I32x4AddHoriz, Operator::kNoProperties, 2, 0, 1) \
267 : V(I32x4Sub, Operator::kNoProperties, 2, 0, 1) \
268 : V(I32x4Mul, Operator::kCommutative, 2, 0, 1) \
269 : V(I32x4MinS, Operator::kCommutative, 2, 0, 1) \
270 : V(I32x4MaxS, Operator::kCommutative, 2, 0, 1) \
271 : V(I32x4Eq, Operator::kCommutative, 2, 0, 1) \
272 : V(I32x4Ne, Operator::kCommutative, 2, 0, 1) \
273 : V(I32x4GtS, Operator::kNoProperties, 2, 0, 1) \
274 : V(I32x4GeS, Operator::kNoProperties, 2, 0, 1) \
275 : V(I32x4UConvertF32x4, Operator::kNoProperties, 1, 0, 1) \
276 : V(I32x4UConvertI16x8Low, Operator::kNoProperties, 1, 0, 1) \
277 : V(I32x4UConvertI16x8High, Operator::kNoProperties, 1, 0, 1) \
278 : V(I32x4MinU, Operator::kCommutative, 2, 0, 1) \
279 : V(I32x4MaxU, Operator::kCommutative, 2, 0, 1) \
280 : V(I32x4GtU, Operator::kNoProperties, 2, 0, 1) \
281 : V(I32x4GeU, Operator::kNoProperties, 2, 0, 1) \
282 : V(I16x8Splat, Operator::kNoProperties, 1, 0, 1) \
283 : V(I16x8SConvertI8x16Low, Operator::kNoProperties, 1, 0, 1) \
284 : V(I16x8SConvertI8x16High, Operator::kNoProperties, 1, 0, 1) \
285 : V(I16x8Neg, Operator::kNoProperties, 1, 0, 1) \
286 : V(I16x8SConvertI32x4, Operator::kNoProperties, 2, 0, 1) \
287 : V(I16x8Add, Operator::kCommutative, 2, 0, 1) \
288 : V(I16x8AddSaturateS, Operator::kCommutative, 2, 0, 1) \
289 : V(I16x8AddHoriz, Operator::kNoProperties, 2, 0, 1) \
290 : V(I16x8Sub, Operator::kNoProperties, 2, 0, 1) \
291 : V(I16x8SubSaturateS, Operator::kNoProperties, 2, 0, 1) \
292 : V(I16x8Mul, Operator::kCommutative, 2, 0, 1) \
293 : V(I16x8MinS, Operator::kCommutative, 2, 0, 1) \
294 : V(I16x8MaxS, Operator::kCommutative, 2, 0, 1) \
295 : V(I16x8Eq, Operator::kCommutative, 2, 0, 1) \
296 : V(I16x8Ne, Operator::kCommutative, 2, 0, 1) \
297 : V(I16x8GtS, Operator::kNoProperties, 2, 0, 1) \
298 : V(I16x8GeS, Operator::kNoProperties, 2, 0, 1) \
299 : V(I16x8UConvertI8x16Low, Operator::kNoProperties, 1, 0, 1) \
300 : V(I16x8UConvertI8x16High, Operator::kNoProperties, 1, 0, 1) \
301 : V(I16x8UConvertI32x4, Operator::kNoProperties, 2, 0, 1) \
302 : V(I16x8AddSaturateU, Operator::kCommutative, 2, 0, 1) \
303 : V(I16x8SubSaturateU, Operator::kNoProperties, 2, 0, 1) \
304 : V(I16x8MinU, Operator::kCommutative, 2, 0, 1) \
305 : V(I16x8MaxU, Operator::kCommutative, 2, 0, 1) \
306 : V(I16x8GtU, Operator::kNoProperties, 2, 0, 1) \
307 : V(I16x8GeU, Operator::kNoProperties, 2, 0, 1) \
308 : V(I8x16Splat, Operator::kNoProperties, 1, 0, 1) \
309 : V(I8x16Neg, Operator::kNoProperties, 1, 0, 1) \
310 : V(I8x16SConvertI16x8, Operator::kNoProperties, 2, 0, 1) \
311 : V(I8x16Add, Operator::kCommutative, 2, 0, 1) \
312 : V(I8x16AddSaturateS, Operator::kCommutative, 2, 0, 1) \
313 : V(I8x16Sub, Operator::kNoProperties, 2, 0, 1) \
314 : V(I8x16SubSaturateS, Operator::kNoProperties, 2, 0, 1) \
315 : V(I8x16Mul, Operator::kCommutative, 2, 0, 1) \
316 : V(I8x16MinS, Operator::kCommutative, 2, 0, 1) \
317 : V(I8x16MaxS, Operator::kCommutative, 2, 0, 1) \
318 : V(I8x16Eq, Operator::kCommutative, 2, 0, 1) \
319 : V(I8x16Ne, Operator::kCommutative, 2, 0, 1) \
320 : V(I8x16GtS, Operator::kNoProperties, 2, 0, 1) \
321 : V(I8x16GeS, Operator::kNoProperties, 2, 0, 1) \
322 : V(I8x16UConvertI16x8, Operator::kNoProperties, 2, 0, 1) \
323 : V(I8x16AddSaturateU, Operator::kCommutative, 2, 0, 1) \
324 : V(I8x16SubSaturateU, Operator::kNoProperties, 2, 0, 1) \
325 : V(I8x16MinU, Operator::kCommutative, 2, 0, 1) \
326 : V(I8x16MaxU, Operator::kCommutative, 2, 0, 1) \
327 : V(I8x16GtU, Operator::kNoProperties, 2, 0, 1) \
328 : V(I8x16GeU, Operator::kNoProperties, 2, 0, 1) \
329 : V(S128Load, Operator::kNoProperties, 2, 0, 1) \
330 : V(S128Store, Operator::kNoProperties, 3, 0, 1) \
331 : V(S128Zero, Operator::kNoProperties, 0, 0, 1) \
332 : V(S128And, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
333 : V(S128Or, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
334 : V(S128Xor, Operator::kAssociative | Operator::kCommutative, 2, 0, 1) \
335 : V(S128Not, Operator::kNoProperties, 1, 0, 1) \
336 : V(S128Select, Operator::kNoProperties, 3, 0, 1) \
337 : V(S1x4AnyTrue, Operator::kNoProperties, 1, 0, 1) \
338 : V(S1x4AllTrue, Operator::kNoProperties, 1, 0, 1) \
339 : V(S1x8AnyTrue, Operator::kNoProperties, 1, 0, 1) \
340 : V(S1x8AllTrue, Operator::kNoProperties, 1, 0, 1) \
341 : V(S1x16AnyTrue, Operator::kNoProperties, 1, 0, 1) \
342 : V(S1x16AllTrue, Operator::kNoProperties, 1, 0, 1)
343 :
344 : #define PURE_OPTIONAL_OP_LIST(V) \
345 : V(Word32Ctz, Operator::kNoProperties, 1, 0, 1) \
346 : V(Word64Ctz, Operator::kNoProperties, 1, 0, 1) \
347 : V(Word32ReverseBits, Operator::kNoProperties, 1, 0, 1) \
348 : V(Word64ReverseBits, Operator::kNoProperties, 1, 0, 1) \
349 : V(Word32ReverseBytes, Operator::kNoProperties, 1, 0, 1) \
350 : V(Word64ReverseBytes, Operator::kNoProperties, 1, 0, 1) \
351 : V(Int32AbsWithOverflow, Operator::kNoProperties, 1, 0, 1) \
352 : V(Int64AbsWithOverflow, Operator::kNoProperties, 1, 0, 1) \
353 : V(Word32Popcnt, Operator::kNoProperties, 1, 0, 1) \
354 : V(Word64Popcnt, Operator::kNoProperties, 1, 0, 1) \
355 : V(Float32RoundDown, Operator::kNoProperties, 1, 0, 1) \
356 : V(Float64RoundDown, Operator::kNoProperties, 1, 0, 1) \
357 : V(Float32RoundUp, Operator::kNoProperties, 1, 0, 1) \
358 : V(Float64RoundUp, Operator::kNoProperties, 1, 0, 1) \
359 : V(Float32RoundTruncate, Operator::kNoProperties, 1, 0, 1) \
360 : V(Float64RoundTruncate, Operator::kNoProperties, 1, 0, 1) \
361 : V(Float64RoundTiesAway, Operator::kNoProperties, 1, 0, 1) \
362 : V(Float32RoundTiesEven, Operator::kNoProperties, 1, 0, 1) \
363 : V(Float64RoundTiesEven, Operator::kNoProperties, 1, 0, 1)
364 :
365 : #define OVERFLOW_OP_LIST(V) \
366 : V(Int32AddWithOverflow, Operator::kAssociative | Operator::kCommutative) \
367 : V(Int32SubWithOverflow, Operator::kNoProperties) \
368 : V(Int32MulWithOverflow, Operator::kAssociative | Operator::kCommutative) \
369 : V(Int64AddWithOverflow, Operator::kAssociative | Operator::kCommutative) \
370 : V(Int64SubWithOverflow, Operator::kNoProperties)
371 :
372 : #define MACHINE_TYPE_LIST(V) \
373 : V(Float32) \
374 : V(Float64) \
375 : V(Simd128) \
376 : V(Int8) \
377 : V(Uint8) \
378 : V(Int16) \
379 : V(Uint16) \
380 : V(Int32) \
381 : V(Uint32) \
382 : V(Int64) \
383 : V(Uint64) \
384 : V(Pointer) \
385 : V(TaggedSigned) \
386 : V(TaggedPointer) \
387 : V(AnyTagged)
388 :
389 : #define MACHINE_REPRESENTATION_LIST(V) \
390 : V(kFloat32) \
391 : V(kFloat64) \
392 : V(kSimd128) \
393 : V(kWord8) \
394 : V(kWord16) \
395 : V(kWord32) \
396 : V(kWord64) \
397 : V(kTaggedSigned) \
398 : V(kTaggedPointer) \
399 : V(kTagged)
400 :
401 : #define ATOMIC_TYPE_LIST(V) \
402 : V(Int8) \
403 : V(Uint8) \
404 : V(Int16) \
405 : V(Uint16) \
406 : V(Int32) \
407 : V(Uint32)
408 :
409 : #define ATOMIC_REPRESENTATION_LIST(V) \
410 : V(kWord8) \
411 : V(kWord16) \
412 : V(kWord32)
413 :
414 : #define SIMD_LANE_OP_LIST(V) \
415 : V(F32x4, 4) \
416 : V(I32x4, 4) \
417 : V(I16x8, 8) \
418 : V(I8x16, 16)
419 :
420 : #define SIMD_FORMAT_LIST(V) \
421 : V(32x4, 32) \
422 : V(16x8, 16) \
423 : V(8x16, 8)
424 :
425 : #define STACK_SLOT_CACHED_SIZES_ALIGNMENTS_LIST(V) \
426 : V(4, 0) V(8, 0) V(16, 0) V(4, 4) V(8, 8) V(16, 16)
427 :
428 0 : struct StackSlotOperator : public Operator1<StackSlotRepresentation> {
429 168891 : explicit StackSlotOperator(int size, int alignment)
430 : : Operator1<StackSlotRepresentation>(
431 : IrOpcode::kStackSlot, Operator::kNoDeopt | Operator::kNoThrow,
432 : "StackSlot", 0, 0, 0, 1, 0, 0,
433 168891 : StackSlotRepresentation(size, alignment)) {}
434 : };
435 :
436 307967 : struct MachineOperatorGlobalCache {
437 : #define PURE(Name, properties, value_input_count, control_input_count, \
438 : output_count) \
439 : struct Name##Operator final : public Operator { \
440 : Name##Operator() \
441 : : Operator(IrOpcode::k##Name, Operator::kPure | properties, #Name, \
442 : value_input_count, 0, control_input_count, output_count, 0, \
443 : 0) {} \
444 : }; \
445 : Name##Operator k##Name;
446 6523301 : MACHINE_PURE_OP_LIST(PURE)
447 531943 : PURE_OPTIONAL_OP_LIST(PURE)
448 : #undef PURE
449 :
450 : #define OVERFLOW_OP(Name, properties) \
451 : struct Name##Operator final : public Operator { \
452 : Name##Operator() \
453 : : Operator(IrOpcode::k##Name, \
454 : Operator::kEliminatable | Operator::kNoRead | properties, \
455 : #Name, 2, 0, 1, 2, 0, 0) {} \
456 : }; \
457 : Name##Operator k##Name;
458 139985 : OVERFLOW_OP_LIST(OVERFLOW_OP)
459 : #undef OVERFLOW_OP
460 :
461 : #define LOAD(Type) \
462 : struct Load##Type##Operator final : public Operator1<LoadRepresentation> { \
463 : Load##Type##Operator() \
464 : : Operator1<LoadRepresentation>( \
465 : IrOpcode::kLoad, \
466 : Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite, \
467 : "Load", 2, 1, 1, 1, 1, 0, MachineType::Type()) {} \
468 : }; \
469 : struct UnalignedLoad##Type##Operator final \
470 : : public Operator1<UnalignedLoadRepresentation> { \
471 : UnalignedLoad##Type##Operator() \
472 : : Operator1<UnalignedLoadRepresentation>( \
473 : IrOpcode::kUnalignedLoad, \
474 : Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite, \
475 : "UnalignedLoad", 2, 1, 1, 1, 1, 0, MachineType::Type()) {} \
476 : }; \
477 : struct CheckedLoad##Type##Operator final \
478 : : public Operator1<CheckedLoadRepresentation> { \
479 : CheckedLoad##Type##Operator() \
480 : : Operator1<CheckedLoadRepresentation>( \
481 : IrOpcode::kCheckedLoad, \
482 : Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite, \
483 : "CheckedLoad", 3, 1, 1, 1, 1, 0, MachineType::Type()) {} \
484 : }; \
485 : struct ProtectedLoad##Type##Operator final \
486 : : public Operator1<LoadRepresentation> { \
487 : ProtectedLoad##Type##Operator() \
488 : : Operator1<LoadRepresentation>( \
489 : IrOpcode::kProtectedLoad, \
490 : Operator::kNoDeopt | Operator::kNoThrow, "ProtectedLoad", 2, 1, \
491 : 1, 1, 1, 0, MachineType::Type()) {} \
492 : }; \
493 : Load##Type##Operator kLoad##Type; \
494 : UnalignedLoad##Type##Operator kUnalignedLoad##Type; \
495 : CheckedLoad##Type##Operator kCheckedLoad##Type; \
496 : ProtectedLoad##Type##Operator kProtectedLoad##Type;
497 3359640 : MACHINE_TYPE_LIST(LOAD)
498 : #undef LOAD
499 :
500 : #define STACKSLOT(Size, Alignment) \
501 : struct StackSlotOfSize##Size##OfAlignment##Alignment##Operator final \
502 : : public StackSlotOperator { \
503 : StackSlotOfSize##Size##OfAlignment##Alignment##Operator() \
504 : : StackSlotOperator(Size, Alignment) {} \
505 : }; \
506 : StackSlotOfSize##Size##OfAlignment##Alignment##Operator \
507 : kStackSlotOfSize##Size##OfAlignment##Alignment;
508 27997 : STACK_SLOT_CACHED_SIZES_ALIGNMENTS_LIST(STACKSLOT)
509 : #undef STACKSLOT
510 :
511 : #define STORE(Type) \
512 : struct Store##Type##Operator : public Operator1<StoreRepresentation> { \
513 : explicit Store##Type##Operator(WriteBarrierKind write_barrier_kind) \
514 : : Operator1<StoreRepresentation>( \
515 : IrOpcode::kStore, \
516 : Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow, \
517 : "Store", 3, 1, 1, 0, 1, 0, \
518 : StoreRepresentation(MachineRepresentation::Type, \
519 : write_barrier_kind)) {} \
520 : }; \
521 : struct Store##Type##NoWriteBarrier##Operator final \
522 : : public Store##Type##Operator { \
523 : Store##Type##NoWriteBarrier##Operator() \
524 : : Store##Type##Operator(kNoWriteBarrier) {} \
525 : }; \
526 : struct Store##Type##MapWriteBarrier##Operator final \
527 : : public Store##Type##Operator { \
528 : Store##Type##MapWriteBarrier##Operator() \
529 : : Store##Type##Operator(kMapWriteBarrier) {} \
530 : }; \
531 : struct Store##Type##PointerWriteBarrier##Operator final \
532 : : public Store##Type##Operator { \
533 : Store##Type##PointerWriteBarrier##Operator() \
534 : : Store##Type##Operator(kPointerWriteBarrier) {} \
535 : }; \
536 : struct Store##Type##FullWriteBarrier##Operator final \
537 : : public Store##Type##Operator { \
538 : Store##Type##FullWriteBarrier##Operator() \
539 : : Store##Type##Operator(kFullWriteBarrier) {} \
540 : }; \
541 : struct UnalignedStore##Type##Operator final \
542 : : public Operator1<UnalignedStoreRepresentation> { \
543 : UnalignedStore##Type##Operator() \
544 : : Operator1<UnalignedStoreRepresentation>( \
545 : IrOpcode::kUnalignedStore, \
546 : Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow, \
547 : "UnalignedStore", 3, 1, 1, 0, 1, 0, \
548 : MachineRepresentation::Type) {} \
549 : }; \
550 : struct CheckedStore##Type##Operator final \
551 : : public Operator1<CheckedStoreRepresentation> { \
552 : CheckedStore##Type##Operator() \
553 : : Operator1<CheckedStoreRepresentation>( \
554 : IrOpcode::kCheckedStore, \
555 : Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow, \
556 : "CheckedStore", 4, 1, 1, 0, 1, 0, MachineRepresentation::Type) { \
557 : } \
558 : }; \
559 : struct ProtectedStore##Type##Operator \
560 : : public Operator1<StoreRepresentation> { \
561 : explicit ProtectedStore##Type##Operator() \
562 : : Operator1<StoreRepresentation>( \
563 : IrOpcode::kProtectedStore, \
564 : Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow, \
565 : "Store", 3, 1, 1, 0, 1, 0, \
566 : StoreRepresentation(MachineRepresentation::Type, \
567 : kNoWriteBarrier)) {} \
568 : }; \
569 : Store##Type##NoWriteBarrier##Operator kStore##Type##NoWriteBarrier; \
570 : Store##Type##MapWriteBarrier##Operator kStore##Type##MapWriteBarrier; \
571 : Store##Type##PointerWriteBarrier##Operator \
572 : kStore##Type##PointerWriteBarrier; \
573 : Store##Type##FullWriteBarrier##Operator kStore##Type##FullWriteBarrier; \
574 : UnalignedStore##Type##Operator kUnalignedStore##Type; \
575 : CheckedStore##Type##Operator kCheckedStore##Type; \
576 : ProtectedStore##Type##Operator kProtectedStore##Type;
577 4199550 : MACHINE_REPRESENTATION_LIST(STORE)
578 : #undef STORE
579 :
580 : #define ATOMIC_LOAD(Type) \
581 : struct AtomicLoad##Type##Operator final \
582 : : public Operator1<LoadRepresentation> { \
583 : AtomicLoad##Type##Operator() \
584 : : Operator1<LoadRepresentation>( \
585 : IrOpcode::kAtomicLoad, \
586 : Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite, \
587 : "AtomicLoad", 2, 1, 1, 1, 1, 0, MachineType::Type()) {} \
588 : }; \
589 : AtomicLoad##Type##Operator kAtomicLoad##Type;
590 335964 : ATOMIC_TYPE_LIST(ATOMIC_LOAD)
591 : #undef ATOMIC_LOAD
592 :
593 : #define ATOMIC_STORE(Type) \
594 : struct AtomicStore##Type##Operator \
595 : : public Operator1<MachineRepresentation> { \
596 : AtomicStore##Type##Operator() \
597 : : Operator1<MachineRepresentation>( \
598 : IrOpcode::kAtomicStore, \
599 : Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow, \
600 : "AtomicStore", 3, 1, 1, 0, 1, 0, MachineRepresentation::Type) {} \
601 : }; \
602 : AtomicStore##Type##Operator kAtomicStore##Type;
603 167982 : ATOMIC_REPRESENTATION_LIST(ATOMIC_STORE)
604 : #undef STORE
605 :
606 : #define ATOMIC_OP(op, type) \
607 : struct op##type##Operator : public Operator1<MachineType> { \
608 : op##type##Operator() \
609 : : Operator1<MachineType>(IrOpcode::k##op, \
610 : Operator::kNoDeopt | Operator::kNoThrow, #op, \
611 : 3, 1, 1, 1, 1, 0, MachineType::type()) {} \
612 : }; \
613 : op##type##Operator k##op##type;
614 : #define ATOMIC_OP_LIST(type) \
615 : ATOMIC_OP(AtomicExchange, type) \
616 : ATOMIC_OP(AtomicAdd, type) \
617 : ATOMIC_OP(AtomicSub, type) \
618 : ATOMIC_OP(AtomicAnd, type) \
619 : ATOMIC_OP(AtomicOr, type) \
620 : ATOMIC_OP(AtomicXor, type)
621 2015784 : ATOMIC_TYPE_LIST(ATOMIC_OP_LIST)
622 : #undef ATOMIC_OP_LIST
623 : #undef ATOMIC_OP
624 :
625 : #define ATOMIC_COMPARE_EXCHANGE(Type) \
626 : struct AtomicCompareExchange##Type##Operator \
627 : : public Operator1<MachineType> { \
628 : AtomicCompareExchange##Type##Operator() \
629 : : Operator1<MachineType>(IrOpcode::kAtomicCompareExchange, \
630 : Operator::kNoDeopt | Operator::kNoThrow, \
631 : "AtomicCompareExchange", 4, 1, 1, 1, 1, 0, \
632 : MachineType::Type()) {} \
633 : }; \
634 : AtomicCompareExchange##Type##Operator kAtomicCompareExchange##Type;
635 335964 : ATOMIC_TYPE_LIST(ATOMIC_COMPARE_EXCHANGE)
636 : #undef ATOMIC_COMPARE_EXCHANGE
637 :
638 : // The {BitcastWordToTagged} operator must not be marked as pure (especially
639 : // not idempotent), because otherwise the splitting logic in the Scheduler
640 : // might decide to split these operators, thus potentially creating live
641 : // ranges of allocation top across calls or other things that might allocate.
642 : // See https://bugs.chromium.org/p/v8/issues/detail?id=6059 for more details.
643 0 : struct BitcastWordToTaggedOperator : public Operator {
644 27997 : BitcastWordToTaggedOperator()
645 : : Operator(IrOpcode::kBitcastWordToTagged,
646 : Operator::kEliminatable | Operator::kNoWrite,
647 27997 : "BitcastWordToTagged", 1, 0, 0, 1, 0, 0) {}
648 : };
649 : BitcastWordToTaggedOperator kBitcastWordToTagged;
650 :
651 0 : struct DebugAbortOperator : public Operator {
652 27997 : DebugAbortOperator()
653 : : Operator(IrOpcode::kDebugAbort, Operator::kNoThrow, "DebugAbort", 1,
654 27997 : 1, 1, 0, 1, 0) {}
655 : };
656 : DebugAbortOperator kDebugAbort;
657 :
658 0 : struct DebugBreakOperator : public Operator {
659 27997 : DebugBreakOperator()
660 : : Operator(IrOpcode::kDebugBreak, Operator::kNoThrow, "DebugBreak", 0,
661 27997 : 1, 1, 0, 1, 0) {}
662 : };
663 : DebugBreakOperator kDebugBreak;
664 :
665 0 : struct UnsafePointerAddOperator final : public Operator {
666 27997 : UnsafePointerAddOperator()
667 : : Operator(IrOpcode::kUnsafePointerAdd, Operator::kKontrol,
668 27997 : "UnsafePointerAdd", 2, 1, 1, 1, 1, 0) {}
669 : };
670 : UnsafePointerAddOperator kUnsafePointerAdd;
671 : };
672 :
673 0 : struct CommentOperator : public Operator1<const char*> {
674 0 : explicit CommentOperator(const char* msg)
675 : : Operator1<const char*>(IrOpcode::kComment, Operator::kNoThrow,
676 0 : "Comment", 0, 0, 0, 0, 0, 0, msg) {}
677 : };
678 :
679 : static base::LazyInstance<MachineOperatorGlobalCache>::type
680 : kMachineOperatorGlobalCache = LAZY_INSTANCE_INITIALIZER;
681 :
682 1376800 : MachineOperatorBuilder::MachineOperatorBuilder(
683 : Zone* zone, MachineRepresentation word, Flags flags,
684 : AlignmentRequirements alignmentRequirements)
685 : : zone_(zone),
686 : cache_(kMachineOperatorGlobalCache.Get()),
687 : word_(word),
688 : flags_(flags),
689 2753604 : alignment_requirements_(alignmentRequirements) {
690 : DCHECK(word == MachineRepresentation::kWord32 ||
691 : word == MachineRepresentation::kWord64);
692 1376804 : }
693 :
694 2 : const Operator* MachineOperatorBuilder::UnalignedLoad(
695 : UnalignedLoadRepresentation rep) {
696 : #define LOAD(Type) \
697 : if (rep == MachineType::Type()) { \
698 : return &cache_.kUnalignedLoad##Type; \
699 : }
700 18 : MACHINE_TYPE_LIST(LOAD)
701 : #undef LOAD
702 0 : UNREACHABLE();
703 : }
704 :
705 2 : const Operator* MachineOperatorBuilder::UnalignedStore(
706 : UnalignedStoreRepresentation rep) {
707 2 : switch (rep) {
708 : #define STORE(kRep) \
709 : case MachineRepresentation::kRep: \
710 : return &cache_.kUnalignedStore##kRep;
711 0 : MACHINE_REPRESENTATION_LIST(STORE)
712 : #undef STORE
713 : case MachineRepresentation::kBit:
714 : case MachineRepresentation::kNone:
715 : break;
716 : }
717 0 : UNREACHABLE();
718 : }
719 :
720 : #define PURE(Name, properties, value_input_count, control_input_count, \
721 : output_count) \
722 : const Operator* MachineOperatorBuilder::Name() { return &cache_.k##Name; }
723 10824278 : MACHINE_PURE_OP_LIST(PURE)
724 : #undef PURE
725 :
726 : #define PURE(Name, properties, value_input_count, control_input_count, \
727 : output_count) \
728 : const OptionalOperator MachineOperatorBuilder::Name() { \
729 : return OptionalOperator(flags_ & k##Name, &cache_.k##Name); \
730 : }
731 145803 : PURE_OPTIONAL_OP_LIST(PURE)
732 : #undef PURE
733 :
734 : #define OVERFLOW_OP(Name, properties) \
735 : const Operator* MachineOperatorBuilder::Name() { return &cache_.k##Name; }
736 237647 : OVERFLOW_OP_LIST(OVERFLOW_OP)
737 : #undef OVERFLOW_OP
738 :
739 4824527 : const Operator* MachineOperatorBuilder::Load(LoadRepresentation rep) {
740 : #define LOAD(Type) \
741 : if (rep == MachineType::Type()) { \
742 : return &cache_.kLoad##Type; \
743 : }
744 56746200 : MACHINE_TYPE_LIST(LOAD)
745 : #undef LOAD
746 0 : UNREACHABLE();
747 : }
748 :
749 3766 : const Operator* MachineOperatorBuilder::ProtectedLoad(LoadRepresentation rep) {
750 : #define LOAD(Type) \
751 : if (rep == MachineType::Type()) { \
752 : return &cache_.kProtectedLoad##Type; \
753 : }
754 24622 : MACHINE_TYPE_LIST(LOAD)
755 : #undef LOAD
756 0 : UNREACHABLE();
757 : }
758 :
759 1179 : const Operator* MachineOperatorBuilder::StackSlot(int size, int alignment) {
760 : DCHECK_LE(0, size);
761 : DCHECK(alignment == 0 || alignment == 4 || alignment == 8 || alignment == 16);
762 : #define CASE_CACHED_SIZE(Size, Alignment) \
763 : if (size == Size && alignment == Alignment) { \
764 : return &cache_.kStackSlotOfSize##Size##OfAlignment##Alignment; \
765 : }
766 :
767 1179 : STACK_SLOT_CACHED_SIZES_ALIGNMENTS_LIST(CASE_CACHED_SIZE)
768 :
769 : #undef CASE_CACHED_SIZE
770 1818 : return new (zone_) StackSlotOperator(size, alignment);
771 : }
772 :
773 150 : const Operator* MachineOperatorBuilder::StackSlot(MachineRepresentation rep,
774 : int alignment) {
775 150 : return StackSlot(1 << ElementSizeLog2Of(rep), alignment);
776 : }
777 :
778 1915870 : const Operator* MachineOperatorBuilder::Store(StoreRepresentation store_rep) {
779 1915870 : switch (store_rep.representation()) {
780 : #define STORE(kRep) \
781 : case MachineRepresentation::kRep: \
782 : switch (store_rep.write_barrier_kind()) { \
783 : case kNoWriteBarrier: \
784 : return &cache_.k##Store##kRep##NoWriteBarrier; \
785 : case kMapWriteBarrier: \
786 : return &cache_.k##Store##kRep##MapWriteBarrier; \
787 : case kPointerWriteBarrier: \
788 : return &cache_.k##Store##kRep##PointerWriteBarrier; \
789 : case kFullWriteBarrier: \
790 : return &cache_.k##Store##kRep##FullWriteBarrier; \
791 : } \
792 : break;
793 7279 : MACHINE_REPRESENTATION_LIST(STORE)
794 : #undef STORE
795 : case MachineRepresentation::kBit:
796 : case MachineRepresentation::kNone:
797 : break;
798 : }
799 0 : UNREACHABLE();
800 : }
801 :
802 1535 : const Operator* MachineOperatorBuilder::ProtectedStore(
803 : MachineRepresentation rep) {
804 1535 : switch (rep) {
805 : #define STORE(kRep) \
806 : case MachineRepresentation::kRep: \
807 : return &cache_.kProtectedStore##kRep; \
808 : break;
809 60 : MACHINE_REPRESENTATION_LIST(STORE)
810 : #undef STORE
811 : case MachineRepresentation::kBit:
812 : case MachineRepresentation::kNone:
813 : break;
814 : }
815 0 : UNREACHABLE();
816 : }
817 :
818 6587 : const Operator* MachineOperatorBuilder::UnsafePointerAdd() {
819 6587 : return &cache_.kUnsafePointerAdd;
820 : }
821 :
822 175362 : const Operator* MachineOperatorBuilder::BitcastWordToTagged() {
823 175362 : return &cache_.kBitcastWordToTagged;
824 : }
825 :
826 0 : const Operator* MachineOperatorBuilder::DebugAbort() {
827 0 : return &cache_.kDebugAbort;
828 : }
829 :
830 11297 : const Operator* MachineOperatorBuilder::DebugBreak() {
831 11297 : return &cache_.kDebugBreak;
832 : }
833 :
834 0 : const Operator* MachineOperatorBuilder::Comment(const char* msg) {
835 0 : return new (zone_) CommentOperator(msg);
836 : }
837 :
838 76325 : const Operator* MachineOperatorBuilder::CheckedLoad(
839 : CheckedLoadRepresentation rep) {
840 : #define LOAD(Type) \
841 : if (rep == MachineType::Type()) { \
842 : return &cache_.kCheckedLoad##Type; \
843 : }
844 523583 : MACHINE_TYPE_LIST(LOAD)
845 : #undef LOAD
846 0 : UNREACHABLE();
847 : }
848 :
849 :
850 54016 : const Operator* MachineOperatorBuilder::CheckedStore(
851 : CheckedStoreRepresentation rep) {
852 54016 : switch (rep) {
853 : #define STORE(kRep) \
854 : case MachineRepresentation::kRep: \
855 : return &cache_.kCheckedStore##kRep;
856 4615 : MACHINE_REPRESENTATION_LIST(STORE)
857 : #undef STORE
858 : case MachineRepresentation::kBit:
859 : case MachineRepresentation::kNone:
860 : break;
861 : }
862 0 : UNREACHABLE();
863 : }
864 :
865 278 : const Operator* MachineOperatorBuilder::AtomicLoad(LoadRepresentation rep) {
866 : #define LOAD(Type) \
867 : if (rep == MachineType::Type()) { \
868 : return &cache_.kAtomicLoad##Type; \
869 : }
870 1071 : ATOMIC_TYPE_LIST(LOAD)
871 : #undef LOAD
872 0 : UNREACHABLE();
873 : }
874 :
875 177 : const Operator* MachineOperatorBuilder::AtomicStore(MachineRepresentation rep) {
876 : #define STORE(kRep) \
877 : if (rep == MachineRepresentation::kRep) { \
878 : return &cache_.kAtomicStore##kRep; \
879 : }
880 177 : ATOMIC_REPRESENTATION_LIST(STORE)
881 : #undef STORE
882 0 : UNREACHABLE();
883 : }
884 :
885 234 : const Operator* MachineOperatorBuilder::AtomicExchange(MachineType rep) {
886 : #define EXCHANGE(kRep) \
887 : if (rep == MachineType::kRep()) { \
888 : return &cache_.kAtomicExchange##kRep; \
889 : }
890 843 : ATOMIC_TYPE_LIST(EXCHANGE)
891 : #undef EXCHANGE
892 0 : UNREACHABLE();
893 : }
894 :
895 234 : const Operator* MachineOperatorBuilder::AtomicCompareExchange(MachineType rep) {
896 : #define COMPARE_EXCHANGE(kRep) \
897 : if (rep == MachineType::kRep()) { \
898 : return &cache_.kAtomicCompareExchange##kRep; \
899 : }
900 843 : ATOMIC_TYPE_LIST(COMPARE_EXCHANGE)
901 : #undef COMPARE_EXCHANGE
902 0 : UNREACHABLE();
903 : }
904 :
905 234 : const Operator* MachineOperatorBuilder::AtomicAdd(MachineType rep) {
906 : #define ADD(kRep) \
907 : if (rep == MachineType::kRep()) { \
908 : return &cache_.kAtomicAdd##kRep; \
909 : }
910 843 : ATOMIC_TYPE_LIST(ADD)
911 : #undef ADD
912 0 : UNREACHABLE();
913 : }
914 :
915 234 : const Operator* MachineOperatorBuilder::AtomicSub(MachineType rep) {
916 : #define SUB(kRep) \
917 : if (rep == MachineType::kRep()) { \
918 : return &cache_.kAtomicSub##kRep; \
919 : }
920 843 : ATOMIC_TYPE_LIST(SUB)
921 : #undef SUB
922 0 : UNREACHABLE();
923 : }
924 :
925 234 : const Operator* MachineOperatorBuilder::AtomicAnd(MachineType rep) {
926 : #define AND(kRep) \
927 : if (rep == MachineType::kRep()) { \
928 : return &cache_.kAtomicAnd##kRep; \
929 : }
930 843 : ATOMIC_TYPE_LIST(AND)
931 : #undef AND
932 0 : UNREACHABLE();
933 : }
934 :
935 234 : const Operator* MachineOperatorBuilder::AtomicOr(MachineType rep) {
936 : #define OR(kRep) \
937 : if (rep == MachineType::kRep()) { \
938 : return &cache_.kAtomicOr##kRep; \
939 : }
940 843 : ATOMIC_TYPE_LIST(OR)
941 : #undef OR
942 0 : UNREACHABLE();
943 : }
944 :
945 234 : const Operator* MachineOperatorBuilder::AtomicXor(MachineType rep) {
946 : #define XOR(kRep) \
947 : if (rep == MachineType::kRep()) { \
948 : return &cache_.kAtomicXor##kRep; \
949 : }
950 843 : ATOMIC_TYPE_LIST(XOR)
951 : #undef XOR
952 0 : UNREACHABLE();
953 : }
954 :
955 : #define SIMD_LANE_OPS(Type, lane_count) \
956 : const Operator* MachineOperatorBuilder::Type##ExtractLane( \
957 : int32_t lane_index) { \
958 : DCHECK(0 <= lane_index && lane_index < lane_count); \
959 : return new (zone_) \
960 : Operator1<int32_t>(IrOpcode::k##Type##ExtractLane, Operator::kPure, \
961 : "Extract lane", 1, 0, 0, 1, 0, 0, lane_index); \
962 : } \
963 : const Operator* MachineOperatorBuilder::Type##ReplaceLane( \
964 : int32_t lane_index) { \
965 : DCHECK(0 <= lane_index && lane_index < lane_count); \
966 : return new (zone_) \
967 : Operator1<int32_t>(IrOpcode::k##Type##ReplaceLane, Operator::kPure, \
968 : "Replace lane", 2, 0, 0, 1, 0, 0, lane_index); \
969 : }
970 25308 : SIMD_LANE_OP_LIST(SIMD_LANE_OPS)
971 : #undef SIMD_LANE_OPS
972 :
973 : #define SIMD_SHIFT_OPS(format, bits) \
974 : const Operator* MachineOperatorBuilder::I##format##Shl(int32_t shift) { \
975 : DCHECK(0 <= shift && shift < bits); \
976 : return new (zone_) \
977 : Operator1<int32_t>(IrOpcode::kI##format##Shl, Operator::kPure, \
978 : "Shift left", 1, 0, 0, 1, 0, 0, shift); \
979 : } \
980 : const Operator* MachineOperatorBuilder::I##format##ShrS(int32_t shift) { \
981 : DCHECK(0 < shift && shift <= bits); \
982 : return new (zone_) \
983 : Operator1<int32_t>(IrOpcode::kI##format##ShrS, Operator::kPure, \
984 : "Arithmetic shift right", 1, 0, 0, 1, 0, 0, shift); \
985 : } \
986 : const Operator* MachineOperatorBuilder::I##format##ShrU(int32_t shift) { \
987 : DCHECK(0 <= shift && shift < bits); \
988 : return new (zone_) \
989 : Operator1<int32_t>(IrOpcode::kI##format##ShrU, Operator::kPure, \
990 : "Shift right", 1, 0, 0, 1, 0, 0, shift); \
991 : }
992 144 : SIMD_FORMAT_LIST(SIMD_SHIFT_OPS)
993 : #undef SIMD_SHIFT_OPS
994 :
995 0 : const Operator* MachineOperatorBuilder::S8x16Shuffle(
996 : const uint8_t shuffle[16]) {
997 0 : uint8_t* array = zone_->NewArray<uint8_t>(16);
998 : memcpy(array, shuffle, 16);
999 : return new (zone_)
1000 : Operator1<uint8_t*>(IrOpcode::kS8x16Shuffle, Operator::kPure, "Shuffle",
1001 0 : 2, 0, 0, 1, 0, 0, array);
1002 : }
1003 :
1004 : } // namespace compiler
1005 : } // namespace internal
1006 : } // namespace v8
|