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 const std::string &CodeGenRegister::getName() const { 116 return TheDef->getName(); 117 } 118 119 120 void CodeGenTarget::ReadInstructions() const { 121 std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction"); 122 123 if (Insts.empty()) 124 throw std::string("No 'Instruction' subclasses defined!"); 125 126 std::string InstFormatName = 127 getAsmWriter()->getValueAsString("InstFormatName"); 128 129 for (unsigned i = 0, e = Insts.size(); i != e; ++i) { 130 std::string AsmStr = Insts[i]->getValueAsString(InstFormatName); 131 Instructions.insert(std::make_pair(Insts[i]->getName(), 132 CodeGenInstruction(Insts[i], AsmStr))); 133 } 134 } 135 136 /// getPHIInstruction - Return the designated PHI instruction. 137 const CodeGenInstruction &CodeGenTarget::getPHIInstruction() const { 138 Record *PHI = getInstructionSet()->getValueAsDef("PHIInst"); 139 std::map<std::string, CodeGenInstruction>::const_iterator I = 140 getInstructions().find(PHI->getName()); 141 if (I == Instructions.end()) 142 throw "Could not find PHI instruction named '" + PHI->getName() + "'!"; 143 return I->second; 144 } 145 146 CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr) 147 : TheDef(R), AsmString(AsmStr) { 148 Name = R->getValueAsString("Name"); 149 Namespace = R->getValueAsString("Namespace"); 150 151 isReturn = R->getValueAsBit("isReturn"); 152 isBranch = R->getValueAsBit("isBranch"); 153 isBarrier = R->getValueAsBit("isBarrier"); 154 isCall = R->getValueAsBit("isCall"); 155 isTwoAddress = R->getValueAsBit("isTwoAddress"); 156 isTerminator = R->getValueAsBit("isTerminator"); 157 158 try { 159 DagInit *DI = R->getValueAsDag("OperandList"); 160 161 unsigned MIOperandNo = 0; 162 for (unsigned i = 0, e = DI->getNumArgs(); i != e; ++i) 163 if (DefInit *Arg = dynamic_cast<DefInit*>(DI->getArg(i))) { 164 Record *Rec = Arg->getDef(); 165 MVT::ValueType Ty; 166 std::string PrintMethod = "printOperand"; 167 unsigned NumOps = 1; 168 if (Rec->isSubClassOf("RegisterClass")) 169 Ty = getValueType(Rec->getValueAsDef("RegType")); 170 else if (Rec->isSubClassOf("Operand")) { 171 Ty = getValueType(Rec->getValueAsDef("Type")); 172 PrintMethod = Rec->getValueAsString("PrintMethod"); 173 NumOps = Rec->getValueAsInt("NumMIOperands"); 174 } else 175 throw "Unknown operand class '" + Rec->getName() + 176 "' in instruction '" + R->getName() + "' instruction!"; 177 178 OperandList.push_back(OperandInfo(Rec, Ty, DI->getArgName(i), 179 PrintMethod, MIOperandNo)); 180 MIOperandNo += NumOps; 181 } else { 182 throw "Illegal operand for the '" + R->getName() + "' instruction!"; 183 } 184 } catch (...) { 185 // Error parsing operands list, just ignore it. 186 AsmString.clear(); 187 OperandList.clear(); 188 } 189 } 190 191 192 193 /// getOperandNamed - Return the index of the operand with the specified 194 /// non-empty name. If the instruction does not have an operand with the 195 /// specified name, throw an exception. 196 unsigned CodeGenInstruction::getOperandNamed(const std::string &Name) const { 197 assert(!Name.empty() && "Cannot search for operand with no name!"); 198 for (unsigned i = 0, e = OperandList.size(); i != e; ++i) 199 if (OperandList[i].Name == Name) return i; 200 throw "Instruction '" + TheDef->getName() + 201 "' does not have an operand named '$" + Name + "'!"; 202 } 203