blob: 3a28b2e5dfaf0553f859618bce082c360eb707bc [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_INSTRUCTION_SELECTOR_TEST_H_
6#define V8_CCTEST_COMPILER_INSTRUCTION_SELECTOR_TEST_H_
7
8#include <deque>
9#include <set>
10
11#include "src/compiler/instruction-selector.h"
12#include "src/compiler/raw-machine-assembler.h"
13#include "src/ostreams.h"
14#include "test/cctest/cctest.h"
15
16namespace v8 {
17namespace internal {
18namespace compiler {
19
20typedef std::set<int> VirtualRegisterSet;
21
22enum InstructionSelectorTesterMode { kTargetMode, kInternalMode };
23
24class InstructionSelectorTester : public HandleAndZoneScope,
25 public RawMachineAssembler {
26 public:
27 enum Mode { kTargetMode, kInternalMode };
28
29 static const int kParameterCount = 3;
30 static MachineType* BuildParameterArray(Zone* zone) {
31 MachineType* array = zone->NewArray<MachineType>(kParameterCount);
32 for (int i = 0; i < kParameterCount; ++i) {
33 array[i] = kMachInt32;
34 }
35 return array;
36 }
37
38 InstructionSelectorTester()
39 : RawMachineAssembler(
40 new (main_zone()) Graph(main_zone()),
41 new (main_zone()) MachineCallDescriptorBuilder(
42 kMachInt32, kParameterCount, BuildParameterArray(main_zone())),
43 kMachPtr) {}
44
45 void SelectInstructions(CpuFeature feature) {
46 SelectInstructions(InstructionSelector::Features(feature));
47 }
48
49 void SelectInstructions(CpuFeature feature1, CpuFeature feature2) {
50 SelectInstructions(InstructionSelector::Features(feature1, feature2));
51 }
52
53 void SelectInstructions(Mode mode = kTargetMode) {
54 SelectInstructions(InstructionSelector::Features(), mode);
55 }
56
57 void SelectInstructions(InstructionSelector::Features features,
58 Mode mode = kTargetMode) {
59 OFStream out(stdout);
60 Schedule* schedule = Export();
61 CHECK_NE(0, graph()->NodeCount());
62 CompilationInfo info(main_isolate(), main_zone());
63 Linkage linkage(&info, call_descriptor());
64 InstructionSequence sequence(&linkage, graph(), schedule);
65 SourcePositionTable source_positions(graph());
66 InstructionSelector selector(&sequence, &source_positions, features);
67 selector.SelectInstructions();
68 out << "--- Code sequence after instruction selection --- " << endl
69 << sequence;
70 for (InstructionSequence::const_iterator i = sequence.begin();
71 i != sequence.end(); ++i) {
72 Instruction* instr = *i;
73 if (instr->opcode() < 0) continue;
74 if (mode == kTargetMode) {
75 switch (ArchOpcodeField::decode(instr->opcode())) {
76#define CASE(Name) \
77 case k##Name: \
78 break;
79 TARGET_ARCH_OPCODE_LIST(CASE)
80#undef CASE
81 default:
82 continue;
83 }
84 }
85 code.push_back(instr);
86 }
87 for (int vreg = 0; vreg < sequence.VirtualRegisterCount(); ++vreg) {
88 if (sequence.IsDouble(vreg)) {
89 CHECK(!sequence.IsReference(vreg));
90 doubles.insert(vreg);
91 }
92 if (sequence.IsReference(vreg)) {
93 CHECK(!sequence.IsDouble(vreg));
94 references.insert(vreg);
95 }
96 }
97 immediates.assign(sequence.immediates().begin(),
98 sequence.immediates().end());
99 }
100
101 int32_t ToInt32(const InstructionOperand* operand) const {
102 size_t i = operand->index();
103 CHECK(i < immediates.size());
104 CHECK_EQ(InstructionOperand::IMMEDIATE, operand->kind());
105 return immediates[i].ToInt32();
106 }
107
108 std::deque<Instruction*> code;
109 VirtualRegisterSet doubles;
110 VirtualRegisterSet references;
111 std::deque<Constant> immediates;
112};
113
114
115static inline void CheckSameVreg(InstructionOperand* exp,
116 InstructionOperand* val) {
117 CHECK_EQ(InstructionOperand::UNALLOCATED, exp->kind());
118 CHECK_EQ(InstructionOperand::UNALLOCATED, val->kind());
119 CHECK_EQ(UnallocatedOperand::cast(exp)->virtual_register(),
120 UnallocatedOperand::cast(val)->virtual_register());
121}
122
123} // namespace compiler
124} // namespace internal
125} // namespace v8
126
127#endif // V8_CCTEST_COMPILER_INSTRUCTION_SELECTOR_TEST_H_