• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef V8_COMPILER_RAW_MACHINE_ASSEMBLER_H_
6 #define V8_COMPILER_RAW_MACHINE_ASSEMBLER_H_
7 
8 #include <initializer_list>
9 
10 #include "src/base/type-traits.h"
11 #include "src/codegen/assembler.h"
12 #include "src/common/globals.h"
13 #include "src/compiler/access-builder.h"
14 #include "src/compiler/common-operator.h"
15 #include "src/compiler/graph.h"
16 #include "src/compiler/linkage.h"
17 #include "src/compiler/machine-operator.h"
18 #include "src/compiler/node.h"
19 #include "src/compiler/operator.h"
20 #include "src/compiler/simplified-operator.h"
21 #include "src/compiler/write-barrier-kind.h"
22 #include "src/execution/isolate.h"
23 #include "src/heap/factory.h"
24 
25 namespace v8 {
26 namespace internal {
27 namespace compiler {
28 
29 class BasicBlock;
30 class RawMachineLabel;
31 class Schedule;
32 class SourcePositionTable;
33 
34 // The RawMachineAssembler produces a low-level IR graph. All nodes are wired
35 // into a graph and also placed into a schedule immediately, hence subsequent
36 // code generation can happen without the need for scheduling.
37 //
38 // In order to create a schedule on-the-fly, the assembler keeps track of basic
39 // blocks by having one current basic block being populated and by referencing
40 // other basic blocks through the use of labels.
41 //
42 // Also note that the generated graph is only valid together with the generated
43 // schedule, using one without the other is invalid as the graph is inherently
44 // non-schedulable due to missing control and effect dependencies.
45 class V8_EXPORT_PRIVATE RawMachineAssembler {
46  public:
47   RawMachineAssembler(
48       Isolate* isolate, Graph* graph, CallDescriptor* call_descriptor,
49       MachineRepresentation word = MachineType::PointerRepresentation(),
50       MachineOperatorBuilder::Flags flags =
51           MachineOperatorBuilder::Flag::kNoFlags,
52       MachineOperatorBuilder::AlignmentRequirements alignment_requirements =
53           MachineOperatorBuilder::AlignmentRequirements::
54               FullUnalignedAccessSupport(),
55       PoisoningMitigationLevel poisoning_level =
56           PoisoningMitigationLevel::kPoisonCriticalOnly);
57   ~RawMachineAssembler() = default;
58 
59   RawMachineAssembler(const RawMachineAssembler&) = delete;
60   RawMachineAssembler& operator=(const RawMachineAssembler&) = delete;
61 
isolate()62   Isolate* isolate() const { return isolate_; }
graph()63   Graph* graph() const { return graph_; }
zone()64   Zone* zone() const { return graph()->zone(); }
machine()65   MachineOperatorBuilder* machine() { return &machine_; }
common()66   CommonOperatorBuilder* common() { return &common_; }
simplified()67   SimplifiedOperatorBuilder* simplified() { return &simplified_; }
call_descriptor()68   CallDescriptor* call_descriptor() const { return call_descriptor_; }
poisoning_level()69   PoisoningMitigationLevel poisoning_level() const { return poisoning_level_; }
70 
71   // Only used for tests: Finalizes the schedule and exports it to be used for
72   // code generation. Note that this RawMachineAssembler becomes invalid after
73   // export.
74   Schedule* ExportForTest();
75   // Finalizes the schedule and transforms it into a graph that's suitable for
76   // it to be used for Turbofan optimization and re-scheduling. Note that this
77   // RawMachineAssembler becomes invalid after export.
78   Graph* ExportForOptimization();
79 
80   // ===========================================================================
81   // The following utility methods create new nodes with specific operators and
82   // place them into the current basic block. They don't perform control flow,
83   // hence will not switch the current basic block.
84 
85   Node* NullConstant();
86   Node* UndefinedConstant();
87 
88   // Constants.
PointerConstant(void * value)89   Node* PointerConstant(void* value) {
90     return IntPtrConstant(reinterpret_cast<intptr_t>(value));
91   }
IntPtrConstant(intptr_t value)92   Node* IntPtrConstant(intptr_t value) {
93     // TODO(dcarney): mark generated code as unserializable if value != 0.
94     return kSystemPointerSize == 8 ? Int64Constant(value)
95                                    : Int32Constant(static_cast<int>(value));
96   }
97   Node* RelocatableIntPtrConstant(intptr_t value, RelocInfo::Mode rmode);
Int32Constant(int32_t value)98   Node* Int32Constant(int32_t value) {
99     return AddNode(common()->Int32Constant(value));
100   }
101   Node* StackSlot(MachineRepresentation rep, int alignment = 0) {
102     return AddNode(machine()->StackSlot(rep, alignment));
103   }
Int64Constant(int64_t value)104   Node* Int64Constant(int64_t value) {
105     return AddNode(common()->Int64Constant(value));
106   }
NumberConstant(double value)107   Node* NumberConstant(double value) {
108     return AddNode(common()->NumberConstant(value));
109   }
Float32Constant(float value)110   Node* Float32Constant(float value) {
111     return AddNode(common()->Float32Constant(value));
112   }
Float64Constant(double value)113   Node* Float64Constant(double value) {
114     return AddNode(common()->Float64Constant(value));
115   }
HeapConstant(Handle<HeapObject> object)116   Node* HeapConstant(Handle<HeapObject> object) {
117     return AddNode(common()->HeapConstant(object));
118   }
ExternalConstant(ExternalReference address)119   Node* ExternalConstant(ExternalReference address) {
120     return AddNode(common()->ExternalConstant(address));
121   }
RelocatableInt32Constant(int32_t value,RelocInfo::Mode rmode)122   Node* RelocatableInt32Constant(int32_t value, RelocInfo::Mode rmode) {
123     return AddNode(common()->RelocatableInt32Constant(value, rmode));
124   }
RelocatableInt64Constant(int64_t value,RelocInfo::Mode rmode)125   Node* RelocatableInt64Constant(int64_t value, RelocInfo::Mode rmode) {
126     return AddNode(common()->RelocatableInt64Constant(value, rmode));
127   }
128 
Projection(int index,Node * a)129   Node* Projection(int index, Node* a) {
130     return AddNode(common()->Projection(index), a);
131   }
132 
133   // Memory Operations.
134   Node* Load(MachineType type, Node* base,
135              LoadSensitivity needs_poisoning = LoadSensitivity::kSafe) {
136     return Load(type, base, IntPtrConstant(0), needs_poisoning);
137   }
138   Node* Load(MachineType type, Node* base, Node* index,
139              LoadSensitivity needs_poisoning = LoadSensitivity::kSafe) {
140     const Operator* op = machine()->Load(type);
141     CHECK_NE(PoisoningMitigationLevel::kPoisonAll, poisoning_level_);
142     if (needs_poisoning == LoadSensitivity::kCritical &&
143         poisoning_level_ == PoisoningMitigationLevel::kPoisonCriticalOnly) {
144       op = machine()->PoisonedLoad(type);
145     }
146 
147     Node* load = AddNode(op, base, index);
148     return load;
149   }
150   Node* LoadFromObject(
151       MachineType type, Node* base, Node* offset,
152       LoadSensitivity needs_poisoning = LoadSensitivity::kSafe) {
153     CHECK_EQ(needs_poisoning, LoadSensitivity::kSafe);
154     ObjectAccess access = {type, WriteBarrierKind::kNoWriteBarrier};
155     Node* load = AddNode(simplified()->LoadFromObject(access), base, offset);
156     return load;
157   }
158 
Store(MachineRepresentation rep,Node * base,Node * value,WriteBarrierKind write_barrier)159   Node* Store(MachineRepresentation rep, Node* base, Node* value,
160               WriteBarrierKind write_barrier) {
161     return Store(rep, base, IntPtrConstant(0), value, write_barrier);
162   }
Store(MachineRepresentation rep,Node * base,Node * index,Node * value,WriteBarrierKind write_barrier)163   Node* Store(MachineRepresentation rep, Node* base, Node* index, Node* value,
164               WriteBarrierKind write_barrier) {
165     return AddNode(machine()->Store(StoreRepresentation(rep, write_barrier)),
166                    base, index, value);
167   }
StoreToObject(MachineRepresentation rep,Node * object,Node * offset,Node * value,WriteBarrierKind write_barrier)168   void StoreToObject(MachineRepresentation rep, Node* object, Node* offset,
169                      Node* value, WriteBarrierKind write_barrier) {
170     ObjectAccess access = {MachineType::TypeForRepresentation(rep),
171                            write_barrier};
172     AddNode(simplified()->StoreToObject(access), object, offset, value);
173   }
OptimizedStoreField(MachineRepresentation rep,Node * object,int offset,Node * value,WriteBarrierKind write_barrier)174   void OptimizedStoreField(MachineRepresentation rep, Node* object, int offset,
175                            Node* value, WriteBarrierKind write_barrier) {
176     AddNode(simplified()->StoreField(FieldAccess(
177                 BaseTaggedness::kTaggedBase, offset, MaybeHandle<Name>(),
178                 MaybeHandle<Map>(), Type::Any(),
179                 MachineType::TypeForRepresentation(rep), write_barrier)),
180             object, value);
181   }
OptimizedStoreMap(Node * object,Node * value)182   void OptimizedStoreMap(Node* object, Node* value) {
183     AddNode(simplified()->StoreField(AccessBuilder::ForMap()), object, value);
184   }
Retain(Node * value)185   Node* Retain(Node* value) { return AddNode(common()->Retain(), value); }
186 
187   Node* OptimizedAllocate(Node* size, AllocationType allocation,
188                           AllowLargeObjects allow_large_objects);
189 
190   // Unaligned memory operations
UnalignedLoad(MachineType type,Node * base)191   Node* UnalignedLoad(MachineType type, Node* base) {
192     return UnalignedLoad(type, base, IntPtrConstant(0));
193   }
UnalignedLoad(MachineType type,Node * base,Node * index)194   Node* UnalignedLoad(MachineType type, Node* base, Node* index) {
195     MachineRepresentation rep = type.representation();
196     // Tagged or compressed should never be unaligned
197     DCHECK(!(IsAnyTagged(rep) || IsAnyCompressed(rep)));
198     if (machine()->UnalignedLoadSupported(rep)) {
199       return AddNode(machine()->Load(type), base, index);
200     } else {
201       return AddNode(machine()->UnalignedLoad(type), base, index);
202     }
203   }
UnalignedStore(MachineRepresentation rep,Node * base,Node * value)204   Node* UnalignedStore(MachineRepresentation rep, Node* base, Node* value) {
205     return UnalignedStore(rep, base, IntPtrConstant(0), value);
206   }
UnalignedStore(MachineRepresentation rep,Node * base,Node * index,Node * value)207   Node* UnalignedStore(MachineRepresentation rep, Node* base, Node* index,
208                        Node* value) {
209     // Tagged or compressed should never be unaligned
210     DCHECK(!(IsAnyTagged(rep) || IsAnyCompressed(rep)));
211     if (machine()->UnalignedStoreSupported(rep)) {
212       return AddNode(machine()->Store(StoreRepresentation(
213                          rep, WriteBarrierKind::kNoWriteBarrier)),
214                      base, index, value);
215     } else {
216       return AddNode(
217           machine()->UnalignedStore(UnalignedStoreRepresentation(rep)), base,
218           index, value);
219     }
220   }
221 
222   // Atomic memory operations.
AtomicLoad(MachineType type,Node * base,Node * index)223   Node* AtomicLoad(MachineType type, Node* base, Node* index) {
224     if (type.representation() == MachineRepresentation::kWord64) {
225       if (machine()->Is64()) {
226         return AddNode(machine()->Word64AtomicLoad(type), base, index);
227       } else {
228         return AddNode(machine()->Word32AtomicPairLoad(), base, index);
229       }
230     }
231     return AddNode(machine()->Word32AtomicLoad(type), base, index);
232   }
233 
234 #if defined(V8_TARGET_BIG_ENDIAN)
235 #define VALUE_HALVES value_high, value
236 #else
237 #define VALUE_HALVES value, value_high
238 #endif
239 
AtomicStore(MachineRepresentation rep,Node * base,Node * index,Node * value,Node * value_high)240   Node* AtomicStore(MachineRepresentation rep, Node* base, Node* index,
241                     Node* value, Node* value_high) {
242     if (rep == MachineRepresentation::kWord64) {
243       if (machine()->Is64()) {
244         DCHECK_NULL(value_high);
245         return AddNode(machine()->Word64AtomicStore(rep), base, index, value);
246       } else {
247         return AddNode(machine()->Word32AtomicPairStore(), base, index,
248                        VALUE_HALVES);
249       }
250     }
251     DCHECK_NULL(value_high);
252     return AddNode(machine()->Word32AtomicStore(rep), base, index, value);
253   }
254 #define ATOMIC_FUNCTION(name)                                                \
255   Node* Atomic##name(MachineType type, Node* base, Node* index, Node* value, \
256                      Node* value_high) {                                     \
257     if (type.representation() == MachineRepresentation::kWord64) {           \
258       if (machine()->Is64()) {                                               \
259         DCHECK_NULL(value_high);                                             \
260         return AddNode(machine()->Word64Atomic##name(type), base, index,     \
261                        value);                                               \
262       } else {                                                               \
263         return AddNode(machine()->Word32AtomicPair##name(), base, index,     \
264                        VALUE_HALVES);                                        \
265       }                                                                      \
266     }                                                                        \
267     DCHECK_NULL(value_high);                                                 \
268     return AddNode(machine()->Word32Atomic##name(type), base, index, value); \
269   }
270   ATOMIC_FUNCTION(Exchange)
ATOMIC_FUNCTION(Add)271   ATOMIC_FUNCTION(Add)
272   ATOMIC_FUNCTION(Sub)
273   ATOMIC_FUNCTION(And)
274   ATOMIC_FUNCTION(Or)
275   ATOMIC_FUNCTION(Xor)
276 #undef ATOMIC_FUNCTION
277 #undef VALUE_HALVES
278 
279   Node* AtomicCompareExchange(MachineType type, Node* base, Node* index,
280                               Node* old_value, Node* old_value_high,
281                               Node* new_value, Node* new_value_high) {
282     if (type.representation() == MachineRepresentation::kWord64) {
283       if (machine()->Is64()) {
284         DCHECK_NULL(old_value_high);
285         DCHECK_NULL(new_value_high);
286         return AddNode(machine()->Word64AtomicCompareExchange(type), base,
287                        index, old_value, new_value);
288       } else {
289         return AddNode(machine()->Word32AtomicPairCompareExchange(), base,
290                        index, old_value, old_value_high, new_value,
291                        new_value_high);
292       }
293     }
294     DCHECK_NULL(old_value_high);
295     DCHECK_NULL(new_value_high);
296     return AddNode(machine()->Word32AtomicCompareExchange(type), base, index,
297                    old_value, new_value);
298   }
299 
300   // Arithmetic Operations.
WordAnd(Node * a,Node * b)301   Node* WordAnd(Node* a, Node* b) {
302     return AddNode(machine()->WordAnd(), a, b);
303   }
WordOr(Node * a,Node * b)304   Node* WordOr(Node* a, Node* b) { return AddNode(machine()->WordOr(), a, b); }
WordXor(Node * a,Node * b)305   Node* WordXor(Node* a, Node* b) {
306     return AddNode(machine()->WordXor(), a, b);
307   }
WordShl(Node * a,Node * b)308   Node* WordShl(Node* a, Node* b) {
309     return AddNode(machine()->WordShl(), a, b);
310   }
WordShr(Node * a,Node * b)311   Node* WordShr(Node* a, Node* b) {
312     return AddNode(machine()->WordShr(), a, b);
313   }
WordSar(Node * a,Node * b)314   Node* WordSar(Node* a, Node* b) {
315     return AddNode(machine()->WordSar(), a, b);
316   }
WordSarShiftOutZeros(Node * a,Node * b)317   Node* WordSarShiftOutZeros(Node* a, Node* b) {
318     return AddNode(machine()->WordSarShiftOutZeros(), a, b);
319   }
WordRor(Node * a,Node * b)320   Node* WordRor(Node* a, Node* b) {
321     return AddNode(machine()->WordRor(), a, b);
322   }
WordEqual(Node * a,Node * b)323   Node* WordEqual(Node* a, Node* b) {
324     return AddNode(machine()->WordEqual(), a, b);
325   }
WordNotEqual(Node * a,Node * b)326   Node* WordNotEqual(Node* a, Node* b) {
327     return Word32BinaryNot(WordEqual(a, b));
328   }
WordNot(Node * a)329   Node* WordNot(Node* a) {
330     if (machine()->Is32()) {
331       return Word32BitwiseNot(a);
332     } else {
333       return Word64Not(a);
334     }
335   }
336 
Word32And(Node * a,Node * b)337   Node* Word32And(Node* a, Node* b) {
338     return AddNode(machine()->Word32And(), a, b);
339   }
Word32Or(Node * a,Node * b)340   Node* Word32Or(Node* a, Node* b) {
341     return AddNode(machine()->Word32Or(), a, b);
342   }
Word32Xor(Node * a,Node * b)343   Node* Word32Xor(Node* a, Node* b) {
344     return AddNode(machine()->Word32Xor(), a, b);
345   }
Word32Shl(Node * a,Node * b)346   Node* Word32Shl(Node* a, Node* b) {
347     return AddNode(machine()->Word32Shl(), a, b);
348   }
Word32Shr(Node * a,Node * b)349   Node* Word32Shr(Node* a, Node* b) {
350     return AddNode(machine()->Word32Shr(), a, b);
351   }
Word32Sar(Node * a,Node * b)352   Node* Word32Sar(Node* a, Node* b) {
353     return AddNode(machine()->Word32Sar(), a, b);
354   }
Word32SarShiftOutZeros(Node * a,Node * b)355   Node* Word32SarShiftOutZeros(Node* a, Node* b) {
356     return AddNode(machine()->Word32SarShiftOutZeros(), a, b);
357   }
Word32Ror(Node * a,Node * b)358   Node* Word32Ror(Node* a, Node* b) {
359     return AddNode(machine()->Word32Ror(), a, b);
360   }
Word32Clz(Node * a)361   Node* Word32Clz(Node* a) { return AddNode(machine()->Word32Clz(), a); }
Word32Equal(Node * a,Node * b)362   Node* Word32Equal(Node* a, Node* b) {
363     return AddNode(machine()->Word32Equal(), a, b);
364   }
Word32NotEqual(Node * a,Node * b)365   Node* Word32NotEqual(Node* a, Node* b) {
366     return Word32BinaryNot(Word32Equal(a, b));
367   }
Word32BitwiseNot(Node * a)368   Node* Word32BitwiseNot(Node* a) { return Word32Xor(a, Int32Constant(-1)); }
Word32BinaryNot(Node * a)369   Node* Word32BinaryNot(Node* a) { return Word32Equal(a, Int32Constant(0)); }
370 
Word64And(Node * a,Node * b)371   Node* Word64And(Node* a, Node* b) {
372     return AddNode(machine()->Word64And(), a, b);
373   }
Word64Or(Node * a,Node * b)374   Node* Word64Or(Node* a, Node* b) {
375     return AddNode(machine()->Word64Or(), a, b);
376   }
Word64Xor(Node * a,Node * b)377   Node* Word64Xor(Node* a, Node* b) {
378     return AddNode(machine()->Word64Xor(), a, b);
379   }
Word64Shl(Node * a,Node * b)380   Node* Word64Shl(Node* a, Node* b) {
381     return AddNode(machine()->Word64Shl(), a, b);
382   }
Word64Shr(Node * a,Node * b)383   Node* Word64Shr(Node* a, Node* b) {
384     return AddNode(machine()->Word64Shr(), a, b);
385   }
Word64Sar(Node * a,Node * b)386   Node* Word64Sar(Node* a, Node* b) {
387     return AddNode(machine()->Word64Sar(), a, b);
388   }
Word64Ror(Node * a,Node * b)389   Node* Word64Ror(Node* a, Node* b) {
390     return AddNode(machine()->Word64Ror(), a, b);
391   }
Word64Clz(Node * a)392   Node* Word64Clz(Node* a) { return AddNode(machine()->Word64Clz(), a); }
Word64Equal(Node * a,Node * b)393   Node* Word64Equal(Node* a, Node* b) {
394     return AddNode(machine()->Word64Equal(), a, b);
395   }
Word64NotEqual(Node * a,Node * b)396   Node* Word64NotEqual(Node* a, Node* b) {
397     return Word32BinaryNot(Word64Equal(a, b));
398   }
Word64Not(Node * a)399   Node* Word64Not(Node* a) { return Word64Xor(a, Int64Constant(-1)); }
400 
Int32Add(Node * a,Node * b)401   Node* Int32Add(Node* a, Node* b) {
402     return AddNode(machine()->Int32Add(), a, b);
403   }
Int32AddWithOverflow(Node * a,Node * b)404   Node* Int32AddWithOverflow(Node* a, Node* b) {
405     return AddNode(machine()->Int32AddWithOverflow(), a, b);
406   }
Int32Sub(Node * a,Node * b)407   Node* Int32Sub(Node* a, Node* b) {
408     return AddNode(machine()->Int32Sub(), a, b);
409   }
Int32SubWithOverflow(Node * a,Node * b)410   Node* Int32SubWithOverflow(Node* a, Node* b) {
411     return AddNode(machine()->Int32SubWithOverflow(), a, b);
412   }
Int32Mul(Node * a,Node * b)413   Node* Int32Mul(Node* a, Node* b) {
414     return AddNode(machine()->Int32Mul(), a, b);
415   }
Int32MulHigh(Node * a,Node * b)416   Node* Int32MulHigh(Node* a, Node* b) {
417     return AddNode(machine()->Int32MulHigh(), a, b);
418   }
Int32MulWithOverflow(Node * a,Node * b)419   Node* Int32MulWithOverflow(Node* a, Node* b) {
420     return AddNode(machine()->Int32MulWithOverflow(), a, b);
421   }
Int32Div(Node * a,Node * b)422   Node* Int32Div(Node* a, Node* b) {
423     return AddNode(machine()->Int32Div(), a, b);
424   }
Int32Mod(Node * a,Node * b)425   Node* Int32Mod(Node* a, Node* b) {
426     return AddNode(machine()->Int32Mod(), a, b);
427   }
Int32LessThan(Node * a,Node * b)428   Node* Int32LessThan(Node* a, Node* b) {
429     return AddNode(machine()->Int32LessThan(), a, b);
430   }
Int32LessThanOrEqual(Node * a,Node * b)431   Node* Int32LessThanOrEqual(Node* a, Node* b) {
432     return AddNode(machine()->Int32LessThanOrEqual(), a, b);
433   }
Uint32Div(Node * a,Node * b)434   Node* Uint32Div(Node* a, Node* b) {
435     return AddNode(machine()->Uint32Div(), a, b);
436   }
Uint32LessThan(Node * a,Node * b)437   Node* Uint32LessThan(Node* a, Node* b) {
438     return AddNode(machine()->Uint32LessThan(), a, b);
439   }
Uint32LessThanOrEqual(Node * a,Node * b)440   Node* Uint32LessThanOrEqual(Node* a, Node* b) {
441     return AddNode(machine()->Uint32LessThanOrEqual(), a, b);
442   }
Uint32Mod(Node * a,Node * b)443   Node* Uint32Mod(Node* a, Node* b) {
444     return AddNode(machine()->Uint32Mod(), a, b);
445   }
Uint32MulHigh(Node * a,Node * b)446   Node* Uint32MulHigh(Node* a, Node* b) {
447     return AddNode(machine()->Uint32MulHigh(), a, b);
448   }
Int32GreaterThan(Node * a,Node * b)449   Node* Int32GreaterThan(Node* a, Node* b) { return Int32LessThan(b, a); }
Int32GreaterThanOrEqual(Node * a,Node * b)450   Node* Int32GreaterThanOrEqual(Node* a, Node* b) {
451     return Int32LessThanOrEqual(b, a);
452   }
Uint32GreaterThan(Node * a,Node * b)453   Node* Uint32GreaterThan(Node* a, Node* b) { return Uint32LessThan(b, a); }
Uint32GreaterThanOrEqual(Node * a,Node * b)454   Node* Uint32GreaterThanOrEqual(Node* a, Node* b) {
455     return Uint32LessThanOrEqual(b, a);
456   }
Int32Neg(Node * a)457   Node* Int32Neg(Node* a) { return Int32Sub(Int32Constant(0), a); }
458 
Int64Add(Node * a,Node * b)459   Node* Int64Add(Node* a, Node* b) {
460     return AddNode(machine()->Int64Add(), a, b);
461   }
Int64AddWithOverflow(Node * a,Node * b)462   Node* Int64AddWithOverflow(Node* a, Node* b) {
463     return AddNode(machine()->Int64AddWithOverflow(), a, b);
464   }
Int64Sub(Node * a,Node * b)465   Node* Int64Sub(Node* a, Node* b) {
466     return AddNode(machine()->Int64Sub(), a, b);
467   }
Int64SubWithOverflow(Node * a,Node * b)468   Node* Int64SubWithOverflow(Node* a, Node* b) {
469     return AddNode(machine()->Int64SubWithOverflow(), a, b);
470   }
Int64Mul(Node * a,Node * b)471   Node* Int64Mul(Node* a, Node* b) {
472     return AddNode(machine()->Int64Mul(), a, b);
473   }
Int64Div(Node * a,Node * b)474   Node* Int64Div(Node* a, Node* b) {
475     return AddNode(machine()->Int64Div(), a, b);
476   }
Int64Mod(Node * a,Node * b)477   Node* Int64Mod(Node* a, Node* b) {
478     return AddNode(machine()->Int64Mod(), a, b);
479   }
Int64Neg(Node * a)480   Node* Int64Neg(Node* a) { return Int64Sub(Int64Constant(0), a); }
Int64LessThan(Node * a,Node * b)481   Node* Int64LessThan(Node* a, Node* b) {
482     return AddNode(machine()->Int64LessThan(), a, b);
483   }
Int64LessThanOrEqual(Node * a,Node * b)484   Node* Int64LessThanOrEqual(Node* a, Node* b) {
485     return AddNode(machine()->Int64LessThanOrEqual(), a, b);
486   }
Uint64LessThan(Node * a,Node * b)487   Node* Uint64LessThan(Node* a, Node* b) {
488     return AddNode(machine()->Uint64LessThan(), a, b);
489   }
Uint64LessThanOrEqual(Node * a,Node * b)490   Node* Uint64LessThanOrEqual(Node* a, Node* b) {
491     return AddNode(machine()->Uint64LessThanOrEqual(), a, b);
492   }
Int64GreaterThan(Node * a,Node * b)493   Node* Int64GreaterThan(Node* a, Node* b) { return Int64LessThan(b, a); }
Int64GreaterThanOrEqual(Node * a,Node * b)494   Node* Int64GreaterThanOrEqual(Node* a, Node* b) {
495     return Int64LessThanOrEqual(b, a);
496   }
Uint64GreaterThan(Node * a,Node * b)497   Node* Uint64GreaterThan(Node* a, Node* b) { return Uint64LessThan(b, a); }
Uint64GreaterThanOrEqual(Node * a,Node * b)498   Node* Uint64GreaterThanOrEqual(Node* a, Node* b) {
499     return Uint64LessThanOrEqual(b, a);
500   }
Uint64Div(Node * a,Node * b)501   Node* Uint64Div(Node* a, Node* b) {
502     return AddNode(machine()->Uint64Div(), a, b);
503   }
Uint64Mod(Node * a,Node * b)504   Node* Uint64Mod(Node* a, Node* b) {
505     return AddNode(machine()->Uint64Mod(), a, b);
506   }
Int32PairAdd(Node * a_low,Node * a_high,Node * b_low,Node * b_high)507   Node* Int32PairAdd(Node* a_low, Node* a_high, Node* b_low, Node* b_high) {
508     return AddNode(machine()->Int32PairAdd(), a_low, a_high, b_low, b_high);
509   }
Int32PairSub(Node * a_low,Node * a_high,Node * b_low,Node * b_high)510   Node* Int32PairSub(Node* a_low, Node* a_high, Node* b_low, Node* b_high) {
511     return AddNode(machine()->Int32PairSub(), a_low, a_high, b_low, b_high);
512   }
Int32PairMul(Node * a_low,Node * a_high,Node * b_low,Node * b_high)513   Node* Int32PairMul(Node* a_low, Node* a_high, Node* b_low, Node* b_high) {
514     return AddNode(machine()->Int32PairMul(), a_low, a_high, b_low, b_high);
515   }
Word32PairShl(Node * low_word,Node * high_word,Node * shift)516   Node* Word32PairShl(Node* low_word, Node* high_word, Node* shift) {
517     return AddNode(machine()->Word32PairShl(), low_word, high_word, shift);
518   }
Word32PairShr(Node * low_word,Node * high_word,Node * shift)519   Node* Word32PairShr(Node* low_word, Node* high_word, Node* shift) {
520     return AddNode(machine()->Word32PairShr(), low_word, high_word, shift);
521   }
Word32PairSar(Node * low_word,Node * high_word,Node * shift)522   Node* Word32PairSar(Node* low_word, Node* high_word, Node* shift) {
523     return AddNode(machine()->Word32PairSar(), low_word, high_word, shift);
524   }
StackPointerGreaterThan(Node * value)525   Node* StackPointerGreaterThan(Node* value) {
526     return AddNode(
527         machine()->StackPointerGreaterThan(StackCheckKind::kCodeStubAssembler),
528         value);
529   }
530 
531 #define INTPTR_BINOP(prefix, name)                           \
532   Node* IntPtr##name(Node* a, Node* b) {                     \
533     return kSystemPointerSize == 8 ? prefix##64##name(a, b)  \
534                                    : prefix##32##name(a, b); \
535   }
536 
INTPTR_BINOP(Int,Add)537   INTPTR_BINOP(Int, Add)
538   INTPTR_BINOP(Int, AddWithOverflow)
539   INTPTR_BINOP(Int, Sub)
540   INTPTR_BINOP(Int, SubWithOverflow)
541   INTPTR_BINOP(Int, Mul)
542   INTPTR_BINOP(Int, Div)
543   INTPTR_BINOP(Int, LessThan)
544   INTPTR_BINOP(Int, LessThanOrEqual)
545   INTPTR_BINOP(Word, Equal)
546   INTPTR_BINOP(Word, NotEqual)
547   INTPTR_BINOP(Int, GreaterThanOrEqual)
548   INTPTR_BINOP(Int, GreaterThan)
549 
550 #undef INTPTR_BINOP
551 
552 #define UINTPTR_BINOP(prefix, name)                          \
553   Node* UintPtr##name(Node* a, Node* b) {                    \
554     return kSystemPointerSize == 8 ? prefix##64##name(a, b)  \
555                                    : prefix##32##name(a, b); \
556   }
557 
558   UINTPTR_BINOP(Uint, LessThan)
559   UINTPTR_BINOP(Uint, LessThanOrEqual)
560   UINTPTR_BINOP(Uint, GreaterThanOrEqual)
561   UINTPTR_BINOP(Uint, GreaterThan)
562 
563 #undef UINTPTR_BINOP
564 
565   Node* Int32AbsWithOverflow(Node* a) {
566     return AddNode(machine()->Int32AbsWithOverflow().op(), a);
567   }
568 
Int64AbsWithOverflow(Node * a)569   Node* Int64AbsWithOverflow(Node* a) {
570     return AddNode(machine()->Int64AbsWithOverflow().op(), a);
571   }
572 
IntPtrAbsWithOverflow(Node * a)573   Node* IntPtrAbsWithOverflow(Node* a) {
574     return kSystemPointerSize == 8 ? Int64AbsWithOverflow(a)
575                                    : Int32AbsWithOverflow(a);
576   }
577 
Float32Add(Node * a,Node * b)578   Node* Float32Add(Node* a, Node* b) {
579     return AddNode(machine()->Float32Add(), a, b);
580   }
Float32Sub(Node * a,Node * b)581   Node* Float32Sub(Node* a, Node* b) {
582     return AddNode(machine()->Float32Sub(), a, b);
583   }
Float32Mul(Node * a,Node * b)584   Node* Float32Mul(Node* a, Node* b) {
585     return AddNode(machine()->Float32Mul(), a, b);
586   }
Float32Div(Node * a,Node * b)587   Node* Float32Div(Node* a, Node* b) {
588     return AddNode(machine()->Float32Div(), a, b);
589   }
Float32Abs(Node * a)590   Node* Float32Abs(Node* a) { return AddNode(machine()->Float32Abs(), a); }
Float32Neg(Node * a)591   Node* Float32Neg(Node* a) { return AddNode(machine()->Float32Neg(), a); }
Float32Sqrt(Node * a)592   Node* Float32Sqrt(Node* a) { return AddNode(machine()->Float32Sqrt(), a); }
Float32Equal(Node * a,Node * b)593   Node* Float32Equal(Node* a, Node* b) {
594     return AddNode(machine()->Float32Equal(), a, b);
595   }
Float32NotEqual(Node * a,Node * b)596   Node* Float32NotEqual(Node* a, Node* b) {
597     return Word32BinaryNot(Float32Equal(a, b));
598   }
Float32LessThan(Node * a,Node * b)599   Node* Float32LessThan(Node* a, Node* b) {
600     return AddNode(machine()->Float32LessThan(), a, b);
601   }
Float32LessThanOrEqual(Node * a,Node * b)602   Node* Float32LessThanOrEqual(Node* a, Node* b) {
603     return AddNode(machine()->Float32LessThanOrEqual(), a, b);
604   }
Float32GreaterThan(Node * a,Node * b)605   Node* Float32GreaterThan(Node* a, Node* b) { return Float32LessThan(b, a); }
Float32GreaterThanOrEqual(Node * a,Node * b)606   Node* Float32GreaterThanOrEqual(Node* a, Node* b) {
607     return Float32LessThanOrEqual(b, a);
608   }
Float32Max(Node * a,Node * b)609   Node* Float32Max(Node* a, Node* b) {
610     return AddNode(machine()->Float32Max(), a, b);
611   }
Float32Min(Node * a,Node * b)612   Node* Float32Min(Node* a, Node* b) {
613     return AddNode(machine()->Float32Min(), a, b);
614   }
Float64Add(Node * a,Node * b)615   Node* Float64Add(Node* a, Node* b) {
616     return AddNode(machine()->Float64Add(), a, b);
617   }
Float64Sub(Node * a,Node * b)618   Node* Float64Sub(Node* a, Node* b) {
619     return AddNode(machine()->Float64Sub(), a, b);
620   }
Float64Mul(Node * a,Node * b)621   Node* Float64Mul(Node* a, Node* b) {
622     return AddNode(machine()->Float64Mul(), a, b);
623   }
Float64Div(Node * a,Node * b)624   Node* Float64Div(Node* a, Node* b) {
625     return AddNode(machine()->Float64Div(), a, b);
626   }
Float64Mod(Node * a,Node * b)627   Node* Float64Mod(Node* a, Node* b) {
628     return AddNode(machine()->Float64Mod(), a, b);
629   }
Float64Max(Node * a,Node * b)630   Node* Float64Max(Node* a, Node* b) {
631     return AddNode(machine()->Float64Max(), a, b);
632   }
Float64Min(Node * a,Node * b)633   Node* Float64Min(Node* a, Node* b) {
634     return AddNode(machine()->Float64Min(), a, b);
635   }
Float64Abs(Node * a)636   Node* Float64Abs(Node* a) { return AddNode(machine()->Float64Abs(), a); }
Float64Neg(Node * a)637   Node* Float64Neg(Node* a) { return AddNode(machine()->Float64Neg(), a); }
Float64Acos(Node * a)638   Node* Float64Acos(Node* a) { return AddNode(machine()->Float64Acos(), a); }
Float64Acosh(Node * a)639   Node* Float64Acosh(Node* a) { return AddNode(machine()->Float64Acosh(), a); }
Float64Asin(Node * a)640   Node* Float64Asin(Node* a) { return AddNode(machine()->Float64Asin(), a); }
Float64Asinh(Node * a)641   Node* Float64Asinh(Node* a) { return AddNode(machine()->Float64Asinh(), a); }
Float64Atan(Node * a)642   Node* Float64Atan(Node* a) { return AddNode(machine()->Float64Atan(), a); }
Float64Atanh(Node * a)643   Node* Float64Atanh(Node* a) { return AddNode(machine()->Float64Atanh(), a); }
Float64Atan2(Node * a,Node * b)644   Node* Float64Atan2(Node* a, Node* b) {
645     return AddNode(machine()->Float64Atan2(), a, b);
646   }
Float64Cbrt(Node * a)647   Node* Float64Cbrt(Node* a) { return AddNode(machine()->Float64Cbrt(), a); }
Float64Cos(Node * a)648   Node* Float64Cos(Node* a) { return AddNode(machine()->Float64Cos(), a); }
Float64Cosh(Node * a)649   Node* Float64Cosh(Node* a) { return AddNode(machine()->Float64Cosh(), a); }
Float64Exp(Node * a)650   Node* Float64Exp(Node* a) { return AddNode(machine()->Float64Exp(), a); }
Float64Expm1(Node * a)651   Node* Float64Expm1(Node* a) { return AddNode(machine()->Float64Expm1(), a); }
Float64Log(Node * a)652   Node* Float64Log(Node* a) { return AddNode(machine()->Float64Log(), a); }
Float64Log1p(Node * a)653   Node* Float64Log1p(Node* a) { return AddNode(machine()->Float64Log1p(), a); }
Float64Log10(Node * a)654   Node* Float64Log10(Node* a) { return AddNode(machine()->Float64Log10(), a); }
Float64Log2(Node * a)655   Node* Float64Log2(Node* a) { return AddNode(machine()->Float64Log2(), a); }
Float64Pow(Node * a,Node * b)656   Node* Float64Pow(Node* a, Node* b) {
657     return AddNode(machine()->Float64Pow(), a, b);
658   }
Float64Sin(Node * a)659   Node* Float64Sin(Node* a) { return AddNode(machine()->Float64Sin(), a); }
Float64Sinh(Node * a)660   Node* Float64Sinh(Node* a) { return AddNode(machine()->Float64Sinh(), a); }
Float64Sqrt(Node * a)661   Node* Float64Sqrt(Node* a) { return AddNode(machine()->Float64Sqrt(), a); }
Float64Tan(Node * a)662   Node* Float64Tan(Node* a) { return AddNode(machine()->Float64Tan(), a); }
Float64Tanh(Node * a)663   Node* Float64Tanh(Node* a) { return AddNode(machine()->Float64Tanh(), a); }
Float64Equal(Node * a,Node * b)664   Node* Float64Equal(Node* a, Node* b) {
665     return AddNode(machine()->Float64Equal(), a, b);
666   }
Float64NotEqual(Node * a,Node * b)667   Node* Float64NotEqual(Node* a, Node* b) {
668     return Word32BinaryNot(Float64Equal(a, b));
669   }
Float64LessThan(Node * a,Node * b)670   Node* Float64LessThan(Node* a, Node* b) {
671     return AddNode(machine()->Float64LessThan(), a, b);
672   }
Float64LessThanOrEqual(Node * a,Node * b)673   Node* Float64LessThanOrEqual(Node* a, Node* b) {
674     return AddNode(machine()->Float64LessThanOrEqual(), a, b);
675   }
Float64GreaterThan(Node * a,Node * b)676   Node* Float64GreaterThan(Node* a, Node* b) { return Float64LessThan(b, a); }
Float64GreaterThanOrEqual(Node * a,Node * b)677   Node* Float64GreaterThanOrEqual(Node* a, Node* b) {
678     return Float64LessThanOrEqual(b, a);
679   }
680 
681   // Conversions.
BitcastTaggedToWord(Node * a)682   Node* BitcastTaggedToWord(Node* a) {
683       return AddNode(machine()->BitcastTaggedToWord(), a);
684   }
BitcastTaggedToWordForTagAndSmiBits(Node * a)685   Node* BitcastTaggedToWordForTagAndSmiBits(Node* a) {
686     return AddNode(machine()->BitcastTaggedToWordForTagAndSmiBits(), a);
687   }
BitcastMaybeObjectToWord(Node * a)688   Node* BitcastMaybeObjectToWord(Node* a) {
689       return AddNode(machine()->BitcastMaybeObjectToWord(), a);
690   }
BitcastWordToTagged(Node * a)691   Node* BitcastWordToTagged(Node* a) {
692     return AddNode(machine()->BitcastWordToTagged(), a);
693   }
BitcastWordToTaggedSigned(Node * a)694   Node* BitcastWordToTaggedSigned(Node* a) {
695       return AddNode(machine()->BitcastWordToTaggedSigned(), a);
696   }
TruncateFloat64ToWord32(Node * a)697   Node* TruncateFloat64ToWord32(Node* a) {
698     return AddNode(machine()->TruncateFloat64ToWord32(), a);
699   }
ChangeFloat32ToFloat64(Node * a)700   Node* ChangeFloat32ToFloat64(Node* a) {
701     return AddNode(machine()->ChangeFloat32ToFloat64(), a);
702   }
ChangeInt32ToFloat64(Node * a)703   Node* ChangeInt32ToFloat64(Node* a) {
704     return AddNode(machine()->ChangeInt32ToFloat64(), a);
705   }
ChangeInt64ToFloat64(Node * a)706   Node* ChangeInt64ToFloat64(Node* a) {
707     return AddNode(machine()->ChangeInt64ToFloat64(), a);
708   }
ChangeUint32ToFloat64(Node * a)709   Node* ChangeUint32ToFloat64(Node* a) {
710     return AddNode(machine()->ChangeUint32ToFloat64(), a);
711   }
ChangeFloat64ToInt32(Node * a)712   Node* ChangeFloat64ToInt32(Node* a) {
713     return AddNode(machine()->ChangeFloat64ToInt32(), a);
714   }
ChangeFloat64ToInt64(Node * a)715   Node* ChangeFloat64ToInt64(Node* a) {
716     return AddNode(machine()->ChangeFloat64ToInt64(), a);
717   }
ChangeFloat64ToUint32(Node * a)718   Node* ChangeFloat64ToUint32(Node* a) {
719     return AddNode(machine()->ChangeFloat64ToUint32(), a);
720   }
ChangeFloat64ToUint64(Node * a)721   Node* ChangeFloat64ToUint64(Node* a) {
722     return AddNode(machine()->ChangeFloat64ToUint64(), a);
723   }
TruncateFloat64ToUint32(Node * a)724   Node* TruncateFloat64ToUint32(Node* a) {
725     return AddNode(machine()->TruncateFloat64ToUint32(), a);
726   }
TruncateFloat32ToInt32(Node * a,TruncateKind kind)727   Node* TruncateFloat32ToInt32(Node* a, TruncateKind kind) {
728     return AddNode(machine()->TruncateFloat32ToInt32(kind), a);
729   }
TruncateFloat32ToUint32(Node * a,TruncateKind kind)730   Node* TruncateFloat32ToUint32(Node* a, TruncateKind kind) {
731     return AddNode(machine()->TruncateFloat32ToUint32(kind), a);
732   }
TryTruncateFloat32ToInt64(Node * a)733   Node* TryTruncateFloat32ToInt64(Node* a) {
734     return AddNode(machine()->TryTruncateFloat32ToInt64(), a);
735   }
TryTruncateFloat64ToInt64(Node * a)736   Node* TryTruncateFloat64ToInt64(Node* a) {
737     return AddNode(machine()->TryTruncateFloat64ToInt64(), a);
738   }
TryTruncateFloat32ToUint64(Node * a)739   Node* TryTruncateFloat32ToUint64(Node* a) {
740     return AddNode(machine()->TryTruncateFloat32ToUint64(), a);
741   }
TryTruncateFloat64ToUint64(Node * a)742   Node* TryTruncateFloat64ToUint64(Node* a) {
743     return AddNode(machine()->TryTruncateFloat64ToUint64(), a);
744   }
ChangeInt32ToInt64(Node * a)745   Node* ChangeInt32ToInt64(Node* a) {
746     return AddNode(machine()->ChangeInt32ToInt64(), a);
747   }
ChangeUint32ToUint64(Node * a)748   Node* ChangeUint32ToUint64(Node* a) {
749     return AddNode(machine()->ChangeUint32ToUint64(), a);
750   }
TruncateFloat64ToFloat32(Node * a)751   Node* TruncateFloat64ToFloat32(Node* a) {
752     return AddNode(machine()->TruncateFloat64ToFloat32(), a);
753   }
TruncateInt64ToInt32(Node * a)754   Node* TruncateInt64ToInt32(Node* a) {
755     return AddNode(machine()->TruncateInt64ToInt32(), a);
756   }
RoundFloat64ToInt32(Node * a)757   Node* RoundFloat64ToInt32(Node* a) {
758     return AddNode(machine()->RoundFloat64ToInt32(), a);
759   }
RoundInt32ToFloat32(Node * a)760   Node* RoundInt32ToFloat32(Node* a) {
761     return AddNode(machine()->RoundInt32ToFloat32(), a);
762   }
RoundInt64ToFloat32(Node * a)763   Node* RoundInt64ToFloat32(Node* a) {
764     return AddNode(machine()->RoundInt64ToFloat32(), a);
765   }
RoundInt64ToFloat64(Node * a)766   Node* RoundInt64ToFloat64(Node* a) {
767     return AddNode(machine()->RoundInt64ToFloat64(), a);
768   }
RoundUint32ToFloat32(Node * a)769   Node* RoundUint32ToFloat32(Node* a) {
770     return AddNode(machine()->RoundUint32ToFloat32(), a);
771   }
RoundUint64ToFloat32(Node * a)772   Node* RoundUint64ToFloat32(Node* a) {
773     return AddNode(machine()->RoundUint64ToFloat32(), a);
774   }
RoundUint64ToFloat64(Node * a)775   Node* RoundUint64ToFloat64(Node* a) {
776     return AddNode(machine()->RoundUint64ToFloat64(), a);
777   }
BitcastFloat32ToInt32(Node * a)778   Node* BitcastFloat32ToInt32(Node* a) {
779     return AddNode(machine()->BitcastFloat32ToInt32(), a);
780   }
BitcastFloat64ToInt64(Node * a)781   Node* BitcastFloat64ToInt64(Node* a) {
782     return AddNode(machine()->BitcastFloat64ToInt64(), a);
783   }
BitcastInt32ToFloat32(Node * a)784   Node* BitcastInt32ToFloat32(Node* a) {
785     return AddNode(machine()->BitcastInt32ToFloat32(), a);
786   }
BitcastInt64ToFloat64(Node * a)787   Node* BitcastInt64ToFloat64(Node* a) {
788     return AddNode(machine()->BitcastInt64ToFloat64(), a);
789   }
Float32RoundDown(Node * a)790   Node* Float32RoundDown(Node* a) {
791     return AddNode(machine()->Float32RoundDown().op(), a);
792   }
Float64RoundDown(Node * a)793   Node* Float64RoundDown(Node* a) {
794     return AddNode(machine()->Float64RoundDown().op(), a);
795   }
Float32RoundUp(Node * a)796   Node* Float32RoundUp(Node* a) {
797     return AddNode(machine()->Float32RoundUp().op(), a);
798   }
Float64RoundUp(Node * a)799   Node* Float64RoundUp(Node* a) {
800     return AddNode(machine()->Float64RoundUp().op(), a);
801   }
Float32RoundTruncate(Node * a)802   Node* Float32RoundTruncate(Node* a) {
803     return AddNode(machine()->Float32RoundTruncate().op(), a);
804   }
Float64RoundTruncate(Node * a)805   Node* Float64RoundTruncate(Node* a) {
806     return AddNode(machine()->Float64RoundTruncate().op(), a);
807   }
Float64RoundTiesAway(Node * a)808   Node* Float64RoundTiesAway(Node* a) {
809     return AddNode(machine()->Float64RoundTiesAway().op(), a);
810   }
Float32RoundTiesEven(Node * a)811   Node* Float32RoundTiesEven(Node* a) {
812     return AddNode(machine()->Float32RoundTiesEven().op(), a);
813   }
Float64RoundTiesEven(Node * a)814   Node* Float64RoundTiesEven(Node* a) {
815     return AddNode(machine()->Float64RoundTiesEven().op(), a);
816   }
Word32ReverseBytes(Node * a)817   Node* Word32ReverseBytes(Node* a) {
818     return AddNode(machine()->Word32ReverseBytes(), a);
819   }
Word64ReverseBytes(Node * a)820   Node* Word64ReverseBytes(Node* a) {
821     return AddNode(machine()->Word64ReverseBytes(), a);
822   }
823 
824   // Float64 bit operations.
Float64ExtractLowWord32(Node * a)825   Node* Float64ExtractLowWord32(Node* a) {
826     return AddNode(machine()->Float64ExtractLowWord32(), a);
827   }
Float64ExtractHighWord32(Node * a)828   Node* Float64ExtractHighWord32(Node* a) {
829     return AddNode(machine()->Float64ExtractHighWord32(), a);
830   }
Float64InsertLowWord32(Node * a,Node * b)831   Node* Float64InsertLowWord32(Node* a, Node* b) {
832     return AddNode(machine()->Float64InsertLowWord32(), a, b);
833   }
Float64InsertHighWord32(Node * a,Node * b)834   Node* Float64InsertHighWord32(Node* a, Node* b) {
835     return AddNode(machine()->Float64InsertHighWord32(), a, b);
836   }
Float64SilenceNaN(Node * a)837   Node* Float64SilenceNaN(Node* a) {
838     return AddNode(machine()->Float64SilenceNaN(), a);
839   }
840 
841   // SIMD operations.
I64x2Splat(Node * a)842   Node* I64x2Splat(Node* a) { return AddNode(machine()->I64x2Splat(), a); }
I64x2SplatI32Pair(Node * a,Node * b)843   Node* I64x2SplatI32Pair(Node* a, Node* b) {
844     return AddNode(machine()->I64x2SplatI32Pair(), a, b);
845   }
I32x4Splat(Node * a)846   Node* I32x4Splat(Node* a) { return AddNode(machine()->I32x4Splat(), a); }
I16x8Splat(Node * a)847   Node* I16x8Splat(Node* a) { return AddNode(machine()->I16x8Splat(), a); }
I8x16Splat(Node * a)848   Node* I8x16Splat(Node* a) { return AddNode(machine()->I8x16Splat(), a); }
849 
850   // Stack operations.
LoadFramePointer()851   Node* LoadFramePointer() { return AddNode(machine()->LoadFramePointer()); }
LoadParentFramePointer()852   Node* LoadParentFramePointer() {
853     return AddNode(machine()->LoadParentFramePointer());
854   }
855 
856   // Parameters.
857   Node* TargetParameter();
858   Node* Parameter(size_t index);
859 
860   // Pointer utilities.
861   Node* LoadFromPointer(void* address, MachineType type, int32_t offset = 0) {
862     return Load(type, PointerConstant(address), Int32Constant(offset));
863   }
StoreToPointer(void * address,MachineRepresentation rep,Node * node)864   Node* StoreToPointer(void* address, MachineRepresentation rep, Node* node) {
865     return Store(rep, PointerConstant(address), node, kNoWriteBarrier);
866   }
867   Node* UnalignedLoadFromPointer(void* address, MachineType type,
868                                  int32_t offset = 0) {
869     return UnalignedLoad(type, PointerConstant(address), Int32Constant(offset));
870   }
UnalignedStoreToPointer(void * address,MachineRepresentation rep,Node * node)871   Node* UnalignedStoreToPointer(void* address, MachineRepresentation rep,
872                                 Node* node) {
873     return UnalignedStore(rep, PointerConstant(address), node);
874   }
StringConstant(const char * string)875   Node* StringConstant(const char* string) {
876     return HeapConstant(isolate()->factory()->InternalizeUtf8String(string));
877   }
878 
TaggedPoisonOnSpeculation(Node * value)879   Node* TaggedPoisonOnSpeculation(Node* value) {
880     if (poisoning_level_ != PoisoningMitigationLevel::kDontPoison) {
881       return AddNode(machine()->TaggedPoisonOnSpeculation(), value);
882     }
883     return value;
884   }
885 
WordPoisonOnSpeculation(Node * value)886   Node* WordPoisonOnSpeculation(Node* value) {
887     if (poisoning_level_ != PoisoningMitigationLevel::kDontPoison) {
888       return AddNode(machine()->WordPoisonOnSpeculation(), value);
889     }
890     return value;
891   }
892 
893   // Call a given call descriptor and the given arguments.
894   // The call target is passed as part of the {inputs} array.
895   Node* CallN(CallDescriptor* call_descriptor, int input_count,
896               Node* const* inputs);
897 
898   // Call a given call descriptor and the given arguments and frame-state.
899   // The call target and frame state are passed as part of the {inputs} array.
900   Node* CallNWithFrameState(CallDescriptor* call_descriptor, int input_count,
901                             Node* const* inputs);
902 
903   // Tail call a given call descriptor and the given arguments.
904   // The call target is passed as part of the {inputs} array.
905   void TailCallN(CallDescriptor* call_descriptor, int input_count,
906                  Node* const* inputs);
907 
908   // Type representing C function argument with type info.
909   using CFunctionArg = std::pair<MachineType, Node*>;
910 
911   // Call to a C function.
912   template <class... CArgs>
CallCFunction(Node * function,MachineType return_type,CArgs...cargs)913   Node* CallCFunction(Node* function, MachineType return_type, CArgs... cargs) {
914     static_assert(v8::internal::conjunction<
915                       std::is_convertible<CArgs, CFunctionArg>...>::value,
916                   "invalid argument types");
917     return CallCFunction(function, return_type, {cargs...});
918   }
919 
920   Node* CallCFunction(Node* function, MachineType return_type,
921                       std::initializer_list<CFunctionArg> args);
922 
923   // Call to a C function without a function discriptor on AIX.
924   template <class... CArgs>
CallCFunctionWithoutFunctionDescriptor(Node * function,MachineType return_type,CArgs...cargs)925   Node* CallCFunctionWithoutFunctionDescriptor(Node* function,
926                                                MachineType return_type,
927                                                CArgs... cargs) {
928     static_assert(v8::internal::conjunction<
929                       std::is_convertible<CArgs, CFunctionArg>...>::value,
930                   "invalid argument types");
931     return CallCFunctionWithoutFunctionDescriptor(function, return_type,
932                                                   {cargs...});
933   }
934 
935   Node* CallCFunctionWithoutFunctionDescriptor(
936       Node* function, MachineType return_type,
937       std::initializer_list<CFunctionArg> args);
938 
939   // Call to a C function, while saving/restoring caller registers.
940   template <class... CArgs>
CallCFunctionWithCallerSavedRegisters(Node * function,MachineType return_type,SaveFPRegsMode mode,CArgs...cargs)941   Node* CallCFunctionWithCallerSavedRegisters(Node* function,
942                                               MachineType return_type,
943                                               SaveFPRegsMode mode,
944                                               CArgs... cargs) {
945     static_assert(v8::internal::conjunction<
946                       std::is_convertible<CArgs, CFunctionArg>...>::value,
947                   "invalid argument types");
948     return CallCFunctionWithCallerSavedRegisters(function, return_type, mode,
949                                                  {cargs...});
950   }
951 
952   Node* CallCFunctionWithCallerSavedRegisters(
953       Node* function, MachineType return_type, SaveFPRegsMode mode,
954       std::initializer_list<CFunctionArg> args);
955 
956   // ===========================================================================
957   // The following utility methods deal with control flow, hence might switch
958   // the current basic block or create new basic blocks for labels.
959 
960   // Control flow.
961   void Goto(RawMachineLabel* label);
962   void Branch(Node* condition, RawMachineLabel* true_val,
963               RawMachineLabel* false_val);
964   void Switch(Node* index, RawMachineLabel* default_label,
965               const int32_t* case_values, RawMachineLabel** case_labels,
966               size_t case_count);
967   void Return(Node* value);
968   void Return(Node* v1, Node* v2);
969   void Return(Node* v1, Node* v2, Node* v3);
970   void Return(Node* v1, Node* v2, Node* v3, Node* v4);
971   void Return(int count, Node* v[]);
972   void PopAndReturn(Node* pop, Node* value);
973   void PopAndReturn(Node* pop, Node* v1, Node* v2);
974   void PopAndReturn(Node* pop, Node* v1, Node* v2, Node* v3);
975   void PopAndReturn(Node* pop, Node* v1, Node* v2, Node* v3, Node* v4);
976   void Bind(RawMachineLabel* label);
977   void Deoptimize(Node* state);
978   void AbortCSAAssert(Node* message);
979   void DebugBreak();
980   void Unreachable();
981   void Comment(const std::string& msg);
982   void StaticAssert(Node* value, const char* source);
983 
984 #if DEBUG
985   void Bind(RawMachineLabel* label, AssemblerDebugInfo info);
986   void SetInitialDebugInformation(AssemblerDebugInfo info);
987   void PrintCurrentBlock(std::ostream& os);
988 #endif  // DEBUG
989   bool InsideBlock();
990 
991   // Add success / exception successor blocks and ends the current block ending
992   // in a potentially throwing call node.
993   void Continuations(Node* call, RawMachineLabel* if_success,
994                      RawMachineLabel* if_exception);
995 
996   // Variables.
Phi(MachineRepresentation rep,Node * n1,Node * n2)997   Node* Phi(MachineRepresentation rep, Node* n1, Node* n2) {
998     return AddNode(common()->Phi(rep, 2), n1, n2, graph()->start());
999   }
Phi(MachineRepresentation rep,Node * n1,Node * n2,Node * n3)1000   Node* Phi(MachineRepresentation rep, Node* n1, Node* n2, Node* n3) {
1001     return AddNode(common()->Phi(rep, 3), n1, n2, n3, graph()->start());
1002   }
Phi(MachineRepresentation rep,Node * n1,Node * n2,Node * n3,Node * n4)1003   Node* Phi(MachineRepresentation rep, Node* n1, Node* n2, Node* n3, Node* n4) {
1004     return AddNode(common()->Phi(rep, 4), n1, n2, n3, n4, graph()->start());
1005   }
1006   Node* Phi(MachineRepresentation rep, int input_count, Node* const* inputs);
1007   void AppendPhiInput(Node* phi, Node* new_input);
1008 
1009   // ===========================================================================
1010   // The following generic node creation methods can be used for operators that
1011   // are not covered by the above utility methods. There should rarely be a need
1012   // to do that outside of testing though.
1013 
1014   Node* AddNode(const Operator* op, int input_count, Node* const* inputs);
1015 
AddNode(const Operator * op)1016   Node* AddNode(const Operator* op) {
1017     return AddNode(op, 0, static_cast<Node* const*>(nullptr));
1018   }
1019 
1020   template <class... TArgs>
AddNode(const Operator * op,Node * n1,TArgs...args)1021   Node* AddNode(const Operator* op, Node* n1, TArgs... args) {
1022     Node* buffer[] = {n1, args...};
1023     return AddNode(op, sizeof...(args) + 1, buffer);
1024   }
1025 
1026   void SetCurrentExternalSourcePosition(FileAndLine file_and_line);
1027   FileAndLine GetCurrentExternalSourcePosition() const;
source_positions()1028   SourcePositionTable* source_positions() { return source_positions_; }
1029 
1030  private:
1031   Node* MakeNode(const Operator* op, int input_count, Node* const* inputs);
1032   BasicBlock* Use(RawMachineLabel* label);
1033   BasicBlock* EnsureBlock(RawMachineLabel* label);
1034   BasicBlock* CurrentBlock();
1035 
1036   // A post-processing pass to add effect and control edges so that the graph
1037   // can be optimized and re-scheduled.
1038   // TODO(tebbi): Move this to a separate class.
1039   void MakeReschedulable();
1040   Node* CreateNodeFromPredecessors(const std::vector<BasicBlock*>& predecessors,
1041                                    const std::vector<Node*>& sidetable,
1042                                    const Operator* op,
1043                                    const std::vector<Node*>& additional_inputs);
1044   void MakePhiBinary(Node* phi, int split_point, Node* left_control,
1045                      Node* right_control);
1046   void MarkControlDeferred(Node* control_input);
1047 
schedule()1048   Schedule* schedule() { return schedule_; }
parameter_count()1049   size_t parameter_count() const { return call_descriptor_->ParameterCount(); }
1050 
1051   static void OptimizeControlFlow(Schedule* schedule, Graph* graph,
1052                                   CommonOperatorBuilder* common);
1053 
1054   Isolate* isolate_;
1055   Graph* graph_;
1056   Schedule* schedule_;
1057   SourcePositionTable* source_positions_;
1058   MachineOperatorBuilder machine_;
1059   CommonOperatorBuilder common_;
1060   SimplifiedOperatorBuilder simplified_;
1061   CallDescriptor* call_descriptor_;
1062   Node* target_parameter_;
1063   NodeVector parameters_;
1064   BasicBlock* current_block_;
1065   PoisoningMitigationLevel poisoning_level_;
1066 };
1067 
1068 class V8_EXPORT_PRIVATE RawMachineLabel final {
1069  public:
1070   enum Type { kDeferred, kNonDeferred };
1071 
1072   explicit RawMachineLabel(Type type = kNonDeferred)
1073       : deferred_(type == kDeferred) {}
1074   ~RawMachineLabel();
1075   RawMachineLabel(const RawMachineLabel&) = delete;
1076   RawMachineLabel& operator=(const RawMachineLabel&) = delete;
1077 
block()1078   BasicBlock* block() const { return block_; }
1079 
1080  private:
1081   BasicBlock* block_ = nullptr;
1082   bool used_ = false;
1083   bool bound_ = false;
1084   bool deferred_;
1085   friend class RawMachineAssembler;
1086 };
1087 
1088 }  // namespace compiler
1089 }  // namespace internal
1090 }  // namespace v8
1091 
1092 #endif  // V8_COMPILER_RAW_MACHINE_ASSEMBLER_H_
1093