Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Side by Side Diff: test/cctest/compiler/codegen-tester.h

Issue 426233002: Land the Fan (disabled) (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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_CCTEST_COMPILER_CODEGEN_TESTER_H_
6 #define V8_CCTEST_COMPILER_CODEGEN_TESTER_H_
7
8 #include "src/v8.h"
9
10 #include "src/compiler/pipeline.h"
11 #include "src/compiler/raw-machine-assembler.h"
12 #include "src/compiler/structured-machine-assembler.h"
13 #include "src/simulator.h"
14 #include "test/cctest/compiler/call-tester.h"
15
16 namespace v8 {
17 namespace internal {
18 namespace compiler {
19
20 template <typename MachineAssembler>
21 class MachineAssemblerTester : public HandleAndZoneScope,
22 public CallHelper,
23 public MachineAssembler {
24 public:
25 MachineAssemblerTester(MachineRepresentation return_type,
26 MachineRepresentation p0, MachineRepresentation p1,
27 MachineRepresentation p2, MachineRepresentation p3,
28 MachineRepresentation p4)
29 : HandleAndZoneScope(),
30 CallHelper(main_isolate()),
31 MachineAssembler(new (main_zone()) Graph(main_zone()),
32 ToCallDescriptorBuilder(main_zone(), return_type, p0,
33 p1, p2, p3, p4),
34 MachineOperatorBuilder::pointer_rep()) {}
35
36 Node* LoadFromPointer(void* address,
37 MachineRepresentation rep,
38 int32_t offset = 0) {
39 return this->Load(rep,
40 this->PointerConstant(address),
41 this->Int32Constant(offset));
42 }
43
44 void StoreToPointer(void* address,
45 MachineRepresentation rep,
46 Node* node) {
47 this->Store(rep,
48 this->PointerConstant(address),
49 node);
50 }
51
52 Node* StringConstant(const char* string) {
53 return this->HeapConstant(
54 this->isolate()->factory()->InternalizeUtf8String(string));
55 }
56
57 void CheckNumber(double expected, Object* number) {
58 CHECK(this->isolate()->factory()->NewNumber(expected)->SameValue(number));
59 }
60
61 void CheckString(const char* expected, Object* string) {
62 CHECK(this->isolate()->factory()->InternalizeUtf8String(expected)->
63 SameValue(string));
64 }
65
66 void GenerateCode() { Generate(); }
67
68 protected:
69 virtual void VerifyParameters(int parameter_count,
70 MachineRepresentation* parameter_types) {
71 CHECK_EQ(this->parameter_count(), parameter_count);
72 const MachineRepresentation* expected_types = this->parameter_types();
73 for (int i = 0; i < parameter_count; i++) {
74 CHECK_EQ(expected_types[i], parameter_types[i]);
75 }
76 }
77
78 virtual byte* Generate() {
79 if (code_.is_null()) {
80 Schedule* schedule = this->Export();
81 CallDescriptor* call_descriptor = this->call_descriptor();
82 Graph* graph = this->graph();
83 CompilationInfo info(graph->zone()->isolate(), graph->zone());
84 Linkage linkage(&info, call_descriptor);
85 Pipeline pipeline(&info);
86 code_ = pipeline.GenerateCodeForMachineGraph(&linkage, graph, schedule);
87 }
88 return this->code_.ToHandleChecked()->entry();
89 }
90
91 private:
92 MaybeHandle<Code> code_;
93 };
94
95
96 template <typename ReturnType>
97 class RawMachineAssemblerTester
98 : public MachineAssemblerTester<RawMachineAssembler>,
99 public CallHelper2<ReturnType, RawMachineAssemblerTester<ReturnType> > {
100 public:
101 RawMachineAssemblerTester(MachineRepresentation p0 = kMachineLast,
102 MachineRepresentation p1 = kMachineLast,
103 MachineRepresentation p2 = kMachineLast,
104 MachineRepresentation p3 = kMachineLast,
105 MachineRepresentation p4 = kMachineLast)
106 : MachineAssemblerTester(ReturnValueTraits<ReturnType>::Representation(),
107 p0, p1, p2, p3, p4) {}
108 };
109
110
111 template <typename ReturnType>
112 class StructuredMachineAssemblerTester
113 : public MachineAssemblerTester<StructuredMachineAssembler>,
114 public CallHelper2<ReturnType,
115 StructuredMachineAssemblerTester<ReturnType> > {
116 public:
117 StructuredMachineAssemblerTester(MachineRepresentation p0 = kMachineLast,
118 MachineRepresentation p1 = kMachineLast,
119 MachineRepresentation p2 = kMachineLast,
120 MachineRepresentation p3 = kMachineLast,
121 MachineRepresentation p4 = kMachineLast)
122 : MachineAssemblerTester(ReturnValueTraits<ReturnType>::Representation(),
123 p0, p1, p2, p3, p4) {}
124 };
125
126
127 static const bool USE_RESULT_BUFFER = true;
128 static const bool USE_RETURN_REGISTER = false;
129
130 // TODO(titzer): use the C-style calling convention, or any register-based
131 // calling convention for binop tests.
132 template <typename CType, MachineRepresentation rep, bool use_result_buffer>
133 class BinopTester {
134 public:
135 static const int32_t CHECK_VALUE = 0x99BEEDCE;
136
137 explicit BinopTester(RawMachineAssemblerTester<int32_t>* tester)
138 : T(tester),
139 param0(T->LoadFromPointer(&p0, rep)),
140 param1(T->LoadFromPointer(&p1, rep)),
141 p0(static_cast<CType>(0)),
142 p1(static_cast<CType>(0)),
143 result(static_cast<CType>(0)) {}
144
145 RawMachineAssemblerTester<int32_t>* T;
146 Node* param0;
147 Node* param1;
148
149 CType call(CType a0, CType a1) {
150 p0 = a0;
151 p1 = a1;
152 if (use_result_buffer) {
153 CHECK_EQ(CHECK_VALUE, T->Call());
154 return result;
155 } else {
156 return T->Call();
157 }
158 }
159
160 void AddReturn(Node* val) {
161 if (use_result_buffer) {
162 T->Store(rep, T->PointerConstant(&result), T->Int32Constant(0), val);
163 T->Return(T->Int32Constant(CHECK_VALUE));
164 } else {
165 T->Return(val);
166 }
167 }
168
169 protected:
170 CType p0;
171 CType p1;
172 CType result;
173 };
174
175
176 // A helper class for testing code sequences that take two int parameters and
177 // return an int value.
178 class Int32BinopTester : public
179 BinopTester<int32_t, kMachineWord32, USE_RETURN_REGISTER> {
180 public:
181 explicit Int32BinopTester(RawMachineAssemblerTester<int32_t>* tester)
182 : BinopTester<int32_t, kMachineWord32, USE_RETURN_REGISTER>(tester) {}
183
184 int32_t call(uint32_t a0, uint32_t a1) {
185 p0 = static_cast<int32_t>(a0);
186 p1 = static_cast<int32_t>(a1);
187 return T->Call();
188 }
189 };
190
191
192 // A helper class for testing code sequences that take two double parameters and
193 // return a double value.
194 // TODO(titzer): figure out how to return doubles correctly on ia32.
195 class Float64BinopTester : public
196 BinopTester<double, kMachineFloat64, USE_RESULT_BUFFER> {
197 public:
198 explicit Float64BinopTester(RawMachineAssemblerTester<int32_t>* tester)
199 : BinopTester<double, kMachineFloat64, USE_RESULT_BUFFER>(tester) {}
200 };
201
202
203 // A helper class for testing code sequences that take two pointer parameters
204 // and return a pointer value.
205 // TODO(titzer): pick word size of pointers based on V8_TARGET.
206 template <typename Type>
207 class PointerBinopTester : public
208 BinopTester<Type*, kMachineWord32, USE_RETURN_REGISTER> {
209 public:
210 explicit PointerBinopTester(RawMachineAssemblerTester<int32_t>* tester)
211 : BinopTester<Type*, kMachineWord32, USE_RETURN_REGISTER>(tester) {}
212 };
213
214
215 // A helper class for testing code sequences that take two tagged parameters and
216 // return a tagged value.
217 template <typename Type>
218 class TaggedBinopTester : public
219 BinopTester<Type*, kMachineTagged, USE_RETURN_REGISTER> {
220 public:
221 explicit TaggedBinopTester(RawMachineAssemblerTester<int32_t>* tester)
222 : BinopTester<Type*, kMachineTagged, USE_RETURN_REGISTER>(tester) {}
223 };
224
225 // A helper class for testing compares. Wraps a machine opcode and provides
226 // evaluation routines and the operators.
227 class CompareWrapper {
228 public:
229 explicit CompareWrapper(IrOpcode::Value op) : opcode(op) {}
230
231 Node* MakeNode(RawMachineAssemblerTester<int32_t>* m, Node* a, Node* b) {
232 return m->NewNode(op(m->machine()), a, b);
233 }
234
235 Operator* op(MachineOperatorBuilder* machine) {
236 switch (opcode) {
237 case IrOpcode::kWord32Equal:
238 return machine->Word32Equal();
239 case IrOpcode::kInt32LessThan:
240 return machine->Int32LessThan();
241 case IrOpcode::kInt32LessThanOrEqual:
242 return machine->Int32LessThanOrEqual();
243 case IrOpcode::kUint32LessThan:
244 return machine->Uint32LessThan();
245 case IrOpcode::kUint32LessThanOrEqual:
246 return machine->Uint32LessThanOrEqual();
247 case IrOpcode::kFloat64Equal:
248 return machine->Float64Equal();
249 case IrOpcode::kFloat64LessThan:
250 return machine->Float64LessThan();
251 case IrOpcode::kFloat64LessThanOrEqual:
252 return machine->Float64LessThanOrEqual();
253 default: UNREACHABLE();
254 }
255 return NULL;
256 }
257
258 bool Int32Compare(int32_t a, int32_t b) {
259 switch (opcode) {
260 case IrOpcode::kWord32Equal: return a == b;
261 case IrOpcode::kInt32LessThan: return a < b;
262 case IrOpcode::kInt32LessThanOrEqual: return a <= b;
263 case IrOpcode::kUint32LessThan:
264 return static_cast<uint32_t>(a) < static_cast<uint32_t>(b);
265 case IrOpcode::kUint32LessThanOrEqual:
266 return static_cast<uint32_t>(a) <= static_cast<uint32_t>(b);
267 default: UNREACHABLE();
268 }
269 return false;
270 }
271
272 bool Float64Compare(double a, double b) {
273 switch (opcode) {
274 case IrOpcode::kFloat64Equal: return a == b;
275 case IrOpcode::kFloat64LessThan: return a < b;
276 case IrOpcode::kFloat64LessThanOrEqual: return a <= b;
277 default: UNREACHABLE();
278 }
279 return false;
280 }
281
282 IrOpcode::Value opcode;
283 };
284
285
286 // A small closure class to generate code for a function of two inputs that
287 // produces a single output so that it can be used in many different contexts.
288 // The {expected()} method should compute the expected output for a given
289 // pair of inputs.
290 template <typename T>
291 class BinopGen {
292 public:
293 virtual void gen(RawMachineAssemblerTester<int32_t>* m, Node* a, Node* b) = 0;
294 virtual T expected(T a, T b) = 0;
295 virtual ~BinopGen() { }
296 };
297
298 // A helper class to generate various combination of input shape combinations
299 // and run the generated code to ensure it produces the correct results.
300 class Int32BinopInputShapeTester {
301 public:
302 explicit Int32BinopInputShapeTester(BinopGen<int32_t>* g) : gen(g) { }
303
304 void TestAllInputShapes();
305
306 private:
307 BinopGen<int32_t>* gen;
308 int32_t input_a;
309 int32_t input_b;
310
311 void Run(RawMachineAssemblerTester<int32_t>* m);
312 void RunLeft(RawMachineAssemblerTester<int32_t>* m);
313 void RunRight(RawMachineAssemblerTester<int32_t>* m);
314 };
315 } // namespace compiler
316 } // namespace internal
317 } // namespace v8
318
319 #endif // V8_CCTEST_COMPILER_CODEGEN_TESTER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698