blob: 83723345952e72e8cf74812c2c8fd99954bdd293 [file] [log] [blame]
Ben Murdochbcf72ee2016-08-08 18:44:38 +01001// Copyright 2015 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_CODE_ASSEMBLER_H_
6#define V8_COMPILER_CODE_ASSEMBLER_H_
7
8#include <map>
Ben Murdochf91f0612016-11-29 16:50:11 +00009#include <memory>
Ben Murdochbcf72ee2016-08-08 18:44:38 +010010
11// Clients of this interface shouldn't depend on lots of compiler internals.
12// Do not include anything from src/compiler here!
13#include "src/allocation.h"
Ben Murdochf91f0612016-11-29 16:50:11 +000014#include "src/builtins/builtins.h"
Ben Murdochbcf72ee2016-08-08 18:44:38 +010015#include "src/heap/heap.h"
16#include "src/machine-type.h"
17#include "src/runtime/runtime.h"
Ben Murdochf3b273f2017-01-17 12:11:28 +000018#include "src/zone/zone-containers.h"
Ben Murdochbcf72ee2016-08-08 18:44:38 +010019
20namespace v8 {
21namespace internal {
22
23class Callable;
24class CallInterfaceDescriptor;
25class Isolate;
26class Factory;
27class Zone;
28
29namespace compiler {
30
31class CallDescriptor;
Ben Murdochbcf72ee2016-08-08 18:44:38 +010032class Node;
Ben Murdochbcf72ee2016-08-08 18:44:38 +010033class RawMachineAssembler;
34class RawMachineLabel;
Ben Murdochbcf72ee2016-08-08 18:44:38 +010035
36#define CODE_ASSEMBLER_COMPARE_BINARY_OP_LIST(V) \
37 V(Float32Equal) \
38 V(Float32LessThan) \
39 V(Float32LessThanOrEqual) \
40 V(Float32GreaterThan) \
41 V(Float32GreaterThanOrEqual) \
42 V(Float64Equal) \
43 V(Float64LessThan) \
44 V(Float64LessThanOrEqual) \
45 V(Float64GreaterThan) \
46 V(Float64GreaterThanOrEqual) \
47 V(Int32GreaterThan) \
48 V(Int32GreaterThanOrEqual) \
49 V(Int32LessThan) \
50 V(Int32LessThanOrEqual) \
51 V(IntPtrLessThan) \
52 V(IntPtrLessThanOrEqual) \
53 V(IntPtrGreaterThan) \
54 V(IntPtrGreaterThanOrEqual) \
55 V(IntPtrEqual) \
56 V(Uint32LessThan) \
Ben Murdochf3b273f2017-01-17 12:11:28 +000057 V(Uint32LessThanOrEqual) \
Ben Murdochf91f0612016-11-29 16:50:11 +000058 V(Uint32GreaterThanOrEqual) \
Ben Murdochbcf72ee2016-08-08 18:44:38 +010059 V(UintPtrLessThan) \
Ben Murdochf3b273f2017-01-17 12:11:28 +000060 V(UintPtrGreaterThan) \
Ben Murdochbcf72ee2016-08-08 18:44:38 +010061 V(UintPtrGreaterThanOrEqual) \
62 V(WordEqual) \
63 V(WordNotEqual) \
64 V(Word32Equal) \
65 V(Word32NotEqual) \
66 V(Word64Equal) \
67 V(Word64NotEqual)
68
69#define CODE_ASSEMBLER_BINARY_OP_LIST(V) \
70 CODE_ASSEMBLER_COMPARE_BINARY_OP_LIST(V) \
71 V(Float64Add) \
72 V(Float64Sub) \
73 V(Float64Mul) \
74 V(Float64Div) \
75 V(Float64Mod) \
Ben Murdoch13e2dad2016-09-16 13:49:30 +010076 V(Float64Atan2) \
Ben Murdochf91f0612016-11-29 16:50:11 +000077 V(Float64Pow) \
Ben Murdochbcf72ee2016-08-08 18:44:38 +010078 V(Float64InsertLowWord32) \
79 V(Float64InsertHighWord32) \
80 V(IntPtrAdd) \
81 V(IntPtrAddWithOverflow) \
82 V(IntPtrSub) \
83 V(IntPtrSubWithOverflow) \
84 V(IntPtrMul) \
85 V(Int32Add) \
86 V(Int32AddWithOverflow) \
87 V(Int32Sub) \
88 V(Int32Mul) \
Ben Murdochf91f0612016-11-29 16:50:11 +000089 V(Int32MulWithOverflow) \
Ben Murdochbcf72ee2016-08-08 18:44:38 +010090 V(Int32Div) \
Ben Murdochf91f0612016-11-29 16:50:11 +000091 V(Int32Mod) \
Ben Murdochbcf72ee2016-08-08 18:44:38 +010092 V(WordOr) \
93 V(WordAnd) \
94 V(WordXor) \
95 V(WordShl) \
96 V(WordShr) \
97 V(WordSar) \
98 V(WordRor) \
99 V(Word32Or) \
100 V(Word32And) \
101 V(Word32Xor) \
102 V(Word32Shl) \
103 V(Word32Shr) \
104 V(Word32Sar) \
105 V(Word32Ror) \
106 V(Word64Or) \
107 V(Word64And) \
108 V(Word64Xor) \
109 V(Word64Shr) \
110 V(Word64Sar) \
111 V(Word64Ror)
112
113#define CODE_ASSEMBLER_UNARY_OP_LIST(V) \
Ben Murdochf91f0612016-11-29 16:50:11 +0000114 V(Float64Abs) \
115 V(Float64Acos) \
116 V(Float64Acosh) \
117 V(Float64Asin) \
118 V(Float64Asinh) \
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100119 V(Float64Atan) \
120 V(Float64Atanh) \
121 V(Float64Cos) \
Ben Murdochf91f0612016-11-29 16:50:11 +0000122 V(Float64Cosh) \
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100123 V(Float64Exp) \
124 V(Float64Expm1) \
125 V(Float64Log) \
126 V(Float64Log1p) \
127 V(Float64Log2) \
128 V(Float64Log10) \
129 V(Float64Cbrt) \
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100130 V(Float64Neg) \
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100131 V(Float64Sin) \
Ben Murdochf91f0612016-11-29 16:50:11 +0000132 V(Float64Sinh) \
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100133 V(Float64Sqrt) \
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100134 V(Float64Tan) \
Ben Murdochf91f0612016-11-29 16:50:11 +0000135 V(Float64Tanh) \
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100136 V(Float64ExtractLowWord32) \
137 V(Float64ExtractHighWord32) \
Ben Murdochf3b273f2017-01-17 12:11:28 +0000138 V(BitcastTaggedToWord) \
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100139 V(BitcastWordToTagged) \
Ben Murdochf3b273f2017-01-17 12:11:28 +0000140 V(BitcastWordToTaggedSigned) \
Ben Murdochf91f0612016-11-29 16:50:11 +0000141 V(TruncateFloat64ToFloat32) \
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100142 V(TruncateFloat64ToWord32) \
143 V(TruncateInt64ToInt32) \
Ben Murdochf91f0612016-11-29 16:50:11 +0000144 V(ChangeFloat32ToFloat64) \
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100145 V(ChangeFloat64ToUint32) \
146 V(ChangeInt32ToFloat64) \
147 V(ChangeInt32ToInt64) \
148 V(ChangeUint32ToFloat64) \
149 V(ChangeUint32ToUint64) \
150 V(RoundFloat64ToInt32) \
Ben Murdochf3b273f2017-01-17 12:11:28 +0000151 V(Float64SilenceNaN) \
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100152 V(Float64RoundDown) \
153 V(Float64RoundUp) \
154 V(Float64RoundTruncate) \
Ben Murdochf3b273f2017-01-17 12:11:28 +0000155 V(Word32Clz) \
156 V(Word32BinaryNot)
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100157
158// A "public" interface used by components outside of compiler directory to
159// create code objects with TurboFan's backend. This class is mostly a thin shim
160// around the RawMachineAssembler, and its primary job is to ensure that the
161// innards of the RawMachineAssembler and other compiler implementation details
162// don't leak outside of the the compiler directory..
163//
164// V8 components that need to generate low-level code using this interface
165// should include this header--and this header only--from the compiler directory
166// (this is actually enforced). Since all interesting data structures are
167// forward declared, it's not possible for clients to peek inside the compiler
168// internals.
169//
170// In addition to providing isolation between TurboFan and code generation
171// clients, CodeAssembler also provides an abstraction for creating variables
172// and enhanced Label functionality to merge variable values along paths where
173// they have differing values, including loops.
174class CodeAssembler {
175 public:
176 // Create with CallStub linkage.
177 // |result_size| specifies the number of results returned by the stub.
178 // TODO(rmcilroy): move result_size to the CallInterfaceDescriptor.
179 CodeAssembler(Isolate* isolate, Zone* zone,
180 const CallInterfaceDescriptor& descriptor, Code::Flags flags,
181 const char* name, size_t result_size = 1);
182
183 // Create with JSCall linkage.
184 CodeAssembler(Isolate* isolate, Zone* zone, int parameter_count,
185 Code::Flags flags, const char* name);
186
187 virtual ~CodeAssembler();
188
189 Handle<Code> GenerateCode();
190
191 bool Is64() const;
192 bool IsFloat64RoundUpSupported() const;
193 bool IsFloat64RoundDownSupported() const;
194 bool IsFloat64RoundTruncateSupported() const;
195
196 class Label;
197 class Variable {
198 public:
199 explicit Variable(CodeAssembler* assembler, MachineRepresentation rep);
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100200 ~Variable();
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100201 void Bind(Node* value);
202 Node* value() const;
203 MachineRepresentation rep() const;
204 bool IsBound() const;
205
206 private:
207 friend class CodeAssembler;
208 class Impl;
209 Impl* impl_;
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100210 CodeAssembler* assembler_;
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100211 };
212
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100213 // ===========================================================================
214 // Base Assembler
215 // ===========================================================================
216
217 // Constants.
218 Node* Int32Constant(int32_t value);
219 Node* Int64Constant(int64_t value);
220 Node* IntPtrConstant(intptr_t value);
221 Node* NumberConstant(double value);
222 Node* SmiConstant(Smi* value);
223 Node* HeapConstant(Handle<HeapObject> object);
224 Node* BooleanConstant(bool value);
225 Node* ExternalConstant(ExternalReference address);
226 Node* Float64Constant(double value);
227 Node* NaNConstant();
228
229 bool ToInt32Constant(Node* node, int32_t& out_value);
230 bool ToInt64Constant(Node* node, int64_t& out_value);
231 bool ToIntPtrConstant(Node* node, intptr_t& out_value);
232
233 Node* Parameter(int value);
234 void Return(Node* value);
235
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100236 void DebugBreak();
237 void Comment(const char* format, ...);
238
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100239 void Bind(Label* label);
240 void Goto(Label* label);
241 void GotoIf(Node* condition, Label* true_label);
242 void GotoUnless(Node* condition, Label* false_label);
243 void Branch(Node* condition, Label* true_label, Label* false_label);
244
Ben Murdochf91f0612016-11-29 16:50:11 +0000245 void Switch(Node* index, Label* default_label, const int32_t* case_values,
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100246 Label** case_labels, size_t case_count);
247
Ben Murdochf91f0612016-11-29 16:50:11 +0000248 Node* Select(Node* condition, Node* true_value, Node* false_value,
249 MachineRepresentation rep = MachineRepresentation::kTagged);
250
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100251 // Access to the frame pointer
252 Node* LoadFramePointer();
253 Node* LoadParentFramePointer();
254
255 // Access to the stack pointer
256 Node* LoadStackPointer();
257
258 // Load raw memory location.
259 Node* Load(MachineType rep, Node* base);
260 Node* Load(MachineType rep, Node* base, Node* index);
261 Node* AtomicLoad(MachineType rep, Node* base, Node* index);
262
263 // Load a value from the root array.
264 Node* LoadRoot(Heap::RootListIndex root_index);
265
266 // Store value to raw memory location.
267 Node* Store(MachineRepresentation rep, Node* base, Node* value);
268 Node* Store(MachineRepresentation rep, Node* base, Node* index, Node* value);
269 Node* StoreNoWriteBarrier(MachineRepresentation rep, Node* base, Node* value);
270 Node* StoreNoWriteBarrier(MachineRepresentation rep, Node* base, Node* index,
271 Node* value);
272 Node* AtomicStore(MachineRepresentation rep, Node* base, Node* index,
273 Node* value);
274
275 // Store a value to the root array.
276 Node* StoreRoot(Heap::RootListIndex root_index, Node* value);
277
278// Basic arithmetic operations.
279#define DECLARE_CODE_ASSEMBLER_BINARY_OP(name) Node* name(Node* a, Node* b);
280 CODE_ASSEMBLER_BINARY_OP_LIST(DECLARE_CODE_ASSEMBLER_BINARY_OP)
281#undef DECLARE_CODE_ASSEMBLER_BINARY_OP
282
283 Node* WordShl(Node* value, int shift);
284 Node* WordShr(Node* value, int shift);
Ben Murdochf91f0612016-11-29 16:50:11 +0000285 Node* Word32Shr(Node* value, int shift);
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100286
287// Unary
288#define DECLARE_CODE_ASSEMBLER_UNARY_OP(name) Node* name(Node* a);
289 CODE_ASSEMBLER_UNARY_OP_LIST(DECLARE_CODE_ASSEMBLER_UNARY_OP)
290#undef DECLARE_CODE_ASSEMBLER_UNARY_OP
291
Ben Murdochf3b273f2017-01-17 12:11:28 +0000292 // Changes an intptr_t to a double, e.g. for storing an element index
293 // outside Smi range in a HeapNumber. Lossless on 32-bit,
294 // rounds on 64-bit (which doesn't affect valid element indices).
295 Node* RoundIntPtrToFloat64(Node* value);
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100296 // No-op on 32-bit, otherwise zero extend.
297 Node* ChangeUint32ToWord(Node* value);
298 // No-op on 32-bit, otherwise sign extend.
299 Node* ChangeInt32ToIntPtr(Node* value);
300
Ben Murdochf3b273f2017-01-17 12:11:28 +0000301 // No-op that guarantees that the value is kept alive till this point even
302 // if GC happens.
303 Node* Retain(Node* value);
304
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100305 // Projections
306 Node* Projection(int index, Node* value);
307
308 // Calls
309 Node* CallRuntime(Runtime::FunctionId function_id, Node* context);
310 Node* CallRuntime(Runtime::FunctionId function_id, Node* context, Node* arg1);
311 Node* CallRuntime(Runtime::FunctionId function_id, Node* context, Node* arg1,
312 Node* arg2);
313 Node* CallRuntime(Runtime::FunctionId function_id, Node* context, Node* arg1,
314 Node* arg2, Node* arg3);
315 Node* CallRuntime(Runtime::FunctionId function_id, Node* context, Node* arg1,
316 Node* arg2, Node* arg3, Node* arg4);
317 Node* CallRuntime(Runtime::FunctionId function_id, Node* context, Node* arg1,
318 Node* arg2, Node* arg3, Node* arg4, Node* arg5);
319
320 Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context);
321 Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context,
322 Node* arg1);
323 Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context,
324 Node* arg1, Node* arg2);
325 Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context,
326 Node* arg1, Node* arg2, Node* arg3);
327 Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context,
328 Node* arg1, Node* arg2, Node* arg3, Node* arg4);
Ben Murdochf91f0612016-11-29 16:50:11 +0000329 Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context,
330 Node* arg1, Node* arg2, Node* arg3, Node* arg4,
331 Node* arg5);
Ben Murdochf3b273f2017-01-17 12:11:28 +0000332 Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context,
333 Node* arg1, Node* arg2, Node* arg3, Node* arg4,
334 Node* arg5, Node* arg6);
Ben Murdochf91f0612016-11-29 16:50:11 +0000335
336 // A pair of a zero-based argument index and a value.
337 // It helps writing arguments order independent code.
338 struct Arg {
339 Arg(int index, Node* value) : index(index), value(value) {}
340
341 int const index;
342 Node* const value;
343 };
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100344
345 Node* CallStub(Callable const& callable, Node* context, Node* arg1,
346 size_t result_size = 1);
347 Node* CallStub(Callable const& callable, Node* context, Node* arg1,
348 Node* arg2, size_t result_size = 1);
349 Node* CallStub(Callable const& callable, Node* context, Node* arg1,
350 Node* arg2, Node* arg3, size_t result_size = 1);
Ben Murdochf3b273f2017-01-17 12:11:28 +0000351 Node* CallStub(Callable const& callable, Node* context, Node* arg1,
352 Node* arg2, Node* arg3, Node* arg4, size_t result_size = 1);
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100353 Node* CallStubN(Callable const& callable, Node** args,
354 size_t result_size = 1);
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100355
356 Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
Ben Murdochf91f0612016-11-29 16:50:11 +0000357 Node* context, size_t result_size = 1);
358 Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100359 Node* context, Node* arg1, size_t result_size = 1);
360 Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
361 Node* context, Node* arg1, Node* arg2, size_t result_size = 1);
362 Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
363 Node* context, Node* arg1, Node* arg2, Node* arg3,
364 size_t result_size = 1);
365 Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
366 Node* context, Node* arg1, Node* arg2, Node* arg3, Node* arg4,
367 size_t result_size = 1);
368 Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
369 Node* context, Node* arg1, Node* arg2, Node* arg3, Node* arg4,
370 Node* arg5, size_t result_size = 1);
Ben Murdochf91f0612016-11-29 16:50:11 +0000371
372 Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
373 Node* context, const Arg& arg1, const Arg& arg2,
374 size_t result_size = 1);
375 Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
376 Node* context, const Arg& arg1, const Arg& arg2,
377 const Arg& arg3, size_t result_size = 1);
378 Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
379 Node* context, const Arg& arg1, const Arg& arg2,
380 const Arg& arg3, const Arg& arg4, size_t result_size = 1);
381 Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
382 Node* context, const Arg& arg1, const Arg& arg2,
383 const Arg& arg3, const Arg& arg4, const Arg& arg5,
384 size_t result_size = 1);
385
Ben Murdochf3b273f2017-01-17 12:11:28 +0000386 Node* CallStubN(const CallInterfaceDescriptor& descriptor,
387 int js_parameter_count, Node* target, Node** args,
388 size_t result_size = 1);
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100389 Node* CallStubN(const CallInterfaceDescriptor& descriptor, Node* target,
Ben Murdochf3b273f2017-01-17 12:11:28 +0000390 Node** args, size_t result_size = 1) {
391 return CallStubN(descriptor, 0, target, args, result_size);
392 }
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100393
394 Node* TailCallStub(Callable const& callable, Node* context, Node* arg1,
Ben Murdochf91f0612016-11-29 16:50:11 +0000395 size_t result_size = 1);
396 Node* TailCallStub(Callable const& callable, Node* context, Node* arg1,
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100397 Node* arg2, size_t result_size = 1);
398 Node* TailCallStub(Callable const& callable, Node* context, Node* arg1,
399 Node* arg2, Node* arg3, size_t result_size = 1);
Ben Murdochf91f0612016-11-29 16:50:11 +0000400 Node* TailCallStub(Callable const& callable, Node* context, Node* arg1,
401 Node* arg2, Node* arg3, Node* arg4,
402 size_t result_size = 1);
403 Node* TailCallStub(const CallInterfaceDescriptor& descriptor, Node* target,
404 Node* context, Node* arg1, size_t result_size = 1);
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100405 Node* TailCallStub(const CallInterfaceDescriptor& descriptor, Node* target,
406 Node* context, Node* arg1, Node* arg2,
407 size_t result_size = 1);
408 Node* TailCallStub(const CallInterfaceDescriptor& descriptor, Node* target,
409 Node* context, Node* arg1, Node* arg2, Node* arg3,
410 size_t result_size = 1);
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100411 Node* TailCallStub(const CallInterfaceDescriptor& descriptor, Node* target,
412 Node* context, Node* arg1, Node* arg2, Node* arg3,
413 Node* arg4, size_t result_size = 1);
Ben Murdochf3b273f2017-01-17 12:11:28 +0000414 Node* TailCallStub(const CallInterfaceDescriptor& descriptor, Node* target,
415 Node* context, Node* arg1, Node* arg2, Node* arg3,
416 Node* arg4, Node* arg5, size_t result_size = 1);
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100417
Ben Murdochf91f0612016-11-29 16:50:11 +0000418 Node* TailCallStub(const CallInterfaceDescriptor& descriptor, Node* target,
419 Node* context, const Arg& arg1, const Arg& arg2,
420 const Arg& arg3, const Arg& arg4, size_t result_size = 1);
421 Node* TailCallStub(const CallInterfaceDescriptor& descriptor, Node* target,
422 Node* context, const Arg& arg1, const Arg& arg2,
423 const Arg& arg3, const Arg& arg4, const Arg& arg5,
424 size_t result_size = 1);
425
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100426 Node* TailCallBytecodeDispatch(const CallInterfaceDescriptor& descriptor,
427 Node* code_target_address, Node** args);
428
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100429 Node* CallJS(Callable const& callable, Node* context, Node* function,
430 Node* receiver, size_t result_size = 1);
431 Node* CallJS(Callable const& callable, Node* context, Node* function,
432 Node* receiver, Node* arg1, size_t result_size = 1);
433 Node* CallJS(Callable const& callable, Node* context, Node* function,
434 Node* receiver, Node* arg1, Node* arg2, size_t result_size = 1);
435
Ben Murdochf3b273f2017-01-17 12:11:28 +0000436 // Call to a C function with two arguments.
437 Node* CallCFunction2(MachineType return_type, MachineType arg0_type,
438 MachineType arg1_type, Node* function, Node* arg0,
439 Node* arg1);
440
Ben Murdochf91f0612016-11-29 16:50:11 +0000441 // Exception handling support.
442 void GotoIfException(Node* node, Label* if_exception,
443 Variable* exception_var = nullptr);
444
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100445 // Branching helpers.
446 void BranchIf(Node* condition, Label* if_true, Label* if_false);
447
448#define BRANCH_HELPER(name) \
449 void BranchIf##name(Node* a, Node* b, Label* if_true, Label* if_false) { \
450 BranchIf(name(a, b), if_true, if_false); \
451 }
452 CODE_ASSEMBLER_COMPARE_BINARY_OP_LIST(BRANCH_HELPER)
453#undef BRANCH_HELPER
454
455 // Helpers which delegate to RawMachineAssembler.
456 Factory* factory() const;
457 Isolate* isolate() const;
458 Zone* zone() const;
459
460 protected:
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100461 // Enables subclasses to perform operations before and after a call.
462 virtual void CallPrologue();
463 virtual void CallEpilogue();
464
465 private:
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100466 CodeAssembler(Isolate* isolate, Zone* zone, CallDescriptor* call_descriptor,
467 Code::Flags flags, const char* name);
468
469 Node* CallN(CallDescriptor* descriptor, Node* code_target, Node** args);
470 Node* TailCallN(CallDescriptor* descriptor, Node* code_target, Node** args);
471
Ben Murdochf91f0612016-11-29 16:50:11 +0000472 std::unique_ptr<RawMachineAssembler> raw_assembler_;
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100473 Code::Flags flags_;
474 const char* name_;
475 bool code_generated_;
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100476 ZoneSet<Variable::Impl*> variables_;
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100477
478 DISALLOW_COPY_AND_ASSIGN(CodeAssembler);
479};
480
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100481class CodeAssembler::Label {
482 public:
483 enum Type { kDeferred, kNonDeferred };
484
485 explicit Label(
486 CodeAssembler* assembler,
487 CodeAssembler::Label::Type type = CodeAssembler::Label::kNonDeferred)
488 : CodeAssembler::Label(assembler, 0, nullptr, type) {}
489 Label(CodeAssembler* assembler, CodeAssembler::Variable* merged_variable,
490 CodeAssembler::Label::Type type = CodeAssembler::Label::kNonDeferred)
491 : CodeAssembler::Label(assembler, 1, &merged_variable, type) {}
492 Label(CodeAssembler* assembler, int merged_variable_count,
493 CodeAssembler::Variable** merged_variables,
494 CodeAssembler::Label::Type type = CodeAssembler::Label::kNonDeferred);
495 ~Label() {}
496
497 private:
498 friend class CodeAssembler;
499
500 void Bind();
501 void MergeVariables();
502
503 bool bound_;
504 size_t merge_count_;
505 CodeAssembler* assembler_;
506 RawMachineLabel* label_;
507 // Map of variables that need to be merged to their phi nodes (or placeholders
508 // for those phis).
509 std::map<Variable::Impl*, Node*> variable_phis_;
510 // Map of variables to the list of value nodes that have been added from each
511 // merge path in their order of merging.
512 std::map<Variable::Impl*, std::vector<Node*>> variable_merges_;
513};
514
515} // namespace compiler
516} // namespace internal
517} // namespace v8
518
519#endif // V8_COMPILER_CODE_ASSEMBLER_H_