blob: 8808a82f8e8950c71f1e74f33685b9b58cabddc3 [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 Murdoch62ed6312017-06-06 11:06:27 +010015#include "src/code-factory.h"
Ben Murdochc8c1d9e2017-03-08 14:04:23 +000016#include "src/globals.h"
Ben Murdochbcf72ee2016-08-08 18:44:38 +010017#include "src/heap/heap.h"
18#include "src/machine-type.h"
19#include "src/runtime/runtime.h"
Ben Murdochf3b273f2017-01-17 12:11:28 +000020#include "src/zone/zone-containers.h"
Ben Murdochbcf72ee2016-08-08 18:44:38 +010021
22namespace v8 {
23namespace internal {
24
25class Callable;
26class CallInterfaceDescriptor;
27class Isolate;
28class Factory;
29class Zone;
30
31namespace compiler {
32
33class CallDescriptor;
Ben Murdoch62ed6312017-06-06 11:06:27 +010034class CodeAssemblerLabel;
35class CodeAssemblerVariable;
36class CodeAssemblerState;
Ben Murdochbcf72ee2016-08-08 18:44:38 +010037class Node;
Ben Murdochbcf72ee2016-08-08 18:44:38 +010038class RawMachineAssembler;
39class RawMachineLabel;
Ben Murdochbcf72ee2016-08-08 18:44:38 +010040
Ben Murdoch62ed6312017-06-06 11:06:27 +010041typedef ZoneList<CodeAssemblerVariable*> CodeAssemblerVariableList;
42
43typedef std::function<void()> CodeAssemblerCallback;
44
Ben Murdochbcf72ee2016-08-08 18:44:38 +010045#define CODE_ASSEMBLER_COMPARE_BINARY_OP_LIST(V) \
46 V(Float32Equal) \
47 V(Float32LessThan) \
48 V(Float32LessThanOrEqual) \
49 V(Float32GreaterThan) \
50 V(Float32GreaterThanOrEqual) \
51 V(Float64Equal) \
52 V(Float64LessThan) \
53 V(Float64LessThanOrEqual) \
54 V(Float64GreaterThan) \
55 V(Float64GreaterThanOrEqual) \
56 V(Int32GreaterThan) \
57 V(Int32GreaterThanOrEqual) \
58 V(Int32LessThan) \
59 V(Int32LessThanOrEqual) \
60 V(IntPtrLessThan) \
61 V(IntPtrLessThanOrEqual) \
62 V(IntPtrGreaterThan) \
63 V(IntPtrGreaterThanOrEqual) \
64 V(IntPtrEqual) \
65 V(Uint32LessThan) \
Ben Murdochf3b273f2017-01-17 12:11:28 +000066 V(Uint32LessThanOrEqual) \
Ben Murdochf91f0612016-11-29 16:50:11 +000067 V(Uint32GreaterThanOrEqual) \
Ben Murdochbcf72ee2016-08-08 18:44:38 +010068 V(UintPtrLessThan) \
Ben Murdochc8c1d9e2017-03-08 14:04:23 +000069 V(UintPtrLessThanOrEqual) \
Ben Murdochf3b273f2017-01-17 12:11:28 +000070 V(UintPtrGreaterThan) \
Ben Murdochbcf72ee2016-08-08 18:44:38 +010071 V(UintPtrGreaterThanOrEqual) \
72 V(WordEqual) \
73 V(WordNotEqual) \
74 V(Word32Equal) \
75 V(Word32NotEqual) \
76 V(Word64Equal) \
77 V(Word64NotEqual)
78
79#define CODE_ASSEMBLER_BINARY_OP_LIST(V) \
80 CODE_ASSEMBLER_COMPARE_BINARY_OP_LIST(V) \
81 V(Float64Add) \
82 V(Float64Sub) \
83 V(Float64Mul) \
84 V(Float64Div) \
85 V(Float64Mod) \
Ben Murdoch13e2dad2016-09-16 13:49:30 +010086 V(Float64Atan2) \
Ben Murdochf91f0612016-11-29 16:50:11 +000087 V(Float64Pow) \
Ben Murdochbcf72ee2016-08-08 18:44:38 +010088 V(Float64InsertLowWord32) \
89 V(Float64InsertHighWord32) \
Ben Murdochbcf72ee2016-08-08 18:44:38 +010090 V(IntPtrAddWithOverflow) \
Ben Murdochbcf72ee2016-08-08 18:44:38 +010091 V(IntPtrSubWithOverflow) \
92 V(IntPtrMul) \
93 V(Int32Add) \
94 V(Int32AddWithOverflow) \
95 V(Int32Sub) \
96 V(Int32Mul) \
Ben Murdochf91f0612016-11-29 16:50:11 +000097 V(Int32MulWithOverflow) \
Ben Murdochbcf72ee2016-08-08 18:44:38 +010098 V(Int32Div) \
Ben Murdochf91f0612016-11-29 16:50:11 +000099 V(Int32Mod) \
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100100 V(WordOr) \
101 V(WordAnd) \
102 V(WordXor) \
103 V(WordShl) \
104 V(WordShr) \
105 V(WordSar) \
106 V(WordRor) \
107 V(Word32Or) \
108 V(Word32And) \
109 V(Word32Xor) \
110 V(Word32Shl) \
111 V(Word32Shr) \
112 V(Word32Sar) \
113 V(Word32Ror) \
114 V(Word64Or) \
115 V(Word64And) \
116 V(Word64Xor) \
117 V(Word64Shr) \
118 V(Word64Sar) \
119 V(Word64Ror)
120
121#define CODE_ASSEMBLER_UNARY_OP_LIST(V) \
Ben Murdochf91f0612016-11-29 16:50:11 +0000122 V(Float64Abs) \
123 V(Float64Acos) \
124 V(Float64Acosh) \
125 V(Float64Asin) \
126 V(Float64Asinh) \
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100127 V(Float64Atan) \
128 V(Float64Atanh) \
129 V(Float64Cos) \
Ben Murdochf91f0612016-11-29 16:50:11 +0000130 V(Float64Cosh) \
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100131 V(Float64Exp) \
132 V(Float64Expm1) \
133 V(Float64Log) \
134 V(Float64Log1p) \
135 V(Float64Log2) \
136 V(Float64Log10) \
137 V(Float64Cbrt) \
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100138 V(Float64Neg) \
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100139 V(Float64Sin) \
Ben Murdochf91f0612016-11-29 16:50:11 +0000140 V(Float64Sinh) \
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100141 V(Float64Sqrt) \
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100142 V(Float64Tan) \
Ben Murdochf91f0612016-11-29 16:50:11 +0000143 V(Float64Tanh) \
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100144 V(Float64ExtractLowWord32) \
145 V(Float64ExtractHighWord32) \
Ben Murdochf3b273f2017-01-17 12:11:28 +0000146 V(BitcastTaggedToWord) \
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100147 V(BitcastWordToTagged) \
Ben Murdochf3b273f2017-01-17 12:11:28 +0000148 V(BitcastWordToTaggedSigned) \
Ben Murdochf91f0612016-11-29 16:50:11 +0000149 V(TruncateFloat64ToFloat32) \
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100150 V(TruncateFloat64ToWord32) \
151 V(TruncateInt64ToInt32) \
Ben Murdochf91f0612016-11-29 16:50:11 +0000152 V(ChangeFloat32ToFloat64) \
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100153 V(ChangeFloat64ToUint32) \
154 V(ChangeInt32ToFloat64) \
155 V(ChangeInt32ToInt64) \
156 V(ChangeUint32ToFloat64) \
157 V(ChangeUint32ToUint64) \
158 V(RoundFloat64ToInt32) \
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000159 V(RoundInt32ToFloat32) \
Ben Murdochf3b273f2017-01-17 12:11:28 +0000160 V(Float64SilenceNaN) \
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100161 V(Float64RoundDown) \
162 V(Float64RoundUp) \
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000163 V(Float64RoundTiesEven) \
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100164 V(Float64RoundTruncate) \
Ben Murdochf3b273f2017-01-17 12:11:28 +0000165 V(Word32Clz) \
Ben Murdoch62ed6312017-06-06 11:06:27 +0100166 V(Word32Not) \
Ben Murdochf3b273f2017-01-17 12:11:28 +0000167 V(Word32BinaryNot)
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100168
169// A "public" interface used by components outside of compiler directory to
170// create code objects with TurboFan's backend. This class is mostly a thin shim
171// around the RawMachineAssembler, and its primary job is to ensure that the
172// innards of the RawMachineAssembler and other compiler implementation details
173// don't leak outside of the the compiler directory..
174//
175// V8 components that need to generate low-level code using this interface
176// should include this header--and this header only--from the compiler directory
177// (this is actually enforced). Since all interesting data structures are
178// forward declared, it's not possible for clients to peek inside the compiler
179// internals.
180//
181// In addition to providing isolation between TurboFan and code generation
182// clients, CodeAssembler also provides an abstraction for creating variables
183// and enhanced Label functionality to merge variable values along paths where
184// they have differing values, including loops.
Ben Murdoch62ed6312017-06-06 11:06:27 +0100185//
186// The CodeAssembler itself is stateless (and instances are expected to be
187// temporary-scoped and short-lived); all its state is encapsulated into
188// a CodeAssemblerState instance.
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000189class V8_EXPORT_PRIVATE CodeAssembler {
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100190 public:
Ben Murdoch62ed6312017-06-06 11:06:27 +0100191 explicit CodeAssembler(CodeAssemblerState* state) : state_(state) {}
192 ~CodeAssembler();
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100193
Ben Murdoch62ed6312017-06-06 11:06:27 +0100194 static Handle<Code> GenerateCode(CodeAssemblerState* state);
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100195
196 bool Is64() const;
197 bool IsFloat64RoundUpSupported() const;
198 bool IsFloat64RoundDownSupported() const;
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000199 bool IsFloat64RoundTiesEvenSupported() const;
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100200 bool IsFloat64RoundTruncateSupported() const;
201
Ben Murdoch62ed6312017-06-06 11:06:27 +0100202 // Shortened aliases for use in CodeAssembler subclasses.
203 typedef CodeAssemblerLabel Label;
204 typedef CodeAssemblerVariable Variable;
205 typedef CodeAssemblerVariableList VariableList;
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000206
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100207 // ===========================================================================
208 // Base Assembler
209 // ===========================================================================
210
211 // Constants.
212 Node* Int32Constant(int32_t value);
213 Node* Int64Constant(int64_t value);
214 Node* IntPtrConstant(intptr_t value);
215 Node* NumberConstant(double value);
216 Node* SmiConstant(Smi* value);
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000217 Node* SmiConstant(int value);
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100218 Node* HeapConstant(Handle<HeapObject> object);
Ben Murdoch62ed6312017-06-06 11:06:27 +0100219 Node* CStringConstant(const char* str);
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100220 Node* BooleanConstant(bool value);
221 Node* ExternalConstant(ExternalReference address);
222 Node* Float64Constant(double value);
223 Node* NaNConstant();
224
225 bool ToInt32Constant(Node* node, int32_t& out_value);
226 bool ToInt64Constant(Node* node, int64_t& out_value);
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000227 bool ToSmiConstant(Node* node, Smi*& out_value);
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100228 bool ToIntPtrConstant(Node* node, intptr_t& out_value);
229
230 Node* Parameter(int value);
Ben Murdoch62ed6312017-06-06 11:06:27 +0100231 Node* GetJSContextParameter();
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100232 void Return(Node* value);
Ben Murdoch62ed6312017-06-06 11:06:27 +0100233 void Return(Node* value1, Node* value2);
234 void Return(Node* value1, Node* value2, Node* value3);
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000235 void PopAndReturn(Node* pop, Node* value);
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100236
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100237 void DebugBreak();
Ben Murdoch62ed6312017-06-06 11:06:27 +0100238 void Unreachable();
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100239 void Comment(const char* format, ...);
240
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100241 void Bind(Label* label);
242 void Goto(Label* label);
243 void GotoIf(Node* condition, Label* true_label);
Ben Murdoch62ed6312017-06-06 11:06:27 +0100244 void GotoIfNot(Node* condition, Label* false_label);
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100245 void Branch(Node* condition, Label* true_label, Label* false_label);
246
Ben Murdochf91f0612016-11-29 16:50:11 +0000247 void Switch(Node* index, Label* default_label, const int32_t* case_values,
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100248 Label** case_labels, size_t case_count);
249
250 // Access to the frame pointer
251 Node* LoadFramePointer();
252 Node* LoadParentFramePointer();
253
254 // Access to the stack pointer
255 Node* LoadStackPointer();
256
257 // Load raw memory location.
258 Node* Load(MachineType rep, Node* base);
Ben Murdoch62ed6312017-06-06 11:06:27 +0100259 Node* Load(MachineType rep, Node* base, Node* offset);
260 Node* AtomicLoad(MachineType rep, Node* base, Node* offset);
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100261
262 // Load a value from the root array.
263 Node* LoadRoot(Heap::RootListIndex root_index);
264
265 // Store value to raw memory location.
Ben Murdoch62ed6312017-06-06 11:06:27 +0100266 Node* Store(Node* base, Node* value);
267 Node* Store(Node* base, Node* offset, Node* value);
268 Node* StoreWithMapWriteBarrier(Node* base, Node* offset, Node* value);
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100269 Node* StoreNoWriteBarrier(MachineRepresentation rep, Node* base, Node* value);
Ben Murdoch62ed6312017-06-06 11:06:27 +0100270 Node* StoreNoWriteBarrier(MachineRepresentation rep, Node* base, Node* offset,
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100271 Node* value);
Ben Murdoch62ed6312017-06-06 11:06:27 +0100272 Node* AtomicStore(MachineRepresentation rep, Node* base, Node* offset,
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100273 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
Ben Murdoch62ed6312017-06-06 11:06:27 +0100283 Node* IntPtrAdd(Node* left, Node* right);
284 Node* IntPtrSub(Node* left, Node* right);
285
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100286 Node* WordShl(Node* value, int shift);
287 Node* WordShr(Node* value, int shift);
Ben Murdochf91f0612016-11-29 16:50:11 +0000288 Node* Word32Shr(Node* value, int shift);
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100289
290// Unary
291#define DECLARE_CODE_ASSEMBLER_UNARY_OP(name) Node* name(Node* a);
292 CODE_ASSEMBLER_UNARY_OP_LIST(DECLARE_CODE_ASSEMBLER_UNARY_OP)
293#undef DECLARE_CODE_ASSEMBLER_UNARY_OP
294
Ben Murdochf3b273f2017-01-17 12:11:28 +0000295 // Changes an intptr_t to a double, e.g. for storing an element index
296 // outside Smi range in a HeapNumber. Lossless on 32-bit,
297 // rounds on 64-bit (which doesn't affect valid element indices).
298 Node* RoundIntPtrToFloat64(Node* value);
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100299 // No-op on 32-bit, otherwise zero extend.
300 Node* ChangeUint32ToWord(Node* value);
301 // No-op on 32-bit, otherwise sign extend.
302 Node* ChangeInt32ToIntPtr(Node* value);
303
Ben Murdochf3b273f2017-01-17 12:11:28 +0000304 // No-op that guarantees that the value is kept alive till this point even
305 // if GC happens.
306 Node* Retain(Node* value);
307
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100308 // Projections
309 Node* Projection(int index, Node* value);
310
311 // Calls
Ben Murdoch62ed6312017-06-06 11:06:27 +0100312 template <class... TArgs>
313 Node* CallRuntime(Runtime::FunctionId function, Node* context, TArgs... args);
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100314
Ben Murdoch62ed6312017-06-06 11:06:27 +0100315 template <class... TArgs>
316 Node* TailCallRuntime(Runtime::FunctionId function, Node* context,
317 TArgs... args);
Ben Murdochf91f0612016-11-29 16:50:11 +0000318
Ben Murdoch62ed6312017-06-06 11:06:27 +0100319 template <class... TArgs>
320 Node* CallStub(Callable const& callable, Node* context, TArgs... args) {
321 Node* target = HeapConstant(callable.code());
322 return CallStub(callable.descriptor(), target, context, args...);
Ben Murdochf3b273f2017-01-17 12:11:28 +0000323 }
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100324
Ben Murdoch62ed6312017-06-06 11:06:27 +0100325 template <class... TArgs>
326 Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
327 Node* context, TArgs... args) {
328 return CallStubR(descriptor, 1, target, context, args...);
329 }
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000330
Ben Murdoch62ed6312017-06-06 11:06:27 +0100331 template <class... TArgs>
332 Node* CallStubR(const CallInterfaceDescriptor& descriptor, size_t result_size,
333 Node* target, Node* context, TArgs... args);
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100334
Ben Murdoch62ed6312017-06-06 11:06:27 +0100335 Node* CallStubN(const CallInterfaceDescriptor& descriptor, size_t result_size,
336 int input_count, Node* const* inputs);
Ben Murdochf91f0612016-11-29 16:50:11 +0000337
Ben Murdoch62ed6312017-06-06 11:06:27 +0100338 template <class... TArgs>
339 Node* TailCallStub(Callable const& callable, Node* context, TArgs... args) {
340 Node* target = HeapConstant(callable.code());
341 return TailCallStub(callable.descriptor(), target, context, args...);
342 }
343
344 template <class... TArgs>
345 Node* TailCallStub(const CallInterfaceDescriptor& descriptor, Node* target,
346 Node* context, TArgs... args);
347
348 template <class... TArgs>
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100349 Node* TailCallBytecodeDispatch(const CallInterfaceDescriptor& descriptor,
Ben Murdoch62ed6312017-06-06 11:06:27 +0100350 Node* target, TArgs... args);
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100351
Ben Murdoch62ed6312017-06-06 11:06:27 +0100352 template <class... TArgs>
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100353 Node* CallJS(Callable const& callable, Node* context, Node* function,
Ben Murdoch62ed6312017-06-06 11:06:27 +0100354 Node* receiver, TArgs... args) {
355 int argc = static_cast<int>(sizeof...(args));
356 Node* arity = Int32Constant(argc);
357 return CallStub(callable, context, function, arity, receiver, args...);
358 }
359
360 template <class... TArgs>
361 Node* ConstructJS(Callable const& callable, Node* context, Node* new_target,
362 TArgs... args) {
363 int argc = static_cast<int>(sizeof...(args));
364 Node* arity = Int32Constant(argc);
365 Node* receiver = LoadRoot(Heap::kUndefinedValueRootIndex);
366
367 // Construct(target, new_target, arity, receiver, arguments...)
368 return CallStub(callable, context, new_target, new_target, arity, receiver,
369 args...);
370 }
371
372 Node* CallCFunctionN(Signature<MachineType>* signature, int input_count,
373 Node* const* inputs);
Ben Murdoch13e2dad2016-09-16 13:49:30 +0100374
Ben Murdochf3b273f2017-01-17 12:11:28 +0000375 // Call to a C function with two arguments.
376 Node* CallCFunction2(MachineType return_type, MachineType arg0_type,
377 MachineType arg1_type, Node* function, Node* arg0,
378 Node* arg1);
379
Ben Murdoch62ed6312017-06-06 11:06:27 +0100380 // Call to a C function with three arguments.
381 Node* CallCFunction3(MachineType return_type, MachineType arg0_type,
382 MachineType arg1_type, MachineType arg2_type,
383 Node* function, Node* arg0, Node* arg1, Node* arg2);
384
Ben Murdochf91f0612016-11-29 16:50:11 +0000385 // Exception handling support.
386 void GotoIfException(Node* node, Label* if_exception,
387 Variable* exception_var = nullptr);
388
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100389 // Helpers which delegate to RawMachineAssembler.
390 Factory* factory() const;
391 Isolate* isolate() const;
392 Zone* zone() const;
393
Ben Murdoch62ed6312017-06-06 11:06:27 +0100394 CodeAssemblerState* state() { return state_; }
395
396 void BreakOnNode(int node_id);
397
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100398 protected:
Ben Murdoch62ed6312017-06-06 11:06:27 +0100399 void RegisterCallGenerationCallbacks(
400 const CodeAssemblerCallback& call_prologue,
401 const CodeAssemblerCallback& call_epilogue);
402 void UnregisterCallGenerationCallbacks();
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100403
404 private:
Ben Murdoch62ed6312017-06-06 11:06:27 +0100405 RawMachineAssembler* raw_assembler() const;
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100406
Ben Murdoch62ed6312017-06-06 11:06:27 +0100407 // Calls respective callback registered in the state.
408 void CallPrologue();
409 void CallEpilogue();
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100410
Ben Murdoch62ed6312017-06-06 11:06:27 +0100411 CodeAssemblerState* state_;
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100412
413 DISALLOW_COPY_AND_ASSIGN(CodeAssembler);
414};
415
Ben Murdoch62ed6312017-06-06 11:06:27 +0100416class CodeAssemblerVariable {
417 public:
418 explicit CodeAssemblerVariable(CodeAssembler* assembler,
419 MachineRepresentation rep);
420 CodeAssemblerVariable(CodeAssembler* assembler, MachineRepresentation rep,
421 Node* initial_value);
422 ~CodeAssemblerVariable();
423 void Bind(Node* value);
424 Node* value() const;
425 MachineRepresentation rep() const;
426 bool IsBound() const;
427
428 private:
429 friend class CodeAssemblerLabel;
430 friend class CodeAssemblerState;
431 class Impl;
432 Impl* impl_;
433 CodeAssemblerState* state_;
434};
435
436class CodeAssemblerLabel {
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100437 public:
438 enum Type { kDeferred, kNonDeferred };
439
Ben Murdoch62ed6312017-06-06 11:06:27 +0100440 explicit CodeAssemblerLabel(
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100441 CodeAssembler* assembler,
Ben Murdoch62ed6312017-06-06 11:06:27 +0100442 CodeAssemblerLabel::Type type = CodeAssemblerLabel::kNonDeferred)
443 : CodeAssemblerLabel(assembler, 0, nullptr, type) {}
444 CodeAssemblerLabel(
445 CodeAssembler* assembler,
446 const CodeAssemblerVariableList& merged_variables,
447 CodeAssemblerLabel::Type type = CodeAssemblerLabel::kNonDeferred)
448 : CodeAssemblerLabel(assembler, merged_variables.length(),
449 &(merged_variables[0]), type) {}
450 CodeAssemblerLabel(
451 CodeAssembler* assembler, size_t count, CodeAssemblerVariable** vars,
452 CodeAssemblerLabel::Type type = CodeAssemblerLabel::kNonDeferred);
453 CodeAssemblerLabel(
454 CodeAssembler* assembler, CodeAssemblerVariable* merged_variable,
455 CodeAssemblerLabel::Type type = CodeAssemblerLabel::kNonDeferred)
456 : CodeAssemblerLabel(assembler, 1, &merged_variable, type) {}
457 ~CodeAssemblerLabel();
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100458
459 private:
460 friend class CodeAssembler;
461
462 void Bind();
463 void MergeVariables();
464
465 bool bound_;
466 size_t merge_count_;
Ben Murdoch62ed6312017-06-06 11:06:27 +0100467 CodeAssemblerState* state_;
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100468 RawMachineLabel* label_;
469 // Map of variables that need to be merged to their phi nodes (or placeholders
470 // for those phis).
Ben Murdoch62ed6312017-06-06 11:06:27 +0100471 std::map<CodeAssemblerVariable::Impl*, Node*> variable_phis_;
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100472 // Map of variables to the list of value nodes that have been added from each
473 // merge path in their order of merging.
Ben Murdoch62ed6312017-06-06 11:06:27 +0100474 std::map<CodeAssemblerVariable::Impl*, std::vector<Node*>> variable_merges_;
475};
476
477class V8_EXPORT_PRIVATE CodeAssemblerState {
478 public:
479 // Create with CallStub linkage.
480 // |result_size| specifies the number of results returned by the stub.
481 // TODO(rmcilroy): move result_size to the CallInterfaceDescriptor.
482 CodeAssemblerState(Isolate* isolate, Zone* zone,
483 const CallInterfaceDescriptor& descriptor,
484 Code::Flags flags, const char* name,
485 size_t result_size = 1);
486
487 // Create with JSCall linkage.
488 CodeAssemblerState(Isolate* isolate, Zone* zone, int parameter_count,
489 Code::Flags flags, const char* name);
490
491 ~CodeAssemblerState();
492
493 const char* name() const { return name_; }
494 int parameter_count() const;
495
496 private:
497 friend class CodeAssembler;
498 friend class CodeAssemblerLabel;
499 friend class CodeAssemblerVariable;
500
501 CodeAssemblerState(Isolate* isolate, Zone* zone,
502 CallDescriptor* call_descriptor, Code::Flags flags,
503 const char* name);
504
505 std::unique_ptr<RawMachineAssembler> raw_assembler_;
506 Code::Flags flags_;
507 const char* name_;
508 bool code_generated_;
509 ZoneSet<CodeAssemblerVariable::Impl*> variables_;
510 CodeAssemblerCallback call_prologue_;
511 CodeAssemblerCallback call_epilogue_;
512
513 DISALLOW_COPY_AND_ASSIGN(CodeAssemblerState);
Ben Murdochbcf72ee2016-08-08 18:44:38 +0100514};
515
516} // namespace compiler
517} // namespace internal
518} // namespace v8
519
520#endif // V8_COMPILER_CODE_ASSEMBLER_H_