Upstream version 10.39.233.0
[platform/framework/web/crosswalk.git] / src / v8 / src / compiler / raw-machine-assembler.h
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/v8.h"
9
10 #include "src/compiler/common-operator.h"
11 #include "src/compiler/graph-builder.h"
12 #include "src/compiler/linkage.h"
13 #include "src/compiler/machine-operator.h"
14 #include "src/compiler/node.h"
15 #include "src/compiler/operator.h"
16
17
18 namespace v8 {
19 namespace internal {
20 namespace compiler {
21
22 class BasicBlock;
23 class Schedule;
24
25
26 class RawMachineAssembler : public GraphBuilder {
27  public:
28   class Label {
29    public:
30     Label() : block_(NULL), used_(false), bound_(false) {}
31     ~Label() { DCHECK(bound_ || !used_); }
32
33     BasicBlock* block() { return block_; }
34
35    private:
36     // Private constructor for exit label.
37     explicit Label(BasicBlock* block)
38         : block_(block), used_(false), bound_(false) {}
39
40     BasicBlock* block_;
41     bool used_;
42     bool bound_;
43     friend class RawMachineAssembler;
44     DISALLOW_COPY_AND_ASSIGN(Label);
45   };
46
47   RawMachineAssembler(Graph* graph, MachineSignature* machine_sig,
48                       MachineType word = kMachPtr);
49   virtual ~RawMachineAssembler() {}
50
51   Isolate* isolate() const { return zone()->isolate(); }
52   Zone* zone() const { return graph()->zone(); }
53   MachineOperatorBuilder* machine() { return &machine_; }
54   CommonOperatorBuilder* common() { return &common_; }
55   CallDescriptor* call_descriptor() const { return call_descriptor_; }
56   size_t parameter_count() const { return machine_sig_->parameter_count(); }
57   MachineSignature* machine_sig() const { return machine_sig_; }
58
59   Node* UndefinedConstant() {
60     Unique<Object> unique = Unique<Object>::CreateImmovable(
61         isolate()->factory()->undefined_value());
62     return NewNode(common()->HeapConstant(unique));
63   }
64
65   // Constants.
66   Node* PointerConstant(void* value) {
67     return IntPtrConstant(reinterpret_cast<intptr_t>(value));
68   }
69   Node* IntPtrConstant(intptr_t value) {
70     // TODO(dcarney): mark generated code as unserializable if value != 0.
71     return kPointerSize == 8 ? Int64Constant(value)
72                              : Int32Constant(static_cast<int>(value));
73   }
74   Node* Int32Constant(int32_t value) {
75     return NewNode(common()->Int32Constant(value));
76   }
77   Node* Int64Constant(int64_t value) {
78     return NewNode(common()->Int64Constant(value));
79   }
80   Node* NumberConstant(double value) {
81     return NewNode(common()->NumberConstant(value));
82   }
83   Node* Float64Constant(double value) {
84     return NewNode(common()->Float64Constant(value));
85   }
86   Node* HeapConstant(Handle<Object> object) {
87     Unique<Object> val = Unique<Object>::CreateUninitialized(object);
88     return NewNode(common()->HeapConstant(val));
89   }
90
91   Node* Projection(int index, Node* a) {
92     return NewNode(common()->Projection(index), a);
93   }
94
95   // Memory Operations.
96   Node* Load(MachineType rep, Node* base) {
97     return Load(rep, base, Int32Constant(0));
98   }
99   Node* Load(MachineType rep, Node* base, Node* index) {
100     return NewNode(machine()->Load(rep), base, index);
101   }
102   void Store(MachineType rep, Node* base, Node* value) {
103     Store(rep, base, Int32Constant(0), value);
104   }
105   void Store(MachineType rep, Node* base, Node* index, Node* value) {
106     NewNode(machine()->Store(StoreRepresentation(rep, kNoWriteBarrier)), base,
107             index, value);
108   }
109   // Arithmetic Operations.
110   Node* WordAnd(Node* a, Node* b) {
111     return NewNode(machine()->WordAnd(), a, b);
112   }
113   Node* WordOr(Node* a, Node* b) { return NewNode(machine()->WordOr(), a, b); }
114   Node* WordXor(Node* a, Node* b) {
115     return NewNode(machine()->WordXor(), a, b);
116   }
117   Node* WordShl(Node* a, Node* b) {
118     return NewNode(machine()->WordShl(), a, b);
119   }
120   Node* WordShr(Node* a, Node* b) {
121     return NewNode(machine()->WordShr(), a, b);
122   }
123   Node* WordSar(Node* a, Node* b) {
124     return NewNode(machine()->WordSar(), a, b);
125   }
126   Node* WordRor(Node* a, Node* b) {
127     return NewNode(machine()->WordRor(), a, b);
128   }
129   Node* WordEqual(Node* a, Node* b) {
130     return NewNode(machine()->WordEqual(), a, b);
131   }
132   Node* WordNotEqual(Node* a, Node* b) {
133     return WordBinaryNot(WordEqual(a, b));
134   }
135   Node* WordNot(Node* a) {
136     if (machine()->Is32()) {
137       return Word32Not(a);
138     } else {
139       return Word64Not(a);
140     }
141   }
142   Node* WordBinaryNot(Node* a) {
143     if (machine()->Is32()) {
144       return Word32BinaryNot(a);
145     } else {
146       return Word64BinaryNot(a);
147     }
148   }
149
150   Node* Word32And(Node* a, Node* b) {
151     return NewNode(machine()->Word32And(), a, b);
152   }
153   Node* Word32Or(Node* a, Node* b) {
154     return NewNode(machine()->Word32Or(), a, b);
155   }
156   Node* Word32Xor(Node* a, Node* b) {
157     return NewNode(machine()->Word32Xor(), a, b);
158   }
159   Node* Word32Shl(Node* a, Node* b) {
160     return NewNode(machine()->Word32Shl(), a, b);
161   }
162   Node* Word32Shr(Node* a, Node* b) {
163     return NewNode(machine()->Word32Shr(), a, b);
164   }
165   Node* Word32Sar(Node* a, Node* b) {
166     return NewNode(machine()->Word32Sar(), a, b);
167   }
168   Node* Word32Ror(Node* a, Node* b) {
169     return NewNode(machine()->Word32Ror(), a, b);
170   }
171   Node* Word32Equal(Node* a, Node* b) {
172     return NewNode(machine()->Word32Equal(), a, b);
173   }
174   Node* Word32NotEqual(Node* a, Node* b) {
175     return Word32BinaryNot(Word32Equal(a, b));
176   }
177   Node* Word32Not(Node* a) { return Word32Xor(a, Int32Constant(-1)); }
178   Node* Word32BinaryNot(Node* a) { return Word32Equal(a, Int32Constant(0)); }
179
180   Node* Word64And(Node* a, Node* b) {
181     return NewNode(machine()->Word64And(), a, b);
182   }
183   Node* Word64Or(Node* a, Node* b) {
184     return NewNode(machine()->Word64Or(), a, b);
185   }
186   Node* Word64Xor(Node* a, Node* b) {
187     return NewNode(machine()->Word64Xor(), a, b);
188   }
189   Node* Word64Shl(Node* a, Node* b) {
190     return NewNode(machine()->Word64Shl(), a, b);
191   }
192   Node* Word64Shr(Node* a, Node* b) {
193     return NewNode(machine()->Word64Shr(), a, b);
194   }
195   Node* Word64Sar(Node* a, Node* b) {
196     return NewNode(machine()->Word64Sar(), a, b);
197   }
198   Node* Word64Ror(Node* a, Node* b) {
199     return NewNode(machine()->Word64Ror(), a, b);
200   }
201   Node* Word64Equal(Node* a, Node* b) {
202     return NewNode(machine()->Word64Equal(), a, b);
203   }
204   Node* Word64NotEqual(Node* a, Node* b) {
205     return Word64BinaryNot(Word64Equal(a, b));
206   }
207   Node* Word64Not(Node* a) { return Word64Xor(a, Int64Constant(-1)); }
208   Node* Word64BinaryNot(Node* a) { return Word64Equal(a, Int64Constant(0)); }
209
210   Node* Int32Add(Node* a, Node* b) {
211     return NewNode(machine()->Int32Add(), a, b);
212   }
213   Node* Int32AddWithOverflow(Node* a, Node* b) {
214     return NewNode(machine()->Int32AddWithOverflow(), a, b);
215   }
216   Node* Int32Sub(Node* a, Node* b) {
217     return NewNode(machine()->Int32Sub(), a, b);
218   }
219   Node* Int32SubWithOverflow(Node* a, Node* b) {
220     return NewNode(machine()->Int32SubWithOverflow(), a, b);
221   }
222   Node* Int32Mul(Node* a, Node* b) {
223     return NewNode(machine()->Int32Mul(), a, b);
224   }
225   Node* Int32Div(Node* a, Node* b) {
226     return NewNode(machine()->Int32Div(), a, b);
227   }
228   Node* Int32UDiv(Node* a, Node* b) {
229     return NewNode(machine()->Int32UDiv(), a, b);
230   }
231   Node* Int32Mod(Node* a, Node* b) {
232     return NewNode(machine()->Int32Mod(), a, b);
233   }
234   Node* Int32UMod(Node* a, Node* b) {
235     return NewNode(machine()->Int32UMod(), a, b);
236   }
237   Node* Int32LessThan(Node* a, Node* b) {
238     return NewNode(machine()->Int32LessThan(), a, b);
239   }
240   Node* Int32LessThanOrEqual(Node* a, Node* b) {
241     return NewNode(machine()->Int32LessThanOrEqual(), a, b);
242   }
243   Node* Uint32LessThan(Node* a, Node* b) {
244     return NewNode(machine()->Uint32LessThan(), a, b);
245   }
246   Node* Uint32LessThanOrEqual(Node* a, Node* b) {
247     return NewNode(machine()->Uint32LessThanOrEqual(), a, b);
248   }
249   Node* Int32GreaterThan(Node* a, Node* b) { return Int32LessThan(b, a); }
250   Node* Int32GreaterThanOrEqual(Node* a, Node* b) {
251     return Int32LessThanOrEqual(b, a);
252   }
253   Node* Int32Neg(Node* a) { return Int32Sub(Int32Constant(0), a); }
254
255   Node* Int64Add(Node* a, Node* b) {
256     return NewNode(machine()->Int64Add(), a, b);
257   }
258   Node* Int64Sub(Node* a, Node* b) {
259     return NewNode(machine()->Int64Sub(), a, b);
260   }
261   Node* Int64Mul(Node* a, Node* b) {
262     return NewNode(machine()->Int64Mul(), a, b);
263   }
264   Node* Int64Div(Node* a, Node* b) {
265     return NewNode(machine()->Int64Div(), a, b);
266   }
267   Node* Int64UDiv(Node* a, Node* b) {
268     return NewNode(machine()->Int64UDiv(), a, b);
269   }
270   Node* Int64Mod(Node* a, Node* b) {
271     return NewNode(machine()->Int64Mod(), a, b);
272   }
273   Node* Int64UMod(Node* a, Node* b) {
274     return NewNode(machine()->Int64UMod(), a, b);
275   }
276   Node* Int64Neg(Node* a) { return Int64Sub(Int64Constant(0), a); }
277   Node* Int64LessThan(Node* a, Node* b) {
278     return NewNode(machine()->Int64LessThan(), a, b);
279   }
280   Node* Int64LessThanOrEqual(Node* a, Node* b) {
281     return NewNode(machine()->Int64LessThanOrEqual(), a, b);
282   }
283   Node* Int64GreaterThan(Node* a, Node* b) { return Int64LessThan(b, a); }
284   Node* Int64GreaterThanOrEqual(Node* a, Node* b) {
285     return Int64LessThanOrEqual(b, a);
286   }
287
288   // TODO(turbofan): What is this used for?
289   Node* ConvertIntPtrToInt32(Node* a) {
290     return kPointerSize == 8 ? NewNode(machine()->TruncateInt64ToInt32(), a)
291                              : a;
292   }
293   Node* ConvertInt32ToIntPtr(Node* a) {
294     return kPointerSize == 8 ? NewNode(machine()->ChangeInt32ToInt64(), a) : a;
295   }
296
297 #define INTPTR_BINOP(prefix, name)                     \
298   Node* IntPtr##name(Node* a, Node* b) {               \
299     return kPointerSize == 8 ? prefix##64##name(a, b)  \
300                              : prefix##32##name(a, b); \
301   }
302
303   INTPTR_BINOP(Int, Add);
304   INTPTR_BINOP(Int, Sub);
305   INTPTR_BINOP(Int, LessThan);
306   INTPTR_BINOP(Int, LessThanOrEqual);
307   INTPTR_BINOP(Word, Equal);
308   INTPTR_BINOP(Word, NotEqual);
309   INTPTR_BINOP(Int, GreaterThanOrEqual);
310   INTPTR_BINOP(Int, GreaterThan);
311
312 #undef INTPTR_BINOP
313
314   Node* Float64Add(Node* a, Node* b) {
315     return NewNode(machine()->Float64Add(), a, b);
316   }
317   Node* Float64Sub(Node* a, Node* b) {
318     return NewNode(machine()->Float64Sub(), a, b);
319   }
320   Node* Float64Mul(Node* a, Node* b) {
321     return NewNode(machine()->Float64Mul(), a, b);
322   }
323   Node* Float64Div(Node* a, Node* b) {
324     return NewNode(machine()->Float64Div(), a, b);
325   }
326   Node* Float64Mod(Node* a, Node* b) {
327     return NewNode(machine()->Float64Mod(), a, b);
328   }
329   Node* Float64Equal(Node* a, Node* b) {
330     return NewNode(machine()->Float64Equal(), a, b);
331   }
332   Node* Float64NotEqual(Node* a, Node* b) {
333     return WordBinaryNot(Float64Equal(a, b));
334   }
335   Node* Float64LessThan(Node* a, Node* b) {
336     return NewNode(machine()->Float64LessThan(), a, b);
337   }
338   Node* Float64LessThanOrEqual(Node* a, Node* b) {
339     return NewNode(machine()->Float64LessThanOrEqual(), a, b);
340   }
341   Node* Float64GreaterThan(Node* a, Node* b) { return Float64LessThan(b, a); }
342   Node* Float64GreaterThanOrEqual(Node* a, Node* b) {
343     return Float64LessThanOrEqual(b, a);
344   }
345
346   // Conversions.
347   Node* ChangeInt32ToFloat64(Node* a) {
348     return NewNode(machine()->ChangeInt32ToFloat64(), a);
349   }
350   Node* ChangeUint32ToFloat64(Node* a) {
351     return NewNode(machine()->ChangeUint32ToFloat64(), a);
352   }
353   Node* ChangeFloat64ToInt32(Node* a) {
354     return NewNode(machine()->ChangeFloat64ToInt32(), a);
355   }
356   Node* ChangeFloat64ToUint32(Node* a) {
357     return NewNode(machine()->ChangeFloat64ToUint32(), a);
358   }
359   Node* ChangeInt32ToInt64(Node* a) {
360     return NewNode(machine()->ChangeInt32ToInt64(), a);
361   }
362   Node* ChangeUint32ToUint64(Node* a) {
363     return NewNode(machine()->ChangeUint32ToUint64(), a);
364   }
365   Node* TruncateFloat64ToInt32(Node* a) {
366     return NewNode(machine()->TruncateFloat64ToInt32(), a);
367   }
368   Node* TruncateInt64ToInt32(Node* a) {
369     return NewNode(machine()->TruncateInt64ToInt32(), a);
370   }
371
372   // Parameters.
373   Node* Parameter(size_t index);
374
375   // Control flow.
376   Label* Exit();
377   void Goto(Label* label);
378   void Branch(Node* condition, Label* true_val, Label* false_val);
379   // Call through CallFunctionStub with lazy deopt and frame-state.
380   Node* CallFunctionStub0(Node* function, Node* receiver, Node* context,
381                           Node* frame_state, CallFunctionFlags flags);
382   // Call to a JS function with zero parameters.
383   Node* CallJS0(Node* function, Node* receiver, Node* context,
384                 Node* frame_state);
385   // Call to a runtime function with zero parameters.
386   Node* CallRuntime1(Runtime::FunctionId function, Node* arg0, Node* context,
387                      Node* frame_state);
388   void Return(Node* value);
389   void Bind(Label* label);
390   void Deoptimize(Node* state);
391
392   // Variables.
393   Node* Phi(MachineType type, Node* n1, Node* n2) {
394     return NewNode(common()->Phi(type, 2), n1, n2);
395   }
396   Node* Phi(MachineType type, Node* n1, Node* n2, Node* n3) {
397     return NewNode(common()->Phi(type, 3), n1, n2, n3);
398   }
399   Node* Phi(MachineType type, Node* n1, Node* n2, Node* n3, Node* n4) {
400     return NewNode(common()->Phi(type, 4), n1, n2, n3, n4);
401   }
402
403   // MachineAssembler is invalid after export.
404   Schedule* Export();
405
406  protected:
407   virtual Node* MakeNode(const Operator* op, int input_count,
408                          Node** inputs) FINAL;
409
410   bool ScheduleValid() { return schedule_ != NULL; }
411
412   Schedule* schedule() {
413     DCHECK(ScheduleValid());
414     return schedule_;
415   }
416
417  private:
418   BasicBlock* Use(Label* label);
419   BasicBlock* EnsureBlock(Label* label);
420   BasicBlock* CurrentBlock();
421
422   Schedule* schedule_;
423   MachineOperatorBuilder machine_;
424   CommonOperatorBuilder common_;
425   MachineSignature* machine_sig_;
426   CallDescriptor* call_descriptor_;
427   Node** parameters_;
428   Label exit_label_;
429   BasicBlock* current_block_;
430
431   DISALLOW_COPY_AND_ASSIGN(RawMachineAssembler);
432 };
433
434 }  // namespace compiler
435 }  // namespace internal
436 }  // namespace v8
437
438 #endif  // V8_COMPILER_RAW_MACHINE_ASSEMBLER_H_