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.
5 #ifndef V8_COMPILER_RAW_MACHINE_ASSEMBLER_H_
6 #define V8_COMPILER_RAW_MACHINE_ASSEMBLER_H_
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"
26 class RawMachineAssembler : public GraphBuilder {
30 Label() : block_(NULL), used_(false), bound_(false) {}
31 ~Label() { DCHECK(bound_ || !used_); }
33 BasicBlock* block() { return block_; }
36 // Private constructor for exit label.
37 explicit Label(BasicBlock* block)
38 : block_(block), used_(false), bound_(false) {}
43 friend class RawMachineAssembler;
44 DISALLOW_COPY_AND_ASSIGN(Label);
47 RawMachineAssembler(Graph* graph, MachineSignature* machine_sig,
48 MachineType word = kMachPtr);
49 virtual ~RawMachineAssembler() {}
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_; }
59 Node* UndefinedConstant() {
60 Unique<Object> unique = Unique<Object>::CreateImmovable(
61 isolate()->factory()->undefined_value());
62 return NewNode(common()->HeapConstant(unique));
66 Node* PointerConstant(void* value) {
67 return IntPtrConstant(reinterpret_cast<intptr_t>(value));
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));
74 Node* Int32Constant(int32_t value) {
75 return NewNode(common()->Int32Constant(value));
77 Node* Int64Constant(int64_t value) {
78 return NewNode(common()->Int64Constant(value));
80 Node* NumberConstant(double value) {
81 return NewNode(common()->NumberConstant(value));
83 Node* Float64Constant(double value) {
84 return NewNode(common()->Float64Constant(value));
86 Node* HeapConstant(Handle<Object> object) {
87 Unique<Object> val = Unique<Object>::CreateUninitialized(object);
88 return NewNode(common()->HeapConstant(val));
91 Node* Projection(int index, Node* a) {
92 return NewNode(common()->Projection(index), a);
96 Node* Load(MachineType rep, Node* base) {
97 return Load(rep, base, Int32Constant(0));
99 Node* Load(MachineType rep, Node* base, Node* index) {
100 return NewNode(machine()->Load(rep), base, index);
102 void Store(MachineType rep, Node* base, Node* value) {
103 Store(rep, base, Int32Constant(0), value);
105 void Store(MachineType rep, Node* base, Node* index, Node* value) {
106 NewNode(machine()->Store(StoreRepresentation(rep, kNoWriteBarrier)), base,
109 // Arithmetic Operations.
110 Node* WordAnd(Node* a, Node* b) {
111 return NewNode(machine()->WordAnd(), a, b);
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);
117 Node* WordShl(Node* a, Node* b) {
118 return NewNode(machine()->WordShl(), a, b);
120 Node* WordShr(Node* a, Node* b) {
121 return NewNode(machine()->WordShr(), a, b);
123 Node* WordSar(Node* a, Node* b) {
124 return NewNode(machine()->WordSar(), a, b);
126 Node* WordRor(Node* a, Node* b) {
127 return NewNode(machine()->WordRor(), a, b);
129 Node* WordEqual(Node* a, Node* b) {
130 return NewNode(machine()->WordEqual(), a, b);
132 Node* WordNotEqual(Node* a, Node* b) {
133 return WordBinaryNot(WordEqual(a, b));
135 Node* WordNot(Node* a) {
136 if (machine()->Is32()) {
142 Node* WordBinaryNot(Node* a) {
143 if (machine()->Is32()) {
144 return Word32BinaryNot(a);
146 return Word64BinaryNot(a);
150 Node* Word32And(Node* a, Node* b) {
151 return NewNode(machine()->Word32And(), a, b);
153 Node* Word32Or(Node* a, Node* b) {
154 return NewNode(machine()->Word32Or(), a, b);
156 Node* Word32Xor(Node* a, Node* b) {
157 return NewNode(machine()->Word32Xor(), a, b);
159 Node* Word32Shl(Node* a, Node* b) {
160 return NewNode(machine()->Word32Shl(), a, b);
162 Node* Word32Shr(Node* a, Node* b) {
163 return NewNode(machine()->Word32Shr(), a, b);
165 Node* Word32Sar(Node* a, Node* b) {
166 return NewNode(machine()->Word32Sar(), a, b);
168 Node* Word32Ror(Node* a, Node* b) {
169 return NewNode(machine()->Word32Ror(), a, b);
171 Node* Word32Equal(Node* a, Node* b) {
172 return NewNode(machine()->Word32Equal(), a, b);
174 Node* Word32NotEqual(Node* a, Node* b) {
175 return Word32BinaryNot(Word32Equal(a, b));
177 Node* Word32Not(Node* a) { return Word32Xor(a, Int32Constant(-1)); }
178 Node* Word32BinaryNot(Node* a) { return Word32Equal(a, Int32Constant(0)); }
180 Node* Word64And(Node* a, Node* b) {
181 return NewNode(machine()->Word64And(), a, b);
183 Node* Word64Or(Node* a, Node* b) {
184 return NewNode(machine()->Word64Or(), a, b);
186 Node* Word64Xor(Node* a, Node* b) {
187 return NewNode(machine()->Word64Xor(), a, b);
189 Node* Word64Shl(Node* a, Node* b) {
190 return NewNode(machine()->Word64Shl(), a, b);
192 Node* Word64Shr(Node* a, Node* b) {
193 return NewNode(machine()->Word64Shr(), a, b);
195 Node* Word64Sar(Node* a, Node* b) {
196 return NewNode(machine()->Word64Sar(), a, b);
198 Node* Word64Ror(Node* a, Node* b) {
199 return NewNode(machine()->Word64Ror(), a, b);
201 Node* Word64Equal(Node* a, Node* b) {
202 return NewNode(machine()->Word64Equal(), a, b);
204 Node* Word64NotEqual(Node* a, Node* b) {
205 return Word64BinaryNot(Word64Equal(a, b));
207 Node* Word64Not(Node* a) { return Word64Xor(a, Int64Constant(-1)); }
208 Node* Word64BinaryNot(Node* a) { return Word64Equal(a, Int64Constant(0)); }
210 Node* Int32Add(Node* a, Node* b) {
211 return NewNode(machine()->Int32Add(), a, b);
213 Node* Int32AddWithOverflow(Node* a, Node* b) {
214 return NewNode(machine()->Int32AddWithOverflow(), a, b);
216 Node* Int32Sub(Node* a, Node* b) {
217 return NewNode(machine()->Int32Sub(), a, b);
219 Node* Int32SubWithOverflow(Node* a, Node* b) {
220 return NewNode(machine()->Int32SubWithOverflow(), a, b);
222 Node* Int32Mul(Node* a, Node* b) {
223 return NewNode(machine()->Int32Mul(), a, b);
225 Node* Int32Div(Node* a, Node* b) {
226 return NewNode(machine()->Int32Div(), a, b);
228 Node* Int32UDiv(Node* a, Node* b) {
229 return NewNode(machine()->Int32UDiv(), a, b);
231 Node* Int32Mod(Node* a, Node* b) {
232 return NewNode(machine()->Int32Mod(), a, b);
234 Node* Int32UMod(Node* a, Node* b) {
235 return NewNode(machine()->Int32UMod(), a, b);
237 Node* Int32LessThan(Node* a, Node* b) {
238 return NewNode(machine()->Int32LessThan(), a, b);
240 Node* Int32LessThanOrEqual(Node* a, Node* b) {
241 return NewNode(machine()->Int32LessThanOrEqual(), a, b);
243 Node* Uint32LessThan(Node* a, Node* b) {
244 return NewNode(machine()->Uint32LessThan(), a, b);
246 Node* Uint32LessThanOrEqual(Node* a, Node* b) {
247 return NewNode(machine()->Uint32LessThanOrEqual(), a, b);
249 Node* Int32GreaterThan(Node* a, Node* b) { return Int32LessThan(b, a); }
250 Node* Int32GreaterThanOrEqual(Node* a, Node* b) {
251 return Int32LessThanOrEqual(b, a);
253 Node* Int32Neg(Node* a) { return Int32Sub(Int32Constant(0), a); }
255 Node* Int64Add(Node* a, Node* b) {
256 return NewNode(machine()->Int64Add(), a, b);
258 Node* Int64Sub(Node* a, Node* b) {
259 return NewNode(machine()->Int64Sub(), a, b);
261 Node* Int64Mul(Node* a, Node* b) {
262 return NewNode(machine()->Int64Mul(), a, b);
264 Node* Int64Div(Node* a, Node* b) {
265 return NewNode(machine()->Int64Div(), a, b);
267 Node* Int64UDiv(Node* a, Node* b) {
268 return NewNode(machine()->Int64UDiv(), a, b);
270 Node* Int64Mod(Node* a, Node* b) {
271 return NewNode(machine()->Int64Mod(), a, b);
273 Node* Int64UMod(Node* a, Node* b) {
274 return NewNode(machine()->Int64UMod(), a, b);
276 Node* Int64Neg(Node* a) { return Int64Sub(Int64Constant(0), a); }
277 Node* Int64LessThan(Node* a, Node* b) {
278 return NewNode(machine()->Int64LessThan(), a, b);
280 Node* Int64LessThanOrEqual(Node* a, Node* b) {
281 return NewNode(machine()->Int64LessThanOrEqual(), a, b);
283 Node* Int64GreaterThan(Node* a, Node* b) { return Int64LessThan(b, a); }
284 Node* Int64GreaterThanOrEqual(Node* a, Node* b) {
285 return Int64LessThanOrEqual(b, a);
288 // TODO(turbofan): What is this used for?
289 Node* ConvertIntPtrToInt32(Node* a) {
290 return kPointerSize == 8 ? NewNode(machine()->TruncateInt64ToInt32(), a)
293 Node* ConvertInt32ToIntPtr(Node* a) {
294 return kPointerSize == 8 ? NewNode(machine()->ChangeInt32ToInt64(), a) : a;
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); \
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);
314 Node* Float64Add(Node* a, Node* b) {
315 return NewNode(machine()->Float64Add(), a, b);
317 Node* Float64Sub(Node* a, Node* b) {
318 return NewNode(machine()->Float64Sub(), a, b);
320 Node* Float64Mul(Node* a, Node* b) {
321 return NewNode(machine()->Float64Mul(), a, b);
323 Node* Float64Div(Node* a, Node* b) {
324 return NewNode(machine()->Float64Div(), a, b);
326 Node* Float64Mod(Node* a, Node* b) {
327 return NewNode(machine()->Float64Mod(), a, b);
329 Node* Float64Equal(Node* a, Node* b) {
330 return NewNode(machine()->Float64Equal(), a, b);
332 Node* Float64NotEqual(Node* a, Node* b) {
333 return WordBinaryNot(Float64Equal(a, b));
335 Node* Float64LessThan(Node* a, Node* b) {
336 return NewNode(machine()->Float64LessThan(), a, b);
338 Node* Float64LessThanOrEqual(Node* a, Node* b) {
339 return NewNode(machine()->Float64LessThanOrEqual(), a, b);
341 Node* Float64GreaterThan(Node* a, Node* b) { return Float64LessThan(b, a); }
342 Node* Float64GreaterThanOrEqual(Node* a, Node* b) {
343 return Float64LessThanOrEqual(b, a);
347 Node* ChangeInt32ToFloat64(Node* a) {
348 return NewNode(machine()->ChangeInt32ToFloat64(), a);
350 Node* ChangeUint32ToFloat64(Node* a) {
351 return NewNode(machine()->ChangeUint32ToFloat64(), a);
353 Node* ChangeFloat64ToInt32(Node* a) {
354 return NewNode(machine()->ChangeFloat64ToInt32(), a);
356 Node* ChangeFloat64ToUint32(Node* a) {
357 return NewNode(machine()->ChangeFloat64ToUint32(), a);
359 Node* ChangeInt32ToInt64(Node* a) {
360 return NewNode(machine()->ChangeInt32ToInt64(), a);
362 Node* ChangeUint32ToUint64(Node* a) {
363 return NewNode(machine()->ChangeUint32ToUint64(), a);
365 Node* TruncateFloat64ToInt32(Node* a) {
366 return NewNode(machine()->TruncateFloat64ToInt32(), a);
368 Node* TruncateInt64ToInt32(Node* a) {
369 return NewNode(machine()->TruncateInt64ToInt32(), a);
373 Node* Parameter(size_t index);
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,
385 // Call to a runtime function with zero parameters.
386 Node* CallRuntime1(Runtime::FunctionId function, Node* arg0, Node* context,
388 void Return(Node* value);
389 void Bind(Label* label);
390 void Deoptimize(Node* state);
393 Node* Phi(MachineType type, Node* n1, Node* n2) {
394 return NewNode(common()->Phi(type, 2), n1, n2);
396 Node* Phi(MachineType type, Node* n1, Node* n2, Node* n3) {
397 return NewNode(common()->Phi(type, 3), n1, n2, n3);
399 Node* Phi(MachineType type, Node* n1, Node* n2, Node* n3, Node* n4) {
400 return NewNode(common()->Phi(type, 4), n1, n2, n3, n4);
403 // MachineAssembler is invalid after export.
407 virtual Node* MakeNode(const Operator* op, int input_count,
408 Node** inputs) FINAL;
410 bool ScheduleValid() { return schedule_ != NULL; }
412 Schedule* schedule() {
413 DCHECK(ScheduleValid());
418 BasicBlock* Use(Label* label);
419 BasicBlock* EnsureBlock(Label* label);
420 BasicBlock* CurrentBlock();
423 MachineOperatorBuilder machine_;
424 CommonOperatorBuilder common_;
425 MachineSignature* machine_sig_;
426 CallDescriptor* call_descriptor_;
429 BasicBlock* current_block_;
431 DISALLOW_COPY_AND_ASSIGN(RawMachineAssembler);
434 } // namespace compiler
435 } // namespace internal
438 #endif // V8_COMPILER_RAW_MACHINE_ASSEMBLER_H_