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 using namespace llvm; 20 21 /// getValueType - Return the MCV::ValueType that the specified TableGen record 22 /// corresponds to. 23 MVT::ValueType llvm::getValueType(Record *Rec) { 24 return (MVT::ValueType)Rec->getValueAsInt("Value"); 25 } 26 27 std::string llvm::getName(MVT::ValueType T) { 28 switch (T) { 29 case MVT::Other: return "UNKNOWN"; 30 case MVT::i1: return "i1"; 31 case MVT::i8: return "i8"; 32 case MVT::i16: return "i16"; 33 case MVT::i32: return "i32"; 34 case MVT::i64: return "i64"; 35 case MVT::i128: return "i128"; 36 case MVT::f32: return "f32"; 37 case MVT::f64: return "f64"; 38 case MVT::f80: return "f80"; 39 case MVT::f128: return "f128"; 40 case MVT::isVoid:return "void"; 41 default: assert(0 && "ILLEGAL VALUE TYPE!"); return ""; 42 } 43 } 44 45 std::string llvm::getEnumName(MVT::ValueType T) { 46 switch (T) { 47 case MVT::Other: return "Other"; 48 case MVT::i1: return "i1"; 49 case MVT::i8: return "i8"; 50 case MVT::i16: return "i16"; 51 case MVT::i32: return "i32"; 52 case MVT::i64: return "i64"; 53 case MVT::i128: return "i128"; 54 case MVT::f32: return "f32"; 55 case MVT::f64: return "f64"; 56 case MVT::f80: return "f80"; 57 case MVT::f128: return "f128"; 58 case MVT::isVoid:return "isVoid"; 59 default: assert(0 && "ILLEGAL VALUE TYPE!"); return ""; 60 } 61 } 62 63 64 std::ostream &llvm::operator<<(std::ostream &OS, MVT::ValueType T) { 65 return OS << getName(T); 66 } 67 68 69 /// getTarget - Return the current instance of the Target class. 70 /// 71 CodeGenTarget::CodeGenTarget() : PointerType(MVT::Other) { 72 std::vector<Record*> Targets = Records.getAllDerivedDefinitions("Target"); 73 if (Targets.size() == 0) 74 throw std::string("ERROR: No 'Target' subclasses defined!"); 75 if (Targets.size() != 1) 76 throw std::string("ERROR: Multiple subclasses of Target defined!"); 77 TargetRec = Targets[0]; 78 79 // Read in all of the CalleeSavedRegisters... 80 ListInit *LI = TargetRec->getValueAsListInit("CalleeSavedRegisters"); 81 for (unsigned i = 0, e = LI->getSize(); i != e; ++i) 82 if (DefInit *DI = dynamic_cast<DefInit*>(LI->getElement(i))) 83 CalleeSavedRegisters.push_back(DI->getDef()); 84 else 85 throw "Target: " + TargetRec->getName() + 86 " expected register definition in CalleeSavedRegisters list!"; 87 88 PointerType = getValueType(TargetRec->getValueAsDef("PointerType")); 89 } 90 91 92 const std::string &CodeGenTarget::getName() const { 93 return TargetRec->getName(); 94 } 95 96 Record *CodeGenTarget::getInstructionSet() const { 97 return TargetRec->getValueAsDef("InstructionSet"); 98 } 99 100 /// getAsmWriter - Return the AssemblyWriter definition for this target. 101 /// 102 Record *CodeGenTarget::getAsmWriter() const { 103 return TargetRec->getValueAsDef("AssemblyWriter"); 104 } 105 106 void CodeGenTarget::ReadRegisters() const { 107 std::vector<Record*> Regs = Records.getAllDerivedDefinitions("Register"); 108 if (Regs.empty()) 109 throw std::string("No 'Register' subclasses defined!"); 110 111 Registers.reserve(Regs.size()); 112 Registers.assign(Regs.begin(), Regs.end()); 113 } 114 115 CodeGenRegister::CodeGenRegister(Record *R) : TheDef(R) { 116 DeclaredSpillSize = R->getValueAsInt("SpillSize"); 117 DeclaredSpillAlignment = R->getValueAsInt("SpillAlignment"); 118 } 119 120 const std::string &CodeGenRegister::getName() const { 121 return TheDef->getName(); 122 } 123 124 void CodeGenTarget::ReadRegisterClasses() const { 125 std::vector<Record*> RegClasses = 126 Records.getAllDerivedDefinitions("RegisterClass"); 127 if (RegClasses.empty()) 128 throw std::string("No 'RegisterClass' subclasses defined!"); 129 130 RegisterClasses.reserve(RegClasses.size()); 131 RegisterClasses.assign(RegClasses.begin(), RegClasses.end()); 132 } 133 134 CodeGenRegisterClass::CodeGenRegisterClass(Record *R) : TheDef(R) { 135 SpillSize = R->getValueAsInt("Size"); 136 // FIXME: should convert to bits in all targets. 137 SpillAlignment = R->getValueAsInt("Alignment")*8; 138 139 if (CodeInit *CI = dynamic_cast<CodeInit*>(R->getValueInit("Methods"))) 140 MethodDefinitions = CI->getValue(); 141 else 142 throw "Expected 'code' fragment for 'Methods' value in register class '"+ 143 getName() + "'!"; 144 145 ListInit *RegList = R->getValueAsListInit("MemberList"); 146 for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) { 147 DefInit *RegDef = dynamic_cast<DefInit*>(RegList->getElement(i)); 148 if (!RegDef) throw "Register class member is not a record!"; 149 Record *Reg = RegDef->getDef(); 150 151 if (!Reg->isSubClassOf("Register")) 152 throw "Register Class member '" + Reg->getName() + 153 "' does not derive from the Register class!"; 154 Elements.push_back(Reg); 155 } 156 } 157 158 const std::string &CodeGenRegisterClass::getName() const { 159 return TheDef->getName(); 160 } 161 162 163 164 void CodeGenTarget::ReadInstructions() const { 165 std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction"); 166 167 if (Insts.empty()) 168 throw std::string("No 'Instruction' subclasses defined!"); 169 170 std::string InstFormatName = 171 getAsmWriter()->getValueAsString("InstFormatName"); 172 173 for (unsigned i = 0, e = Insts.size(); i != e; ++i) { 174 std::string AsmStr = Insts[i]->getValueAsString(InstFormatName); 175 Instructions.insert(std::make_pair(Insts[i]->getName(), 176 CodeGenInstruction(Insts[i], AsmStr))); 177 } 178 } 179 180 /// getPHIInstruction - Return the designated PHI instruction. 181 const CodeGenInstruction &CodeGenTarget::getPHIInstruction() const { 182 Record *PHI = getInstructionSet()->getValueAsDef("PHIInst"); 183 std::map<std::string, CodeGenInstruction>::const_iterator I = 184 getInstructions().find(PHI->getName()); 185 if (I == Instructions.end()) 186 throw "Could not find PHI instruction named '" + PHI->getName() + "'!"; 187 return I->second; 188 } 189 190 CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr) 191 : TheDef(R), AsmString(AsmStr) { 192 Name = R->getValueAsString("Name"); 193 Namespace = R->getValueAsString("Namespace"); 194 195 isReturn = R->getValueAsBit("isReturn"); 196 isBranch = R->getValueAsBit("isBranch"); 197 isBarrier = R->getValueAsBit("isBarrier"); 198 isCall = R->getValueAsBit("isCall"); 199 isTwoAddress = R->getValueAsBit("isTwoAddress"); 200 isTerminator = R->getValueAsBit("isTerminator"); 201 202 try { 203 DagInit *DI = R->getValueAsDag("OperandList"); 204 205 unsigned MIOperandNo = 0; 206 for (unsigned i = 0, e = DI->getNumArgs(); i != e; ++i) 207 if (DefInit *Arg = dynamic_cast<DefInit*>(DI->getArg(i))) { 208 Record *Rec = Arg->getDef(); 209 MVT::ValueType Ty; 210 std::string PrintMethod = "printOperand"; 211 unsigned NumOps = 1; 212 if (Rec->isSubClassOf("RegisterClass")) 213 Ty = getValueType(Rec->getValueAsDef("RegType")); 214 else if (Rec->isSubClassOf("Operand")) { 215 Ty = getValueType(Rec->getValueAsDef("Type")); 216 PrintMethod = Rec->getValueAsString("PrintMethod"); 217 NumOps = Rec->getValueAsInt("NumMIOperands"); 218 } else 219 throw "Unknown operand class '" + Rec->getName() + 220 "' in instruction '" + R->getName() + "' instruction!"; 221 222 OperandList.push_back(OperandInfo(Rec, Ty, DI->getArgName(i), 223 PrintMethod, MIOperandNo)); 224 MIOperandNo += NumOps; 225 } else { 226 throw "Illegal operand for the '" + R->getName() + "' instruction!"; 227 } 228 } catch (...) { 229 // Error parsing operands list, just ignore it. 230 AsmString.clear(); 231 OperandList.clear(); 232 } 233 } 234 235 236 237 /// getOperandNamed - Return the index of the operand with the specified 238 /// non-empty name. If the instruction does not have an operand with the 239 /// specified name, throw an exception. 240 unsigned CodeGenInstruction::getOperandNamed(const std::string &Name) const { 241 assert(!Name.empty() && "Cannot search for operand with no name!"); 242 for (unsigned i = 0, e = OperandList.size(); i != e; ++i) 243 if (OperandList[i].Name == Name) return i; 244 throw "Instruction '" + TheDef->getName() + 245 "' does not have an operand named '$" + Name + "'!"; 246 } 247