More refactoring. Move getRegClass from TargetOperandInfo to TargetInstrInfo.
[oota-llvm.git] / lib / Target / TargetInstrInfo.cpp
1 //===-- TargetInstrInfo.cpp - Target Instruction Information --------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the TargetInstrInfo class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/Target/TargetInstrInfo.h"
15 #include "llvm/Target/TargetInstrItineraries.h"
16 #include "llvm/Target/TargetRegisterInfo.h"
17 #include "llvm/CodeGen/SelectionDAGNodes.h"
18 #include "llvm/MC/MCAsmInfo.h"
19 #include "llvm/Support/ErrorHandling.h"
20 #include <cctype>
21 using namespace llvm;
22
23 //===----------------------------------------------------------------------===//
24 //  TargetInstrInfo
25 //===----------------------------------------------------------------------===//
26
27 TargetInstrInfo::TargetInstrInfo(const TargetInstrDesc* Desc,
28                                  unsigned numOpcodes)
29   : Descriptors(Desc), NumOpcodes(numOpcodes) {
30 }
31
32 TargetInstrInfo::~TargetInstrInfo() {
33 }
34
35 const TargetRegisterClass*
36 TargetInstrInfo::getRegClass(const TargetInstrDesc &TID, unsigned OpNum,
37                              const TargetRegisterInfo *TRI) const {
38   if (OpNum >= TID.getNumOperands())
39     return 0;
40
41   short RegClass = TID.OpInfo[OpNum].RegClass;
42   if (TID.OpInfo[OpNum].isLookupPtrRegClass())
43     return TRI->getPointerRegClass(RegClass);
44
45   // Instructions like INSERT_SUBREG do not have fixed register classes.
46   if (RegClass < 0)
47     return 0;
48
49   // Otherwise just look it up normally.
50   return TRI->getRegClass(RegClass);
51 }
52
53 unsigned
54 TargetInstrInfo::getNumMicroOps(const InstrItineraryData *ItinData,
55                                 const MachineInstr *MI) const {
56   if (!ItinData || ItinData->isEmpty())
57     return 1;
58
59   unsigned Class = MI->getDesc().getSchedClass();
60   unsigned UOps = ItinData->Itineraries[Class].NumMicroOps;
61   if (UOps)
62     return UOps;
63
64   // The # of u-ops is dynamically determined. The specific target should
65   // override this function to return the right number.
66   return 1;
67 }
68
69 int
70 TargetInstrInfo::getOperandLatency(const InstrItineraryData *ItinData,
71                              const MachineInstr *DefMI, unsigned DefIdx,
72                              const MachineInstr *UseMI, unsigned UseIdx) const {
73   if (!ItinData || ItinData->isEmpty())
74     return -1;
75
76   unsigned DefClass = DefMI->getDesc().getSchedClass();
77   unsigned UseClass = UseMI->getDesc().getSchedClass();
78   return ItinData->getOperandLatency(DefClass, DefIdx, UseClass, UseIdx);
79 }
80
81 int
82 TargetInstrInfo::getOperandLatency(const InstrItineraryData *ItinData,
83                                    SDNode *DefNode, unsigned DefIdx,
84                                    SDNode *UseNode, unsigned UseIdx) const {
85   if (!ItinData || ItinData->isEmpty())
86     return -1;
87
88   if (!DefNode->isMachineOpcode())
89     return -1;
90
91   unsigned DefClass = get(DefNode->getMachineOpcode()).getSchedClass();
92   if (!UseNode->isMachineOpcode())
93     return ItinData->getOperandCycle(DefClass, DefIdx);
94   unsigned UseClass = get(UseNode->getMachineOpcode()).getSchedClass();
95   return ItinData->getOperandLatency(DefClass, DefIdx, UseClass, UseIdx);
96 }
97
98 int TargetInstrInfo::getInstrLatency(const InstrItineraryData *ItinData,
99                                      const MachineInstr *MI,
100                                      unsigned *PredCost) const {
101   if (!ItinData || ItinData->isEmpty())
102     return 1;
103
104   return ItinData->getStageLatency(MI->getDesc().getSchedClass());
105 }
106
107 int TargetInstrInfo::getInstrLatency(const InstrItineraryData *ItinData,
108                                      SDNode *N) const {
109   if (!ItinData || ItinData->isEmpty())
110     return 1;
111
112   if (!N->isMachineOpcode())
113     return 1;
114
115   return ItinData->getStageLatency(get(N->getMachineOpcode()).getSchedClass());
116 }
117
118 bool TargetInstrInfo::hasLowDefLatency(const InstrItineraryData *ItinData,
119                                        const MachineInstr *DefMI,
120                                        unsigned DefIdx) const {
121   if (!ItinData || ItinData->isEmpty())
122     return false;
123
124   unsigned DefClass = DefMI->getDesc().getSchedClass();
125   int DefCycle = ItinData->getOperandCycle(DefClass, DefIdx);
126   return (DefCycle != -1 && DefCycle <= 1);
127 }
128
129 /// insertNoop - Insert a noop into the instruction stream at the specified
130 /// point.
131 void TargetInstrInfo::insertNoop(MachineBasicBlock &MBB,
132                                  MachineBasicBlock::iterator MI) const {
133   llvm_unreachable("Target didn't implement insertNoop!");
134 }
135
136
137 bool TargetInstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const {
138   const TargetInstrDesc &TID = MI->getDesc();
139   if (!TID.isTerminator()) return false;
140
141   // Conditional branch is a special case.
142   if (TID.isBranch() && !TID.isBarrier())
143     return true;
144   if (!TID.isPredicable())
145     return true;
146   return !isPredicated(MI);
147 }
148
149
150 /// Measure the specified inline asm to determine an approximation of its
151 /// length.
152 /// Comments (which run till the next SeparatorString or newline) do not
153 /// count as an instruction.
154 /// Any other non-whitespace text is considered an instruction, with
155 /// multiple instructions separated by SeparatorString or newlines.
156 /// Variable-length instructions are not handled here; this function
157 /// may be overloaded in the target code to do that.
158 unsigned TargetInstrInfo::getInlineAsmLength(const char *Str,
159                                              const MCAsmInfo &MAI) const {
160
161
162   // Count the number of instructions in the asm.
163   bool atInsnStart = true;
164   unsigned Length = 0;
165   for (; *Str; ++Str) {
166     if (*Str == '\n' || strncmp(Str, MAI.getSeparatorString(),
167                                 strlen(MAI.getSeparatorString())) == 0)
168       atInsnStart = true;
169     if (atInsnStart && !std::isspace(*Str)) {
170       Length += MAI.getMaxInstLength();
171       atInsnStart = false;
172     }
173     if (atInsnStart && strncmp(Str, MAI.getCommentString(),
174                                strlen(MAI.getCommentString())) == 0)
175       atInsnStart = false;
176   }
177
178   return Length;
179 }