• 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 "src/assembler.h"
9 #include "src/compiler/common-operator.h"
10 #include "src/compiler/graph.h"
11 #include "src/compiler/linkage.h"
12 #include "src/compiler/machine-operator.h"
13 #include "src/compiler/node.h"
14 #include "src/compiler/operator.h"
15 #include "src/factory.h"
16 
17 namespace v8 {
18 namespace internal {
19 namespace compiler {
20 
21 class BasicBlock;
22 class RawMachineLabel;
23 class Schedule;
24 
25 
26 // The RawMachineAssembler produces a low-level IR graph. All nodes are wired
27 // into a graph and also placed into a schedule immediately, hence subsequent
28 // code generation can happen without the need for scheduling.
29 //
30 // In order to create a schedule on-the-fly, the assembler keeps track of basic
31 // blocks by having one current basic block being populated and by referencing
32 // other basic blocks through the use of labels.
33 //
34 // Also note that the generated graph is only valid together with the generated
35 // schedule, using one without the other is invalid as the graph is inherently
36 // non-schedulable due to missing control and effect dependencies.
37 class RawMachineAssembler {
38  public:
39   RawMachineAssembler(
40       Isolate* isolate, Graph* graph, CallDescriptor* call_descriptor,
41       MachineRepresentation word = MachineType::PointerRepresentation(),
42       MachineOperatorBuilder::Flags flags =
43           MachineOperatorBuilder::Flag::kNoFlags);
~RawMachineAssembler()44   ~RawMachineAssembler() {}
45 
isolate()46   Isolate* isolate() const { return isolate_; }
graph()47   Graph* graph() const { return graph_; }
zone()48   Zone* zone() const { return graph()->zone(); }
machine()49   MachineOperatorBuilder* machine() { return &machine_; }
common()50   CommonOperatorBuilder* common() { return &common_; }
call_descriptor()51   CallDescriptor* call_descriptor() const { return call_descriptor_; }
52 
53   // Finalizes the schedule and exports it to be used for code generation. Note
54   // that this RawMachineAssembler becomes invalid after export.
55   Schedule* Export();
56 
57   // ===========================================================================
58   // The following utility methods create new nodes with specific operators and
59   // place them into the current basic block. They don't perform control flow,
60   // hence will not switch the current basic block.
61 
NullConstant()62   Node* NullConstant() {
63     return HeapConstant(isolate()->factory()->null_value());
64   }
65 
UndefinedConstant()66   Node* UndefinedConstant() {
67     return HeapConstant(isolate()->factory()->undefined_value());
68   }
69 
70   // Constants.
PointerConstant(void * value)71   Node* PointerConstant(void* value) {
72     return IntPtrConstant(reinterpret_cast<intptr_t>(value));
73   }
IntPtrConstant(intptr_t value)74   Node* IntPtrConstant(intptr_t value) {
75     // TODO(dcarney): mark generated code as unserializable if value != 0.
76     return kPointerSize == 8 ? Int64Constant(value)
77                              : Int32Constant(static_cast<int>(value));
78   }
79   Node* RelocatableIntPtrConstant(intptr_t value, RelocInfo::Mode rmode);
Int32Constant(int32_t value)80   Node* Int32Constant(int32_t value) {
81     return AddNode(common()->Int32Constant(value));
82   }
StackSlot(MachineRepresentation rep)83   Node* StackSlot(MachineRepresentation rep) {
84     return AddNode(machine()->StackSlot(rep));
85   }
Int64Constant(int64_t value)86   Node* Int64Constant(int64_t value) {
87     return AddNode(common()->Int64Constant(value));
88   }
NumberConstant(double value)89   Node* NumberConstant(double value) {
90     return AddNode(common()->NumberConstant(value));
91   }
Float32Constant(float value)92   Node* Float32Constant(float value) {
93     return AddNode(common()->Float32Constant(value));
94   }
Float64Constant(double value)95   Node* Float64Constant(double value) {
96     return AddNode(common()->Float64Constant(value));
97   }
HeapConstant(Handle<HeapObject> object)98   Node* HeapConstant(Handle<HeapObject> object) {
99     return AddNode(common()->HeapConstant(object));
100   }
BooleanConstant(bool value)101   Node* BooleanConstant(bool value) {
102     Handle<Object> object = isolate()->factory()->ToBoolean(value);
103     return HeapConstant(Handle<HeapObject>::cast(object));
104   }
ExternalConstant(ExternalReference address)105   Node* ExternalConstant(ExternalReference address) {
106     return AddNode(common()->ExternalConstant(address));
107   }
RelocatableInt32Constant(int32_t value,RelocInfo::Mode rmode)108   Node* RelocatableInt32Constant(int32_t value, RelocInfo::Mode rmode) {
109     return AddNode(common()->RelocatableInt32Constant(value, rmode));
110   }
RelocatableInt64Constant(int64_t value,RelocInfo::Mode rmode)111   Node* RelocatableInt64Constant(int64_t value, RelocInfo::Mode rmode) {
112     return AddNode(common()->RelocatableInt64Constant(value, rmode));
113   }
114 
Projection(int index,Node * a)115   Node* Projection(int index, Node* a) {
116     return AddNode(common()->Projection(index), a);
117   }
118 
119   // Memory Operations.
Load(MachineType rep,Node * base)120   Node* Load(MachineType rep, Node* base) {
121     return Load(rep, base, IntPtrConstant(0));
122   }
Load(MachineType rep,Node * base,Node * index)123   Node* Load(MachineType rep, Node* base, Node* index) {
124     return AddNode(machine()->Load(rep), base, index);
125   }
Store(MachineRepresentation rep,Node * base,Node * value,WriteBarrierKind write_barrier)126   Node* Store(MachineRepresentation rep, Node* base, Node* value,
127               WriteBarrierKind write_barrier) {
128     return Store(rep, base, IntPtrConstant(0), value, write_barrier);
129   }
Store(MachineRepresentation rep,Node * base,Node * index,Node * value,WriteBarrierKind write_barrier)130   Node* Store(MachineRepresentation rep, Node* base, Node* index, Node* value,
131               WriteBarrierKind write_barrier) {
132     return AddNode(machine()->Store(StoreRepresentation(rep, write_barrier)),
133                    base, index, value);
134   }
135 
136   // Atomic memory operations.
AtomicLoad(MachineType rep,Node * base,Node * index)137   Node* AtomicLoad(MachineType rep, Node* base, Node* index) {
138     return AddNode(machine()->AtomicLoad(rep), base, index);
139   }
AtomicStore(MachineRepresentation rep,Node * base,Node * index,Node * value)140   Node* AtomicStore(MachineRepresentation rep, Node* base, Node* index,
141                     Node* value) {
142     return AddNode(machine()->AtomicStore(rep), base, index, value);
143   }
144 
145   // Arithmetic Operations.
WordAnd(Node * a,Node * b)146   Node* WordAnd(Node* a, Node* b) {
147     return AddNode(machine()->WordAnd(), a, b);
148   }
WordOr(Node * a,Node * b)149   Node* WordOr(Node* a, Node* b) { return AddNode(machine()->WordOr(), a, b); }
WordXor(Node * a,Node * b)150   Node* WordXor(Node* a, Node* b) {
151     return AddNode(machine()->WordXor(), a, b);
152   }
WordShl(Node * a,Node * b)153   Node* WordShl(Node* a, Node* b) {
154     return AddNode(machine()->WordShl(), a, b);
155   }
WordShr(Node * a,Node * b)156   Node* WordShr(Node* a, Node* b) {
157     return AddNode(machine()->WordShr(), a, b);
158   }
WordSar(Node * a,Node * b)159   Node* WordSar(Node* a, Node* b) {
160     return AddNode(machine()->WordSar(), a, b);
161   }
WordRor(Node * a,Node * b)162   Node* WordRor(Node* a, Node* b) {
163     return AddNode(machine()->WordRor(), a, b);
164   }
WordEqual(Node * a,Node * b)165   Node* WordEqual(Node* a, Node* b) {
166     return AddNode(machine()->WordEqual(), a, b);
167   }
WordNotEqual(Node * a,Node * b)168   Node* WordNotEqual(Node* a, Node* b) {
169     return Word32BinaryNot(WordEqual(a, b));
170   }
WordNot(Node * a)171   Node* WordNot(Node* a) {
172     if (machine()->Is32()) {
173       return Word32Not(a);
174     } else {
175       return Word64Not(a);
176     }
177   }
178 
Word32And(Node * a,Node * b)179   Node* Word32And(Node* a, Node* b) {
180     return AddNode(machine()->Word32And(), a, b);
181   }
Word32Or(Node * a,Node * b)182   Node* Word32Or(Node* a, Node* b) {
183     return AddNode(machine()->Word32Or(), a, b);
184   }
Word32Xor(Node * a,Node * b)185   Node* Word32Xor(Node* a, Node* b) {
186     return AddNode(machine()->Word32Xor(), a, b);
187   }
Word32Shl(Node * a,Node * b)188   Node* Word32Shl(Node* a, Node* b) {
189     return AddNode(machine()->Word32Shl(), a, b);
190   }
Word32Shr(Node * a,Node * b)191   Node* Word32Shr(Node* a, Node* b) {
192     return AddNode(machine()->Word32Shr(), a, b);
193   }
Word32Sar(Node * a,Node * b)194   Node* Word32Sar(Node* a, Node* b) {
195     return AddNode(machine()->Word32Sar(), a, b);
196   }
Word32Ror(Node * a,Node * b)197   Node* Word32Ror(Node* a, Node* b) {
198     return AddNode(machine()->Word32Ror(), a, b);
199   }
Word32Clz(Node * a)200   Node* Word32Clz(Node* a) { return AddNode(machine()->Word32Clz(), a); }
Word32Equal(Node * a,Node * b)201   Node* Word32Equal(Node* a, Node* b) {
202     return AddNode(machine()->Word32Equal(), a, b);
203   }
Word32NotEqual(Node * a,Node * b)204   Node* Word32NotEqual(Node* a, Node* b) {
205     return Word32BinaryNot(Word32Equal(a, b));
206   }
Word32Not(Node * a)207   Node* Word32Not(Node* a) { return Word32Xor(a, Int32Constant(-1)); }
Word32BinaryNot(Node * a)208   Node* Word32BinaryNot(Node* a) { return Word32Equal(a, Int32Constant(0)); }
209 
Word64And(Node * a,Node * b)210   Node* Word64And(Node* a, Node* b) {
211     return AddNode(machine()->Word64And(), a, b);
212   }
Word64Or(Node * a,Node * b)213   Node* Word64Or(Node* a, Node* b) {
214     return AddNode(machine()->Word64Or(), a, b);
215   }
Word64Xor(Node * a,Node * b)216   Node* Word64Xor(Node* a, Node* b) {
217     return AddNode(machine()->Word64Xor(), a, b);
218   }
Word64Shl(Node * a,Node * b)219   Node* Word64Shl(Node* a, Node* b) {
220     return AddNode(machine()->Word64Shl(), a, b);
221   }
Word64Shr(Node * a,Node * b)222   Node* Word64Shr(Node* a, Node* b) {
223     return AddNode(machine()->Word64Shr(), a, b);
224   }
Word64Sar(Node * a,Node * b)225   Node* Word64Sar(Node* a, Node* b) {
226     return AddNode(machine()->Word64Sar(), a, b);
227   }
Word64Ror(Node * a,Node * b)228   Node* Word64Ror(Node* a, Node* b) {
229     return AddNode(machine()->Word64Ror(), a, b);
230   }
Word64Clz(Node * a)231   Node* Word64Clz(Node* a) { return AddNode(machine()->Word64Clz(), a); }
Word64Equal(Node * a,Node * b)232   Node* Word64Equal(Node* a, Node* b) {
233     return AddNode(machine()->Word64Equal(), a, b);
234   }
Word64NotEqual(Node * a,Node * b)235   Node* Word64NotEqual(Node* a, Node* b) {
236     return Word32BinaryNot(Word64Equal(a, b));
237   }
Word64Not(Node * a)238   Node* Word64Not(Node* a) { return Word64Xor(a, Int64Constant(-1)); }
239 
Int32Add(Node * a,Node * b)240   Node* Int32Add(Node* a, Node* b) {
241     return AddNode(machine()->Int32Add(), a, b);
242   }
Int32AddWithOverflow(Node * a,Node * b)243   Node* Int32AddWithOverflow(Node* a, Node* b) {
244     return AddNode(machine()->Int32AddWithOverflow(), a, b);
245   }
Int32Sub(Node * a,Node * b)246   Node* Int32Sub(Node* a, Node* b) {
247     return AddNode(machine()->Int32Sub(), a, b);
248   }
Int32SubWithOverflow(Node * a,Node * b)249   Node* Int32SubWithOverflow(Node* a, Node* b) {
250     return AddNode(machine()->Int32SubWithOverflow(), a, b);
251   }
Int32Mul(Node * a,Node * b)252   Node* Int32Mul(Node* a, Node* b) {
253     return AddNode(machine()->Int32Mul(), a, b);
254   }
Int32MulHigh(Node * a,Node * b)255   Node* Int32MulHigh(Node* a, Node* b) {
256     return AddNode(machine()->Int32MulHigh(), a, b);
257   }
Int32Div(Node * a,Node * b)258   Node* Int32Div(Node* a, Node* b) {
259     return AddNode(machine()->Int32Div(), a, b);
260   }
Int32Mod(Node * a,Node * b)261   Node* Int32Mod(Node* a, Node* b) {
262     return AddNode(machine()->Int32Mod(), a, b);
263   }
Int32LessThan(Node * a,Node * b)264   Node* Int32LessThan(Node* a, Node* b) {
265     return AddNode(machine()->Int32LessThan(), a, b);
266   }
Int32LessThanOrEqual(Node * a,Node * b)267   Node* Int32LessThanOrEqual(Node* a, Node* b) {
268     return AddNode(machine()->Int32LessThanOrEqual(), a, b);
269   }
Uint32Div(Node * a,Node * b)270   Node* Uint32Div(Node* a, Node* b) {
271     return AddNode(machine()->Uint32Div(), a, b);
272   }
Uint32LessThan(Node * a,Node * b)273   Node* Uint32LessThan(Node* a, Node* b) {
274     return AddNode(machine()->Uint32LessThan(), a, b);
275   }
Uint32LessThanOrEqual(Node * a,Node * b)276   Node* Uint32LessThanOrEqual(Node* a, Node* b) {
277     return AddNode(machine()->Uint32LessThanOrEqual(), a, b);
278   }
Uint32Mod(Node * a,Node * b)279   Node* Uint32Mod(Node* a, Node* b) {
280     return AddNode(machine()->Uint32Mod(), a, b);
281   }
Uint32MulHigh(Node * a,Node * b)282   Node* Uint32MulHigh(Node* a, Node* b) {
283     return AddNode(machine()->Uint32MulHigh(), a, b);
284   }
Int32GreaterThan(Node * a,Node * b)285   Node* Int32GreaterThan(Node* a, Node* b) { return Int32LessThan(b, a); }
Int32GreaterThanOrEqual(Node * a,Node * b)286   Node* Int32GreaterThanOrEqual(Node* a, Node* b) {
287     return Int32LessThanOrEqual(b, a);
288   }
Uint32GreaterThan(Node * a,Node * b)289   Node* Uint32GreaterThan(Node* a, Node* b) { return Uint32LessThan(b, a); }
Uint32GreaterThanOrEqual(Node * a,Node * b)290   Node* Uint32GreaterThanOrEqual(Node* a, Node* b) {
291     return Uint32LessThanOrEqual(b, a);
292   }
Int32Neg(Node * a)293   Node* Int32Neg(Node* a) { return Int32Sub(Int32Constant(0), a); }
294 
Int64Add(Node * a,Node * b)295   Node* Int64Add(Node* a, Node* b) {
296     return AddNode(machine()->Int64Add(), a, b);
297   }
Int64AddWithOverflow(Node * a,Node * b)298   Node* Int64AddWithOverflow(Node* a, Node* b) {
299     return AddNode(machine()->Int64AddWithOverflow(), a, b);
300   }
Int64Sub(Node * a,Node * b)301   Node* Int64Sub(Node* a, Node* b) {
302     return AddNode(machine()->Int64Sub(), a, b);
303   }
Int64SubWithOverflow(Node * a,Node * b)304   Node* Int64SubWithOverflow(Node* a, Node* b) {
305     return AddNode(machine()->Int64SubWithOverflow(), a, b);
306   }
Int64Mul(Node * a,Node * b)307   Node* Int64Mul(Node* a, Node* b) {
308     return AddNode(machine()->Int64Mul(), a, b);
309   }
Int64Div(Node * a,Node * b)310   Node* Int64Div(Node* a, Node* b) {
311     return AddNode(machine()->Int64Div(), a, b);
312   }
Int64Mod(Node * a,Node * b)313   Node* Int64Mod(Node* a, Node* b) {
314     return AddNode(machine()->Int64Mod(), a, b);
315   }
Int64Neg(Node * a)316   Node* Int64Neg(Node* a) { return Int64Sub(Int64Constant(0), a); }
Int64LessThan(Node * a,Node * b)317   Node* Int64LessThan(Node* a, Node* b) {
318     return AddNode(machine()->Int64LessThan(), a, b);
319   }
Int64LessThanOrEqual(Node * a,Node * b)320   Node* Int64LessThanOrEqual(Node* a, Node* b) {
321     return AddNode(machine()->Int64LessThanOrEqual(), a, b);
322   }
Uint64LessThan(Node * a,Node * b)323   Node* Uint64LessThan(Node* a, Node* b) {
324     return AddNode(machine()->Uint64LessThan(), a, b);
325   }
Uint64LessThanOrEqual(Node * a,Node * b)326   Node* Uint64LessThanOrEqual(Node* a, Node* b) {
327     return AddNode(machine()->Uint64LessThanOrEqual(), a, b);
328   }
Int64GreaterThan(Node * a,Node * b)329   Node* Int64GreaterThan(Node* a, Node* b) { return Int64LessThan(b, a); }
Int64GreaterThanOrEqual(Node * a,Node * b)330   Node* Int64GreaterThanOrEqual(Node* a, Node* b) {
331     return Int64LessThanOrEqual(b, a);
332   }
Uint64GreaterThan(Node * a,Node * b)333   Node* Uint64GreaterThan(Node* a, Node* b) { return Uint64LessThan(b, a); }
Uint64GreaterThanOrEqual(Node * a,Node * b)334   Node* Uint64GreaterThanOrEqual(Node* a, Node* b) {
335     return Uint64LessThanOrEqual(b, a);
336   }
Uint64Div(Node * a,Node * b)337   Node* Uint64Div(Node* a, Node* b) {
338     return AddNode(machine()->Uint64Div(), a, b);
339   }
Uint64Mod(Node * a,Node * b)340   Node* Uint64Mod(Node* a, Node* b) {
341     return AddNode(machine()->Uint64Mod(), a, b);
342   }
Int32PairAdd(Node * a_low,Node * a_high,Node * b_low,Node * b_high)343   Node* Int32PairAdd(Node* a_low, Node* a_high, Node* b_low, Node* b_high) {
344     return AddNode(machine()->Int32PairAdd(), a_low, a_high, b_low, b_high);
345   }
Int32PairSub(Node * a_low,Node * a_high,Node * b_low,Node * b_high)346   Node* Int32PairSub(Node* a_low, Node* a_high, Node* b_low, Node* b_high) {
347     return AddNode(machine()->Int32PairSub(), a_low, a_high, b_low, b_high);
348   }
Int32PairMul(Node * a_low,Node * a_high,Node * b_low,Node * b_high)349   Node* Int32PairMul(Node* a_low, Node* a_high, Node* b_low, Node* b_high) {
350     return AddNode(machine()->Int32PairMul(), a_low, a_high, b_low, b_high);
351   }
Word32PairShl(Node * low_word,Node * high_word,Node * shift)352   Node* Word32PairShl(Node* low_word, Node* high_word, Node* shift) {
353     return AddNode(machine()->Word32PairShl(), low_word, high_word, shift);
354   }
Word32PairShr(Node * low_word,Node * high_word,Node * shift)355   Node* Word32PairShr(Node* low_word, Node* high_word, Node* shift) {
356     return AddNode(machine()->Word32PairShr(), low_word, high_word, shift);
357   }
Word32PairSar(Node * low_word,Node * high_word,Node * shift)358   Node* Word32PairSar(Node* low_word, Node* high_word, Node* shift) {
359     return AddNode(machine()->Word32PairSar(), low_word, high_word, shift);
360   }
361 
362 #define INTPTR_BINOP(prefix, name)                     \
363   Node* IntPtr##name(Node* a, Node* b) {               \
364     return kPointerSize == 8 ? prefix##64##name(a, b)  \
365                              : prefix##32##name(a, b); \
366   }
367 
368   INTPTR_BINOP(Int, Add);
369   INTPTR_BINOP(Int, AddWithOverflow);
370   INTPTR_BINOP(Int, Sub);
371   INTPTR_BINOP(Int, SubWithOverflow);
372   INTPTR_BINOP(Int, Mul);
373   INTPTR_BINOP(Int, Div);
374   INTPTR_BINOP(Int, LessThan);
375   INTPTR_BINOP(Int, LessThanOrEqual);
376   INTPTR_BINOP(Word, Equal);
377   INTPTR_BINOP(Word, NotEqual);
378   INTPTR_BINOP(Int, GreaterThanOrEqual);
379   INTPTR_BINOP(Int, GreaterThan);
380 
381 #undef INTPTR_BINOP
382 
383 #define UINTPTR_BINOP(prefix, name)                    \
384   Node* UintPtr##name(Node* a, Node* b) {              \
385     return kPointerSize == 8 ? prefix##64##name(a, b)  \
386                              : prefix##32##name(a, b); \
387   }
388 
389   UINTPTR_BINOP(Uint, LessThan);
390   UINTPTR_BINOP(Uint, LessThanOrEqual);
391   UINTPTR_BINOP(Uint, GreaterThanOrEqual);
392   UINTPTR_BINOP(Uint, GreaterThan);
393 
394 #undef UINTPTR_BINOP
395 
Float32Add(Node * a,Node * b)396   Node* Float32Add(Node* a, Node* b) {
397     return AddNode(machine()->Float32Add(), a, b);
398   }
Float32Sub(Node * a,Node * b)399   Node* Float32Sub(Node* a, Node* b) {
400     return AddNode(machine()->Float32Sub(), a, b);
401   }
Float32SubPreserveNan(Node * a,Node * b)402   Node* Float32SubPreserveNan(Node* a, Node* b) {
403     return AddNode(machine()->Float32SubPreserveNan(), a, b);
404   }
Float32Mul(Node * a,Node * b)405   Node* Float32Mul(Node* a, Node* b) {
406     return AddNode(machine()->Float32Mul(), a, b);
407   }
Float32Div(Node * a,Node * b)408   Node* Float32Div(Node* a, Node* b) {
409     return AddNode(machine()->Float32Div(), a, b);
410   }
Float32Max(Node * a,Node * b)411   Node* Float32Max(Node* a, Node* b) {
412     return AddNode(machine()->Float32Max().op(), a, b);
413   }
Float32Min(Node * a,Node * b)414   Node* Float32Min(Node* a, Node* b) {
415     return AddNode(machine()->Float32Min().op(), a, b);
416   }
Float32Abs(Node * a)417   Node* Float32Abs(Node* a) { return AddNode(machine()->Float32Abs(), a); }
Float32Neg(Node * a)418   Node* Float32Neg(Node* a) { return Float32Sub(Float32Constant(-0.0f), a); }
Float32Sqrt(Node * a)419   Node* Float32Sqrt(Node* a) { return AddNode(machine()->Float32Sqrt(), a); }
Float32Equal(Node * a,Node * b)420   Node* Float32Equal(Node* a, Node* b) {
421     return AddNode(machine()->Float32Equal(), a, b);
422   }
Float32NotEqual(Node * a,Node * b)423   Node* Float32NotEqual(Node* a, Node* b) {
424     return Word32BinaryNot(Float32Equal(a, b));
425   }
Float32LessThan(Node * a,Node * b)426   Node* Float32LessThan(Node* a, Node* b) {
427     return AddNode(machine()->Float32LessThan(), a, b);
428   }
Float32LessThanOrEqual(Node * a,Node * b)429   Node* Float32LessThanOrEqual(Node* a, Node* b) {
430     return AddNode(machine()->Float32LessThanOrEqual(), a, b);
431   }
Float32GreaterThan(Node * a,Node * b)432   Node* Float32GreaterThan(Node* a, Node* b) { return Float32LessThan(b, a); }
Float32GreaterThanOrEqual(Node * a,Node * b)433   Node* Float32GreaterThanOrEqual(Node* a, Node* b) {
434     return Float32LessThanOrEqual(b, a);
435   }
436 
Float64Add(Node * a,Node * b)437   Node* Float64Add(Node* a, Node* b) {
438     return AddNode(machine()->Float64Add(), a, b);
439   }
Float64Sub(Node * a,Node * b)440   Node* Float64Sub(Node* a, Node* b) {
441     return AddNode(machine()->Float64Sub(), a, b);
442   }
Float64SubPreserveNan(Node * a,Node * b)443   Node* Float64SubPreserveNan(Node* a, Node* b) {
444     return AddNode(machine()->Float64SubPreserveNan(), a, b);
445   }
Float64Mul(Node * a,Node * b)446   Node* Float64Mul(Node* a, Node* b) {
447     return AddNode(machine()->Float64Mul(), a, b);
448   }
Float64Div(Node * a,Node * b)449   Node* Float64Div(Node* a, Node* b) {
450     return AddNode(machine()->Float64Div(), a, b);
451   }
Float64Mod(Node * a,Node * b)452   Node* Float64Mod(Node* a, Node* b) {
453     return AddNode(machine()->Float64Mod(), a, b);
454   }
Float64Max(Node * a,Node * b)455   Node* Float64Max(Node* a, Node* b) {
456     return AddNode(machine()->Float64Max().op(), a, b);
457   }
Float64Min(Node * a,Node * b)458   Node* Float64Min(Node* a, Node* b) {
459     return AddNode(machine()->Float64Min().op(), a, b);
460   }
Float64Abs(Node * a)461   Node* Float64Abs(Node* a) { return AddNode(machine()->Float64Abs(), a); }
Float64Neg(Node * a)462   Node* Float64Neg(Node* a) { return Float64Sub(Float64Constant(-0.0), a); }
Float64Atan(Node * a)463   Node* Float64Atan(Node* a) { return AddNode(machine()->Float64Atan(), a); }
Float64Atan2(Node * a,Node * b)464   Node* Float64Atan2(Node* a, Node* b) {
465     return AddNode(machine()->Float64Atan2(), a, b);
466   }
Float64Atanh(Node * a)467   Node* Float64Atanh(Node* a) { return AddNode(machine()->Float64Atanh(), a); }
Float64Cbrt(Node * a)468   Node* Float64Cbrt(Node* a) { return AddNode(machine()->Float64Cbrt(), a); }
Float64Cos(Node * a)469   Node* Float64Cos(Node* a) { return AddNode(machine()->Float64Cos(), a); }
Float64Exp(Node * a)470   Node* Float64Exp(Node* a) { return AddNode(machine()->Float64Exp(), a); }
Float64Expm1(Node * a)471   Node* Float64Expm1(Node* a) { return AddNode(machine()->Float64Expm1(), a); }
Float64Log(Node * a)472   Node* Float64Log(Node* a) { return AddNode(machine()->Float64Log(), a); }
Float64Log1p(Node * a)473   Node* Float64Log1p(Node* a) { return AddNode(machine()->Float64Log1p(), a); }
Float64Log10(Node * a)474   Node* Float64Log10(Node* a) { return AddNode(machine()->Float64Log10(), a); }
Float64Log2(Node * a)475   Node* Float64Log2(Node* a) { return AddNode(machine()->Float64Log2(), a); }
Float64Sin(Node * a)476   Node* Float64Sin(Node* a) { return AddNode(machine()->Float64Sin(), a); }
Float64Sqrt(Node * a)477   Node* Float64Sqrt(Node* a) { return AddNode(machine()->Float64Sqrt(), a); }
Float64Tan(Node * a)478   Node* Float64Tan(Node* a) { return AddNode(machine()->Float64Tan(), a); }
Float64Equal(Node * a,Node * b)479   Node* Float64Equal(Node* a, Node* b) {
480     return AddNode(machine()->Float64Equal(), a, b);
481   }
Float64NotEqual(Node * a,Node * b)482   Node* Float64NotEqual(Node* a, Node* b) {
483     return Word32BinaryNot(Float64Equal(a, b));
484   }
Float64LessThan(Node * a,Node * b)485   Node* Float64LessThan(Node* a, Node* b) {
486     return AddNode(machine()->Float64LessThan(), a, b);
487   }
Float64LessThanOrEqual(Node * a,Node * b)488   Node* Float64LessThanOrEqual(Node* a, Node* b) {
489     return AddNode(machine()->Float64LessThanOrEqual(), a, b);
490   }
Float64GreaterThan(Node * a,Node * b)491   Node* Float64GreaterThan(Node* a, Node* b) { return Float64LessThan(b, a); }
Float64GreaterThanOrEqual(Node * a,Node * b)492   Node* Float64GreaterThanOrEqual(Node* a, Node* b) {
493     return Float64LessThanOrEqual(b, a);
494   }
495 
496   // Conversions.
BitcastWordToTagged(Node * a)497   Node* BitcastWordToTagged(Node* a) {
498     return AddNode(machine()->BitcastWordToTagged(), a);
499   }
TruncateFloat64ToWord32(Node * a)500   Node* TruncateFloat64ToWord32(Node* a) {
501     return AddNode(machine()->TruncateFloat64ToWord32(), a);
502   }
ChangeFloat32ToFloat64(Node * a)503   Node* ChangeFloat32ToFloat64(Node* a) {
504     return AddNode(machine()->ChangeFloat32ToFloat64(), a);
505   }
ChangeInt32ToFloat64(Node * a)506   Node* ChangeInt32ToFloat64(Node* a) {
507     return AddNode(machine()->ChangeInt32ToFloat64(), a);
508   }
ChangeUint32ToFloat64(Node * a)509   Node* ChangeUint32ToFloat64(Node* a) {
510     return AddNode(machine()->ChangeUint32ToFloat64(), a);
511   }
ChangeFloat64ToInt32(Node * a)512   Node* ChangeFloat64ToInt32(Node* a) {
513     return AddNode(machine()->ChangeFloat64ToInt32(), a);
514   }
ChangeFloat64ToUint32(Node * a)515   Node* ChangeFloat64ToUint32(Node* a) {
516     return AddNode(machine()->ChangeFloat64ToUint32(), a);
517   }
TruncateFloat64ToUint32(Node * a)518   Node* TruncateFloat64ToUint32(Node* a) {
519     return AddNode(machine()->TruncateFloat64ToUint32(), a);
520   }
TruncateFloat32ToInt32(Node * a)521   Node* TruncateFloat32ToInt32(Node* a) {
522     return AddNode(machine()->TruncateFloat32ToInt32(), a);
523   }
TruncateFloat32ToUint32(Node * a)524   Node* TruncateFloat32ToUint32(Node* a) {
525     return AddNode(machine()->TruncateFloat32ToUint32(), a);
526   }
TryTruncateFloat32ToInt64(Node * a)527   Node* TryTruncateFloat32ToInt64(Node* a) {
528     return AddNode(machine()->TryTruncateFloat32ToInt64(), a);
529   }
TryTruncateFloat64ToInt64(Node * a)530   Node* TryTruncateFloat64ToInt64(Node* a) {
531     return AddNode(machine()->TryTruncateFloat64ToInt64(), a);
532   }
TryTruncateFloat32ToUint64(Node * a)533   Node* TryTruncateFloat32ToUint64(Node* a) {
534     return AddNode(machine()->TryTruncateFloat32ToUint64(), a);
535   }
TryTruncateFloat64ToUint64(Node * a)536   Node* TryTruncateFloat64ToUint64(Node* a) {
537     return AddNode(machine()->TryTruncateFloat64ToUint64(), a);
538   }
ChangeInt32ToInt64(Node * a)539   Node* ChangeInt32ToInt64(Node* a) {
540     return AddNode(machine()->ChangeInt32ToInt64(), a);
541   }
ChangeUint32ToUint64(Node * a)542   Node* ChangeUint32ToUint64(Node* a) {
543     return AddNode(machine()->ChangeUint32ToUint64(), a);
544   }
TruncateFloat64ToFloat32(Node * a)545   Node* TruncateFloat64ToFloat32(Node* a) {
546     return AddNode(machine()->TruncateFloat64ToFloat32(), a);
547   }
TruncateInt64ToInt32(Node * a)548   Node* TruncateInt64ToInt32(Node* a) {
549     return AddNode(machine()->TruncateInt64ToInt32(), a);
550   }
RoundFloat64ToInt32(Node * a)551   Node* RoundFloat64ToInt32(Node* a) {
552     return AddNode(machine()->RoundFloat64ToInt32(), a);
553   }
RoundInt32ToFloat32(Node * a)554   Node* RoundInt32ToFloat32(Node* a) {
555     return AddNode(machine()->RoundInt32ToFloat32(), a);
556   }
RoundInt64ToFloat32(Node * a)557   Node* RoundInt64ToFloat32(Node* a) {
558     return AddNode(machine()->RoundInt64ToFloat32(), a);
559   }
RoundInt64ToFloat64(Node * a)560   Node* RoundInt64ToFloat64(Node* a) {
561     return AddNode(machine()->RoundInt64ToFloat64(), a);
562   }
RoundUint32ToFloat32(Node * a)563   Node* RoundUint32ToFloat32(Node* a) {
564     return AddNode(machine()->RoundUint32ToFloat32(), a);
565   }
RoundUint64ToFloat32(Node * a)566   Node* RoundUint64ToFloat32(Node* a) {
567     return AddNode(machine()->RoundUint64ToFloat32(), a);
568   }
RoundUint64ToFloat64(Node * a)569   Node* RoundUint64ToFloat64(Node* a) {
570     return AddNode(machine()->RoundUint64ToFloat64(), a);
571   }
BitcastFloat32ToInt32(Node * a)572   Node* BitcastFloat32ToInt32(Node* a) {
573     return AddNode(machine()->BitcastFloat32ToInt32(), a);
574   }
BitcastFloat64ToInt64(Node * a)575   Node* BitcastFloat64ToInt64(Node* a) {
576     return AddNode(machine()->BitcastFloat64ToInt64(), a);
577   }
BitcastInt32ToFloat32(Node * a)578   Node* BitcastInt32ToFloat32(Node* a) {
579     return AddNode(machine()->BitcastInt32ToFloat32(), a);
580   }
BitcastInt64ToFloat64(Node * a)581   Node* BitcastInt64ToFloat64(Node* a) {
582     return AddNode(machine()->BitcastInt64ToFloat64(), a);
583   }
Float32RoundDown(Node * a)584   Node* Float32RoundDown(Node* a) {
585     return AddNode(machine()->Float32RoundDown().op(), a);
586   }
Float64RoundDown(Node * a)587   Node* Float64RoundDown(Node* a) {
588     return AddNode(machine()->Float64RoundDown().op(), a);
589   }
Float32RoundUp(Node * a)590   Node* Float32RoundUp(Node* a) {
591     return AddNode(machine()->Float32RoundUp().op(), a);
592   }
Float64RoundUp(Node * a)593   Node* Float64RoundUp(Node* a) {
594     return AddNode(machine()->Float64RoundUp().op(), a);
595   }
Float32RoundTruncate(Node * a)596   Node* Float32RoundTruncate(Node* a) {
597     return AddNode(machine()->Float32RoundTruncate().op(), a);
598   }
Float64RoundTruncate(Node * a)599   Node* Float64RoundTruncate(Node* a) {
600     return AddNode(machine()->Float64RoundTruncate().op(), a);
601   }
Float64RoundTiesAway(Node * a)602   Node* Float64RoundTiesAway(Node* a) {
603     return AddNode(machine()->Float64RoundTiesAway().op(), a);
604   }
Float32RoundTiesEven(Node * a)605   Node* Float32RoundTiesEven(Node* a) {
606     return AddNode(machine()->Float32RoundTiesEven().op(), a);
607   }
Float64RoundTiesEven(Node * a)608   Node* Float64RoundTiesEven(Node* a) {
609     return AddNode(machine()->Float64RoundTiesEven().op(), a);
610   }
611 
612   // Float64 bit operations.
Float64ExtractLowWord32(Node * a)613   Node* Float64ExtractLowWord32(Node* a) {
614     return AddNode(machine()->Float64ExtractLowWord32(), a);
615   }
Float64ExtractHighWord32(Node * a)616   Node* Float64ExtractHighWord32(Node* a) {
617     return AddNode(machine()->Float64ExtractHighWord32(), a);
618   }
Float64InsertLowWord32(Node * a,Node * b)619   Node* Float64InsertLowWord32(Node* a, Node* b) {
620     return AddNode(machine()->Float64InsertLowWord32(), a, b);
621   }
Float64InsertHighWord32(Node * a,Node * b)622   Node* Float64InsertHighWord32(Node* a, Node* b) {
623     return AddNode(machine()->Float64InsertHighWord32(), a, b);
624   }
625 
626   // Stack operations.
LoadStackPointer()627   Node* LoadStackPointer() { return AddNode(machine()->LoadStackPointer()); }
LoadFramePointer()628   Node* LoadFramePointer() { return AddNode(machine()->LoadFramePointer()); }
LoadParentFramePointer()629   Node* LoadParentFramePointer() {
630     return AddNode(machine()->LoadParentFramePointer());
631   }
632 
633   // Parameters.
634   Node* Parameter(size_t index);
635 
636   // Pointer utilities.
637   Node* LoadFromPointer(void* address, MachineType rep, int32_t offset = 0) {
638     return Load(rep, PointerConstant(address), Int32Constant(offset));
639   }
StoreToPointer(void * address,MachineRepresentation rep,Node * node)640   Node* StoreToPointer(void* address, MachineRepresentation rep, Node* node) {
641     return Store(rep, PointerConstant(address), node, kNoWriteBarrier);
642   }
StringConstant(const char * string)643   Node* StringConstant(const char* string) {
644     return HeapConstant(isolate()->factory()->InternalizeUtf8String(string));
645   }
646 
647   // Call a given call descriptor and the given arguments.
648   Node* CallN(CallDescriptor* desc, Node* function, Node** args);
649   // Call a given call descriptor and the given arguments and frame-state.
650   Node* CallNWithFrameState(CallDescriptor* desc, Node* function, Node** args,
651                             Node* frame_state);
652   // Call to a runtime function with zero arguments.
653   Node* CallRuntime0(Runtime::FunctionId function, Node* context);
654   // Call to a runtime function with one arguments.
655   Node* CallRuntime1(Runtime::FunctionId function, Node* arg0, Node* context);
656   // Call to a runtime function with two arguments.
657   Node* CallRuntime2(Runtime::FunctionId function, Node* arg1, Node* arg2,
658                      Node* context);
659   // Call to a runtime function with three arguments.
660   Node* CallRuntime3(Runtime::FunctionId function, Node* arg1, Node* arg2,
661                      Node* arg3, Node* context);
662   // Call to a runtime function with four arguments.
663   Node* CallRuntime4(Runtime::FunctionId function, Node* arg1, Node* arg2,
664                      Node* arg3, Node* arg4, Node* context);
665   // Call to a C function with zero arguments.
666   Node* CallCFunction0(MachineType return_type, Node* function);
667   // Call to a C function with one parameter.
668   Node* CallCFunction1(MachineType return_type, MachineType arg0_type,
669                        Node* function, Node* arg0);
670   // Call to a C function with two arguments.
671   Node* CallCFunction2(MachineType return_type, MachineType arg0_type,
672                        MachineType arg1_type, Node* function, Node* arg0,
673                        Node* arg1);
674   // Call to a C function with eight arguments.
675   Node* CallCFunction8(MachineType return_type, MachineType arg0_type,
676                        MachineType arg1_type, MachineType arg2_type,
677                        MachineType arg3_type, MachineType arg4_type,
678                        MachineType arg5_type, MachineType arg6_type,
679                        MachineType arg7_type, Node* function, Node* arg0,
680                        Node* arg1, Node* arg2, Node* arg3, Node* arg4,
681                        Node* arg5, Node* arg6, Node* arg7);
682 
683   // Tail call the given call descriptor and the given arguments.
684   Node* TailCallN(CallDescriptor* call_descriptor, Node* function, Node** args);
685   // Tail call to a runtime function with zero arguments.
686   Node* TailCallRuntime0(Runtime::FunctionId function, Node* context);
687   // Tail call to a runtime function with one argument.
688   Node* TailCallRuntime1(Runtime::FunctionId function, Node* arg0,
689                          Node* context);
690   // Tail call to a runtime function with two arguments.
691   Node* TailCallRuntime2(Runtime::FunctionId function, Node* arg1, Node* arg2,
692                          Node* context);
693   // Tail call to a runtime function with three arguments.
694   Node* TailCallRuntime3(Runtime::FunctionId function, Node* arg1, Node* arg2,
695                          Node* arg3, Node* context);
696   // Tail call to a runtime function with four arguments.
697   Node* TailCallRuntime4(Runtime::FunctionId function, Node* arg1, Node* arg2,
698                          Node* arg3, Node* arg4, Node* context);
699 
700   // ===========================================================================
701   // The following utility methods deal with control flow, hence might switch
702   // the current basic block or create new basic blocks for labels.
703 
704   // Control flow.
705   void Goto(RawMachineLabel* label);
706   void Branch(Node* condition, RawMachineLabel* true_val,
707               RawMachineLabel* false_val);
708   void Switch(Node* index, RawMachineLabel* default_label, int32_t* case_values,
709               RawMachineLabel** case_labels, size_t case_count);
710   void Return(Node* value);
711   void Return(Node* v1, Node* v2);
712   void Return(Node* v1, Node* v2, Node* v3);
713   void Bind(RawMachineLabel* label);
714   void Deoptimize(Node* state);
715   void DebugBreak();
716   void Comment(const char* msg);
717 
718   // Variables.
Phi(MachineRepresentation rep,Node * n1,Node * n2)719   Node* Phi(MachineRepresentation rep, Node* n1, Node* n2) {
720     return AddNode(common()->Phi(rep, 2), n1, n2, graph()->start());
721   }
Phi(MachineRepresentation rep,Node * n1,Node * n2,Node * n3)722   Node* Phi(MachineRepresentation rep, Node* n1, Node* n2, Node* n3) {
723     return AddNode(common()->Phi(rep, 3), n1, n2, n3, graph()->start());
724   }
Phi(MachineRepresentation rep,Node * n1,Node * n2,Node * n3,Node * n4)725   Node* Phi(MachineRepresentation rep, Node* n1, Node* n2, Node* n3, Node* n4) {
726     return AddNode(common()->Phi(rep, 4), n1, n2, n3, n4, graph()->start());
727   }
728   Node* Phi(MachineRepresentation rep, int input_count, Node* const* inputs);
729   void AppendPhiInput(Node* phi, Node* new_input);
730 
731   // ===========================================================================
732   // The following generic node creation methods can be used for operators that
733   // are not covered by the above utility methods. There should rarely be a need
734   // to do that outside of testing though.
735 
736   Node* AddNode(const Operator* op, int input_count, Node* const* inputs);
737 
AddNode(const Operator * op)738   Node* AddNode(const Operator* op) {
739     return AddNode(op, 0, static_cast<Node* const*>(nullptr));
740   }
741 
742   template <class... TArgs>
AddNode(const Operator * op,Node * n1,TArgs...args)743   Node* AddNode(const Operator* op, Node* n1, TArgs... args) {
744     Node* buffer[] = {n1, args...};
745     return AddNode(op, sizeof...(args) + 1, buffer);
746   }
747 
748  private:
749   Node* MakeNode(const Operator* op, int input_count, Node* const* inputs);
750   BasicBlock* Use(RawMachineLabel* label);
751   BasicBlock* EnsureBlock(RawMachineLabel* label);
752   BasicBlock* CurrentBlock();
753 
schedule()754   Schedule* schedule() { return schedule_; }
parameter_count()755   size_t parameter_count() const { return machine_sig()->parameter_count(); }
machine_sig()756   const MachineSignature* machine_sig() const {
757     return call_descriptor_->GetMachineSignature();
758   }
759 
760   Isolate* isolate_;
761   Graph* graph_;
762   Schedule* schedule_;
763   MachineOperatorBuilder machine_;
764   CommonOperatorBuilder common_;
765   CallDescriptor* call_descriptor_;
766   NodeVector parameters_;
767   BasicBlock* current_block_;
768 
769   DISALLOW_COPY_AND_ASSIGN(RawMachineAssembler);
770 };
771 
772 
773 class RawMachineLabel final {
774  public:
775   enum Type { kDeferred, kNonDeferred };
776 
777   explicit RawMachineLabel(Type type = kNonDeferred)
778       : deferred_(type == kDeferred) {}
779   ~RawMachineLabel();
780 
781  private:
782   BasicBlock* block_ = nullptr;
783   bool used_ = false;
784   bool bound_ = false;
785   bool deferred_;
786   friend class RawMachineAssembler;
787   DISALLOW_COPY_AND_ASSIGN(RawMachineLabel);
788 };
789 
790 }  // namespace compiler
791 }  // namespace internal
792 }  // namespace v8
793 
794 #endif  // V8_COMPILER_RAW_MACHINE_ASSEMBLER_H_
795