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.
5 #ifndef V8_COMPILER_INSTRUCTION_SELECTOR_UNITTEST_H_
6 #define V8_COMPILER_INSTRUCTION_SELECTOR_UNITTEST_H_
11 #include "src/base/utils/random-number-generator.h"
12 #include "src/compiler/instruction-selector.h"
13 #include "src/compiler/raw-machine-assembler.h"
14 #include "src/test/test-utils.h"
20 class InstructionSelectorTest : public TestWithContext, public TestWithZone {
22 InstructionSelectorTest();
23 virtual ~InstructionSelectorTest();
25 base::RandomNumberGenerator* rng() { return &rng_; }
29 enum StreamBuilderMode {
32 kAllExceptNopInstructions
35 class StreamBuilder FINAL : public RawMachineAssembler {
37 StreamBuilder(InstructionSelectorTest* test, MachineType return_type)
38 : RawMachineAssembler(new (test->zone()) Graph(test->zone()),
39 MakeMachineSignature(test->zone(), return_type)),
41 StreamBuilder(InstructionSelectorTest* test, MachineType return_type,
42 MachineType parameter0_type)
43 : RawMachineAssembler(
44 new (test->zone()) Graph(test->zone()),
45 MakeMachineSignature(test->zone(), return_type, parameter0_type)),
47 StreamBuilder(InstructionSelectorTest* test, MachineType return_type,
48 MachineType parameter0_type, MachineType parameter1_type)
49 : RawMachineAssembler(
50 new (test->zone()) Graph(test->zone()),
51 MakeMachineSignature(test->zone(), return_type, parameter0_type,
54 StreamBuilder(InstructionSelectorTest* test, MachineType return_type,
55 MachineType parameter0_type, MachineType parameter1_type,
56 MachineType parameter2_type)
57 : RawMachineAssembler(
58 new (test->zone()) Graph(test->zone()),
59 MakeMachineSignature(test->zone(), return_type, parameter0_type,
60 parameter1_type, parameter2_type)),
63 Stream Build(CpuFeature feature) {
64 return Build(InstructionSelector::Features(feature));
66 Stream Build(CpuFeature feature1, CpuFeature feature2) {
67 return Build(InstructionSelector::Features(feature1, feature2));
69 Stream Build(StreamBuilderMode mode = kTargetInstructions) {
70 return Build(InstructionSelector::Features(), mode);
72 Stream Build(InstructionSelector::Features features,
73 StreamBuilderMode mode = kTargetInstructions);
76 MachineSignature* MakeMachineSignature(Zone* zone,
77 MachineType return_type) {
78 MachineSignature::Builder builder(zone, 1, 0);
79 builder.AddReturn(return_type);
80 return builder.Build();
83 MachineSignature* MakeMachineSignature(Zone* zone, MachineType return_type,
84 MachineType parameter0_type) {
85 MachineSignature::Builder builder(zone, 1, 1);
86 builder.AddReturn(return_type);
87 builder.AddParam(parameter0_type);
88 return builder.Build();
91 MachineSignature* MakeMachineSignature(Zone* zone, MachineType return_type,
92 MachineType parameter0_type,
93 MachineType parameter1_type) {
94 MachineSignature::Builder builder(zone, 1, 2);
95 builder.AddReturn(return_type);
96 builder.AddParam(parameter0_type);
97 builder.AddParam(parameter1_type);
98 return builder.Build();
101 MachineSignature* MakeMachineSignature(Zone* zone, MachineType return_type,
102 MachineType parameter0_type,
103 MachineType parameter1_type,
104 MachineType parameter2_type) {
105 MachineSignature::Builder builder(zone, 1, 3);
106 builder.AddReturn(return_type);
107 builder.AddParam(parameter0_type);
108 builder.AddParam(parameter1_type);
109 builder.AddParam(parameter2_type);
110 return builder.Build();
114 InstructionSelectorTest* test_;
119 size_t size() const { return instructions_.size(); }
120 const Instruction* operator[](size_t index) const {
121 EXPECT_LT(index, size());
122 return instructions_[index];
125 bool IsDouble(const InstructionOperand* operand) const {
126 return IsDouble(ToVreg(operand));
128 bool IsDouble(int virtual_register) const {
129 return doubles_.find(virtual_register) != doubles_.end();
132 bool IsInteger(const InstructionOperand* operand) const {
133 return IsInteger(ToVreg(operand));
135 bool IsInteger(int virtual_register) const {
136 return !IsDouble(virtual_register) && !IsReference(virtual_register);
139 bool IsReference(const InstructionOperand* operand) const {
140 return IsReference(ToVreg(operand));
142 bool IsReference(int virtual_register) const {
143 return references_.find(virtual_register) != references_.end();
146 int32_t ToInt32(const InstructionOperand* operand) const {
147 return ToConstant(operand).ToInt32();
150 int64_t ToInt64(const InstructionOperand* operand) const {
151 return ToConstant(operand).ToInt64();
154 int ToVreg(const InstructionOperand* operand) const {
155 if (operand->IsConstant()) return operand->index();
156 EXPECT_EQ(InstructionOperand::UNALLOCATED, operand->kind());
157 return UnallocatedOperand::cast(operand)->virtual_register();
160 FrameStateDescriptor* GetFrameStateDescriptor(int deoptimization_id) {
161 EXPECT_LT(deoptimization_id, GetFrameStateDescriptorCount());
162 return deoptimization_entries_[deoptimization_id];
165 int GetFrameStateDescriptorCount() {
166 return static_cast<int>(deoptimization_entries_.size());
170 Constant ToConstant(const InstructionOperand* operand) const {
171 ConstantMap::const_iterator i;
172 if (operand->IsConstant()) {
173 i = constants_.find(operand->index());
174 EXPECT_FALSE(constants_.end() == i);
176 EXPECT_EQ(InstructionOperand::IMMEDIATE, operand->kind());
177 i = immediates_.find(operand->index());
178 EXPECT_FALSE(immediates_.end() == i);
180 EXPECT_EQ(operand->index(), i->first);
184 friend class StreamBuilder;
186 typedef std::map<int, Constant> ConstantMap;
188 ConstantMap constants_;
189 ConstantMap immediates_;
190 std::deque<Instruction*> instructions_;
191 std::set<int> doubles_;
192 std::set<int> references_;
193 std::deque<FrameStateDescriptor*> deoptimization_entries_;
196 base::RandomNumberGenerator rng_;
200 template <typename T>
201 class InstructionSelectorTestWithParam
202 : public InstructionSelectorTest,
203 public ::testing::WithParamInterface<T> {};
205 } // namespace compiler
206 } // namespace internal
209 #endif // V8_COMPILER_INSTRUCTION_SELECTOR_UNITTEST_H_