CodeGenInstruction.cpp revision 8370d38adee63b3a4d87bfe81be4aacc55fe7cda
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 Namespace = R->getValueAsString("Namespace"); 80 81 isReturn = R->getValueAsBit("isReturn"); 82 isBranch = R->getValueAsBit("isBranch"); 83 isIndirectBranch = R->getValueAsBit("isIndirectBranch"); 84 isBarrier = R->getValueAsBit("isBarrier"); 85 isCall = R->getValueAsBit("isCall"); 86 isSimpleLoad = R->getValueAsBit("isSimpleLoad"); 87 mayLoad = R->getValueAsBit("mayLoad"); 88 mayStore = R->getValueAsBit("mayStore"); 89 bool isTwoAddress = R->getValueAsBit("isTwoAddress"); 90 isPredicable = R->getValueAsBit("isPredicable"); 91 isConvertibleToThreeAddress = R->getValueAsBit("isConvertibleToThreeAddress"); 92 isCommutable = R->getValueAsBit("isCommutable"); 93 isTerminator = R->getValueAsBit("isTerminator"); 94 isReMaterializable = R->getValueAsBit("isReMaterializable"); 95 hasDelaySlot = R->getValueAsBit("hasDelaySlot"); 96 usesCustomDAGSchedInserter = R->getValueAsBit("usesCustomDAGSchedInserter"); 97 hasCtrlDep = R->getValueAsBit("hasCtrlDep"); 98 isNotDuplicable = R->getValueAsBit("isNotDuplicable"); 99 hasSideEffects = R->getValueAsBit("hasSideEffects"); 100 mayHaveSideEffects = R->getValueAsBit("mayHaveSideEffects"); 101 neverHasSideEffects = R->getValueAsBit("neverHasSideEffects"); 102 isAsCheapAsAMove = R->getValueAsBit("isAsCheapAsAMove"); 103 hasOptionalDef = false; 104 isVariadic = false; 105 106 if (mayHaveSideEffects + neverHasSideEffects + hasSideEffects > 1) 107 throw R->getName() + ": multiple conflicting side-effect flags 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 isVariadic = true; 164 continue; 165 } else if (!Rec->isSubClassOf("RegisterClass") && 166 Rec->getName() != "ptr_rc" && Rec->getName() != "unknown") 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/// getOperandNamed - Return the index of the operand with the specified 218/// non-empty name. If the instruction does not have an operand with the 219/// specified name, throw an exception. 220/// 221unsigned CodeGenInstruction::getOperandNamed(const std::string &Name) const { 222 assert(!Name.empty() && "Cannot search for operand with no name!"); 223 for (unsigned i = 0, e = OperandList.size(); i != e; ++i) 224 if (OperandList[i].Name == Name) return i; 225 throw "Instruction '" + TheDef->getName() + 226 "' does not have an operand named '$" + Name + "'!"; 227} 228 229std::pair<unsigned,unsigned> 230CodeGenInstruction::ParseOperandName(const std::string &Op, 231 bool AllowWholeOp) { 232 if (Op.empty() || Op[0] != '$') 233 throw TheDef->getName() + ": Illegal operand name: '" + Op + "'"; 234 235 std::string OpName = Op.substr(1); 236 std::string SubOpName; 237 238 // Check to see if this is $foo.bar. 239 std::string::size_type DotIdx = OpName.find_first_of("."); 240 if (DotIdx != std::string::npos) { 241 SubOpName = OpName.substr(DotIdx+1); 242 if (SubOpName.empty()) 243 throw TheDef->getName() + ": illegal empty suboperand name in '" +Op +"'"; 244 OpName = OpName.substr(0, DotIdx); 245 } 246 247 unsigned OpIdx = getOperandNamed(OpName); 248 249 if (SubOpName.empty()) { // If no suboperand name was specified: 250 // If one was needed, throw. 251 if (OperandList[OpIdx].MINumOperands > 1 && !AllowWholeOp && 252 SubOpName.empty()) 253 throw TheDef->getName() + ": Illegal to refer to" 254 " whole operand part of complex operand '" + Op + "'"; 255 256 // Otherwise, return the operand. 257 return std::make_pair(OpIdx, 0U); 258 } 259 260 // Find the suboperand number involved. 261 DagInit *MIOpInfo = OperandList[OpIdx].MIOperandInfo; 262 if (MIOpInfo == 0) 263 throw TheDef->getName() + ": unknown suboperand name in '" + Op + "'"; 264 265 // Find the operand with the right name. 266 for (unsigned i = 0, e = MIOpInfo->getNumArgs(); i != e; ++i) 267 if (MIOpInfo->getArgName(i) == SubOpName) 268 return std::make_pair(OpIdx, i); 269 270 // Otherwise, didn't find it! 271 throw TheDef->getName() + ": unknown suboperand name in '" + Op + "'"; 272} 273