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 #include "llvm/ADT/StringExtras.h" 20 #include "llvm/Support/CommandLine.h" 21 #include <set> 22 using namespace llvm; 23 24 static cl::opt<unsigned> 25 AsmWriterNum("asmwriternum", cl::init(0), 26 cl::desc("Make -gen-asm-writer emit assembly writer #N")); 27 28 /// getValueType - Return the MCV::ValueType that the specified TableGen record 29 /// corresponds to. 30 MVT::ValueType llvm::getValueType(Record *Rec) { 31 return (MVT::ValueType)Rec->getValueAsInt("Value"); 32 } 33 34 std::string llvm::getName(MVT::ValueType T) { 35 switch (T) { 36 case MVT::Other: return "UNKNOWN"; 37 case MVT::i1: return "i1"; 38 case MVT::i8: return "i8"; 39 case MVT::i16: return "i16"; 40 case MVT::i32: return "i32"; 41 case MVT::i64: return "i64"; 42 case MVT::i128: return "i128"; 43 case MVT::f32: return "f32"; 44 case MVT::f64: return "f64"; 45 case MVT::f80: return "f80"; 46 case MVT::f128: return "f128"; 47 case MVT::isVoid:return "void"; 48 default: assert(0 && "ILLEGAL VALUE TYPE!"); return ""; 49 } 50 } 51 52 std::string llvm::getEnumName(MVT::ValueType T) { 53 switch (T) { 54 case MVT::Other: return "Other"; 55 case MVT::i1: return "i1"; 56 case MVT::i8: return "i8"; 57 case MVT::i16: return "i16"; 58 case MVT::i32: return "i32"; 59 case MVT::i64: return "i64"; 60 case MVT::i128: return "i128"; 61 case MVT::f32: return "f32"; 62 case MVT::f64: return "f64"; 63 case MVT::f80: return "f80"; 64 case MVT::f128: return "f128"; 65 case MVT::isVoid:return "isVoid"; 66 default: assert(0 && "ILLEGAL VALUE TYPE!"); return ""; 67 } 68 } 69 70 71 std::ostream &llvm::operator<<(std::ostream &OS, MVT::ValueType T) { 72 return OS << getName(T); 73 } 74 75 76 /// getTarget - Return the current instance of the Target class. 77 /// 78 CodeGenTarget::CodeGenTarget() : PointerType(MVT::Other) { 79 std::vector<Record*> Targets = Records.getAllDerivedDefinitions("Target"); 80 if (Targets.size() == 0) 81 throw std::string("ERROR: No 'Target' subclasses defined!"); 82 if (Targets.size() != 1) 83 throw std::string("ERROR: Multiple subclasses of Target defined!"); 84 TargetRec = Targets[0]; 85 86 // Read in all of the CalleeSavedRegisters... 87 ListInit *LI = TargetRec->getValueAsListInit("CalleeSavedRegisters"); 88 for (unsigned i = 0, e = LI->getSize(); i != e; ++i) 89 if (DefInit *DI = dynamic_cast<DefInit*>(LI->getElement(i))) 90 CalleeSavedRegisters.push_back(DI->getDef()); 91 else 92 throw "Target: " + TargetRec->getName() + 93 " expected register definition in CalleeSavedRegisters list!"; 94 95 PointerType = getValueType(TargetRec->getValueAsDef("PointerType")); 96 } 97 98 99 const std::string &CodeGenTarget::getName() const { 100 return TargetRec->getName(); 101 } 102 103 Record *CodeGenTarget::getInstructionSet() const { 104 return TargetRec->getValueAsDef("InstructionSet"); 105 } 106 107 /// getAsmWriter - Return the AssemblyWriter definition for this target. 108 /// 109 Record *CodeGenTarget::getAsmWriter() const { 110 ListInit *LI = TargetRec->getValueAsListInit("AssemblyWriters"); 111 if (AsmWriterNum >= LI->getSize()) 112 throw "Target does not have an AsmWriter #" + utostr(AsmWriterNum) + "!"; 113 DefInit *DI = dynamic_cast<DefInit*>(LI->getElement(AsmWriterNum)); 114 if (!DI) throw std::string("AssemblyWriter list should be a list of defs!"); 115 return DI->getDef(); 116 } 117 118 void CodeGenTarget::ReadRegisters() const { 119 std::vector<Record*> Regs = Records.getAllDerivedDefinitions("Register"); 120 if (Regs.empty()) 121 throw std::string("No 'Register' subclasses defined!"); 122 123 Registers.reserve(Regs.size()); 124 Registers.assign(Regs.begin(), Regs.end()); 125 } 126 127 CodeGenRegister::CodeGenRegister(Record *R) : TheDef(R) { 128 DeclaredSpillSize = R->getValueAsInt("SpillSize"); 129 DeclaredSpillAlignment = R->getValueAsInt("SpillAlignment"); 130 } 131 132 const std::string &CodeGenRegister::getName() const { 133 return TheDef->getName(); 134 } 135 136 void CodeGenTarget::ReadRegisterClasses() const { 137 std::vector<Record*> RegClasses = 138 Records.getAllDerivedDefinitions("RegisterClass"); 139 if (RegClasses.empty()) 140 throw std::string("No 'RegisterClass' subclasses defined!"); 141 142 RegisterClasses.reserve(RegClasses.size()); 143 RegisterClasses.assign(RegClasses.begin(), RegClasses.end()); 144 } 145 146 CodeGenRegisterClass::CodeGenRegisterClass(Record *R) : TheDef(R) { 147 // Rename anonymous register classes. 148 if (R->getName().size() > 9 && R->getName()[9] == '.') { 149 static unsigned AnonCounter = 0; 150 R->setName("AnonRegClass_"+utostr(AnonCounter++)); 151 } 152 153 Namespace = R->getValueAsString("Namespace"); 154 SpillSize = R->getValueAsInt("Size"); 155 SpillAlignment = R->getValueAsInt("Alignment"); 156 VT = getValueType(R->getValueAsDef("RegType")); 157 158 MethodBodies = R->getValueAsCode("MethodBodies"); 159 MethodProtos = R->getValueAsCode("MethodProtos"); 160 161 ListInit *RegList = R->getValueAsListInit("MemberList"); 162 for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) { 163 DefInit *RegDef = dynamic_cast<DefInit*>(RegList->getElement(i)); 164 if (!RegDef) throw "Register class member is not a record!"; 165 Record *Reg = RegDef->getDef(); 166 167 if (!Reg->isSubClassOf("Register")) 168 throw "Register Class member '" + Reg->getName() + 169 "' does not derive from the Register class!"; 170 Elements.push_back(Reg); 171 } 172 } 173 174 const std::string &CodeGenRegisterClass::getName() const { 175 return TheDef->getName(); 176 } 177 178 void CodeGenTarget::ReadLegalValueTypes() const { 179 const std::vector<CodeGenRegisterClass> &RCs = getRegisterClasses(); 180 for (unsigned i = 0, e = RCs.size(); i != e; ++i) 181 LegalValueTypes.push_back(RCs[i].VT); 182 } 183 184 185 void CodeGenTarget::ReadInstructions() const { 186 std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction"); 187 188 if (Insts.empty()) 189 throw std::string("No 'Instruction' subclasses defined!"); 190 191 std::string InstFormatName = 192 getAsmWriter()->getValueAsString("InstFormatName"); 193 194 for (unsigned i = 0, e = Insts.size(); i != e; ++i) { 195 std::string AsmStr = Insts[i]->getValueAsString(InstFormatName); 196 Instructions.insert(std::make_pair(Insts[i]->getName(), 197 CodeGenInstruction(Insts[i], AsmStr))); 198 } 199 } 200 201 /// getPHIInstruction - Return the designated PHI instruction. 202 /// 203 const CodeGenInstruction &CodeGenTarget::getPHIInstruction() const { 204 Record *PHI = getInstructionSet()->getValueAsDef("PHIInst"); 205 std::map<std::string, CodeGenInstruction>::const_iterator I = 206 getInstructions().find(PHI->getName()); 207 if (I == Instructions.end()) 208 throw "Could not find PHI instruction named '" + PHI->getName() + "'!"; 209 return I->second; 210 } 211 212 /// getInstructionsByEnumValue - Return all of the instructions defined by the 213 /// target, ordered by their enum value. 214 void CodeGenTarget:: 215 getInstructionsByEnumValue(std::vector<const CodeGenInstruction*> 216 &NumberedInstructions) { 217 218 // Print out the rest of the instructions now. 219 unsigned i = 0; 220 const CodeGenInstruction *PHI = &getPHIInstruction(); 221 NumberedInstructions.push_back(PHI); 222 for (inst_iterator II = inst_begin(), E = inst_end(); II != E; ++II) 223 if (&II->second != PHI) 224 NumberedInstructions.push_back(&II->second); 225 } 226 227 228 /// isLittleEndianEncoding - Return whether this target encodes its instruction 229 /// in little-endian format, i.e. bits laid out in the order [0..n] 230 /// 231 bool CodeGenTarget::isLittleEndianEncoding() const { 232 return getInstructionSet()->getValueAsBit("isLittleEndianEncoding"); 233 } 234 235 CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr) 236 : TheDef(R), AsmString(AsmStr) { 237 Name = R->getValueAsString("Name"); 238 Namespace = R->getValueAsString("Namespace"); 239 240 isReturn = R->getValueAsBit("isReturn"); 241 isBranch = R->getValueAsBit("isBranch"); 242 isBarrier = R->getValueAsBit("isBarrier"); 243 isCall = R->getValueAsBit("isCall"); 244 isLoad = R->getValueAsBit("isLoad"); 245 isStore = R->getValueAsBit("isStore"); 246 isTwoAddress = R->getValueAsBit("isTwoAddress"); 247 isConvertibleToThreeAddress = R->getValueAsBit("isConvertibleToThreeAddress"); 248 isCommutable = R->getValueAsBit("isCommutable"); 249 isTerminator = R->getValueAsBit("isTerminator"); 250 hasDelaySlot = R->getValueAsBit("hasDelaySlot"); 251 usesCustomDAGSchedInserter = R->getValueAsBit("usesCustomDAGSchedInserter"); 252 hasVariableNumberOfOperands = false; 253 254 DagInit *DI; 255 try { 256 DI = R->getValueAsDag("OperandList"); 257 } catch (...) { 258 // Error getting operand list, just ignore it (sparcv9). 259 AsmString.clear(); 260 OperandList.clear(); 261 return; 262 } 263 264 unsigned MIOperandNo = 0; 265 std::set<std::string> OperandNames; 266 for (unsigned i = 0, e = DI->getNumArgs(); i != e; ++i) { 267 DefInit *Arg = dynamic_cast<DefInit*>(DI->getArg(i)); 268 if (!Arg) 269 throw "Illegal operand for the '" + R->getName() + "' instruction!"; 270 271 Record *Rec = Arg->getDef(); 272 MVT::ValueType Ty; 273 std::string PrintMethod = "printOperand"; 274 unsigned NumOps = 1; 275 if (Rec->isSubClassOf("RegisterClass")) { 276 Ty = getValueType(Rec->getValueAsDef("RegType")); 277 } else if (Rec->isSubClassOf("Operand")) { 278 Ty = getValueType(Rec->getValueAsDef("Type")); 279 PrintMethod = Rec->getValueAsString("PrintMethod"); 280 NumOps = Rec->getValueAsInt("NumMIOperands"); 281 } else if (Rec->getName() == "variable_ops") { 282 hasVariableNumberOfOperands = true; 283 continue; 284 } else 285 throw "Unknown operand class '" + Rec->getName() + 286 "' in instruction '" + R->getName() + "' instruction!"; 287 288 if (!DI->getArgName(i).empty() && 289 !OperandNames.insert(DI->getArgName(i)).second) 290 throw "In instruction '" + R->getName() + "', operand #" + utostr(i) + 291 " has the same name as a previous operand!"; 292 293 OperandList.push_back(OperandInfo(Rec, Ty, DI->getArgName(i), 294 PrintMethod, MIOperandNo, NumOps)); 295 MIOperandNo += NumOps; 296 } 297 } 298 299 300 301 /// getOperandNamed - Return the index of the operand with the specified 302 /// non-empty name. If the instruction does not have an operand with the 303 /// specified name, throw an exception. 304 /// 305 unsigned CodeGenInstruction::getOperandNamed(const std::string &Name) const { 306 assert(!Name.empty() && "Cannot search for operand with no name!"); 307 for (unsigned i = 0, e = OperandList.size(); i != e; ++i) 308 if (OperandList[i].Name == Name) return i; 309 throw "Instruction '" + TheDef->getName() + 310 "' does not have an operand named '$" + Name + "'!"; 311 } 312