• 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