blob: 2ab13764c46acdb4e67bcc78cf9306d832e57e30 [file] [log] [blame]
Ben Murdoch014dc512016-03-22 12:00:34 +00001// 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_STUB_ASSEMBLER_H_
6#define V8_COMPILER_CODE_STUB_ASSEMBLER_H_
7
Ben Murdoch83897452016-05-17 11:12:09 +01008#include <map>
9
Ben Murdoch014dc512016-03-22 12:00:34 +000010// Clients of this interface shouldn't depend on lots of compiler internals.
11// Do not include anything from src/compiler here!
12#include "src/allocation.h"
13#include "src/builtins.h"
Ben Murdoch83897452016-05-17 11:12:09 +010014#include "src/heap/heap.h"
15#include "src/machine-type.h"
Ben Murdoch014dc512016-03-22 12:00:34 +000016#include "src/runtime/runtime.h"
Ben Murdoch83897452016-05-17 11:12:09 +010017#include "src/zone-containers.h"
Ben Murdoch014dc512016-03-22 12:00:34 +000018
19namespace v8 {
20namespace internal {
21
22class CallInterfaceDescriptor;
23class Isolate;
24class Zone;
25
26namespace compiler {
27
28class CallDescriptor;
29class Graph;
30class Node;
31class Operator;
32class RawMachineAssembler;
Ben Murdoch83897452016-05-17 11:12:09 +010033class RawMachineLabel;
Ben Murdoch014dc512016-03-22 12:00:34 +000034class Schedule;
35
Ben Murdoch83897452016-05-17 11:12:09 +010036#define CODE_STUB_ASSEMBLER_BINARY_OP_LIST(V) \
37 V(IntPtrAdd) \
38 V(IntPtrSub) \
39 V(Int32Add) \
40 V(Int32Sub) \
41 V(Int32Mul) \
42 V(Int32GreaterThanOrEqual) \
43 V(WordEqual) \
44 V(WordNotEqual) \
45 V(WordOr) \
46 V(WordAnd) \
47 V(WordXor) \
48 V(WordShl) \
49 V(WordShr) \
50 V(WordSar) \
51 V(WordRor) \
52 V(Word32Equal) \
53 V(Word32NotEqual) \
54 V(Word32Or) \
55 V(Word32And) \
56 V(Word32Xor) \
57 V(Word32Shl) \
58 V(Word32Shr) \
59 V(Word32Sar) \
60 V(Word32Ror) \
61 V(Word64Equal) \
62 V(Word64NotEqual) \
63 V(Word64Or) \
64 V(Word64And) \
65 V(Word64Xor) \
66 V(Word64Shr) \
67 V(Word64Sar) \
68 V(Word64Ror) \
69 V(UintPtrGreaterThanOrEqual)
70
Ben Murdoch014dc512016-03-22 12:00:34 +000071class CodeStubAssembler {
72 public:
Ben Murdoch83897452016-05-17 11:12:09 +010073 // |result_size| specifies the number of results returned by the stub.
74 // TODO(rmcilroy): move result_size to the CallInterfaceDescriptor.
Ben Murdoch014dc512016-03-22 12:00:34 +000075 CodeStubAssembler(Isolate* isolate, Zone* zone,
Ben Murdoch83897452016-05-17 11:12:09 +010076 const CallInterfaceDescriptor& descriptor,
77 Code::Flags flags, const char* name,
78 size_t result_size = 1);
Ben Murdoch014dc512016-03-22 12:00:34 +000079 virtual ~CodeStubAssembler();
80
81 Handle<Code> GenerateCode();
82
Ben Murdoch83897452016-05-17 11:12:09 +010083 class Label;
84 class Variable {
85 public:
86 explicit Variable(CodeStubAssembler* assembler, MachineRepresentation rep);
87 void Bind(Node* value);
88 Node* value() const;
89 MachineRepresentation rep() const;
90 bool IsBound() const;
91
92 private:
93 friend class CodeStubAssembler;
94 class Impl;
95 Impl* impl_;
96 };
97
98 // ===========================================================================
99 // Base Assembler
100 // ===========================================================================
101
Ben Murdoch014dc512016-03-22 12:00:34 +0000102 // Constants.
103 Node* Int32Constant(int value);
104 Node* IntPtrConstant(intptr_t value);
105 Node* NumberConstant(double value);
106 Node* HeapConstant(Handle<HeapObject> object);
107 Node* BooleanConstant(bool value);
Ben Murdoch83897452016-05-17 11:12:09 +0100108 Node* ExternalConstant(ExternalReference address);
Ben Murdoch014dc512016-03-22 12:00:34 +0000109
110 Node* Parameter(int value);
111 void Return(Node* value);
112
Ben Murdoch83897452016-05-17 11:12:09 +0100113 void Bind(Label* label);
114 void Goto(Label* label);
115 void Branch(Node* condition, Label* true_label, Label* false_label);
Ben Murdoch014dc512016-03-22 12:00:34 +0000116
Ben Murdoch83897452016-05-17 11:12:09 +0100117 void Switch(Node* index, Label* default_label, int32_t* case_values,
118 Label** case_labels, size_t case_count);
119
120 // Access to the frame pointer
121 Node* LoadFramePointer();
122 Node* LoadParentFramePointer();
123
124 // Access to the stack pointer
125 Node* LoadStackPointer();
126
127 // Load raw memory location.
128 Node* Load(MachineType rep, Node* base);
129 Node* Load(MachineType rep, Node* base, Node* index);
130
131 // Store value to raw memory location.
132 Node* Store(MachineRepresentation rep, Node* base, Node* value);
133 Node* Store(MachineRepresentation rep, Node* base, Node* index, Node* value);
134 Node* StoreNoWriteBarrier(MachineRepresentation rep, Node* base, Node* value);
135 Node* StoreNoWriteBarrier(MachineRepresentation rep, Node* base, Node* index,
136 Node* value);
137
138// Basic arithmetic operations.
139#define DECLARE_CODE_STUB_ASSEMBER_BINARY_OP(name) Node* name(Node* a, Node* b);
140 CODE_STUB_ASSEMBLER_BINARY_OP_LIST(DECLARE_CODE_STUB_ASSEMBER_BINARY_OP)
141#undef DECLARE_CODE_STUB_ASSEMBER_BINARY_OP
142
Ben Murdoch014dc512016-03-22 12:00:34 +0000143 Node* WordShl(Node* value, int shift);
144
Ben Murdoch83897452016-05-17 11:12:09 +0100145 // Conversions
146 Node* ChangeInt32ToInt64(Node* value);
Ben Murdoch014dc512016-03-22 12:00:34 +0000147
Ben Murdoch83897452016-05-17 11:12:09 +0100148 // Projections
149 Node* Projection(int index, Node* value);
150
151 // Calls
152 Node* CallRuntime(Runtime::FunctionId function_id, Node* context);
Ben Murdoch014dc512016-03-22 12:00:34 +0000153 Node* CallRuntime(Runtime::FunctionId function_id, Node* context, Node* arg1);
154 Node* CallRuntime(Runtime::FunctionId function_id, Node* context, Node* arg1,
155 Node* arg2);
Ben Murdoch83897452016-05-17 11:12:09 +0100156 Node* CallRuntime(Runtime::FunctionId function_id, Node* context, Node* arg1,
157 Node* arg2, Node* arg3);
158 Node* CallRuntime(Runtime::FunctionId function_id, Node* context, Node* arg1,
159 Node* arg2, Node* arg3, Node* arg4);
160 Node* CallRuntime(Runtime::FunctionId function_id, Node* context, Node* arg1,
161 Node* arg2, Node* arg3, Node* arg4, Node* arg5);
Ben Murdoch014dc512016-03-22 12:00:34 +0000162
163 Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context,
164 Node* arg1);
165 Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context,
166 Node* arg1, Node* arg2);
Ben Murdoch83897452016-05-17 11:12:09 +0100167 Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context,
168 Node* arg1, Node* arg2, Node* arg3);
169 Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context,
170 Node* arg1, Node* arg2, Node* arg3, Node* arg4);
171
172 Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
173 Node* context, Node* arg1, size_t result_size = 1);
174 Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
175 Node* context, Node* arg1, Node* arg2, size_t result_size = 1);
176 Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
177 Node* context, Node* arg1, Node* arg2, Node* arg3,
178 size_t result_size = 1);
179 Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
180 Node* context, Node* arg1, Node* arg2, Node* arg3, Node* arg4,
181 size_t result_size = 1);
182 Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
183 Node* context, Node* arg1, Node* arg2, Node* arg3, Node* arg4,
184 Node* arg5, size_t result_size = 1);
185
186 Node* TailCallStub(CodeStub& stub, Node** args);
187 Node* TailCall(const CallInterfaceDescriptor& descriptor, Node* target,
188 Node** args, size_t result_size = 1);
189
190 // ===========================================================================
191 // Macros
192 // ===========================================================================
193
194 // Tag and untag Smi values.
195 Node* SmiTag(Node* value);
196 Node* SmiUntag(Node* value);
197
198 // Load a value from the root array.
199 Node* LoadRoot(Heap::RootListIndex root_index);
200
201 // Check a value for smi-ness
202 Node* WordIsSmi(Node* a);
203
204 // Load an object pointer from a buffer that isn't in the heap.
205 Node* LoadBufferObject(Node* buffer, int offset);
206 // Load a field from an object on the heap.
207 Node* LoadObjectField(Node* object, int offset);
208
209 // Load an array element from a FixedArray.
210 Node* LoadFixedArrayElementSmiIndex(Node* object, Node* smi_index,
211 int additional_offset = 0);
212 Node* LoadFixedArrayElementConstantIndex(Node* object, int index);
213
214 protected:
215 // Protected helpers which delegate to RawMachineAssembler.
216 Graph* graph();
217 Isolate* isolate();
218 Zone* zone();
219
220 // Enables subclasses to perform operations before and after a call.
221 virtual void CallPrologue();
222 virtual void CallEpilogue();
Ben Murdoch014dc512016-03-22 12:00:34 +0000223
224 private:
225 friend class CodeStubAssemblerTester;
226
227 Node* CallN(CallDescriptor* descriptor, Node* code_target, Node** args);
228 Node* TailCallN(CallDescriptor* descriptor, Node* code_target, Node** args);
229
230 Node* SmiShiftBitsConstant();
231
Ben Murdoch014dc512016-03-22 12:00:34 +0000232 base::SmartPointer<RawMachineAssembler> raw_assembler_;
Ben Murdoch83897452016-05-17 11:12:09 +0100233 Code::Flags flags_;
Ben Murdoch014dc512016-03-22 12:00:34 +0000234 const char* name_;
235 bool code_generated_;
Ben Murdoch83897452016-05-17 11:12:09 +0100236 ZoneVector<Variable::Impl*> variables_;
Ben Murdoch014dc512016-03-22 12:00:34 +0000237
238 DISALLOW_COPY_AND_ASSIGN(CodeStubAssembler);
239};
240
Ben Murdoch83897452016-05-17 11:12:09 +0100241class CodeStubAssembler::Label {
242 public:
243 explicit Label(CodeStubAssembler* assembler);
244 Label(CodeStubAssembler* assembler, int merged_variable_count,
245 CodeStubAssembler::Variable** merged_variables);
246 Label(CodeStubAssembler* assembler,
247 CodeStubAssembler::Variable* merged_variable);
248 ~Label() {}
249
250 private:
251 friend class CodeStubAssembler;
252
253 void Bind();
254 void MergeVariables();
255
256 bool bound_;
257 size_t merge_count_;
258 CodeStubAssembler* assembler_;
259 RawMachineLabel* label_;
260 // Map of variables that need to be merged to their phi nodes (or placeholders
261 // for those phis).
262 std::map<Variable::Impl*, Node*> variable_phis_;
263 // Map of variables to the list of value nodes that have been added from each
264 // merge path in their order of merging.
265 std::map<Variable::Impl*, std::vector<Node*>> variable_merges_;
266};
267
Ben Murdoch014dc512016-03-22 12:00:34 +0000268} // namespace compiler
269} // namespace internal
270} // namespace v8
271
272#endif // V8_COMPILER_CODE_STUB_ASSEMBLER_H_