blob: 3450c3a1a5f08f21bd4784526197115238f88b50 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008#include "src/compiler/instruction-selector.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009#include "src/compiler/pipeline.h"
10#include "src/compiler/raw-machine-assembler.h"
11#include "src/simulator.h"
12#include "test/cctest/compiler/call-tester.h"
13
14namespace v8 {
15namespace internal {
16namespace compiler {
17
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000018template <typename ReturnType>
19class RawMachineAssemblerTester : public HandleAndZoneScope,
20 public CallHelper<ReturnType>,
21 public RawMachineAssembler {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000022 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000023 RawMachineAssemblerTester(MachineType p0 = MachineType::None(),
24 MachineType p1 = MachineType::None(),
25 MachineType p2 = MachineType::None(),
26 MachineType p3 = MachineType::None(),
27 MachineType p4 = MachineType::None())
Ben Murdochb8a8cc12014-11-26 15:28:44 +000028 : HandleAndZoneScope(),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000029 CallHelper<ReturnType>(
Ben Murdochb8a8cc12014-11-26 15:28:44 +000030 main_isolate(),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000031 CSignature::New(main_zone(), MachineTypeForC<ReturnType>(), p0, p1,
32 p2, p3, p4)),
33 RawMachineAssembler(
34 main_isolate(), new (main_zone()) Graph(main_zone()),
35 Linkage::GetSimplifiedCDescriptor(
36 main_zone(),
37 CSignature::New(main_zone(), MachineTypeForC<ReturnType>(), p0,
Ben Murdoch097c5b22016-05-18 11:27:45 +010038 p1, p2, p3, p4),
39 true),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000040 MachineType::PointerRepresentation(),
41 InstructionSelector::SupportedMachineOperatorFlags()) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +000042
Ben Murdoch097c5b22016-05-18 11:27:45 +010043 virtual ~RawMachineAssemblerTester() {}
44
Ben Murdochb8a8cc12014-11-26 15:28:44 +000045 void CheckNumber(double expected, Object* number) {
46 CHECK(this->isolate()->factory()->NewNumber(expected)->SameValue(number));
47 }
48
49 void CheckString(const char* expected, Object* string) {
50 CHECK(
51 this->isolate()->factory()->InternalizeUtf8String(expected)->SameValue(
52 string));
53 }
54
55 void GenerateCode() { Generate(); }
56
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000057 Handle<Code> GetCode() {
58 Generate();
59 return code_.ToHandleChecked();
60 }
61
Ben Murdochb8a8cc12014-11-26 15:28:44 +000062 protected:
63 virtual byte* Generate() {
64 if (code_.is_null()) {
65 Schedule* schedule = this->Export();
66 CallDescriptor* call_descriptor = this->call_descriptor();
67 Graph* graph = this->graph();
Ben Murdochc5610432016-08-08 18:44:38 +010068 CompilationInfo info(ArrayVector("testing"), main_isolate(), main_zone());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000069 code_ = Pipeline::GenerateCodeForTesting(&info, call_descriptor, graph,
70 schedule);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000071 }
72 return this->code_.ToHandleChecked()->entry();
73 }
74
75 private:
76 MaybeHandle<Code> code_;
77};
78
79
80template <typename ReturnType>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000081class BufferedRawMachineAssemblerTester
82 : public RawMachineAssemblerTester<int32_t> {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000083 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000084 BufferedRawMachineAssemblerTester(MachineType p0 = MachineType::None(),
85 MachineType p1 = MachineType::None(),
86 MachineType p2 = MachineType::None(),
87 MachineType p3 = MachineType::None())
88 : BufferedRawMachineAssemblerTester(ComputeParameterCount(p0, p1, p2, p3),
89 p0, p1, p2, p3) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +000090
Ben Murdoch097c5b22016-05-18 11:27:45 +010091 virtual byte* Generate() { return RawMachineAssemblerTester::Generate(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000092
93 // The BufferedRawMachineAssemblerTester does not pass parameters directly
94 // to the constructed IR graph. Instead it passes a pointer to the parameter
95 // to the IR graph, and adds Load nodes to the IR graph to load the
96 // parameters from memory. Thereby it is possible to pass 64 bit parameters
97 // to the IR graph.
98 Node* Parameter(size_t index) {
Ben Murdoch097c5b22016-05-18 11:27:45 +010099 CHECK(index < 4);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000100 return parameter_nodes_[index];
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000101 }
102
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000103 // The BufferedRawMachineAssemblerTester adds a Store node to the IR graph
104 // to store the graph's return value in memory. The memory address for the
105 // Store node is provided as a parameter. By storing the return value in
106 // memory it is possible to return 64 bit values.
107 void Return(Node* input) {
108 Store(MachineTypeForC<ReturnType>().representation(),
109 RawMachineAssembler::Parameter(return_parameter_index_), input,
110 kNoWriteBarrier);
111 RawMachineAssembler::Return(Int32Constant(1234));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000112 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000113
114 ReturnType Call() {
115 ReturnType return_value;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100116 CSignature::VerifyParams(test_graph_signature_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000117 CallHelper<int32_t>::Call(reinterpret_cast<void*>(&return_value));
118 return return_value;
119 }
120
121 template <typename P0>
122 ReturnType Call(P0 p0) {
123 ReturnType return_value;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100124 CSignature::VerifyParams<P0>(test_graph_signature_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000125 CallHelper<int32_t>::Call(reinterpret_cast<void*>(&p0),
126 reinterpret_cast<void*>(&return_value));
127 return return_value;
128 }
129
130 template <typename P0, typename P1>
131 ReturnType Call(P0 p0, P1 p1) {
132 ReturnType return_value;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100133 CSignature::VerifyParams<P0, P1>(test_graph_signature_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000134 CallHelper<int32_t>::Call(reinterpret_cast<void*>(&p0),
135 reinterpret_cast<void*>(&p1),
136 reinterpret_cast<void*>(&return_value));
137 return return_value;
138 }
139
140 template <typename P0, typename P1, typename P2>
141 ReturnType Call(P0 p0, P1 p1, P2 p2) {
142 ReturnType return_value;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100143 CSignature::VerifyParams<P0, P1, P2>(test_graph_signature_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000144 CallHelper<int32_t>::Call(
145 reinterpret_cast<void*>(&p0), reinterpret_cast<void*>(&p1),
146 reinterpret_cast<void*>(&p2), reinterpret_cast<void*>(&return_value));
147 return return_value;
148 }
149
150 template <typename P0, typename P1, typename P2, typename P3>
151 ReturnType Call(P0 p0, P1 p1, P2 p2, P3 p3) {
152 ReturnType return_value;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100153 CSignature::VerifyParams<P0, P1, P2, P3>(test_graph_signature_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000154 CallHelper<int32_t>::Call(
155 reinterpret_cast<void*>(&p0), reinterpret_cast<void*>(&p1),
156 reinterpret_cast<void*>(&p2), reinterpret_cast<void*>(&p3),
157 reinterpret_cast<void*>(&return_value));
158 return return_value;
159 }
160
161 private:
162 BufferedRawMachineAssemblerTester(uint32_t return_parameter_index,
163 MachineType p0, MachineType p1,
164 MachineType p2, MachineType p3)
165 : RawMachineAssemblerTester<int32_t>(
166 MachineType::Pointer(),
167 p0 == MachineType::None() ? MachineType::None()
168 : MachineType::Pointer(),
169 p1 == MachineType::None() ? MachineType::None()
170 : MachineType::Pointer(),
171 p2 == MachineType::None() ? MachineType::None()
172 : MachineType::Pointer(),
173 p3 == MachineType::None() ? MachineType::None()
174 : MachineType::Pointer()),
175 test_graph_signature_(
176 CSignature::New(main_zone(), MachineType::Int32(), p0, p1, p2, p3)),
177 return_parameter_index_(return_parameter_index) {
178 parameter_nodes_[0] = p0 == MachineType::None()
179 ? nullptr
180 : Load(p0, RawMachineAssembler::Parameter(0));
181 parameter_nodes_[1] = p1 == MachineType::None()
182 ? nullptr
183 : Load(p1, RawMachineAssembler::Parameter(1));
184 parameter_nodes_[2] = p2 == MachineType::None()
185 ? nullptr
186 : Load(p2, RawMachineAssembler::Parameter(2));
187 parameter_nodes_[3] = p3 == MachineType::None()
188 ? nullptr
189 : Load(p3, RawMachineAssembler::Parameter(3));
190 }
191
192
193 static uint32_t ComputeParameterCount(MachineType p0, MachineType p1,
194 MachineType p2, MachineType p3) {
195 if (p0 == MachineType::None()) {
196 return 0;
197 }
198 if (p1 == MachineType::None()) {
199 return 1;
200 }
201 if (p2 == MachineType::None()) {
202 return 2;
203 }
204 if (p3 == MachineType::None()) {
205 return 3;
206 }
207 return 4;
208 }
209
210
211 CSignature* test_graph_signature_;
212 Node* parameter_nodes_[4];
213 uint32_t return_parameter_index_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000214};
215
216
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000217template <>
218class BufferedRawMachineAssemblerTester<void>
219 : public RawMachineAssemblerTester<void> {
220 public:
221 BufferedRawMachineAssemblerTester(MachineType p0 = MachineType::None(),
222 MachineType p1 = MachineType::None(),
223 MachineType p2 = MachineType::None(),
224 MachineType p3 = MachineType::None())
225 : RawMachineAssemblerTester<void>(
226 p0 == MachineType::None() ? MachineType::None()
227 : MachineType::Pointer(),
228 p1 == MachineType::None() ? MachineType::None()
229 : MachineType::Pointer(),
230 p2 == MachineType::None() ? MachineType::None()
231 : MachineType::Pointer(),
232 p3 == MachineType::None() ? MachineType::None()
233 : MachineType::Pointer()),
234 test_graph_signature_(
235 CSignature::New(RawMachineAssemblerTester<void>::main_zone(),
236 MachineType::None(), p0, p1, p2, p3)) {
237 parameter_nodes_[0] = p0 == MachineType::None()
238 ? nullptr
239 : Load(p0, RawMachineAssembler::Parameter(0));
240 parameter_nodes_[1] = p1 == MachineType::None()
241 ? nullptr
242 : Load(p1, RawMachineAssembler::Parameter(1));
243 parameter_nodes_[2] = p2 == MachineType::None()
244 ? nullptr
245 : Load(p2, RawMachineAssembler::Parameter(2));
246 parameter_nodes_[3] = p3 == MachineType::None()
247 ? nullptr
248 : Load(p3, RawMachineAssembler::Parameter(3));
249 }
250
Ben Murdoch097c5b22016-05-18 11:27:45 +0100251 virtual byte* Generate() { return RawMachineAssemblerTester::Generate(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000252
253 // The BufferedRawMachineAssemblerTester does not pass parameters directly
254 // to the constructed IR graph. Instead it passes a pointer to the parameter
255 // to the IR graph, and adds Load nodes to the IR graph to load the
256 // parameters from memory. Thereby it is possible to pass 64 bit parameters
257 // to the IR graph.
258 Node* Parameter(size_t index) {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100259 CHECK(index < 4);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000260 return parameter_nodes_[index];
261 }
262
263
264 void Call() {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100265 CSignature::VerifyParams(test_graph_signature_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000266 CallHelper<void>::Call();
267 }
268
269 template <typename P0>
270 void Call(P0 p0) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100271 CSignature::VerifyParams<P0>(test_graph_signature_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000272 CallHelper<void>::Call(reinterpret_cast<void*>(&p0));
273 }
274
275 template <typename P0, typename P1>
276 void Call(P0 p0, P1 p1) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100277 CSignature::VerifyParams<P0, P1>(test_graph_signature_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000278 CallHelper<void>::Call(reinterpret_cast<void*>(&p0),
279 reinterpret_cast<void*>(&p1));
280 }
281
282 template <typename P0, typename P1, typename P2>
283 void Call(P0 p0, P1 p1, P2 p2) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100284 CSignature::VerifyParams<P0, P1, P2>(test_graph_signature_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000285 CallHelper<void>::Call(reinterpret_cast<void*>(&p0),
286 reinterpret_cast<void*>(&p1),
287 reinterpret_cast<void*>(&p2));
288 }
289
290 template <typename P0, typename P1, typename P2, typename P3>
291 void Call(P0 p0, P1 p1, P2 p2, P3 p3) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100292 CSignature::VerifyParams<P0, P1, P2, P3>(test_graph_signature_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000293 CallHelper<void>::Call(
294 reinterpret_cast<void*>(&p0), reinterpret_cast<void*>(&p1),
295 reinterpret_cast<void*>(&p2), reinterpret_cast<void*>(&p3));
296 }
297
298 private:
299 CSignature* test_graph_signature_;
300 Node* parameter_nodes_[4];
301};
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000302static const bool USE_RESULT_BUFFER = true;
303static const bool USE_RETURN_REGISTER = false;
304static const int32_t CHECK_VALUE = 0x99BEEDCE;
305
306
307// TODO(titzer): use the C-style calling convention, or any register-based
308// calling convention for binop tests.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000309template <typename CType, bool use_result_buffer>
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000310class BinopTester {
311 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000312 explicit BinopTester(RawMachineAssemblerTester<int32_t>* tester,
313 MachineType rep)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000314 : T(tester),
315 param0(T->LoadFromPointer(&p0, rep)),
316 param1(T->LoadFromPointer(&p1, rep)),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000317 rep(rep),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000318 p0(static_cast<CType>(0)),
319 p1(static_cast<CType>(0)),
320 result(static_cast<CType>(0)) {}
321
322 RawMachineAssemblerTester<int32_t>* T;
323 Node* param0;
324 Node* param1;
325
326 CType call(CType a0, CType a1) {
327 p0 = a0;
328 p1 = a1;
329 if (use_result_buffer) {
330 CHECK_EQ(CHECK_VALUE, T->Call());
331 return result;
332 } else {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000333 return static_cast<CType>(T->Call());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000334 }
335 }
336
337 void AddReturn(Node* val) {
338 if (use_result_buffer) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000339 T->Store(rep.representation(), T->PointerConstant(&result),
340 T->Int32Constant(0), val, kNoWriteBarrier);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000341 T->Return(T->Int32Constant(CHECK_VALUE));
342 } else {
343 T->Return(val);
344 }
345 }
346
347 template <typename Ci, typename Cj, typename Fn>
348 void Run(const Ci& ci, const Cj& cj, const Fn& fn) {
349 typename Ci::const_iterator i;
350 typename Cj::const_iterator j;
351 for (i = ci.begin(); i != ci.end(); ++i) {
352 for (j = cj.begin(); j != cj.end(); ++j) {
353 CHECK_EQ(fn(*i, *j), this->call(*i, *j));
354 }
355 }
356 }
357
358 protected:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000359 MachineType rep;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000360 CType p0;
361 CType p1;
362 CType result;
363};
364
365
366// A helper class for testing code sequences that take two int parameters and
367// return an int value.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000368class Int32BinopTester : public BinopTester<int32_t, USE_RETURN_REGISTER> {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000369 public:
370 explicit Int32BinopTester(RawMachineAssemblerTester<int32_t>* tester)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000371 : BinopTester<int32_t, USE_RETURN_REGISTER>(tester,
372 MachineType::Int32()) {}
373};
374
375
376// A helper class for testing code sequences that take two int parameters and
377// return an int value.
378class Int64BinopTester : public BinopTester<int64_t, USE_RETURN_REGISTER> {
379 public:
380 explicit Int64BinopTester(RawMachineAssemblerTester<int32_t>* tester)
381 : BinopTester<int64_t, USE_RETURN_REGISTER>(tester,
382 MachineType::Int64()) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000383};
384
385
386// A helper class for testing code sequences that take two uint parameters and
387// return an uint value.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000388class Uint32BinopTester : public BinopTester<uint32_t, USE_RETURN_REGISTER> {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000389 public:
390 explicit Uint32BinopTester(RawMachineAssemblerTester<int32_t>* tester)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000391 : BinopTester<uint32_t, USE_RETURN_REGISTER>(tester,
392 MachineType::Uint32()) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000393
394 uint32_t call(uint32_t a0, uint32_t a1) {
395 p0 = a0;
396 p1 = a1;
397 return static_cast<uint32_t>(T->Call());
398 }
399};
400
401
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000402// A helper class for testing code sequences that take two float parameters and
403// return a float value.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000404class Float32BinopTester : public BinopTester<float, USE_RESULT_BUFFER> {
405 public:
406 explicit Float32BinopTester(RawMachineAssemblerTester<int32_t>* tester)
407 : BinopTester<float, USE_RESULT_BUFFER>(tester, MachineType::Float32()) {}
408};
409
410
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000411// A helper class for testing code sequences that take two double parameters and
412// return a double value.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000413class Float64BinopTester : public BinopTester<double, USE_RESULT_BUFFER> {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000414 public:
415 explicit Float64BinopTester(RawMachineAssemblerTester<int32_t>* tester)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000416 : BinopTester<double, USE_RESULT_BUFFER>(tester, MachineType::Float64()) {
417 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000418};
419
420
421// A helper class for testing code sequences that take two pointer parameters
422// and return a pointer value.
423// TODO(titzer): pick word size of pointers based on V8_TARGET.
424template <typename Type>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000425class PointerBinopTester : public BinopTester<Type*, USE_RETURN_REGISTER> {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000426 public:
427 explicit PointerBinopTester(RawMachineAssemblerTester<int32_t>* tester)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000428 : BinopTester<Type*, USE_RETURN_REGISTER>(tester,
429 MachineType::Pointer()) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000430};
431
432
433// A helper class for testing code sequences that take two tagged parameters and
434// return a tagged value.
435template <typename Type>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000436class TaggedBinopTester : public BinopTester<Type*, USE_RETURN_REGISTER> {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000437 public:
438 explicit TaggedBinopTester(RawMachineAssemblerTester<int32_t>* tester)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000439 : BinopTester<Type*, USE_RETURN_REGISTER>(tester,
440 MachineType::AnyTagged()) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000441};
442
443// A helper class for testing compares. Wraps a machine opcode and provides
444// evaluation routines and the operators.
445class CompareWrapper {
446 public:
447 explicit CompareWrapper(IrOpcode::Value op) : opcode(op) {}
448
449 Node* MakeNode(RawMachineAssemblerTester<int32_t>* m, Node* a, Node* b) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000450 return m->AddNode(op(m->machine()), a, b);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000451 }
452
453 const Operator* op(MachineOperatorBuilder* machine) {
454 switch (opcode) {
455 case IrOpcode::kWord32Equal:
456 return machine->Word32Equal();
457 case IrOpcode::kInt32LessThan:
458 return machine->Int32LessThan();
459 case IrOpcode::kInt32LessThanOrEqual:
460 return machine->Int32LessThanOrEqual();
461 case IrOpcode::kUint32LessThan:
462 return machine->Uint32LessThan();
463 case IrOpcode::kUint32LessThanOrEqual:
464 return machine->Uint32LessThanOrEqual();
465 case IrOpcode::kFloat64Equal:
466 return machine->Float64Equal();
467 case IrOpcode::kFloat64LessThan:
468 return machine->Float64LessThan();
469 case IrOpcode::kFloat64LessThanOrEqual:
470 return machine->Float64LessThanOrEqual();
471 default:
472 UNREACHABLE();
473 }
474 return NULL;
475 }
476
477 bool Int32Compare(int32_t a, int32_t b) {
478 switch (opcode) {
479 case IrOpcode::kWord32Equal:
480 return a == b;
481 case IrOpcode::kInt32LessThan:
482 return a < b;
483 case IrOpcode::kInt32LessThanOrEqual:
484 return a <= b;
485 case IrOpcode::kUint32LessThan:
486 return static_cast<uint32_t>(a) < static_cast<uint32_t>(b);
487 case IrOpcode::kUint32LessThanOrEqual:
488 return static_cast<uint32_t>(a) <= static_cast<uint32_t>(b);
489 default:
490 UNREACHABLE();
491 }
492 return false;
493 }
494
495 bool Float64Compare(double a, double b) {
496 switch (opcode) {
497 case IrOpcode::kFloat64Equal:
498 return a == b;
499 case IrOpcode::kFloat64LessThan:
500 return a < b;
501 case IrOpcode::kFloat64LessThanOrEqual:
502 return a <= b;
503 default:
504 UNREACHABLE();
505 }
506 return false;
507 }
508
509 IrOpcode::Value opcode;
510};
511
512
513// A small closure class to generate code for a function of two inputs that
514// produces a single output so that it can be used in many different contexts.
515// The {expected()} method should compute the expected output for a given
516// pair of inputs.
517template <typename T>
518class BinopGen {
519 public:
520 virtual void gen(RawMachineAssemblerTester<int32_t>* m, Node* a, Node* b) = 0;
521 virtual T expected(T a, T b) = 0;
522 virtual ~BinopGen() {}
523};
524
525// A helper class to generate various combination of input shape combinations
526// and run the generated code to ensure it produces the correct results.
527class Int32BinopInputShapeTester {
528 public:
Ben Murdoch097c5b22016-05-18 11:27:45 +0100529 explicit Int32BinopInputShapeTester(BinopGen<int32_t>* g)
530 : gen(g), input_a(0), input_b(0) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000531
532 void TestAllInputShapes();
533
534 private:
535 BinopGen<int32_t>* gen;
536 int32_t input_a;
537 int32_t input_b;
538
539 void Run(RawMachineAssemblerTester<int32_t>* m);
540 void RunLeft(RawMachineAssemblerTester<int32_t>* m);
541 void RunRight(RawMachineAssemblerTester<int32_t>* m);
542};
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000543} // namespace compiler
544} // namespace internal
545} // namespace v8
546
547#endif // V8_CCTEST_COMPILER_CODEGEN_TESTER_H_