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