• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_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 
16 namespace v8 {
17 namespace internal {
18 namespace compiler {
19 
20 typedef std::set<int> VirtualRegisterSet;
21 
22 enum InstructionSelectorTesterMode { kTargetMode, kInternalMode };
23 
24 class InstructionSelectorTester : public HandleAndZoneScope,
25                                   public RawMachineAssembler {
26  public:
27   enum Mode { kTargetMode, kInternalMode };
28 
29   static const int kParameterCount = 3;
BuildParameterArray(Zone * zone)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 
InstructionSelectorTester()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 
SelectInstructions(CpuFeature feature)45   void SelectInstructions(CpuFeature feature) {
46     SelectInstructions(InstructionSelector::Features(feature));
47   }
48 
SelectInstructions(CpuFeature feature1,CpuFeature feature2)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 
ToInt32(const InstructionOperand * operand)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 
CheckSameVreg(InstructionOperand * exp,InstructionOperand * val)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());
121 }
122 
123 }  // namespace compiler
124 }  // namespace internal
125 }  // namespace v8
126 
127 #endif  // V8_CCTEST_COMPILER_INSTRUCTION_SELECTOR_TEST_H_
128