1 //===- CodeGenTarget.cpp - CodeGen Target Class Wrapper ---------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file was developed by the LLVM research group and is distributed under 6 // the University of Illinois Open Source License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This class wrap target description classes used by the various code 11 // generation TableGen backends. This makes it easier to access the data and 12 // provides a single place that needs to check it for validity. All of these 13 // classes throw exceptions on error conditions. 14 // 15 //===----------------------------------------------------------------------===// 16 17 #include "CodeGenTarget.h" 18 #include "Record.h" 19 using namespace llvm; 20 21 /// getValueType - Return the MCV::ValueType that the specified TableGen record 22 /// corresponds to. 23 MVT::ValueType llvm::getValueType(Record *Rec) { 24 return (MVT::ValueType)Rec->getValueAsInt("Value"); 25 } 26 27 std::string llvm::getName(MVT::ValueType T) { 28 switch (T) { 29 case MVT::Other: return "UNKNOWN"; 30 case MVT::i1: return "i1"; 31 case MVT::i8: return "i8"; 32 case MVT::i16: return "i16"; 33 case MVT::i32: return "i32"; 34 case MVT::i64: return "i64"; 35 case MVT::i128: return "i128"; 36 case MVT::f32: return "f32"; 37 case MVT::f64: return "f64"; 38 case MVT::f80: return "f80"; 39 case MVT::f128: return "f128"; 40 case MVT::isVoid:return "void"; 41 default: assert(0 && "ILLEGAL VALUE TYPE!"); return ""; 42 } 43 } 44 45 std::string llvm::getEnumName(MVT::ValueType T) { 46 switch (T) { 47 case MVT::Other: return "Other"; 48 case MVT::i1: return "i1"; 49 case MVT::i8: return "i8"; 50 case MVT::i16: return "i16"; 51 case MVT::i32: return "i32"; 52 case MVT::i64: return "i64"; 53 case MVT::i128: return "i128"; 54 case MVT::f32: return "f32"; 55 case MVT::f64: return "f64"; 56 case MVT::f80: return "f80"; 57 case MVT::f128: return "f128"; 58 case MVT::isVoid:return "isVoid"; 59 default: assert(0 && "ILLEGAL VALUE TYPE!"); return ""; 60 } 61 } 62 63 64 std::ostream &llvm::operator<<(std::ostream &OS, MVT::ValueType T) { 65 return OS << getName(T); 66 } 67 68 69 /// getTarget - Return the current instance of the Target class. 70 /// 71 CodeGenTarget::CodeGenTarget() : PointerType(MVT::Other) { 72 std::vector<Record*> Targets = Records.getAllDerivedDefinitions("Target"); 73 if (Targets.size() == 0) 74 throw std::string("ERROR: No 'Target' subclasses defined!"); 75 if (Targets.size() != 1) 76 throw std::string("ERROR: Multiple subclasses of Target defined!"); 77 TargetRec = Targets[0]; 78 79 // Read in all of the CalleeSavedRegisters... 80 ListInit *LI = TargetRec->getValueAsListInit("CalleeSavedRegisters"); 81 for (unsigned i = 0, e = LI->getSize(); i != e; ++i) 82 if (DefInit *DI = dynamic_cast<DefInit*>(LI->getElement(i))) 83 CalleeSavedRegisters.push_back(DI->getDef()); 84 else 85 throw "Target: " + TargetRec->getName() + 86 " expected register definition in CalleeSavedRegisters list!"; 87 88 PointerType = getValueType(TargetRec->getValueAsDef("PointerType")); 89 } 90 91 92 const std::string &CodeGenTarget::getName() const { 93 return TargetRec->getName(); 94 } 95 96 Record *CodeGenTarget::getInstructionSet() const { 97 return TargetRec->getValueAsDef("InstructionSet"); 98 } 99 100 void CodeGenTarget::ReadInstructions() const { 101 std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction"); 102 103 if (Insts.size() == 0) 104 throw std::string("No 'Instruction' subclasses defined!"); 105 106 for (unsigned i = 0, e = Insts.size(); i != e; ++i) 107 Instructions.insert(std::make_pair(Insts[i]->getName(), Insts[i])); 108 } 109 110 /// getPHIInstruction - Return the designated PHI instruction. 111 const CodeGenInstruction &CodeGenTarget::getPHIInstruction() const { 112 Record *PHI = getInstructionSet()->getValueAsDef("PHIInst"); 113 std::map<std::string, CodeGenInstruction>::const_iterator I = 114 getInstructions().find(PHI->getName()); 115 if (I == Instructions.end()) 116 throw "Could not find PHI instruction named '" + PHI->getName() + "'!"; 117 return I->second; 118 } 119 120 CodeGenInstruction::CodeGenInstruction(Record *R) : TheDef(R) { 121 Name = R->getValueAsString("Name"); 122 Namespace = R->getValueAsString("Namespace"); 123 AsmString = R->getValueAsString("AsmString"); 124 125 isReturn = R->getValueAsBit("isReturn"); 126 isBranch = R->getValueAsBit("isBranch"); 127 isBarrier = R->getValueAsBit("isBarrier"); 128 isCall = R->getValueAsBit("isCall"); 129 isTwoAddress = R->getValueAsBit("isTwoAddress"); 130 isTerminator = R->getValueAsBit("isTerminator"); 131 132 try { 133 DagInit *DI = R->getValueAsDag("OperandList"); 134 135 for (unsigned i = 0, e = DI->getNumArgs(); i != e; ++i) 136 if (DefInit *Arg = dynamic_cast<DefInit*>(DI->getArg(i))) { 137 Record *Rec = Arg->getDef(); 138 MVT::ValueType Ty; 139 if (Rec->isSubClassOf("RegisterClass")) 140 Ty = getValueType(Rec->getValueAsDef("RegType")); 141 else if (Rec->isSubClassOf("Operand")) 142 Ty = getValueType(Rec->getValueAsDef("Type")); 143 else 144 throw "Unknown operand class '" + Rec->getName() + 145 "' in instruction '" + R->getName() + "' instruction!"; 146 147 OperandList.push_back(OperandInfo(Rec, Ty, DI->getArgName(i))); 148 } else { 149 throw "Illegal operand for the '" + R->getName() + "' instruction!"; 150 } 151 } catch (...) { 152 // Error parsing operands list, just ignore it. 153 AsmString.clear(); 154 OperandList.clear(); 155 } 156 } 157 158 159 160 /// getOperandNamed - Return the index of the operand with the specified 161 /// non-empty name. If the instruction does not have an operand with the 162 /// specified name, throw an exception. 163 unsigned CodeGenInstruction::getOperandNamed(const std::string &Name) const { 164 assert(!Name.empty() && "Cannot search for operand with no name!"); 165 for (unsigned i = 0, e = OperandList.size(); i != e; ++i) 166 if (OperandList[i].Name == Name) return i; 167 throw "Instruction '" + TheDef->getName() + 168 "' does not have an operand named '$" + Name + "'!"; 169 } 170