| OLD | NEW | 
|---|
|  | (Empty) | 
| 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; |  | 
| 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 |  | 
| 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_ |  | 
| OLD | NEW | 
|---|