CodeGenInstruction.cpp revision 2e48a70b35635165703838fc8d3796b664207aa1
1//===- CodeGenInstruction.cpp - CodeGen Instruction Class Wrapper ---------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements the CodeGenInstruction class. 11// 12//===----------------------------------------------------------------------===// 13 14#include "CodeGenInstruction.h" 15#include "Record.h" 16#include "llvm/ADT/StringExtras.h" 17#include <set> 18using namespace llvm; 19 20static void ParseConstraint(const std::string &CStr, CodeGenInstruction *I) { 21 // FIXME: Only supports TIED_TO for now. 22 std::string::size_type pos = CStr.find_first_of('='); 23 assert(pos != std::string::npos && "Unrecognized constraint"); 24 std::string Name = CStr.substr(0, pos); 25 26 // TIED_TO: $src1 = $dst 27 std::string::size_type wpos = Name.find_first_of(" \t"); 28 if (wpos == std::string::npos) 29 throw "Illegal format for tied-to constraint: '" + CStr + "'"; 30 std::string DestOpName = Name.substr(0, wpos); 31 std::pair<unsigned,unsigned> DestOp = I->ParseOperandName(DestOpName, false); 32 33 Name = CStr.substr(pos+1); 34 wpos = Name.find_first_not_of(" \t"); 35 if (wpos == std::string::npos) 36 throw "Illegal format for tied-to constraint: '" + CStr + "'"; 37 38 std::pair<unsigned,unsigned> SrcOp = 39 I->ParseOperandName(Name.substr(wpos), false); 40 if (SrcOp > DestOp) 41 throw "Illegal tied-to operand constraint '" + CStr + "'"; 42 43 44 unsigned FlatOpNo = I->getFlattenedOperandNumber(SrcOp); 45 // Build the string for the operand. 46 std::string OpConstraint = 47 "((" + utostr(FlatOpNo) + " << 16) | (1 << TOI::TIED_TO))"; 48 49 50 if (!I->OperandList[DestOp.first].Constraints[DestOp.second].empty()) 51 throw "Operand '" + DestOpName + "' cannot have multiple constraints!"; 52 I->OperandList[DestOp.first].Constraints[DestOp.second] = OpConstraint; 53} 54 55static void ParseConstraints(const std::string &CStr, CodeGenInstruction *I) { 56 // Make sure the constraints list for each operand is large enough to hold 57 // constraint info, even if none is present. 58 for (unsigned i = 0, e = I->OperandList.size(); i != e; ++i) 59 I->OperandList[i].Constraints.resize(I->OperandList[i].MINumOperands); 60 61 if (CStr.empty()) return; 62 63 const std::string delims(","); 64 std::string::size_type bidx, eidx; 65 66 bidx = CStr.find_first_not_of(delims); 67 while (bidx != std::string::npos) { 68 eidx = CStr.find_first_of(delims, bidx); 69 if (eidx == std::string::npos) 70 eidx = CStr.length(); 71 72 ParseConstraint(CStr.substr(bidx, eidx), I); 73 bidx = CStr.find_first_not_of(delims, eidx); 74 } 75} 76 77CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr) 78 : TheDef(R), AsmString(AsmStr) { 79 Name = R->getValueAsString("Name"); 80 Namespace = R->getValueAsString("Namespace"); 81 82 isReturn = R->getValueAsBit("isReturn"); 83 isBranch = R->getValueAsBit("isBranch"); 84 isIndirectBranch = R->getValueAsBit("isIndirectBranch"); 85 isBarrier = R->getValueAsBit("isBarrier"); 86 isCall = R->getValueAsBit("isCall"); 87 isLoad = R->getValueAsBit("isLoad"); 88 mayStore = R->getValueAsBit("mayStore"); 89 isImplicitDef= R->getValueAsBit("isImplicitDef"); 90 bool isTwoAddress = R->getValueAsBit("isTwoAddress"); 91 isPredicable = R->getValueAsBit("isPredicable"); 92 isConvertibleToThreeAddress = R->getValueAsBit("isConvertibleToThreeAddress"); 93 isCommutable = R->getValueAsBit("isCommutable"); 94 isTerminator = R->getValueAsBit("isTerminator"); 95 isReMaterializable = R->getValueAsBit("isReMaterializable"); 96 hasDelaySlot = R->getValueAsBit("hasDelaySlot"); 97 usesCustomDAGSchedInserter = R->getValueAsBit("usesCustomDAGSchedInserter"); 98 hasCtrlDep = R->getValueAsBit("hasCtrlDep"); 99 isNotDuplicable = R->getValueAsBit("isNotDuplicable"); 100 mayHaveSideEffects = R->getValueAsBit("mayHaveSideEffects"); 101 neverHasSideEffects = R->getValueAsBit("neverHasSideEffects"); 102 hasOptionalDef = false; 103 hasVariableNumberOfOperands = false; 104 105 if (mayHaveSideEffects && neverHasSideEffects) 106 throw R->getName() + 107 ": cannot have both 'mayHaveSideEffects' and 'neverHasSideEffects' set!"; 108 109 DagInit *DI; 110 try { 111 DI = R->getValueAsDag("OutOperandList"); 112 } catch (...) { 113 // Error getting operand list, just ignore it (sparcv9). 114 AsmString.clear(); 115 OperandList.clear(); 116 return; 117 } 118 NumDefs = DI->getNumArgs(); 119 120 DagInit *IDI; 121 try { 122 IDI = R->getValueAsDag("InOperandList"); 123 } catch (...) { 124 // Error getting operand list, just ignore it (sparcv9). 125 AsmString.clear(); 126 OperandList.clear(); 127 return; 128 } 129 DI = (DagInit*)(new BinOpInit(BinOpInit::CONCAT, DI, IDI))->Fold(); 130 131 unsigned MIOperandNo = 0; 132 std::set<std::string> OperandNames; 133 for (unsigned i = 0, e = DI->getNumArgs(); i != e; ++i) { 134 DefInit *Arg = dynamic_cast<DefInit*>(DI->getArg(i)); 135 if (!Arg) 136 throw "Illegal operand for the '" + R->getName() + "' instruction!"; 137 138 Record *Rec = Arg->getDef(); 139 std::string PrintMethod = "printOperand"; 140 unsigned NumOps = 1; 141 DagInit *MIOpInfo = 0; 142 if (Rec->isSubClassOf("Operand")) { 143 PrintMethod = Rec->getValueAsString("PrintMethod"); 144 MIOpInfo = Rec->getValueAsDag("MIOperandInfo"); 145 146 // Verify that MIOpInfo has an 'ops' root value. 147 if (!dynamic_cast<DefInit*>(MIOpInfo->getOperator()) || 148 dynamic_cast<DefInit*>(MIOpInfo->getOperator()) 149 ->getDef()->getName() != "ops") 150 throw "Bad value for MIOperandInfo in operand '" + Rec->getName() + 151 "'\n"; 152 153 // If we have MIOpInfo, then we have #operands equal to number of entries 154 // in MIOperandInfo. 155 if (unsigned NumArgs = MIOpInfo->getNumArgs()) 156 NumOps = NumArgs; 157 158 if (Rec->isSubClassOf("PredicateOperand")) 159 isPredicable = true; 160 else if (Rec->isSubClassOf("OptionalDefOperand")) 161 hasOptionalDef = true; 162 } else if (Rec->getName() == "variable_ops") { 163 hasVariableNumberOfOperands = true; 164 continue; 165 } else if (!Rec->isSubClassOf("RegisterClass") && 166 Rec->getName() != "ptr_rc") 167 throw "Unknown operand class '" + Rec->getName() + 168 "' in instruction '" + R->getName() + "' instruction!"; 169 170 // Check that the operand has a name and that it's unique. 171 if (DI->getArgName(i).empty()) 172 throw "In instruction '" + R->getName() + "', operand #" + utostr(i) + 173 " has no name!"; 174 if (!OperandNames.insert(DI->getArgName(i)).second) 175 throw "In instruction '" + R->getName() + "', operand #" + utostr(i) + 176 " has the same name as a previous operand!"; 177 178 OperandList.push_back(OperandInfo(Rec, DI->getArgName(i), PrintMethod, 179 MIOperandNo, NumOps, MIOpInfo)); 180 MIOperandNo += NumOps; 181 } 182 183 // Parse Constraints. 184 ParseConstraints(R->getValueAsString("Constraints"), this); 185 186 // For backward compatibility: isTwoAddress means operand 1 is tied to 187 // operand 0. 188 if (isTwoAddress) { 189 if (!OperandList[1].Constraints[0].empty()) 190 throw R->getName() + ": cannot use isTwoAddress property: instruction " 191 "already has constraint set!"; 192 OperandList[1].Constraints[0] = "((0 << 16) | (1 << TOI::TIED_TO))"; 193 } 194 195 // Any operands with unset constraints get 0 as their constraint. 196 for (unsigned op = 0, e = OperandList.size(); op != e; ++op) 197 for (unsigned j = 0, e = OperandList[op].MINumOperands; j != e; ++j) 198 if (OperandList[op].Constraints[j].empty()) 199 OperandList[op].Constraints[j] = "0"; 200 201 // Parse the DisableEncoding field. 202 std::string DisableEncoding = R->getValueAsString("DisableEncoding"); 203 while (1) { 204 std::string OpName = getToken(DisableEncoding, " ,\t"); 205 if (OpName.empty()) break; 206 207 // Figure out which operand this is. 208 std::pair<unsigned,unsigned> Op = ParseOperandName(OpName, false); 209 210 // Mark the operand as not-to-be encoded. 211 if (Op.second >= OperandList[Op.first].DoNotEncode.size()) 212 OperandList[Op.first].DoNotEncode.resize(Op.second+1); 213 OperandList[Op.first].DoNotEncode[Op.second] = true; 214 } 215} 216 217/// getName - Return the contents of the instruction Name field if set, 218/// otherwise return the name of the def. 219std::string CodeGenInstruction::getName() const { 220 if (!Name.empty()) return Name; 221 return TheDef->getName(); 222} 223 224 225/// getOperandNamed - Return the index of the operand with the specified 226/// non-empty name. If the instruction does not have an operand with the 227/// specified name, throw an exception. 228/// 229unsigned CodeGenInstruction::getOperandNamed(const std::string &Name) const { 230 assert(!Name.empty() && "Cannot search for operand with no name!"); 231 for (unsigned i = 0, e = OperandList.size(); i != e; ++i) 232 if (OperandList[i].Name == Name) return i; 233 throw "Instruction '" + TheDef->getName() + 234 "' does not have an operand named '$" + Name + "'!"; 235} 236 237std::pair<unsigned,unsigned> 238CodeGenInstruction::ParseOperandName(const std::string &Op, 239 bool AllowWholeOp) { 240 if (Op.empty() || Op[0] != '$') 241 throw TheDef->getName() + ": Illegal operand name: '" + Op + "'"; 242 243 std::string OpName = Op.substr(1); 244 std::string SubOpName; 245 246 // Check to see if this is $foo.bar. 247 std::string::size_type DotIdx = OpName.find_first_of("."); 248 if (DotIdx != std::string::npos) { 249 SubOpName = OpName.substr(DotIdx+1); 250 if (SubOpName.empty()) 251 throw TheDef->getName() + ": illegal empty suboperand name in '" +Op +"'"; 252 OpName = OpName.substr(0, DotIdx); 253 } 254 255 unsigned OpIdx = getOperandNamed(OpName); 256 257 if (SubOpName.empty()) { // If no suboperand name was specified: 258 // If one was needed, throw. 259 if (OperandList[OpIdx].MINumOperands > 1 && !AllowWholeOp && 260 SubOpName.empty()) 261 throw TheDef->getName() + ": Illegal to refer to" 262 " whole operand part of complex operand '" + Op + "'"; 263 264 // Otherwise, return the operand. 265 return std::make_pair(OpIdx, 0U); 266 } 267 268 // Find the suboperand number involved. 269 DagInit *MIOpInfo = OperandList[OpIdx].MIOperandInfo; 270 if (MIOpInfo == 0) 271 throw TheDef->getName() + ": unknown suboperand name in '" + Op + "'"; 272 273 // Find the operand with the right name. 274 for (unsigned i = 0, e = MIOpInfo->getNumArgs(); i != e; ++i) 275 if (MIOpInfo->getArgName(i) == SubOpName) 276 return std::make_pair(OpIdx, i); 277 278 // Otherwise, didn't find it! 279 throw TheDef->getName() + ": unknown suboperand name in '" + Op + "'"; 280} 281