CodeGenTarget.cpp revision 8f493130bb51dea34c49e08aeab161e6a32dfdc6
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" 21using namespace llvm; 22 23static cl::opt<unsigned> 24AsmWriterNum("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. 29MVT::ValueType llvm::getValueType(Record *Rec) { 30 return (MVT::ValueType)Rec->getValueAsInt("Value"); 31} 32 33std::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 51std::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 70std::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/// 77CodeGenTarget::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 98const std::string &CodeGenTarget::getName() const { 99 return TargetRec->getName(); 100} 101 102Record *CodeGenTarget::getInstructionSet() const { 103 return TargetRec->getValueAsDef("InstructionSet"); 104} 105 106/// getAsmWriter - Return the AssemblyWriter definition for this target. 107/// 108Record *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 117void 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 126CodeGenRegister::CodeGenRegister(Record *R) : TheDef(R) { 127 DeclaredSpillSize = R->getValueAsInt("SpillSize"); 128 DeclaredSpillAlignment = R->getValueAsInt("SpillAlignment"); 129} 130 131const std::string &CodeGenRegister::getName() const { 132 return TheDef->getName(); 133} 134 135void 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 145CodeGenRegisterClass::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 MethodBodies = R->getValueAsCode("MethodBodies"); 158 MethodProtos = R->getValueAsCode("MethodProtos"); 159 160 ListInit *RegList = R->getValueAsListInit("MemberList"); 161 for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) { 162 DefInit *RegDef = dynamic_cast<DefInit*>(RegList->getElement(i)); 163 if (!RegDef) throw "Register class member is not a record!"; 164 Record *Reg = RegDef->getDef(); 165 166 if (!Reg->isSubClassOf("Register")) 167 throw "Register Class member '" + Reg->getName() + 168 "' does not derive from the Register class!"; 169 Elements.push_back(Reg); 170 } 171} 172 173const std::string &CodeGenRegisterClass::getName() const { 174 return TheDef->getName(); 175} 176 177void CodeGenTarget::ReadLegalValueTypes() const { 178 const std::vector<CodeGenRegisterClass> &RCs = getRegisterClasses(); 179 for (unsigned i = 0, e = RCs.size(); i != e; ++i) 180 LegalValueTypes.push_back(RCs[i].VT); 181} 182 183 184void CodeGenTarget::ReadInstructions() const { 185 std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction"); 186 187 if (Insts.empty()) 188 throw std::string("No 'Instruction' subclasses defined!"); 189 190 std::string InstFormatName = 191 getAsmWriter()->getValueAsString("InstFormatName"); 192 193 for (unsigned i = 0, e = Insts.size(); i != e; ++i) { 194 std::string AsmStr = Insts[i]->getValueAsString(InstFormatName); 195 Instructions.insert(std::make_pair(Insts[i]->getName(), 196 CodeGenInstruction(Insts[i], AsmStr))); 197 } 198} 199 200/// getPHIInstruction - Return the designated PHI instruction. 201/// 202const CodeGenInstruction &CodeGenTarget::getPHIInstruction() const { 203 Record *PHI = getInstructionSet()->getValueAsDef("PHIInst"); 204 std::map<std::string, CodeGenInstruction>::const_iterator I = 205 getInstructions().find(PHI->getName()); 206 if (I == Instructions.end()) 207 throw "Could not find PHI instruction named '" + PHI->getName() + "'!"; 208 return I->second; 209} 210 211/// getInstructionsByEnumValue - Return all of the instructions defined by the 212/// target, ordered by their enum value. 213void CodeGenTarget:: 214getInstructionsByEnumValue(std::vector<const CodeGenInstruction*> 215 &NumberedInstructions) { 216 217 // Print out the rest of the instructions now. 218 unsigned i = 0; 219 const CodeGenInstruction *PHI = &getPHIInstruction(); 220 NumberedInstructions.push_back(PHI); 221 for (inst_iterator II = inst_begin(), E = inst_end(); II != E; ++II) 222 if (&II->second != PHI) 223 NumberedInstructions.push_back(&II->second); 224} 225 226 227/// isLittleEndianEncoding - Return whether this target encodes its instruction 228/// in little-endian format, i.e. bits laid out in the order [0..n] 229/// 230bool CodeGenTarget::isLittleEndianEncoding() const { 231 return getInstructionSet()->getValueAsBit("isLittleEndianEncoding"); 232} 233 234CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr) 235 : TheDef(R), AsmString(AsmStr) { 236 Name = R->getValueAsString("Name"); 237 Namespace = R->getValueAsString("Namespace"); 238 239 isReturn = R->getValueAsBit("isReturn"); 240 isBranch = R->getValueAsBit("isBranch"); 241 isBarrier = R->getValueAsBit("isBarrier"); 242 isCall = R->getValueAsBit("isCall"); 243 isLoad = R->getValueAsBit("isLoad"); 244 isStore = R->getValueAsBit("isStore"); 245 isTwoAddress = R->getValueAsBit("isTwoAddress"); 246 isConvertibleToThreeAddress = R->getValueAsBit("isConvertibleToThreeAddress"); 247 isCommutable = R->getValueAsBit("isCommutable"); 248 isTerminator = R->getValueAsBit("isTerminator"); 249 hasDelaySlot = R->getValueAsBit("hasDelaySlot"); 250 usesCustomDAGSchedInserter = R->getValueAsBit("usesCustomDAGSchedInserter"); 251 hasVariableNumberOfOperands = false; 252 253 try { 254 DagInit *DI = R->getValueAsDag("OperandList"); 255 256 unsigned MIOperandNo = 0; 257 for (unsigned i = 0, e = DI->getNumArgs(); i != e; ++i) 258 if (DefInit *Arg = dynamic_cast<DefInit*>(DI->getArg(i))) { 259 Record *Rec = Arg->getDef(); 260 MVT::ValueType Ty; 261 std::string PrintMethod = "printOperand"; 262 unsigned NumOps = 1; 263 if (Rec->isSubClassOf("RegisterClass")) { 264 Ty = getValueType(Rec->getValueAsDef("RegType")); 265 } else if (Rec->isSubClassOf("Operand")) { 266 Ty = getValueType(Rec->getValueAsDef("Type")); 267 PrintMethod = Rec->getValueAsString("PrintMethod"); 268 NumOps = Rec->getValueAsInt("NumMIOperands"); 269 } else if (Rec->getName() == "variable_ops") { 270 hasVariableNumberOfOperands = true; 271 continue; 272 } else 273 throw "Unknown operand class '" + Rec->getName() + 274 "' in instruction '" + R->getName() + "' instruction!"; 275 276 OperandList.push_back(OperandInfo(Rec, Ty, DI->getArgName(i), 277 PrintMethod, MIOperandNo, NumOps)); 278 MIOperandNo += NumOps; 279 } else { 280 throw "Illegal operand for the '" + R->getName() + "' instruction!"; 281 } 282 } catch (...) { 283 // Error parsing operands list, just ignore it. 284 AsmString.clear(); 285 OperandList.clear(); 286 } 287} 288 289 290 291/// getOperandNamed - Return the index of the operand with the specified 292/// non-empty name. If the instruction does not have an operand with the 293/// specified name, throw an exception. 294/// 295unsigned CodeGenInstruction::getOperandNamed(const std::string &Name) const { 296 assert(!Name.empty() && "Cannot search for operand with no name!"); 297 for (unsigned i = 0, e = OperandList.size(); i != e; ++i) 298 if (OperandList[i].Name == Name) return i; 299 throw "Instruction '" + TheDef->getName() + 300 "' does not have an operand named '$" + Name + "'!"; 301} 302