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