CodeGenInstruction.cpp revision af3eb7c7583555ea5fd08e99f28b0042811e4dc2
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 mayStore = R->getValueAsBit("mayStore"); 88 isImplicitDef= R->getValueAsBit("isImplicitDef"); 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 mayHaveSideEffects = R->getValueAsBit("mayHaveSideEffects"); 100 neverHasSideEffects = R->getValueAsBit("neverHasSideEffects"); 101 hasOptionalDef = false; 102 hasVariableNumberOfOperands = false; 103 104 if (mayHaveSideEffects && neverHasSideEffects) 105 throw R->getName() + 106 ": cannot have both 'mayHaveSideEffects' and 'neverHasSideEffects' set!"; 107 108 DagInit *DI; 109 try { 110 DI = R->getValueAsDag("OutOperandList"); 111 } catch (...) { 112 // Error getting operand list, just ignore it (sparcv9). 113 AsmString.clear(); 114 OperandList.clear(); 115 return; 116 } 117 NumDefs = DI->getNumArgs(); 118 119 DagInit *IDI; 120 try { 121 IDI = R->getValueAsDag("InOperandList"); 122 } catch (...) { 123 // Error getting operand list, just ignore it (sparcv9). 124 AsmString.clear(); 125 OperandList.clear(); 126 return; 127 } 128 DI = (DagInit*)(new BinOpInit(BinOpInit::CONCAT, DI, IDI))->Fold(); 129 130 unsigned MIOperandNo = 0; 131 std::set<std::string> OperandNames; 132 for (unsigned i = 0, e = DI->getNumArgs(); i != e; ++i) { 133 DefInit *Arg = dynamic_cast<DefInit*>(DI->getArg(i)); 134 if (!Arg) 135 throw "Illegal operand for the '" + R->getName() + "' instruction!"; 136 137 Record *Rec = Arg->getDef(); 138 std::string PrintMethod = "printOperand"; 139 unsigned NumOps = 1; 140 DagInit *MIOpInfo = 0; 141 if (Rec->isSubClassOf("Operand")) { 142 PrintMethod = Rec->getValueAsString("PrintMethod"); 143 MIOpInfo = Rec->getValueAsDag("MIOperandInfo"); 144 145 // Verify that MIOpInfo has an 'ops' root value. 146 if (!dynamic_cast<DefInit*>(MIOpInfo->getOperator()) || 147 dynamic_cast<DefInit*>(MIOpInfo->getOperator()) 148 ->getDef()->getName() != "ops") 149 throw "Bad value for MIOperandInfo in operand '" + Rec->getName() + 150 "'\n"; 151 152 // If we have MIOpInfo, then we have #operands equal to number of entries 153 // in MIOperandInfo. 154 if (unsigned NumArgs = MIOpInfo->getNumArgs()) 155 NumOps = NumArgs; 156 157 if (Rec->isSubClassOf("PredicateOperand")) 158 isPredicable = true; 159 else if (Rec->isSubClassOf("OptionalDefOperand")) 160 hasOptionalDef = true; 161 } else if (Rec->getName() == "variable_ops") { 162 hasVariableNumberOfOperands = true; 163 continue; 164 } else if (!Rec->isSubClassOf("RegisterClass") && 165 Rec->getName() != "ptr_rc") 166 throw "Unknown operand class '" + Rec->getName() + 167 "' in instruction '" + R->getName() + "' instruction!"; 168 169 // Check that the operand has a name and that it's unique. 170 if (DI->getArgName(i).empty()) 171 throw "In instruction '" + R->getName() + "', operand #" + utostr(i) + 172 " has no name!"; 173 if (!OperandNames.insert(DI->getArgName(i)).second) 174 throw "In instruction '" + R->getName() + "', operand #" + utostr(i) + 175 " has the same name as a previous operand!"; 176 177 OperandList.push_back(OperandInfo(Rec, DI->getArgName(i), PrintMethod, 178 MIOperandNo, NumOps, MIOpInfo)); 179 MIOperandNo += NumOps; 180 } 181 182 // Parse Constraints. 183 ParseConstraints(R->getValueAsString("Constraints"), this); 184 185 // For backward compatibility: isTwoAddress means operand 1 is tied to 186 // operand 0. 187 if (isTwoAddress) { 188 if (!OperandList[1].Constraints[0].empty()) 189 throw R->getName() + ": cannot use isTwoAddress property: instruction " 190 "already has constraint set!"; 191 OperandList[1].Constraints[0] = "((0 << 16) | (1 << TOI::TIED_TO))"; 192 } 193 194 // Any operands with unset constraints get 0 as their constraint. 195 for (unsigned op = 0, e = OperandList.size(); op != e; ++op) 196 for (unsigned j = 0, e = OperandList[op].MINumOperands; j != e; ++j) 197 if (OperandList[op].Constraints[j].empty()) 198 OperandList[op].Constraints[j] = "0"; 199 200 // Parse the DisableEncoding field. 201 std::string DisableEncoding = R->getValueAsString("DisableEncoding"); 202 while (1) { 203 std::string OpName = getToken(DisableEncoding, " ,\t"); 204 if (OpName.empty()) break; 205 206 // Figure out which operand this is. 207 std::pair<unsigned,unsigned> Op = ParseOperandName(OpName, false); 208 209 // Mark the operand as not-to-be encoded. 210 if (Op.second >= OperandList[Op.first].DoNotEncode.size()) 211 OperandList[Op.first].DoNotEncode.resize(Op.second+1); 212 OperandList[Op.first].DoNotEncode[Op.second] = true; 213 } 214} 215 216/// getOperandNamed - Return the index of the operand with the specified 217/// non-empty name. If the instruction does not have an operand with the 218/// specified name, throw an exception. 219/// 220unsigned CodeGenInstruction::getOperandNamed(const std::string &Name) const { 221 assert(!Name.empty() && "Cannot search for operand with no name!"); 222 for (unsigned i = 0, e = OperandList.size(); i != e; ++i) 223 if (OperandList[i].Name == Name) return i; 224 throw "Instruction '" + TheDef->getName() + 225 "' does not have an operand named '$" + Name + "'!"; 226} 227 228std::pair<unsigned,unsigned> 229CodeGenInstruction::ParseOperandName(const std::string &Op, 230 bool AllowWholeOp) { 231 if (Op.empty() || Op[0] != '$') 232 throw TheDef->getName() + ": Illegal operand name: '" + Op + "'"; 233 234 std::string OpName = Op.substr(1); 235 std::string SubOpName; 236 237 // Check to see if this is $foo.bar. 238 std::string::size_type DotIdx = OpName.find_first_of("."); 239 if (DotIdx != std::string::npos) { 240 SubOpName = OpName.substr(DotIdx+1); 241 if (SubOpName.empty()) 242 throw TheDef->getName() + ": illegal empty suboperand name in '" +Op +"'"; 243 OpName = OpName.substr(0, DotIdx); 244 } 245 246 unsigned OpIdx = getOperandNamed(OpName); 247 248 if (SubOpName.empty()) { // If no suboperand name was specified: 249 // If one was needed, throw. 250 if (OperandList[OpIdx].MINumOperands > 1 && !AllowWholeOp && 251 SubOpName.empty()) 252 throw TheDef->getName() + ": Illegal to refer to" 253 " whole operand part of complex operand '" + Op + "'"; 254 255 // Otherwise, return the operand. 256 return std::make_pair(OpIdx, 0U); 257 } 258 259 // Find the suboperand number involved. 260 DagInit *MIOpInfo = OperandList[OpIdx].MIOperandInfo; 261 if (MIOpInfo == 0) 262 throw TheDef->getName() + ": unknown suboperand name in '" + Op + "'"; 263 264 // Find the operand with the right name. 265 for (unsigned i = 0, e = MIOpInfo->getNumArgs(); i != e; ++i) 266 if (MIOpInfo->getArgName(i) == SubOpName) 267 return std::make_pair(OpIdx, i); 268 269 // Otherwise, didn't find it! 270 throw TheDef->getName() + ": unknown suboperand name in '" + Op + "'"; 271} 272