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/TargetRegisterInfo.h" 16 #include "llvm/MC/MCAsmInfo.h" 17 #include "llvm/MC/MCInstrItineraries.h" 18 #include "llvm/Support/ErrorHandling.h" 19 #include <cctype> 20 using namespace llvm; 21 22 //===----------------------------------------------------------------------===// 23 // TargetInstrInfo 24 //===----------------------------------------------------------------------===// 25 26 TargetInstrInfo::~TargetInstrInfo() { 27 } 28 29 const TargetRegisterClass* 30 TargetInstrInfo::getRegClass(const MCInstrDesc &MCID, unsigned OpNum, 31 const TargetRegisterInfo *TRI) const { 32 if (OpNum >= MCID.getNumOperands()) 33 return 0; 34 35 short RegClass = MCID.OpInfo[OpNum].RegClass; 36 if (MCID.OpInfo[OpNum].isLookupPtrRegClass()) 37 return TRI->getPointerRegClass(RegClass); 38 39 // Instructions like INSERT_SUBREG do not have fixed register classes. 40 if (RegClass < 0) 41 return 0; 42 43 // Otherwise just look it up normally. 44 return TRI->getRegClass(RegClass); 45 } 46 47 unsigned 48 TargetInstrInfo::getNumMicroOps(const InstrItineraryData *ItinData, 49 const MachineInstr *MI) const { 50 if (!ItinData || ItinData->isEmpty()) 51 return 1; 52 53 unsigned Class = MI->getDesc().getSchedClass(); 54 unsigned UOps = ItinData->Itineraries[Class].NumMicroOps; 55 if (UOps) 56 return UOps; 57 58 // The # of u-ops is dynamically determined. The specific target should 59 // override this function to return the right number. 60 return 1; 61 } 62 63 int 64 TargetInstrInfo::getOperandLatency(const InstrItineraryData *ItinData, 65 const MachineInstr *DefMI, unsigned DefIdx, 66 const MachineInstr *UseMI, unsigned UseIdx) const { 67 if (!ItinData || ItinData->isEmpty()) 68 return -1; 69 70 unsigned DefClass = DefMI->getDesc().getSchedClass(); 71 unsigned UseClass = UseMI->getDesc().getSchedClass(); 72 return ItinData->getOperandLatency(DefClass, DefIdx, UseClass, UseIdx); 73 } 74 75 int TargetInstrInfo::getInstrLatency(const InstrItineraryData *ItinData, 76 const MachineInstr *MI, 77 unsigned *PredCost) const { 78 if (!ItinData || ItinData->isEmpty()) 79 return 1; 80 81 return ItinData->getStageLatency(MI->getDesc().getSchedClass()); 82 } 83 84 bool TargetInstrInfo::hasLowDefLatency(const InstrItineraryData *ItinData, 85 const MachineInstr *DefMI, 86 unsigned DefIdx) const { 87 if (!ItinData || ItinData->isEmpty()) 88 return false; 89 90 unsigned DefClass = DefMI->getDesc().getSchedClass(); 91 int DefCycle = ItinData->getOperandCycle(DefClass, DefIdx); 92 return (DefCycle != -1 && DefCycle <= 1); 93 } 94 95 /// insertNoop - Insert a noop into the instruction stream at the specified 96 /// point. 97 void TargetInstrInfo::insertNoop(MachineBasicBlock &MBB, 98 MachineBasicBlock::iterator MI) const { 99 llvm_unreachable("Target didn't implement insertNoop!"); 100 } 101 102 103 /// Measure the specified inline asm to determine an approximation of its 104 /// length. 105 /// Comments (which run till the next SeparatorString or newline) do not 106 /// count as an instruction. 107 /// Any other non-whitespace text is considered an instruction, with 108 /// multiple instructions separated by SeparatorString or newlines. 109 /// Variable-length instructions are not handled here; this function 110 /// may be overloaded in the target code to do that. 111 unsigned TargetInstrInfo::getInlineAsmLength(const char *Str, 112 const MCAsmInfo &MAI) const { 113 114 115 // Count the number of instructions in the asm. 116 bool atInsnStart = true; 117 unsigned Length = 0; 118 for (; *Str; ++Str) { 119 if (*Str == '\n' || strncmp(Str, MAI.getSeparatorString(), 120 strlen(MAI.getSeparatorString())) == 0) 121 atInsnStart = true; 122 if (atInsnStart && !std::isspace(*Str)) { 123 Length += MAI.getMaxInstLength(); 124 atInsnStart = false; 125 } 126 if (atInsnStart && strncmp(Str, MAI.getCommentString(), 127 strlen(MAI.getCommentString())) == 0) 128 atInsnStart = false; 129 } 130 131 return Length; 132 } 133