blob: 5c232ed1d124f3f600aac12259bec0fbb129376c [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
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008#include "src/assembler.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009#include "src/compiler/common-operator.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010#include "src/compiler/graph.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000011#include "src/compiler/linkage.h"
12#include "src/compiler/machine-operator.h"
13#include "src/compiler/node.h"
14#include "src/compiler/operator.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000015#include "src/factory.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000016
17namespace v8 {
18namespace internal {
19namespace compiler {
20
21class BasicBlock;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000022class RawMachineLabel;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000023class Schedule;
24
25
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000026// 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.
37class RawMachineAssembler {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000038 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000039 RawMachineAssembler(
40 Isolate* isolate, Graph* graph, CallDescriptor* call_descriptor,
41 MachineRepresentation word = MachineType::PointerRepresentation(),
42 MachineOperatorBuilder::Flags flags =
43 MachineOperatorBuilder::Flag::kNoFlags);
44 ~RawMachineAssembler() {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +000045
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000046 Isolate* isolate() const { return isolate_; }
47 Graph* graph() const { return graph_; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000048 Zone* zone() const { return graph()->zone(); }
49 MachineOperatorBuilder* machine() { return &machine_; }
50 CommonOperatorBuilder* common() { return &common_; }
51 CallDescriptor* call_descriptor() const { return call_descriptor_; }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000052
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
62 Node* NullConstant() {
63 return HeapConstant(isolate()->factory()->null_value());
64 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000065
66 Node* UndefinedConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000067 return HeapConstant(isolate()->factory()->undefined_value());
Ben Murdochb8a8cc12014-11-26 15:28:44 +000068 }
69
70 // Constants.
71 Node* PointerConstant(void* value) {
72 return IntPtrConstant(reinterpret_cast<intptr_t>(value));
73 }
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* Int32Constant(int32_t value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000080 return AddNode(common()->Int32Constant(value));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000081 }
82 Node* Int64Constant(int64_t value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000083 return AddNode(common()->Int64Constant(value));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000084 }
85 Node* NumberConstant(double value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000086 return AddNode(common()->NumberConstant(value));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000087 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -040088 Node* Float32Constant(float value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000089 return AddNode(common()->Float32Constant(value));
Emily Bernierd0a1eb72015-03-24 16:35:39 -040090 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000091 Node* Float64Constant(double value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000092 return AddNode(common()->Float64Constant(value));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000093 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -040094 Node* HeapConstant(Handle<HeapObject> object) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000095 return AddNode(common()->HeapConstant(object));
96 }
97 Node* BooleanConstant(bool value) {
98 Handle<Object> object = isolate()->factory()->ToBoolean(value);
99 return HeapConstant(Handle<HeapObject>::cast(object));
100 }
101 Node* ExternalConstant(ExternalReference address) {
102 return AddNode(common()->ExternalConstant(address));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000103 }
104
105 Node* Projection(int index, Node* a) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000106 return AddNode(common()->Projection(index), a);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000107 }
108
109 // Memory Operations.
110 Node* Load(MachineType rep, Node* base) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000111 return Load(rep, base, IntPtrConstant(0));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000112 }
113 Node* Load(MachineType rep, Node* base, Node* index) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000114 return AddNode(machine()->Load(rep), base, index);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000115 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000116 Node* Store(MachineRepresentation rep, Node* base, Node* value,
117 WriteBarrierKind write_barrier) {
118 return Store(rep, base, IntPtrConstant(0), value, write_barrier);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000119 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000120 Node* Store(MachineRepresentation rep, Node* base, Node* index, Node* value,
121 WriteBarrierKind write_barrier) {
122 return AddNode(machine()->Store(StoreRepresentation(rep, write_barrier)),
123 base, index, value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000124 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000125
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000126 // Arithmetic Operations.
127 Node* WordAnd(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000128 return AddNode(machine()->WordAnd(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000129 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000130 Node* WordOr(Node* a, Node* b) { return AddNode(machine()->WordOr(), a, b); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000131 Node* WordXor(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000132 return AddNode(machine()->WordXor(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000133 }
134 Node* WordShl(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000135 return AddNode(machine()->WordShl(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000136 }
137 Node* WordShr(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000138 return AddNode(machine()->WordShr(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000139 }
140 Node* WordSar(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000141 return AddNode(machine()->WordSar(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000142 }
143 Node* WordRor(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000144 return AddNode(machine()->WordRor(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000145 }
146 Node* WordEqual(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000147 return AddNode(machine()->WordEqual(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000148 }
149 Node* WordNotEqual(Node* a, Node* b) {
150 return WordBinaryNot(WordEqual(a, b));
151 }
152 Node* WordNot(Node* a) {
153 if (machine()->Is32()) {
154 return Word32Not(a);
155 } else {
156 return Word64Not(a);
157 }
158 }
159 Node* WordBinaryNot(Node* a) {
160 if (machine()->Is32()) {
161 return Word32BinaryNot(a);
162 } else {
163 return Word64BinaryNot(a);
164 }
165 }
166
167 Node* Word32And(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000168 return AddNode(machine()->Word32And(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000169 }
170 Node* Word32Or(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000171 return AddNode(machine()->Word32Or(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000172 }
173 Node* Word32Xor(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000174 return AddNode(machine()->Word32Xor(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000175 }
176 Node* Word32Shl(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000177 return AddNode(machine()->Word32Shl(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000178 }
179 Node* Word32Shr(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000180 return AddNode(machine()->Word32Shr(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000181 }
182 Node* Word32Sar(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000183 return AddNode(machine()->Word32Sar(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000184 }
185 Node* Word32Ror(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000186 return AddNode(machine()->Word32Ror(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000187 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000188 Node* Word32Clz(Node* a) { return AddNode(machine()->Word32Clz(), a); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000189 Node* Word32Equal(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000190 return AddNode(machine()->Word32Equal(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000191 }
192 Node* Word32NotEqual(Node* a, Node* b) {
193 return Word32BinaryNot(Word32Equal(a, b));
194 }
195 Node* Word32Not(Node* a) { return Word32Xor(a, Int32Constant(-1)); }
196 Node* Word32BinaryNot(Node* a) { return Word32Equal(a, Int32Constant(0)); }
197
198 Node* Word64And(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000199 return AddNode(machine()->Word64And(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000200 }
201 Node* Word64Or(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000202 return AddNode(machine()->Word64Or(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000203 }
204 Node* Word64Xor(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000205 return AddNode(machine()->Word64Xor(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000206 }
207 Node* Word64Shl(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000208 return AddNode(machine()->Word64Shl(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000209 }
210 Node* Word64Shr(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000211 return AddNode(machine()->Word64Shr(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000212 }
213 Node* Word64Sar(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000214 return AddNode(machine()->Word64Sar(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000215 }
216 Node* Word64Ror(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000217 return AddNode(machine()->Word64Ror(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000218 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000219 Node* Word64Clz(Node* a) { return AddNode(machine()->Word64Clz(), a); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000220 Node* Word64Equal(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000221 return AddNode(machine()->Word64Equal(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000222 }
223 Node* Word64NotEqual(Node* a, Node* b) {
224 return Word64BinaryNot(Word64Equal(a, b));
225 }
226 Node* Word64Not(Node* a) { return Word64Xor(a, Int64Constant(-1)); }
227 Node* Word64BinaryNot(Node* a) { return Word64Equal(a, Int64Constant(0)); }
228
229 Node* Int32Add(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000230 return AddNode(machine()->Int32Add(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000231 }
232 Node* Int32AddWithOverflow(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000233 return AddNode(machine()->Int32AddWithOverflow(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000234 }
235 Node* Int32Sub(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000236 return AddNode(machine()->Int32Sub(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000237 }
238 Node* Int32SubWithOverflow(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000239 return AddNode(machine()->Int32SubWithOverflow(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000240 }
241 Node* Int32Mul(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000242 return AddNode(machine()->Int32Mul(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000243 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400244 Node* Int32MulHigh(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000245 return AddNode(machine()->Int32MulHigh(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000246 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400247 Node* Int32Div(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000248 return AddNode(machine()->Int32Div(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000249 }
250 Node* Int32Mod(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000251 return AddNode(machine()->Int32Mod(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000252 }
253 Node* Int32LessThan(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000254 return AddNode(machine()->Int32LessThan(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000255 }
256 Node* Int32LessThanOrEqual(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000257 return AddNode(machine()->Int32LessThanOrEqual(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000258 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400259 Node* Uint32Div(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000260 return AddNode(machine()->Uint32Div(), a, b);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400261 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000262 Node* Uint32LessThan(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000263 return AddNode(machine()->Uint32LessThan(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000264 }
265 Node* Uint32LessThanOrEqual(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000266 return AddNode(machine()->Uint32LessThanOrEqual(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000267 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400268 Node* Uint32Mod(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000269 return AddNode(machine()->Uint32Mod(), a, b);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400270 }
271 Node* Uint32MulHigh(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000272 return AddNode(machine()->Uint32MulHigh(), a, b);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400273 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000274 Node* Int32GreaterThan(Node* a, Node* b) { return Int32LessThan(b, a); }
275 Node* Int32GreaterThanOrEqual(Node* a, Node* b) {
276 return Int32LessThanOrEqual(b, a);
277 }
278 Node* Int32Neg(Node* a) { return Int32Sub(Int32Constant(0), a); }
279
280 Node* Int64Add(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000281 return AddNode(machine()->Int64Add(), a, b);
282 }
283 Node* Int64AddWithOverflow(Node* a, Node* b) {
284 return AddNode(machine()->Int64AddWithOverflow(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000285 }
286 Node* Int64Sub(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000287 return AddNode(machine()->Int64Sub(), a, b);
288 }
289 Node* Int64SubWithOverflow(Node* a, Node* b) {
290 return AddNode(machine()->Int64SubWithOverflow(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000291 }
292 Node* Int64Mul(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000293 return AddNode(machine()->Int64Mul(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000294 }
295 Node* Int64Div(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000296 return AddNode(machine()->Int64Div(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000297 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000298 Node* Int64Mod(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000299 return AddNode(machine()->Int64Mod(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000300 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000301 Node* Int64Neg(Node* a) { return Int64Sub(Int64Constant(0), a); }
302 Node* Int64LessThan(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000303 return AddNode(machine()->Int64LessThan(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000304 }
305 Node* Int64LessThanOrEqual(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000306 return AddNode(machine()->Int64LessThanOrEqual(), a, b);
307 }
308 Node* Uint64LessThan(Node* a, Node* b) {
309 return AddNode(machine()->Uint64LessThan(), a, b);
310 }
311 Node* Uint64LessThanOrEqual(Node* a, Node* b) {
312 return AddNode(machine()->Uint64LessThanOrEqual(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000313 }
314 Node* Int64GreaterThan(Node* a, Node* b) { return Int64LessThan(b, a); }
315 Node* Int64GreaterThanOrEqual(Node* a, Node* b) {
316 return Int64LessThanOrEqual(b, a);
317 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400318 Node* Uint64Div(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000319 return AddNode(machine()->Uint64Div(), a, b);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400320 }
321 Node* Uint64Mod(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000322 return AddNode(machine()->Uint64Mod(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000323 }
324
325#define INTPTR_BINOP(prefix, name) \
326 Node* IntPtr##name(Node* a, Node* b) { \
327 return kPointerSize == 8 ? prefix##64##name(a, b) \
328 : prefix##32##name(a, b); \
329 }
330
331 INTPTR_BINOP(Int, Add);
332 INTPTR_BINOP(Int, Sub);
333 INTPTR_BINOP(Int, LessThan);
334 INTPTR_BINOP(Int, LessThanOrEqual);
335 INTPTR_BINOP(Word, Equal);
336 INTPTR_BINOP(Word, NotEqual);
337 INTPTR_BINOP(Int, GreaterThanOrEqual);
338 INTPTR_BINOP(Int, GreaterThan);
339
340#undef INTPTR_BINOP
341
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000342 Node* Float32Add(Node* a, Node* b) {
343 return AddNode(machine()->Float32Add(), a, b);
344 }
345 Node* Float32Sub(Node* a, Node* b) {
346 return AddNode(machine()->Float32Sub(), a, b);
347 }
348 Node* Float32Mul(Node* a, Node* b) {
349 return AddNode(machine()->Float32Mul(), a, b);
350 }
351 Node* Float32Div(Node* a, Node* b) {
352 return AddNode(machine()->Float32Div(), a, b);
353 }
354 Node* Float32Max(Node* a, Node* b) {
355 return AddNode(machine()->Float32Max().op(), a, b);
356 }
357 Node* Float32Min(Node* a, Node* b) {
358 return AddNode(machine()->Float32Min().op(), a, b);
359 }
360 Node* Float32Abs(Node* a) { return AddNode(machine()->Float32Abs(), a); }
361 Node* Float32Sqrt(Node* a) { return AddNode(machine()->Float32Sqrt(), a); }
362 Node* Float32Equal(Node* a, Node* b) {
363 return AddNode(machine()->Float32Equal(), a, b);
364 }
365 Node* Float32NotEqual(Node* a, Node* b) {
366 return WordBinaryNot(Float32Equal(a, b));
367 }
368 Node* Float32LessThan(Node* a, Node* b) {
369 return AddNode(machine()->Float32LessThan(), a, b);
370 }
371 Node* Float32LessThanOrEqual(Node* a, Node* b) {
372 return AddNode(machine()->Float32LessThanOrEqual(), a, b);
373 }
374 Node* Float32GreaterThan(Node* a, Node* b) { return Float32LessThan(b, a); }
375 Node* Float32GreaterThanOrEqual(Node* a, Node* b) {
376 return Float32LessThanOrEqual(b, a);
377 }
378
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000379 Node* Float64Add(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000380 return AddNode(machine()->Float64Add(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000381 }
382 Node* Float64Sub(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000383 return AddNode(machine()->Float64Sub(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000384 }
385 Node* Float64Mul(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000386 return AddNode(machine()->Float64Mul(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000387 }
388 Node* Float64Div(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000389 return AddNode(machine()->Float64Div(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000390 }
391 Node* Float64Mod(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000392 return AddNode(machine()->Float64Mod(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000393 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000394 Node* Float64Max(Node* a, Node* b) {
395 return AddNode(machine()->Float64Max().op(), a, b);
396 }
397 Node* Float64Min(Node* a, Node* b) {
398 return AddNode(machine()->Float64Min().op(), a, b);
399 }
400 Node* Float64Abs(Node* a) { return AddNode(machine()->Float64Abs(), a); }
401 Node* Float64Sqrt(Node* a) { return AddNode(machine()->Float64Sqrt(), a); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000402 Node* Float64Equal(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000403 return AddNode(machine()->Float64Equal(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000404 }
405 Node* Float64NotEqual(Node* a, Node* b) {
406 return WordBinaryNot(Float64Equal(a, b));
407 }
408 Node* Float64LessThan(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000409 return AddNode(machine()->Float64LessThan(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000410 }
411 Node* Float64LessThanOrEqual(Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000412 return AddNode(machine()->Float64LessThanOrEqual(), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000413 }
414 Node* Float64GreaterThan(Node* a, Node* b) { return Float64LessThan(b, a); }
415 Node* Float64GreaterThanOrEqual(Node* a, Node* b) {
416 return Float64LessThanOrEqual(b, a);
417 }
418
419 // Conversions.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400420 Node* ChangeFloat32ToFloat64(Node* a) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000421 return AddNode(machine()->ChangeFloat32ToFloat64(), a);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400422 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000423 Node* ChangeInt32ToFloat64(Node* a) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000424 return AddNode(machine()->ChangeInt32ToFloat64(), a);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000425 }
426 Node* ChangeUint32ToFloat64(Node* a) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000427 return AddNode(machine()->ChangeUint32ToFloat64(), a);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000428 }
429 Node* ChangeFloat64ToInt32(Node* a) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000430 return AddNode(machine()->ChangeFloat64ToInt32(), a);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000431 }
432 Node* ChangeFloat64ToUint32(Node* a) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000433 return AddNode(machine()->ChangeFloat64ToUint32(), a);
434 }
435 Node* TruncateFloat32ToInt64(Node* a) {
436 // TODO(ahaas): Remove this function as soon as it is not used anymore in
437 // WebAssembly.
438 return AddNode(machine()->TryTruncateFloat32ToInt64(), a);
439 }
440 Node* TryTruncateFloat32ToInt64(Node* a) {
441 return AddNode(machine()->TryTruncateFloat32ToInt64(), a);
442 }
443 Node* TruncateFloat64ToInt64(Node* a) {
444 // TODO(ahaas): Remove this function as soon as it is not used anymore in
445 // WebAssembly.
446 return AddNode(machine()->TryTruncateFloat64ToInt64(), a);
447 }
448 Node* TryTruncateFloat64ToInt64(Node* a) {
449 return AddNode(machine()->TryTruncateFloat64ToInt64(), a);
450 }
451 Node* TruncateFloat32ToUint64(Node* a) {
452 // TODO(ahaas): Remove this function as soon as it is not used anymore in
453 // WebAssembly.
454 return AddNode(machine()->TryTruncateFloat32ToUint64(), a);
455 }
456 Node* TryTruncateFloat32ToUint64(Node* a) {
457 return AddNode(machine()->TryTruncateFloat32ToUint64(), a);
458 }
459 Node* TruncateFloat64ToUint64(Node* a) {
460 // TODO(ahaas): Remove this function as soon as it is not used anymore in
461 // WebAssembly.
462 return AddNode(machine()->TryTruncateFloat64ToUint64(), a);
463 }
464 Node* TryTruncateFloat64ToUint64(Node* a) {
465 return AddNode(machine()->TryTruncateFloat64ToUint64(), a);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000466 }
467 Node* ChangeInt32ToInt64(Node* a) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000468 return AddNode(machine()->ChangeInt32ToInt64(), a);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000469 }
470 Node* ChangeUint32ToUint64(Node* a) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000471 return AddNode(machine()->ChangeUint32ToUint64(), a);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000472 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400473 Node* TruncateFloat64ToFloat32(Node* a) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000474 return AddNode(machine()->TruncateFloat64ToFloat32(), a);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400475 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000476 Node* TruncateFloat64ToInt32(TruncationMode mode, Node* a) {
477 return AddNode(machine()->TruncateFloat64ToInt32(mode), a);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000478 }
479 Node* TruncateInt64ToInt32(Node* a) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000480 return AddNode(machine()->TruncateInt64ToInt32(), a);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000481 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000482 Node* RoundInt64ToFloat32(Node* a) {
483 return AddNode(machine()->RoundInt64ToFloat32(), a);
484 }
485 Node* RoundInt64ToFloat64(Node* a) {
486 return AddNode(machine()->RoundInt64ToFloat64(), a);
487 }
488 Node* RoundUint64ToFloat32(Node* a) {
489 return AddNode(machine()->RoundUint64ToFloat32(), a);
490 }
491 Node* RoundUint64ToFloat64(Node* a) {
492 return AddNode(machine()->RoundUint64ToFloat64(), a);
493 }
494 Node* BitcastFloat32ToInt32(Node* a) {
495 return AddNode(machine()->BitcastFloat32ToInt32(), a);
496 }
497 Node* BitcastFloat64ToInt64(Node* a) {
498 return AddNode(machine()->BitcastFloat64ToInt64(), a);
499 }
500 Node* BitcastInt32ToFloat32(Node* a) {
501 return AddNode(machine()->BitcastInt32ToFloat32(), a);
502 }
503 Node* BitcastInt64ToFloat64(Node* a) {
504 return AddNode(machine()->BitcastInt64ToFloat64(), a);
505 }
506 Node* Float32RoundDown(Node* a) {
507 return AddNode(machine()->Float32RoundDown().op(), a);
508 }
509 Node* Float64RoundDown(Node* a) {
510 return AddNode(machine()->Float64RoundDown().op(), a);
511 }
512 Node* Float32RoundUp(Node* a) {
513 return AddNode(machine()->Float32RoundUp().op(), a);
514 }
515 Node* Float64RoundUp(Node* a) {
516 return AddNode(machine()->Float64RoundUp().op(), a);
517 }
518 Node* Float32RoundTruncate(Node* a) {
519 return AddNode(machine()->Float32RoundTruncate().op(), a);
520 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400521 Node* Float64RoundTruncate(Node* a) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000522 return AddNode(machine()->Float64RoundTruncate().op(), a);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400523 }
524 Node* Float64RoundTiesAway(Node* a) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000525 return AddNode(machine()->Float64RoundTiesAway().op(), a);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400526 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000527 Node* Float32RoundTiesEven(Node* a) {
528 return AddNode(machine()->Float32RoundTiesEven().op(), a);
529 }
530 Node* Float64RoundTiesEven(Node* a) {
531 return AddNode(machine()->Float64RoundTiesEven().op(), a);
532 }
533
534 // Float64 bit operations.
535 Node* Float64ExtractLowWord32(Node* a) {
536 return AddNode(machine()->Float64ExtractLowWord32(), a);
537 }
538 Node* Float64ExtractHighWord32(Node* a) {
539 return AddNode(machine()->Float64ExtractHighWord32(), a);
540 }
541 Node* Float64InsertLowWord32(Node* a, Node* b) {
542 return AddNode(machine()->Float64InsertLowWord32(), a, b);
543 }
544 Node* Float64InsertHighWord32(Node* a, Node* b) {
545 return AddNode(machine()->Float64InsertHighWord32(), a, b);
546 }
547
548 // Stack operations.
549 Node* LoadStackPointer() { return AddNode(machine()->LoadStackPointer()); }
550 Node* LoadFramePointer() { return AddNode(machine()->LoadFramePointer()); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000551
552 // Parameters.
553 Node* Parameter(size_t index);
554
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000555 // Pointer utilities.
556 Node* LoadFromPointer(void* address, MachineType rep, int32_t offset = 0) {
557 return Load(rep, PointerConstant(address), Int32Constant(offset));
558 }
559 Node* StoreToPointer(void* address, MachineRepresentation rep, Node* node) {
560 return Store(rep, PointerConstant(address), node, kNoWriteBarrier);
561 }
562 Node* StringConstant(const char* string) {
563 return HeapConstant(isolate()->factory()->InternalizeUtf8String(string));
564 }
565
566 // Call a given call descriptor and the given arguments.
567 Node* CallN(CallDescriptor* desc, Node* function, Node** args);
568 // Call a given call descriptor and the given arguments and frame-state.
569 Node* CallNWithFrameState(CallDescriptor* desc, Node* function, Node** args,
570 Node* frame_state);
571 // Call to a runtime function with one arguments.
572 Node* CallRuntime1(Runtime::FunctionId function, Node* arg0, Node* context);
573 // Call to a runtime function with two arguments.
574 Node* CallRuntime2(Runtime::FunctionId function, Node* arg1, Node* arg2,
575 Node* context);
576 // Call to a runtime function with four arguments.
577 Node* CallRuntime4(Runtime::FunctionId function, Node* arg1, Node* arg2,
578 Node* arg3, Node* arg4, Node* context);
579 // Call to a C function with zero arguments.
580 Node* CallCFunction0(MachineType return_type, Node* function);
581 // Call to a C function with one parameter.
582 Node* CallCFunction1(MachineType return_type, MachineType arg0_type,
583 Node* function, Node* arg0);
584 // Call to a C function with two arguments.
585 Node* CallCFunction2(MachineType return_type, MachineType arg0_type,
586 MachineType arg1_type, Node* function, Node* arg0,
587 Node* arg1);
588 // Call to a C function with eight arguments.
589 Node* CallCFunction8(MachineType return_type, MachineType arg0_type,
590 MachineType arg1_type, MachineType arg2_type,
591 MachineType arg3_type, MachineType arg4_type,
592 MachineType arg5_type, MachineType arg6_type,
593 MachineType arg7_type, Node* function, Node* arg0,
594 Node* arg1, Node* arg2, Node* arg3, Node* arg4,
595 Node* arg5, Node* arg6, Node* arg7);
596
597 // Tail call the given call descriptor and the given arguments.
598 Node* TailCallN(CallDescriptor* call_descriptor, Node* function, Node** args);
599 // Tail call to a runtime function with one argument.
600 Node* TailCallRuntime1(Runtime::FunctionId function, Node* arg0,
601 Node* context);
602 // Tail call to a runtime function with two arguments.
603 Node* TailCallRuntime2(Runtime::FunctionId function, Node* arg1, Node* arg2,
604 Node* context);
605
606
607 // ===========================================================================
608 // The following utility methods deal with control flow, hence might switch
609 // the current basic block or create new basic blocks for labels.
610
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000611 // Control flow.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000612 void Goto(RawMachineLabel* label);
613 void Branch(Node* condition, RawMachineLabel* true_val,
614 RawMachineLabel* false_val);
615 void Switch(Node* index, RawMachineLabel* default_label, int32_t* case_values,
616 RawMachineLabel** case_labels, size_t case_count);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000617 void Return(Node* value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000618 void Return(Node* v1, Node* v2);
619 void Return(Node* v1, Node* v2, Node* v3);
620 void Bind(RawMachineLabel* label);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000621 void Deoptimize(Node* state);
622
623 // Variables.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000624 Node* Phi(MachineRepresentation rep, Node* n1, Node* n2) {
625 return AddNode(common()->Phi(rep, 2), n1, n2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000626 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000627 Node* Phi(MachineRepresentation rep, Node* n1, Node* n2, Node* n3) {
628 return AddNode(common()->Phi(rep, 3), n1, n2, n3);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000629 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000630 Node* Phi(MachineRepresentation rep, Node* n1, Node* n2, Node* n3, Node* n4) {
631 return AddNode(common()->Phi(rep, 4), n1, n2, n3, n4);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000632 }
633
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000634 // ===========================================================================
635 // The following generic node creation methods can be used for operators that
636 // are not covered by the above utility methods. There should rarely be a need
637 // to do that outside of testing though.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000638
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000639 Node* AddNode(const Operator* op, int input_count, Node** inputs);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000640
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000641 Node* AddNode(const Operator* op) {
642 return AddNode(op, 0, static_cast<Node**>(nullptr));
643 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000644
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000645 template <class... TArgs>
646 Node* AddNode(const Operator* op, Node* n1, TArgs... args) {
647 Node* buffer[] = {n1, args...};
648 return AddNode(op, sizeof...(args) + 1, buffer);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000649 }
650
651 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000652 Node* MakeNode(const Operator* op, int input_count, Node** inputs);
653 BasicBlock* Use(RawMachineLabel* label);
654 BasicBlock* EnsureBlock(RawMachineLabel* label);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000655 BasicBlock* CurrentBlock();
656
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000657 Schedule* schedule() { return schedule_; }
658 size_t parameter_count() const { return machine_sig()->parameter_count(); }
659 const MachineSignature* machine_sig() const {
660 return call_descriptor_->GetMachineSignature();
661 }
662
663 Isolate* isolate_;
664 Graph* graph_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000665 Schedule* schedule_;
666 MachineOperatorBuilder machine_;
667 CommonOperatorBuilder common_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000668 CallDescriptor* call_descriptor_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000669 NodeVector parameters_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000670 BasicBlock* current_block_;
671
672 DISALLOW_COPY_AND_ASSIGN(RawMachineAssembler);
673};
674
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000675
676class RawMachineLabel final {
677 public:
678 RawMachineLabel();
679 ~RawMachineLabel();
680
681 private:
682 BasicBlock* block_;
683 bool used_;
684 bool bound_;
685 friend class RawMachineAssembler;
686 DISALLOW_COPY_AND_ASSIGN(RawMachineLabel);
687};
688
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000689} // namespace compiler
690} // namespace internal
691} // namespace v8
692
693#endif // V8_COMPILER_RAW_MACHINE_ASSEMBLER_H_