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