OLD | NEW |
| (Empty) |
1 // Copyright 2014 the V8 project authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef V8_COMPILER_MACHINE_NODE_FACTORY_H_ | |
6 #define V8_COMPILER_MACHINE_NODE_FACTORY_H_ | |
7 | |
8 #ifdef USE_SIMULATOR | |
9 #define MACHINE_ASSEMBLER_SUPPORTS_CALL_C 0 | |
10 #else | |
11 #define MACHINE_ASSEMBLER_SUPPORTS_CALL_C 1 | |
12 #endif | |
13 | |
14 #include "src/v8.h" | |
15 | |
16 #include "src/compiler/machine-operator.h" | |
17 #include "src/compiler/node.h" | |
18 | |
19 namespace v8 { | |
20 namespace internal { | |
21 namespace compiler { | |
22 | |
23 #define ZONE() static_cast<NodeFactory*>(this)->zone() | |
24 #define COMMON() static_cast<NodeFactory*>(this)->common() | |
25 #define MACHINE() static_cast<NodeFactory*>(this)->machine() | |
26 #define MACHINE_SIG() static_cast<NodeFactory*>(this)->machine_sig() | |
27 #define NEW_NODE_0(op) static_cast<NodeFactory*>(this)->NewNode(op) | |
28 #define NEW_NODE_1(op, a) static_cast<NodeFactory*>(this)->NewNode(op, a) | |
29 #define NEW_NODE_2(op, a, b) static_cast<NodeFactory*>(this)->NewNode(op, a, b) | |
30 #define NEW_NODE_3(op, a, b, c) \ | |
31 static_cast<NodeFactory*>(this)->NewNode(op, a, b, c) | |
32 | |
33 template <typename NodeFactory> | |
34 class MachineNodeFactory { | |
35 public: | |
36 // Constants. | |
37 Node* PointerConstant(void* value) { | |
38 return IntPtrConstant(reinterpret_cast<intptr_t>(value)); | |
39 } | |
40 Node* IntPtrConstant(intptr_t value) { | |
41 // TODO(dcarney): mark generated code as unserializable if value != 0. | |
42 return kPointerSize == 8 ? Int64Constant(value) | |
43 : Int32Constant(static_cast<int>(value)); | |
44 } | |
45 Node* Int32Constant(int32_t value) { | |
46 return NEW_NODE_0(COMMON()->Int32Constant(value)); | |
47 } | |
48 Node* Int64Constant(int64_t value) { | |
49 return NEW_NODE_0(COMMON()->Int64Constant(value)); | |
50 } | |
51 Node* NumberConstant(double value) { | |
52 return NEW_NODE_0(COMMON()->NumberConstant(value)); | |
53 } | |
54 Node* Float64Constant(double value) { | |
55 return NEW_NODE_0(COMMON()->Float64Constant(value)); | |
56 } | |
57 Node* HeapConstant(Handle<Object> object) { | |
58 Unique<Object> val = Unique<Object>::CreateUninitialized(object); | |
59 return NEW_NODE_0(COMMON()->HeapConstant(val)); | |
60 } | |
61 | |
62 Node* Projection(int index, Node* a) { | |
63 return NEW_NODE_1(COMMON()->Projection(index), a); | |
64 } | |
65 | |
66 // Memory Operations. | |
67 Node* Load(MachineType rep, Node* base) { | |
68 return Load(rep, base, Int32Constant(0)); | |
69 } | |
70 Node* Load(MachineType rep, Node* base, Node* index) { | |
71 return NEW_NODE_2(MACHINE()->Load(rep), base, index); | |
72 } | |
73 void Store(MachineType rep, Node* base, Node* value) { | |
74 Store(rep, base, Int32Constant(0), value); | |
75 } | |
76 void Store(MachineType rep, Node* base, Node* index, Node* value) { | |
77 NEW_NODE_3(MACHINE()->Store(rep, kNoWriteBarrier), base, index, value); | |
78 } | |
79 // Arithmetic Operations. | |
80 Node* WordAnd(Node* a, Node* b) { | |
81 return NEW_NODE_2(MACHINE()->WordAnd(), a, b); | |
82 } | |
83 Node* WordOr(Node* a, Node* b) { | |
84 return NEW_NODE_2(MACHINE()->WordOr(), a, b); | |
85 } | |
86 Node* WordXor(Node* a, Node* b) { | |
87 return NEW_NODE_2(MACHINE()->WordXor(), a, b); | |
88 } | |
89 Node* WordShl(Node* a, Node* b) { | |
90 return NEW_NODE_2(MACHINE()->WordShl(), a, b); | |
91 } | |
92 Node* WordShr(Node* a, Node* b) { | |
93 return NEW_NODE_2(MACHINE()->WordShr(), a, b); | |
94 } | |
95 Node* WordSar(Node* a, Node* b) { | |
96 return NEW_NODE_2(MACHINE()->WordSar(), a, b); | |
97 } | |
98 Node* WordRor(Node* a, Node* b) { | |
99 return NEW_NODE_2(MACHINE()->WordRor(), a, b); | |
100 } | |
101 Node* WordEqual(Node* a, Node* b) { | |
102 return NEW_NODE_2(MACHINE()->WordEqual(), a, b); | |
103 } | |
104 Node* WordNotEqual(Node* a, Node* b) { | |
105 return WordBinaryNot(WordEqual(a, b)); | |
106 } | |
107 Node* WordNot(Node* a) { | |
108 if (MACHINE()->is32()) { | |
109 return Word32Not(a); | |
110 } else { | |
111 return Word64Not(a); | |
112 } | |
113 } | |
114 Node* WordBinaryNot(Node* a) { | |
115 if (MACHINE()->is32()) { | |
116 return Word32BinaryNot(a); | |
117 } else { | |
118 return Word64BinaryNot(a); | |
119 } | |
120 } | |
121 | |
122 Node* Word32And(Node* a, Node* b) { | |
123 return NEW_NODE_2(MACHINE()->Word32And(), a, b); | |
124 } | |
125 Node* Word32Or(Node* a, Node* b) { | |
126 return NEW_NODE_2(MACHINE()->Word32Or(), a, b); | |
127 } | |
128 Node* Word32Xor(Node* a, Node* b) { | |
129 return NEW_NODE_2(MACHINE()->Word32Xor(), a, b); | |
130 } | |
131 Node* Word32Shl(Node* a, Node* b) { | |
132 return NEW_NODE_2(MACHINE()->Word32Shl(), a, b); | |
133 } | |
134 Node* Word32Shr(Node* a, Node* b) { | |
135 return NEW_NODE_2(MACHINE()->Word32Shr(), a, b); | |
136 } | |
137 Node* Word32Sar(Node* a, Node* b) { | |
138 return NEW_NODE_2(MACHINE()->Word32Sar(), a, b); | |
139 } | |
140 Node* Word32Ror(Node* a, Node* b) { | |
141 return NEW_NODE_2(MACHINE()->Word32Ror(), a, b); | |
142 } | |
143 Node* Word32Equal(Node* a, Node* b) { | |
144 return NEW_NODE_2(MACHINE()->Word32Equal(), a, b); | |
145 } | |
146 Node* Word32NotEqual(Node* a, Node* b) { | |
147 return Word32BinaryNot(Word32Equal(a, b)); | |
148 } | |
149 Node* Word32Not(Node* a) { return Word32Xor(a, Int32Constant(-1)); } | |
150 Node* Word32BinaryNot(Node* a) { return Word32Equal(a, Int32Constant(0)); } | |
151 | |
152 Node* Word64And(Node* a, Node* b) { | |
153 return NEW_NODE_2(MACHINE()->Word64And(), a, b); | |
154 } | |
155 Node* Word64Or(Node* a, Node* b) { | |
156 return NEW_NODE_2(MACHINE()->Word64Or(), a, b); | |
157 } | |
158 Node* Word64Xor(Node* a, Node* b) { | |
159 return NEW_NODE_2(MACHINE()->Word64Xor(), a, b); | |
160 } | |
161 Node* Word64Shl(Node* a, Node* b) { | |
162 return NEW_NODE_2(MACHINE()->Word64Shl(), a, b); | |
163 } | |
164 Node* Word64Shr(Node* a, Node* b) { | |
165 return NEW_NODE_2(MACHINE()->Word64Shr(), a, b); | |
166 } | |
167 Node* Word64Sar(Node* a, Node* b) { | |
168 return NEW_NODE_2(MACHINE()->Word64Sar(), a, b); | |
169 } | |
170 Node* Word64Ror(Node* a, Node* b) { | |
171 return NEW_NODE_2(MACHINE()->Word64Ror(), a, b); | |
172 } | |
173 Node* Word64Equal(Node* a, Node* b) { | |
174 return NEW_NODE_2(MACHINE()->Word64Equal(), a, b); | |
175 } | |
176 Node* Word64NotEqual(Node* a, Node* b) { | |
177 return Word64BinaryNot(Word64Equal(a, b)); | |
178 } | |
179 Node* Word64Not(Node* a) { return Word64Xor(a, Int64Constant(-1)); } | |
180 Node* Word64BinaryNot(Node* a) { return Word64Equal(a, Int64Constant(0)); } | |
181 | |
182 Node* Int32Add(Node* a, Node* b) { | |
183 return NEW_NODE_2(MACHINE()->Int32Add(), a, b); | |
184 } | |
185 Node* Int32AddWithOverflow(Node* a, Node* b) { | |
186 return NEW_NODE_2(MACHINE()->Int32AddWithOverflow(), a, b); | |
187 } | |
188 Node* Int32Sub(Node* a, Node* b) { | |
189 return NEW_NODE_2(MACHINE()->Int32Sub(), a, b); | |
190 } | |
191 Node* Int32SubWithOverflow(Node* a, Node* b) { | |
192 return NEW_NODE_2(MACHINE()->Int32SubWithOverflow(), a, b); | |
193 } | |
194 Node* Int32Mul(Node* a, Node* b) { | |
195 return NEW_NODE_2(MACHINE()->Int32Mul(), a, b); | |
196 } | |
197 Node* Int32Div(Node* a, Node* b) { | |
198 return NEW_NODE_2(MACHINE()->Int32Div(), a, b); | |
199 } | |
200 Node* Int32UDiv(Node* a, Node* b) { | |
201 return NEW_NODE_2(MACHINE()->Int32UDiv(), a, b); | |
202 } | |
203 Node* Int32Mod(Node* a, Node* b) { | |
204 return NEW_NODE_2(MACHINE()->Int32Mod(), a, b); | |
205 } | |
206 Node* Int32UMod(Node* a, Node* b) { | |
207 return NEW_NODE_2(MACHINE()->Int32UMod(), a, b); | |
208 } | |
209 Node* Int32LessThan(Node* a, Node* b) { | |
210 return NEW_NODE_2(MACHINE()->Int32LessThan(), a, b); | |
211 } | |
212 Node* Int32LessThanOrEqual(Node* a, Node* b) { | |
213 return NEW_NODE_2(MACHINE()->Int32LessThanOrEqual(), a, b); | |
214 } | |
215 Node* Uint32LessThan(Node* a, Node* b) { | |
216 return NEW_NODE_2(MACHINE()->Uint32LessThan(), a, b); | |
217 } | |
218 Node* Uint32LessThanOrEqual(Node* a, Node* b) { | |
219 return NEW_NODE_2(MACHINE()->Uint32LessThanOrEqual(), a, b); | |
220 } | |
221 Node* Int32GreaterThan(Node* a, Node* b) { return Int32LessThan(b, a); } | |
222 Node* Int32GreaterThanOrEqual(Node* a, Node* b) { | |
223 return Int32LessThanOrEqual(b, a); | |
224 } | |
225 Node* Int32Neg(Node* a) { return Int32Sub(Int32Constant(0), a); } | |
226 | |
227 Node* Int64Add(Node* a, Node* b) { | |
228 return NEW_NODE_2(MACHINE()->Int64Add(), a, b); | |
229 } | |
230 Node* Int64Sub(Node* a, Node* b) { | |
231 return NEW_NODE_2(MACHINE()->Int64Sub(), a, b); | |
232 } | |
233 Node* Int64Mul(Node* a, Node* b) { | |
234 return NEW_NODE_2(MACHINE()->Int64Mul(), a, b); | |
235 } | |
236 Node* Int64Div(Node* a, Node* b) { | |
237 return NEW_NODE_2(MACHINE()->Int64Div(), a, b); | |
238 } | |
239 Node* Int64UDiv(Node* a, Node* b) { | |
240 return NEW_NODE_2(MACHINE()->Int64UDiv(), a, b); | |
241 } | |
242 Node* Int64Mod(Node* a, Node* b) { | |
243 return NEW_NODE_2(MACHINE()->Int64Mod(), a, b); | |
244 } | |
245 Node* Int64UMod(Node* a, Node* b) { | |
246 return NEW_NODE_2(MACHINE()->Int64UMod(), a, b); | |
247 } | |
248 Node* Int64Neg(Node* a) { return Int64Sub(Int64Constant(0), a); } | |
249 Node* Int64LessThan(Node* a, Node* b) { | |
250 return NEW_NODE_2(MACHINE()->Int64LessThan(), a, b); | |
251 } | |
252 Node* Int64LessThanOrEqual(Node* a, Node* b) { | |
253 return NEW_NODE_2(MACHINE()->Int64LessThanOrEqual(), a, b); | |
254 } | |
255 Node* Int64GreaterThan(Node* a, Node* b) { return Int64LessThan(b, a); } | |
256 Node* Int64GreaterThanOrEqual(Node* a, Node* b) { | |
257 return Int64LessThanOrEqual(b, a); | |
258 } | |
259 | |
260 // TODO(turbofan): What is this used for? | |
261 Node* ConvertIntPtrToInt32(Node* a) { | |
262 return kPointerSize == 8 ? NEW_NODE_1(MACHINE()->TruncateInt64ToInt32(), a) | |
263 : a; | |
264 } | |
265 Node* ConvertInt32ToIntPtr(Node* a) { | |
266 return kPointerSize == 8 ? NEW_NODE_1(MACHINE()->ChangeInt32ToInt64(), a) | |
267 : a; | |
268 } | |
269 | |
270 #define INTPTR_BINOP(prefix, name) \ | |
271 Node* IntPtr##name(Node* a, Node* b) { \ | |
272 return kPointerSize == 8 ? prefix##64##name(a, b) \ | |
273 : prefix##32##name(a, b); \ | |
274 } | |
275 | |
276 INTPTR_BINOP(Int, Add); | |
277 INTPTR_BINOP(Int, Sub); | |
278 INTPTR_BINOP(Int, LessThan); | |
279 INTPTR_BINOP(Int, LessThanOrEqual); | |
280 INTPTR_BINOP(Word, Equal); | |
281 INTPTR_BINOP(Word, NotEqual); | |
282 INTPTR_BINOP(Int, GreaterThanOrEqual); | |
283 INTPTR_BINOP(Int, GreaterThan); | |
284 | |
285 #undef INTPTR_BINOP | |
286 | |
287 Node* Float64Add(Node* a, Node* b) { | |
288 return NEW_NODE_2(MACHINE()->Float64Add(), a, b); | |
289 } | |
290 Node* Float64Sub(Node* a, Node* b) { | |
291 return NEW_NODE_2(MACHINE()->Float64Sub(), a, b); | |
292 } | |
293 Node* Float64Mul(Node* a, Node* b) { | |
294 return NEW_NODE_2(MACHINE()->Float64Mul(), a, b); | |
295 } | |
296 Node* Float64Div(Node* a, Node* b) { | |
297 return NEW_NODE_2(MACHINE()->Float64Div(), a, b); | |
298 } | |
299 Node* Float64Mod(Node* a, Node* b) { | |
300 return NEW_NODE_2(MACHINE()->Float64Mod(), a, b); | |
301 } | |
302 Node* Float64Equal(Node* a, Node* b) { | |
303 return NEW_NODE_2(MACHINE()->Float64Equal(), a, b); | |
304 } | |
305 Node* Float64NotEqual(Node* a, Node* b) { | |
306 return WordBinaryNot(Float64Equal(a, b)); | |
307 } | |
308 Node* Float64LessThan(Node* a, Node* b) { | |
309 return NEW_NODE_2(MACHINE()->Float64LessThan(), a, b); | |
310 } | |
311 Node* Float64LessThanOrEqual(Node* a, Node* b) { | |
312 return NEW_NODE_2(MACHINE()->Float64LessThanOrEqual(), a, b); | |
313 } | |
314 Node* Float64GreaterThan(Node* a, Node* b) { return Float64LessThan(b, a); } | |
315 Node* Float64GreaterThanOrEqual(Node* a, Node* b) { | |
316 return Float64LessThanOrEqual(b, a); | |
317 } | |
318 | |
319 // Conversions. | |
320 Node* ChangeInt32ToFloat64(Node* a) { | |
321 return NEW_NODE_1(MACHINE()->ChangeInt32ToFloat64(), a); | |
322 } | |
323 Node* ChangeUint32ToFloat64(Node* a) { | |
324 return NEW_NODE_1(MACHINE()->ChangeUint32ToFloat64(), a); | |
325 } | |
326 Node* ChangeFloat64ToInt32(Node* a) { | |
327 return NEW_NODE_1(MACHINE()->ChangeFloat64ToInt32(), a); | |
328 } | |
329 Node* ChangeFloat64ToUint32(Node* a) { | |
330 return NEW_NODE_1(MACHINE()->ChangeFloat64ToUint32(), a); | |
331 } | |
332 Node* ChangeInt32ToInt64(Node* a) { | |
333 return NEW_NODE_1(MACHINE()->ChangeInt32ToInt64(), a); | |
334 } | |
335 Node* ChangeUint32ToUint64(Node* a) { | |
336 return NEW_NODE_1(MACHINE()->ChangeUint32ToUint64(), a); | |
337 } | |
338 Node* TruncateFloat64ToInt32(Node* a) { | |
339 return NEW_NODE_1(MACHINE()->TruncateFloat64ToInt32(), a); | |
340 } | |
341 Node* TruncateInt64ToInt32(Node* a) { | |
342 return NEW_NODE_1(MACHINE()->TruncateInt64ToInt32(), a); | |
343 } | |
344 | |
345 #ifdef MACHINE_ASSEMBLER_SUPPORTS_CALL_C | |
346 // Call to C. | |
347 Node* CallC(Node* function_address, MachineType return_type, | |
348 MachineType* arg_types, Node** args, int n_args) { | |
349 Zone* zone = ZONE(); | |
350 CallDescriptor* descriptor = | |
351 Linkage::GetSimplifiedCDescriptor(ZONE(), MACHINE_SIG()); | |
352 Node** passed_args = zone->NewArray<Node*>(n_args + 1); | |
353 passed_args[0] = function_address; | |
354 for (int i = 0; i < n_args; ++i) { | |
355 passed_args[i + 1] = args[i]; | |
356 } | |
357 return NEW_NODE_2(COMMON()->Call(descriptor), n_args + 1, passed_args); | |
358 } | |
359 #endif | |
360 }; | |
361 | |
362 #undef NEW_NODE_0 | |
363 #undef NEW_NODE_1 | |
364 #undef NEW_NODE_2 | |
365 #undef NEW_NODE_3 | |
366 #undef MACHINE | |
367 #undef COMMON | |
368 #undef ZONE | |
369 | |
370 } // namespace compiler | |
371 } // namespace internal | |
372 } // namespace v8 | |
373 | |
374 #endif // V8_COMPILER_MACHINE_NODE_FACTORY_H_ | |
OLD | NEW |