Line data Source code
1 : // Copyright 2013 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 : #ifndef V8_COMPILER_MACHINE_OPERATOR_H_
6 : #define V8_COMPILER_MACHINE_OPERATOR_H_
7 :
8 : #include "src/base/compiler-specific.h"
9 : #include "src/base/enum-set.h"
10 : #include "src/base/flags.h"
11 : #include "src/globals.h"
12 : #include "src/machine-type.h"
13 : #include "src/zone/zone.h"
14 :
15 : namespace v8 {
16 : namespace internal {
17 : namespace compiler {
18 :
19 : // Forward declarations.
20 : struct MachineOperatorGlobalCache;
21 : class Operator;
22 :
23 :
24 : // For operators that are not supported on all platforms.
25 : class OptionalOperator final {
26 : public:
27 : OptionalOperator(bool supported, const Operator* op)
28 101158 : : supported_(supported), op_(op) {}
29 :
30 : bool IsSupported() const { return supported_; }
31 : // Gets the operator only if it is supported.
32 : const Operator* op() const {
33 : DCHECK(supported_);
34 : return op_;
35 : }
36 : // Always gets the operator, even for unsupported operators. This is useful to
37 : // use the operator as a placeholder in a graph, for instance.
38 : const Operator* placeholder() const { return op_; }
39 :
40 : private:
41 : bool supported_;
42 : const Operator* const op_;
43 : };
44 :
45 :
46 : // A Load needs a MachineType.
47 : typedef MachineType LoadRepresentation;
48 :
49 : V8_EXPORT_PRIVATE LoadRepresentation LoadRepresentationOf(Operator const*)
50 : V8_WARN_UNUSED_RESULT;
51 :
52 : // A Store needs a MachineType and a WriteBarrierKind in order to emit the
53 : // correct write barrier.
54 : class StoreRepresentation final {
55 : public:
56 : StoreRepresentation(MachineRepresentation representation,
57 : WriteBarrierKind write_barrier_kind)
58 : : representation_(representation),
59 4334641 : write_barrier_kind_(write_barrier_kind) {}
60 :
61 : MachineRepresentation representation() const { return representation_; }
62 : WriteBarrierKind write_barrier_kind() const { return write_barrier_kind_; }
63 :
64 : private:
65 : MachineRepresentation representation_;
66 : WriteBarrierKind write_barrier_kind_;
67 : };
68 :
69 : V8_EXPORT_PRIVATE bool operator==(StoreRepresentation, StoreRepresentation);
70 : bool operator!=(StoreRepresentation, StoreRepresentation);
71 :
72 : size_t hash_value(StoreRepresentation);
73 :
74 : V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, StoreRepresentation);
75 :
76 : V8_EXPORT_PRIVATE StoreRepresentation const& StoreRepresentationOf(
77 : Operator const*) V8_WARN_UNUSED_RESULT;
78 :
79 : // An UnalignedStore needs a MachineType.
80 : typedef MachineRepresentation UnalignedStoreRepresentation;
81 :
82 : UnalignedStoreRepresentation const& UnalignedStoreRepresentationOf(
83 : Operator const*) V8_WARN_UNUSED_RESULT;
84 :
85 : class StackSlotRepresentation final {
86 : public:
87 : StackSlotRepresentation(int size, int alignment)
88 2 : : size_(size), alignment_(alignment) {}
89 :
90 : int size() const { return size_; }
91 : int alignment() const { return alignment_; }
92 :
93 : private:
94 : int size_;
95 : int alignment_;
96 : };
97 :
98 : V8_EXPORT_PRIVATE bool operator==(StackSlotRepresentation,
99 : StackSlotRepresentation);
100 : bool operator!=(StackSlotRepresentation, StackSlotRepresentation);
101 :
102 : size_t hash_value(StackSlotRepresentation);
103 :
104 : V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&,
105 : StackSlotRepresentation);
106 :
107 : V8_EXPORT_PRIVATE StackSlotRepresentation const& StackSlotRepresentationOf(
108 : Operator const* op) V8_WARN_UNUSED_RESULT;
109 :
110 : MachineRepresentation AtomicStoreRepresentationOf(Operator const* op)
111 : V8_WARN_UNUSED_RESULT;
112 :
113 : MachineType AtomicOpType(Operator const* op) V8_WARN_UNUSED_RESULT;
114 :
115 : // Interface for building machine-level operators. These operators are
116 : // machine-level but machine-independent and thus define a language suitable
117 : // for generating code to run on architectures such as ia32, x64, arm, etc.
118 : class V8_EXPORT_PRIVATE MachineOperatorBuilder final
119 : : public NON_EXPORTED_BASE(ZoneObject) {
120 : public:
121 : // Flags that specify which operations are available. This is useful
122 : // for operations that are unsupported by some back-ends.
123 : enum Flag : unsigned {
124 : kNoFlags = 0u,
125 : kFloat32RoundDown = 1u << 0,
126 : kFloat64RoundDown = 1u << 1,
127 : kFloat32RoundUp = 1u << 2,
128 : kFloat64RoundUp = 1u << 3,
129 : kFloat32RoundTruncate = 1u << 4,
130 : kFloat64RoundTruncate = 1u << 5,
131 : kFloat32RoundTiesEven = 1u << 6,
132 : kFloat64RoundTiesEven = 1u << 7,
133 : kFloat64RoundTiesAway = 1u << 8,
134 : kInt32DivIsSafe = 1u << 9,
135 : kUint32DivIsSafe = 1u << 10,
136 : kWord32ShiftIsSafe = 1u << 11,
137 : kWord32Ctz = 1u << 12,
138 : kWord64Ctz = 1u << 13,
139 : kWord32Popcnt = 1u << 14,
140 : kWord64Popcnt = 1u << 15,
141 : kWord32ReverseBits = 1u << 16,
142 : kWord64ReverseBits = 1u << 17,
143 : kInt32AbsWithOverflow = 1u << 20,
144 : kInt64AbsWithOverflow = 1u << 21,
145 : kAllOptionalOps = kFloat32RoundDown | kFloat64RoundDown | kFloat32RoundUp |
146 : kFloat64RoundUp | kFloat32RoundTruncate |
147 : kFloat64RoundTruncate | kFloat64RoundTiesAway |
148 : kFloat32RoundTiesEven | kFloat64RoundTiesEven |
149 : kWord32Ctz | kWord64Ctz | kWord32Popcnt | kWord64Popcnt |
150 : kWord32ReverseBits | kWord64ReverseBits |
151 : kInt32AbsWithOverflow | kInt64AbsWithOverflow
152 : };
153 : typedef base::Flags<Flag, unsigned> Flags;
154 :
155 : class AlignmentRequirements {
156 : public:
157 : enum UnalignedAccessSupport { kNoSupport, kSomeSupport, kFullSupport };
158 :
159 : bool IsUnalignedLoadSupported(MachineRepresentation rep) const {
160 102230 : return IsUnalignedSupported(unalignedLoadUnsupportedTypes_, rep);
161 : }
162 :
163 : bool IsUnalignedStoreSupported(MachineRepresentation rep) const {
164 146891 : return IsUnalignedSupported(unalignedStoreUnsupportedTypes_, rep);
165 : }
166 :
167 : static AlignmentRequirements FullUnalignedAccessSupport() {
168 : return AlignmentRequirements(kFullSupport);
169 : }
170 : static AlignmentRequirements NoUnalignedAccessSupport() {
171 : return AlignmentRequirements(kNoSupport);
172 : }
173 : static AlignmentRequirements SomeUnalignedAccessUnsupported(
174 : base::EnumSet<MachineRepresentation> unalignedLoadUnsupportedTypes,
175 : base::EnumSet<MachineRepresentation> unalignedStoreUnsupportedTypes) {
176 : return AlignmentRequirements(kSomeSupport, unalignedLoadUnsupportedTypes,
177 : unalignedStoreUnsupportedTypes);
178 : }
179 :
180 : private:
181 : explicit AlignmentRequirements(
182 : AlignmentRequirements::UnalignedAccessSupport unalignedAccessSupport,
183 : base::EnumSet<MachineRepresentation> unalignedLoadUnsupportedTypes =
184 : base::EnumSet<MachineRepresentation>(),
185 : base::EnumSet<MachineRepresentation> unalignedStoreUnsupportedTypes =
186 : base::EnumSet<MachineRepresentation>())
187 : : unalignedSupport_(unalignedAccessSupport),
188 : unalignedLoadUnsupportedTypes_(unalignedLoadUnsupportedTypes),
189 : unalignedStoreUnsupportedTypes_(unalignedStoreUnsupportedTypes) {}
190 :
191 248956 : bool IsUnalignedSupported(base::EnumSet<MachineRepresentation> unsupported,
192 : MachineRepresentation rep) const {
193 : // All accesses of bytes in memory are aligned.
194 : DCHECK_NE(MachineRepresentation::kWord8, rep);
195 248956 : switch (unalignedSupport_) {
196 : case kFullSupport:
197 : return true;
198 : case kNoSupport:
199 : return false;
200 : case kSomeSupport:
201 0 : return !unsupported.contains(rep);
202 : }
203 0 : UNREACHABLE();
204 : }
205 :
206 : const AlignmentRequirements::UnalignedAccessSupport unalignedSupport_;
207 : const base::EnumSet<MachineRepresentation> unalignedLoadUnsupportedTypes_;
208 : const base::EnumSet<MachineRepresentation> unalignedStoreUnsupportedTypes_;
209 : };
210 :
211 : explicit MachineOperatorBuilder(
212 : Zone* zone,
213 : MachineRepresentation word = MachineType::PointerRepresentation(),
214 : Flags supportedOperators = kNoFlags,
215 : AlignmentRequirements alignmentRequirements =
216 : AlignmentRequirements::FullUnalignedAccessSupport());
217 :
218 : const Operator* Comment(const char* msg);
219 : const Operator* DebugAbort();
220 : const Operator* DebugBreak();
221 : const Operator* UnsafePointerAdd();
222 :
223 : const Operator* Word32And();
224 : const Operator* Word32Or();
225 : const Operator* Word32Xor();
226 : const Operator* Word32Shl();
227 : const Operator* Word32Shr();
228 : const Operator* Word32Sar();
229 : const Operator* Word32Ror();
230 : const Operator* Word32Equal();
231 : const Operator* Word32Clz();
232 : const OptionalOperator Word32Ctz();
233 : const OptionalOperator Word32Popcnt();
234 : const OptionalOperator Word64Popcnt();
235 : const OptionalOperator Word32ReverseBits();
236 : const OptionalOperator Word64ReverseBits();
237 : const Operator* Word32ReverseBytes();
238 : const Operator* Word64ReverseBytes();
239 : const OptionalOperator Int32AbsWithOverflow();
240 : const OptionalOperator Int64AbsWithOverflow();
241 :
242 : // Return true if the target's Word32 shift implementation is directly
243 : // compatible with JavaScript's specification. Otherwise, we have to manually
244 : // generate a mask with 0x1f on the amount ahead of generating the shift.
245 1176 : bool Word32ShiftIsSafe() const { return flags_ & kWord32ShiftIsSafe; }
246 :
247 : const Operator* Word64And();
248 : const Operator* Word64Or();
249 : const Operator* Word64Xor();
250 : const Operator* Word64Shl();
251 : const Operator* Word64Shr();
252 : const Operator* Word64Sar();
253 : const Operator* Word64Ror();
254 : const Operator* Word64Clz();
255 : const OptionalOperator Word64Ctz();
256 : const Operator* Word64Equal();
257 :
258 : const Operator* Int32PairAdd();
259 : const Operator* Int32PairSub();
260 : const Operator* Int32PairMul();
261 : const Operator* Word32PairShl();
262 : const Operator* Word32PairShr();
263 : const Operator* Word32PairSar();
264 :
265 : const Operator* Int32Add();
266 : const Operator* Int32AddWithOverflow();
267 : const Operator* Int32Sub();
268 : const Operator* Int32SubWithOverflow();
269 : const Operator* Int32Mul();
270 : const Operator* Int32MulWithOverflow();
271 : const Operator* Int32MulHigh();
272 : const Operator* Int32Div();
273 : const Operator* Int32Mod();
274 : const Operator* Int32LessThan();
275 : const Operator* Int32LessThanOrEqual();
276 : const Operator* Uint32Div();
277 : const Operator* Uint32LessThan();
278 : const Operator* Uint32LessThanOrEqual();
279 : const Operator* Uint32Mod();
280 : const Operator* Uint32MulHigh();
281 : bool Int32DivIsSafe() const { return flags_ & kInt32DivIsSafe; }
282 : bool Uint32DivIsSafe() const { return flags_ & kUint32DivIsSafe; }
283 :
284 : const Operator* Int64Add();
285 : const Operator* Int64AddWithOverflow();
286 : const Operator* Int64Sub();
287 : const Operator* Int64SubWithOverflow();
288 : const Operator* Int64Mul();
289 : const Operator* Int64Div();
290 : const Operator* Int64Mod();
291 : const Operator* Int64LessThan();
292 : const Operator* Int64LessThanOrEqual();
293 : const Operator* Uint64Div();
294 : const Operator* Uint64LessThan();
295 : const Operator* Uint64LessThanOrEqual();
296 : const Operator* Uint64Mod();
297 :
298 : // This operator reinterprets the bits of a tagged pointer as word.
299 : const Operator* BitcastTaggedToWord();
300 :
301 : // This operator reinterprets the bits of a tagged MaybeObject pointer as
302 : // word.
303 : const Operator* BitcastMaybeObjectToWord();
304 :
305 : // This operator reinterprets the bits of a word as tagged pointer.
306 : const Operator* BitcastWordToTagged();
307 :
308 : // This operator reinterprets the bits of a word as a Smi.
309 : const Operator* BitcastWordToTaggedSigned();
310 :
311 : // JavaScript float64 to int32/uint32 truncation.
312 : const Operator* TruncateFloat64ToWord32();
313 :
314 : // These operators change the representation of numbers while preserving the
315 : // value of the number. Narrowing operators assume the input is representable
316 : // in the target type and are *not* defined for other inputs.
317 : // Use narrowing change operators only when there is a static guarantee that
318 : // the input value is representable in the target value.
319 : const Operator* ChangeFloat32ToFloat64();
320 : const Operator* ChangeFloat64ToInt32(); // narrowing
321 : const Operator* ChangeFloat64ToInt64();
322 : const Operator* ChangeFloat64ToUint32(); // narrowing
323 : const Operator* ChangeFloat64ToUint64();
324 : const Operator* TruncateFloat64ToInt64();
325 : const Operator* TruncateFloat64ToUint32();
326 : const Operator* TruncateFloat32ToInt32();
327 : const Operator* TruncateFloat32ToUint32();
328 : const Operator* TryTruncateFloat32ToInt64();
329 : const Operator* TryTruncateFloat64ToInt64();
330 : const Operator* TryTruncateFloat32ToUint64();
331 : const Operator* TryTruncateFloat64ToUint64();
332 : const Operator* ChangeInt32ToFloat64();
333 : const Operator* ChangeInt32ToInt64();
334 : const Operator* ChangeInt64ToFloat64();
335 : const Operator* ChangeUint32ToFloat64();
336 : const Operator* ChangeUint32ToUint64();
337 : const Operator* ChangeTaggedToCompressed();
338 : const Operator* ChangeTaggedPointerToCompressedPointer();
339 : const Operator* ChangeTaggedSignedToCompressedSigned();
340 : const Operator* ChangeCompressedToTagged();
341 : const Operator* ChangeCompressedPointerToTaggedPointer();
342 : const Operator* ChangeCompressedSignedToTaggedSigned();
343 :
344 : // These operators truncate or round numbers, both changing the representation
345 : // of the number and mapping multiple input values onto the same output value.
346 : const Operator* TruncateFloat64ToFloat32();
347 : const Operator* TruncateInt64ToInt32();
348 : const Operator* RoundFloat64ToInt32();
349 : const Operator* RoundInt32ToFloat32();
350 : const Operator* RoundInt64ToFloat32();
351 : const Operator* RoundInt64ToFloat64();
352 : const Operator* RoundUint32ToFloat32();
353 : const Operator* RoundUint64ToFloat32();
354 : const Operator* RoundUint64ToFloat64();
355 :
356 : // These operators reinterpret the bits of a floating point number as an
357 : // integer and vice versa.
358 : const Operator* BitcastFloat32ToInt32();
359 : const Operator* BitcastFloat64ToInt64();
360 : const Operator* BitcastInt32ToFloat32();
361 : const Operator* BitcastInt64ToFloat64();
362 :
363 : // These operators sign-extend to Int32/Int64
364 : const Operator* SignExtendWord8ToInt32();
365 : const Operator* SignExtendWord16ToInt32();
366 : const Operator* SignExtendWord8ToInt64();
367 : const Operator* SignExtendWord16ToInt64();
368 : const Operator* SignExtendWord32ToInt64();
369 :
370 : // Floating point operators always operate with IEEE 754 round-to-nearest
371 : // (single-precision).
372 : const Operator* Float32Add();
373 : const Operator* Float32Sub();
374 : const Operator* Float32Mul();
375 : const Operator* Float32Div();
376 : const Operator* Float32Sqrt();
377 :
378 : // Floating point operators always operate with IEEE 754 round-to-nearest
379 : // (double-precision).
380 : const Operator* Float64Add();
381 : const Operator* Float64Sub();
382 : const Operator* Float64Mul();
383 : const Operator* Float64Div();
384 : const Operator* Float64Mod();
385 : const Operator* Float64Sqrt();
386 :
387 : // Floating point comparisons complying to IEEE 754 (single-precision).
388 : const Operator* Float32Equal();
389 : const Operator* Float32LessThan();
390 : const Operator* Float32LessThanOrEqual();
391 :
392 : // Floating point comparisons complying to IEEE 754 (double-precision).
393 : const Operator* Float64Equal();
394 : const Operator* Float64LessThan();
395 : const Operator* Float64LessThanOrEqual();
396 :
397 : // Floating point min/max complying to EcmaScript 6 (double-precision).
398 : const Operator* Float64Max();
399 : const Operator* Float64Min();
400 : // Floating point min/max complying to WebAssembly (single-precision).
401 : const Operator* Float32Max();
402 : const Operator* Float32Min();
403 :
404 : // Floating point abs complying to IEEE 754 (single-precision).
405 : const Operator* Float32Abs();
406 :
407 : // Floating point abs complying to IEEE 754 (double-precision).
408 : const Operator* Float64Abs();
409 :
410 : // Floating point rounding.
411 : const OptionalOperator Float32RoundDown();
412 : const OptionalOperator Float64RoundDown();
413 : const OptionalOperator Float32RoundUp();
414 : const OptionalOperator Float64RoundUp();
415 : const OptionalOperator Float32RoundTruncate();
416 : const OptionalOperator Float64RoundTruncate();
417 : const OptionalOperator Float64RoundTiesAway();
418 : const OptionalOperator Float32RoundTiesEven();
419 : const OptionalOperator Float64RoundTiesEven();
420 :
421 : // Floating point neg.
422 : const Operator* Float32Neg();
423 : const Operator* Float64Neg();
424 :
425 : // Floating point trigonometric functions (double-precision).
426 : const Operator* Float64Acos();
427 : const Operator* Float64Acosh();
428 : const Operator* Float64Asin();
429 : const Operator* Float64Asinh();
430 : const Operator* Float64Atan();
431 : const Operator* Float64Atan2();
432 : const Operator* Float64Atanh();
433 : const Operator* Float64Cos();
434 : const Operator* Float64Cosh();
435 : const Operator* Float64Sin();
436 : const Operator* Float64Sinh();
437 : const Operator* Float64Tan();
438 : const Operator* Float64Tanh();
439 :
440 : // Floating point exponential functions (double-precision).
441 : const Operator* Float64Exp();
442 : const Operator* Float64Expm1();
443 : const Operator* Float64Pow();
444 :
445 : // Floating point logarithm (double-precision).
446 : const Operator* Float64Log();
447 : const Operator* Float64Log1p();
448 : const Operator* Float64Log2();
449 : const Operator* Float64Log10();
450 :
451 : // Floating point cube root (double-precision).
452 : const Operator* Float64Cbrt();
453 :
454 : // Floating point bit representation.
455 : const Operator* Float64ExtractLowWord32();
456 : const Operator* Float64ExtractHighWord32();
457 : const Operator* Float64InsertLowWord32();
458 : const Operator* Float64InsertHighWord32();
459 :
460 : // Change signalling NaN to quiet NaN.
461 : // Identity for any input that is not signalling NaN.
462 : const Operator* Float64SilenceNaN();
463 :
464 : // SIMD operators.
465 : const Operator* F32x4Splat();
466 : const Operator* F32x4ExtractLane(int32_t);
467 : const Operator* F32x4ReplaceLane(int32_t);
468 : const Operator* F32x4SConvertI32x4();
469 : const Operator* F32x4UConvertI32x4();
470 : const Operator* F32x4Abs();
471 : const Operator* F32x4Neg();
472 : const Operator* F32x4RecipApprox();
473 : const Operator* F32x4RecipSqrtApprox();
474 : const Operator* F32x4Add();
475 : const Operator* F32x4AddHoriz();
476 : const Operator* F32x4Sub();
477 : const Operator* F32x4Mul();
478 : const Operator* F32x4Div();
479 : const Operator* F32x4Min();
480 : const Operator* F32x4Max();
481 : const Operator* F32x4Eq();
482 : const Operator* F32x4Ne();
483 : const Operator* F32x4Lt();
484 : const Operator* F32x4Le();
485 :
486 : const Operator* I32x4Splat();
487 : const Operator* I32x4ExtractLane(int32_t);
488 : const Operator* I32x4ReplaceLane(int32_t);
489 : const Operator* I32x4SConvertF32x4();
490 : const Operator* I32x4SConvertI16x8Low();
491 : const Operator* I32x4SConvertI16x8High();
492 : const Operator* I32x4Neg();
493 : const Operator* I32x4Shl(int32_t);
494 : const Operator* I32x4ShrS(int32_t);
495 : const Operator* I32x4Add();
496 : const Operator* I32x4AddHoriz();
497 : const Operator* I32x4Sub();
498 : const Operator* I32x4Mul();
499 : const Operator* I32x4MinS();
500 : const Operator* I32x4MaxS();
501 : const Operator* I32x4Eq();
502 : const Operator* I32x4Ne();
503 : const Operator* I32x4GtS();
504 : const Operator* I32x4GeS();
505 :
506 : const Operator* I32x4UConvertF32x4();
507 : const Operator* I32x4UConvertI16x8Low();
508 : const Operator* I32x4UConvertI16x8High();
509 : const Operator* I32x4ShrU(int32_t);
510 : const Operator* I32x4MinU();
511 : const Operator* I32x4MaxU();
512 : const Operator* I32x4GtU();
513 : const Operator* I32x4GeU();
514 :
515 : const Operator* I16x8Splat();
516 : const Operator* I16x8ExtractLane(int32_t);
517 : const Operator* I16x8ReplaceLane(int32_t);
518 : const Operator* I16x8SConvertI8x16Low();
519 : const Operator* I16x8SConvertI8x16High();
520 : const Operator* I16x8Neg();
521 : const Operator* I16x8Shl(int32_t);
522 : const Operator* I16x8ShrS(int32_t);
523 : const Operator* I16x8SConvertI32x4();
524 : const Operator* I16x8Add();
525 : const Operator* I16x8AddSaturateS();
526 : const Operator* I16x8AddHoriz();
527 : const Operator* I16x8Sub();
528 : const Operator* I16x8SubSaturateS();
529 : const Operator* I16x8Mul();
530 : const Operator* I16x8MinS();
531 : const Operator* I16x8MaxS();
532 : const Operator* I16x8Eq();
533 : const Operator* I16x8Ne();
534 : const Operator* I16x8GtS();
535 : const Operator* I16x8GeS();
536 :
537 : const Operator* I16x8UConvertI8x16Low();
538 : const Operator* I16x8UConvertI8x16High();
539 : const Operator* I16x8ShrU(int32_t);
540 : const Operator* I16x8UConvertI32x4();
541 : const Operator* I16x8AddSaturateU();
542 : const Operator* I16x8SubSaturateU();
543 : const Operator* I16x8MinU();
544 : const Operator* I16x8MaxU();
545 : const Operator* I16x8GtU();
546 : const Operator* I16x8GeU();
547 :
548 : const Operator* I8x16Splat();
549 : const Operator* I8x16ExtractLane(int32_t);
550 : const Operator* I8x16ReplaceLane(int32_t);
551 : const Operator* I8x16Neg();
552 : const Operator* I8x16Shl(int32_t);
553 : const Operator* I8x16ShrS(int32_t);
554 : const Operator* I8x16SConvertI16x8();
555 : const Operator* I8x16Add();
556 : const Operator* I8x16AddSaturateS();
557 : const Operator* I8x16Sub();
558 : const Operator* I8x16SubSaturateS();
559 : const Operator* I8x16Mul();
560 : const Operator* I8x16MinS();
561 : const Operator* I8x16MaxS();
562 : const Operator* I8x16Eq();
563 : const Operator* I8x16Ne();
564 : const Operator* I8x16GtS();
565 : const Operator* I8x16GeS();
566 :
567 : const Operator* I8x16ShrU(int32_t);
568 : const Operator* I8x16UConvertI16x8();
569 : const Operator* I8x16AddSaturateU();
570 : const Operator* I8x16SubSaturateU();
571 : const Operator* I8x16MinU();
572 : const Operator* I8x16MaxU();
573 : const Operator* I8x16GtU();
574 : const Operator* I8x16GeU();
575 :
576 : const Operator* S128Load();
577 : const Operator* S128Store();
578 :
579 : const Operator* S128Zero();
580 : const Operator* S128And();
581 : const Operator* S128Or();
582 : const Operator* S128Xor();
583 : const Operator* S128Not();
584 : const Operator* S128Select();
585 :
586 : const Operator* S8x16Shuffle(const uint8_t shuffle[16]);
587 :
588 : const Operator* S1x4AnyTrue();
589 : const Operator* S1x4AllTrue();
590 : const Operator* S1x8AnyTrue();
591 : const Operator* S1x8AllTrue();
592 : const Operator* S1x16AnyTrue();
593 : const Operator* S1x16AllTrue();
594 :
595 : // load [base + index]
596 : const Operator* Load(LoadRepresentation rep);
597 : const Operator* PoisonedLoad(LoadRepresentation rep);
598 : const Operator* ProtectedLoad(LoadRepresentation rep);
599 :
600 : // store [base + index], value
601 : const Operator* Store(StoreRepresentation rep);
602 : const Operator* ProtectedStore(MachineRepresentation rep);
603 :
604 : // unaligned load [base + index]
605 : const Operator* UnalignedLoad(LoadRepresentation rep);
606 :
607 : // unaligned store [base + index], value
608 : const Operator* UnalignedStore(UnalignedStoreRepresentation rep);
609 :
610 : const Operator* StackSlot(int size, int alignment = 0);
611 : const Operator* StackSlot(MachineRepresentation rep, int alignment = 0);
612 :
613 : // Destroy value by masking when misspeculating.
614 : const Operator* TaggedPoisonOnSpeculation();
615 : const Operator* Word32PoisonOnSpeculation();
616 : const Operator* Word64PoisonOnSpeculation();
617 :
618 : // Access to the machine stack.
619 : const Operator* LoadStackPointer();
620 : const Operator* LoadFramePointer();
621 : const Operator* LoadParentFramePointer();
622 :
623 : // atomic-load [base + index]
624 : const Operator* Word32AtomicLoad(LoadRepresentation rep);
625 : // atomic-load [base + index]
626 : const Operator* Word64AtomicLoad(LoadRepresentation rep);
627 : // atomic-store [base + index], value
628 : const Operator* Word32AtomicStore(MachineRepresentation rep);
629 : // atomic-store [base + index], value
630 : const Operator* Word64AtomicStore(MachineRepresentation rep);
631 : // atomic-exchange [base + index], value
632 : const Operator* Word32AtomicExchange(MachineType type);
633 : // atomic-exchange [base + index], value
634 : const Operator* Word64AtomicExchange(MachineType type);
635 : // atomic-compare-exchange [base + index], old_value, new_value
636 : const Operator* Word32AtomicCompareExchange(MachineType type);
637 : // atomic-compare-exchange [base + index], old_value, new_value
638 : const Operator* Word64AtomicCompareExchange(MachineType type);
639 : // atomic-add [base + index], value
640 : const Operator* Word32AtomicAdd(MachineType type);
641 : // atomic-sub [base + index], value
642 : const Operator* Word32AtomicSub(MachineType type);
643 : // atomic-and [base + index], value
644 : const Operator* Word32AtomicAnd(MachineType type);
645 : // atomic-or [base + index], value
646 : const Operator* Word32AtomicOr(MachineType type);
647 : // atomic-xor [base + index], value
648 : const Operator* Word32AtomicXor(MachineType rep);
649 : // atomic-add [base + index], value
650 : const Operator* Word64AtomicAdd(MachineType rep);
651 : // atomic-sub [base + index], value
652 : const Operator* Word64AtomicSub(MachineType type);
653 : // atomic-and [base + index], value
654 : const Operator* Word64AtomicAnd(MachineType type);
655 : // atomic-or [base + index], value
656 : const Operator* Word64AtomicOr(MachineType type);
657 : // atomic-xor [base + index], value
658 : const Operator* Word64AtomicXor(MachineType rep);
659 : // atomic-pair-load [base + index]
660 : const Operator* Word32AtomicPairLoad();
661 : // atomic-pair-sub [base + index], value_high, value-low
662 : const Operator* Word32AtomicPairStore();
663 : // atomic-pair-add [base + index], value_high, value_low
664 : const Operator* Word32AtomicPairAdd();
665 : // atomic-pair-sub [base + index], value_high, value-low
666 : const Operator* Word32AtomicPairSub();
667 : // atomic-pair-and [base + index], value_high, value_low
668 : const Operator* Word32AtomicPairAnd();
669 : // atomic-pair-or [base + index], value_high, value_low
670 : const Operator* Word32AtomicPairOr();
671 : // atomic-pair-xor [base + index], value_high, value_low
672 : const Operator* Word32AtomicPairXor();
673 : // atomic-pair-exchange [base + index], value_high, value_low
674 : const Operator* Word32AtomicPairExchange();
675 : // atomic-pair-compare-exchange [base + index], old_value_high, old_value_low,
676 : // new_value_high, new_value_low
677 : const Operator* Word32AtomicPairCompareExchange();
678 :
679 : // Target machine word-size assumed by this builder.
680 : bool Is32() const { return word() == MachineRepresentation::kWord32; }
681 398144 : bool Is64() const { return word() == MachineRepresentation::kWord64; }
682 : MachineRepresentation word() const { return word_; }
683 :
684 : bool UnalignedLoadSupported(MachineRepresentation rep) {
685 102230 : return alignment_requirements_.IsUnalignedLoadSupported(rep);
686 : }
687 :
688 : bool UnalignedStoreSupported(MachineRepresentation rep) {
689 146891 : return alignment_requirements_.IsUnalignedStoreSupported(rep);
690 : }
691 :
692 : // Pseudo operators that translate to 32/64-bit operators depending on the
693 : // word-size of the target machine assumed by this builder.
694 : #define PSEUDO_OP_LIST(V) \
695 : V(Word, And) \
696 : V(Word, Or) \
697 : V(Word, Xor) \
698 : V(Word, Shl) \
699 : V(Word, Shr) \
700 : V(Word, Sar) \
701 : V(Word, Ror) \
702 : V(Word, Clz) \
703 : V(Word, Equal) \
704 : V(Word, PoisonOnSpeculation) \
705 : V(Int, Add) \
706 : V(Int, Sub) \
707 : V(Int, Mul) \
708 : V(Int, Div) \
709 : V(Int, Mod) \
710 : V(Int, LessThan) \
711 : V(Int, LessThanOrEqual) \
712 : V(Uint, Div) \
713 : V(Uint, LessThan) \
714 : V(Uint, Mod)
715 : #define PSEUDO_OP(Prefix, Suffix) \
716 : const Operator* Prefix##Suffix() { \
717 : return Is32() ? Prefix##32##Suffix() : Prefix##64##Suffix(); \
718 : }
719 5462651 : PSEUDO_OP_LIST(PSEUDO_OP)
720 : #undef PSEUDO_OP
721 : #undef PSEUDO_OP_LIST
722 :
723 : private:
724 : Zone* zone_;
725 : MachineOperatorGlobalCache const& cache_;
726 : MachineRepresentation const word_;
727 : Flags const flags_;
728 : AlignmentRequirements const alignment_requirements_;
729 :
730 : DISALLOW_COPY_AND_ASSIGN(MachineOperatorBuilder);
731 : };
732 :
733 :
734 : DEFINE_OPERATORS_FOR_FLAGS(MachineOperatorBuilder::Flags)
735 :
736 : } // namespace compiler
737 : } // namespace internal
738 : } // namespace v8
739 :
740 : #endif // V8_COMPILER_MACHINE_OPERATOR_H_
|