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