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_CCTEST_COMPILER_INSTRUCTION_SELECTOR_TEST_H_
6 #define V8_CCTEST_COMPILER_INSTRUCTION_SELECTOR_TEST_H_
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"
20 typedef std::set<int> VirtualRegisterSet;
22 enum InstructionSelectorTesterMode { kTargetMode, kInternalMode };
24 class InstructionSelectorTester : public HandleAndZoneScope,
25 public RawMachineAssembler {
27 enum Mode { kTargetMode, kInternalMode };
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] = kMachineWord32;
38 InstructionSelectorTester()
39 : RawMachineAssembler(
40 new (main_zone()) Graph(main_zone()), new (main_zone())
41 MachineCallDescriptorBuilder(kMachineWord32, kParameterCount,
42 BuildParameterArray(main_zone())),
43 MachineOperatorBuilder::pointer_rep()) {}
45 void SelectInstructions(CpuFeature feature) {
46 SelectInstructions(InstructionSelector::Features(feature));
49 void SelectInstructions(CpuFeature feature1, CpuFeature feature2) {
50 SelectInstructions(InstructionSelector::Features(feature1, feature2));
53 void SelectInstructions(Mode mode = kTargetMode) {
54 SelectInstructions(InstructionSelector::Features(), mode);
57 void SelectInstructions(InstructionSelector::Features features,
58 Mode mode = kTargetMode) {
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
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())) {
79 TARGET_ARCH_OPCODE_LIST(CASE)
85 code.push_back(instr);
87 for (int vreg = 0; vreg < sequence.VirtualRegisterCount(); ++vreg) {
88 if (sequence.IsDouble(vreg)) {
89 CHECK(!sequence.IsReference(vreg));
92 if (sequence.IsReference(vreg)) {
93 CHECK(!sequence.IsDouble(vreg));
94 references.insert(vreg);
97 immediates.assign(sequence.immediates().begin(),
98 sequence.immediates().end());
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();
108 std::deque<Instruction*> code;
109 VirtualRegisterSet doubles;
110 VirtualRegisterSet references;
111 std::deque<Constant> immediates;
115 static 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());
123 } // namespace compiler
124 } // namespace internal
127 #endif // V8_CCTEST_COMPILER_INSTRUCTION_SELECTOR_TEST_H_