blob: a4af55a68bc2747b091a175467a3157d6edccfa8 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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
18namespace v8 {
19namespace internal {
20namespace compiler {
21
22class BasicBlock;
23class Schedule;
24
25
26class 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_