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