CodeGenInstruction.cpp revision 206083
1193323Sed//===- CodeGenInstruction.cpp - CodeGen Instruction Class Wrapper ---------===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This file implements the CodeGenInstruction class. 11193323Sed// 12193323Sed//===----------------------------------------------------------------------===// 13193323Sed 14193323Sed#include "CodeGenInstruction.h" 15206083Srdivacky#include "CodeGenTarget.h" 16193323Sed#include "Record.h" 17193323Sed#include "llvm/ADT/StringExtras.h" 18202375Srdivacky#include "llvm/ADT/STLExtras.h" 19193323Sed#include <set> 20193323Sedusing namespace llvm; 21193323Sed 22193323Sedstatic void ParseConstraint(const std::string &CStr, CodeGenInstruction *I) { 23201360Srdivacky // EARLY_CLOBBER: @early $reg 24201360Srdivacky std::string::size_type wpos = CStr.find_first_of(" \t"); 25201360Srdivacky std::string::size_type start = CStr.find_first_not_of(" \t"); 26201360Srdivacky std::string Tok = CStr.substr(start, wpos - start); 27201360Srdivacky if (Tok == "@earlyclobber") { 28201360Srdivacky std::string Name = CStr.substr(wpos+1); 29201360Srdivacky wpos = Name.find_first_not_of(" \t"); 30201360Srdivacky if (wpos == std::string::npos) 31201360Srdivacky throw "Illegal format for @earlyclobber constraint: '" + CStr + "'"; 32201360Srdivacky Name = Name.substr(wpos); 33201360Srdivacky std::pair<unsigned,unsigned> Op = 34201360Srdivacky I->ParseOperandName(Name, false); 35201360Srdivacky 36201360Srdivacky // Build the string for the operand 37203954Srdivacky if (!I->OperandList[Op.first].Constraints[Op.second].isNone()) 38201360Srdivacky throw "Operand '" + Name + "' cannot have multiple constraints!"; 39203954Srdivacky I->OperandList[Op.first].Constraints[Op.second] = 40203954Srdivacky CodeGenInstruction::ConstraintInfo::getEarlyClobber(); 41201360Srdivacky return; 42201360Srdivacky } 43201360Srdivacky 44201360Srdivacky // Only other constraint is "TIED_TO" for now. 45193323Sed std::string::size_type pos = CStr.find_first_of('='); 46193323Sed assert(pos != std::string::npos && "Unrecognized constraint"); 47201360Srdivacky start = CStr.find_first_not_of(" \t"); 48198090Srdivacky std::string Name = CStr.substr(start, pos - start); 49201360Srdivacky 50193323Sed // TIED_TO: $src1 = $dst 51201360Srdivacky wpos = Name.find_first_of(" \t"); 52193323Sed if (wpos == std::string::npos) 53193323Sed throw "Illegal format for tied-to constraint: '" + CStr + "'"; 54193323Sed std::string DestOpName = Name.substr(0, wpos); 55193323Sed std::pair<unsigned,unsigned> DestOp = I->ParseOperandName(DestOpName, false); 56201360Srdivacky 57193323Sed Name = CStr.substr(pos+1); 58193323Sed wpos = Name.find_first_not_of(" \t"); 59193323Sed if (wpos == std::string::npos) 60193323Sed throw "Illegal format for tied-to constraint: '" + CStr + "'"; 61201360Srdivacky 62193323Sed std::pair<unsigned,unsigned> SrcOp = 63193323Sed I->ParseOperandName(Name.substr(wpos), false); 64193323Sed if (SrcOp > DestOp) 65193323Sed throw "Illegal tied-to operand constraint '" + CStr + "'"; 66201360Srdivacky 67201360Srdivacky 68193323Sed unsigned FlatOpNo = I->getFlattenedOperandNumber(SrcOp); 69201360Srdivacky 70203954Srdivacky if (!I->OperandList[DestOp.first].Constraints[DestOp.second].isNone()) 71193323Sed throw "Operand '" + DestOpName + "' cannot have multiple constraints!"; 72203954Srdivacky I->OperandList[DestOp.first].Constraints[DestOp.second] = 73203954Srdivacky CodeGenInstruction::ConstraintInfo::getTied(FlatOpNo); 74193323Sed} 75193323Sed 76193323Sedstatic void ParseConstraints(const std::string &CStr, CodeGenInstruction *I) { 77193323Sed // Make sure the constraints list for each operand is large enough to hold 78193323Sed // constraint info, even if none is present. 79201360Srdivacky for (unsigned i = 0, e = I->OperandList.size(); i != e; ++i) 80193323Sed I->OperandList[i].Constraints.resize(I->OperandList[i].MINumOperands); 81201360Srdivacky 82193323Sed if (CStr.empty()) return; 83201360Srdivacky 84193323Sed const std::string delims(","); 85193323Sed std::string::size_type bidx, eidx; 86201360Srdivacky 87193323Sed bidx = CStr.find_first_not_of(delims); 88193323Sed while (bidx != std::string::npos) { 89193323Sed eidx = CStr.find_first_of(delims, bidx); 90193323Sed if (eidx == std::string::npos) 91193323Sed eidx = CStr.length(); 92201360Srdivacky 93198090Srdivacky ParseConstraint(CStr.substr(bidx, eidx - bidx), I); 94193323Sed bidx = CStr.find_first_not_of(delims, eidx); 95193323Sed } 96193323Sed} 97193323Sed 98193323SedCodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr) 99193323Sed : TheDef(R), AsmString(AsmStr) { 100193323Sed Namespace = R->getValueAsString("Namespace"); 101193323Sed 102193323Sed isReturn = R->getValueAsBit("isReturn"); 103193323Sed isBranch = R->getValueAsBit("isBranch"); 104193323Sed isIndirectBranch = R->getValueAsBit("isIndirectBranch"); 105193323Sed isBarrier = R->getValueAsBit("isBarrier"); 106193323Sed isCall = R->getValueAsBit("isCall"); 107193323Sed canFoldAsLoad = R->getValueAsBit("canFoldAsLoad"); 108193323Sed mayLoad = R->getValueAsBit("mayLoad"); 109193323Sed mayStore = R->getValueAsBit("mayStore"); 110193323Sed bool isTwoAddress = R->getValueAsBit("isTwoAddress"); 111193323Sed isPredicable = R->getValueAsBit("isPredicable"); 112193323Sed isConvertibleToThreeAddress = R->getValueAsBit("isConvertibleToThreeAddress"); 113193323Sed isCommutable = R->getValueAsBit("isCommutable"); 114193323Sed isTerminator = R->getValueAsBit("isTerminator"); 115193323Sed isReMaterializable = R->getValueAsBit("isReMaterializable"); 116193323Sed hasDelaySlot = R->getValueAsBit("hasDelaySlot"); 117198892Srdivacky usesCustomInserter = R->getValueAsBit("usesCustomInserter"); 118193323Sed hasCtrlDep = R->getValueAsBit("hasCtrlDep"); 119193323Sed isNotDuplicable = R->getValueAsBit("isNotDuplicable"); 120193323Sed hasSideEffects = R->getValueAsBit("hasSideEffects"); 121193323Sed neverHasSideEffects = R->getValueAsBit("neverHasSideEffects"); 122193323Sed isAsCheapAsAMove = R->getValueAsBit("isAsCheapAsAMove"); 123198090Srdivacky hasExtraSrcRegAllocReq = R->getValueAsBit("hasExtraSrcRegAllocReq"); 124198090Srdivacky hasExtraDefRegAllocReq = R->getValueAsBit("hasExtraDefRegAllocReq"); 125193323Sed hasOptionalDef = false; 126193323Sed isVariadic = false; 127205407Srdivacky ImplicitDefs = R->getValueAsListOfDefs("Defs"); 128205407Srdivacky ImplicitUses = R->getValueAsListOfDefs("Uses"); 129193323Sed 130204642Srdivacky if (neverHasSideEffects + hasSideEffects > 1) 131193323Sed throw R->getName() + ": multiple conflicting side-effect flags set!"; 132193323Sed 133205407Srdivacky DagInit *OutDI = R->getValueAsDag("OutOperandList"); 134193323Sed 135205407Srdivacky if (DefInit *Init = dynamic_cast<DefInit*>(OutDI->getOperator())) { 136205407Srdivacky if (Init->getDef()->getName() != "outs") 137205407Srdivacky throw R->getName() + ": invalid def name for output list: use 'outs'"; 138205407Srdivacky } else 139205407Srdivacky throw R->getName() + ": invalid output list: use 'outs'"; 140205407Srdivacky 141205407Srdivacky NumDefs = OutDI->getNumArgs(); 142205407Srdivacky 143205407Srdivacky DagInit *InDI = R->getValueAsDag("InOperandList"); 144205407Srdivacky if (DefInit *Init = dynamic_cast<DefInit*>(InDI->getOperator())) { 145205407Srdivacky if (Init->getDef()->getName() != "ins") 146205407Srdivacky throw R->getName() + ": invalid def name for input list: use 'ins'"; 147205407Srdivacky } else 148205407Srdivacky throw R->getName() + ": invalid input list: use 'ins'"; 149205407Srdivacky 150193323Sed unsigned MIOperandNo = 0; 151193323Sed std::set<std::string> OperandNames; 152205407Srdivacky for (unsigned i = 0, e = InDI->getNumArgs()+OutDI->getNumArgs(); i != e; ++i){ 153205407Srdivacky Init *ArgInit; 154205407Srdivacky std::string ArgName; 155205407Srdivacky if (i < NumDefs) { 156205407Srdivacky ArgInit = OutDI->getArg(i); 157205407Srdivacky ArgName = OutDI->getArgName(i); 158205407Srdivacky } else { 159205407Srdivacky ArgInit = InDI->getArg(i-NumDefs); 160205407Srdivacky ArgName = InDI->getArgName(i-NumDefs); 161205407Srdivacky } 162205407Srdivacky 163205407Srdivacky DefInit *Arg = dynamic_cast<DefInit*>(ArgInit); 164193323Sed if (!Arg) 165193323Sed throw "Illegal operand for the '" + R->getName() + "' instruction!"; 166193323Sed 167193323Sed Record *Rec = Arg->getDef(); 168193323Sed std::string PrintMethod = "printOperand"; 169193323Sed unsigned NumOps = 1; 170193323Sed DagInit *MIOpInfo = 0; 171193323Sed if (Rec->isSubClassOf("Operand")) { 172193323Sed PrintMethod = Rec->getValueAsString("PrintMethod"); 173193323Sed MIOpInfo = Rec->getValueAsDag("MIOperandInfo"); 174201360Srdivacky 175193323Sed // Verify that MIOpInfo has an 'ops' root value. 176193323Sed if (!dynamic_cast<DefInit*>(MIOpInfo->getOperator()) || 177193323Sed dynamic_cast<DefInit*>(MIOpInfo->getOperator()) 178193323Sed ->getDef()->getName() != "ops") 179193323Sed throw "Bad value for MIOperandInfo in operand '" + Rec->getName() + 180193323Sed "'\n"; 181193323Sed 182193323Sed // If we have MIOpInfo, then we have #operands equal to number of entries 183193323Sed // in MIOperandInfo. 184193323Sed if (unsigned NumArgs = MIOpInfo->getNumArgs()) 185193323Sed NumOps = NumArgs; 186193323Sed 187193323Sed if (Rec->isSubClassOf("PredicateOperand")) 188193323Sed isPredicable = true; 189193323Sed else if (Rec->isSubClassOf("OptionalDefOperand")) 190193323Sed hasOptionalDef = true; 191193323Sed } else if (Rec->getName() == "variable_ops") { 192193323Sed isVariadic = true; 193193323Sed continue; 194201360Srdivacky } else if (!Rec->isSubClassOf("RegisterClass") && 195193323Sed Rec->getName() != "ptr_rc" && Rec->getName() != "unknown") 196193323Sed throw "Unknown operand class '" + Rec->getName() + 197193323Sed "' in '" + R->getName() + "' instruction!"; 198193323Sed 199193323Sed // Check that the operand has a name and that it's unique. 200205407Srdivacky if (ArgName.empty()) 201193323Sed throw "In instruction '" + R->getName() + "', operand #" + utostr(i) + 202193323Sed " has no name!"; 203205407Srdivacky if (!OperandNames.insert(ArgName).second) 204193323Sed throw "In instruction '" + R->getName() + "', operand #" + utostr(i) + 205193323Sed " has the same name as a previous operand!"; 206201360Srdivacky 207205407Srdivacky OperandList.push_back(OperandInfo(Rec, ArgName, PrintMethod, 208193323Sed MIOperandNo, NumOps, MIOpInfo)); 209193323Sed MIOperandNo += NumOps; 210193323Sed } 211193323Sed 212193323Sed // Parse Constraints. 213193323Sed ParseConstraints(R->getValueAsString("Constraints"), this); 214201360Srdivacky 215193323Sed // For backward compatibility: isTwoAddress means operand 1 is tied to 216193323Sed // operand 0. 217193323Sed if (isTwoAddress) { 218203954Srdivacky if (!OperandList[1].Constraints[0].isNone()) 219193323Sed throw R->getName() + ": cannot use isTwoAddress property: instruction " 220193323Sed "already has constraint set!"; 221203954Srdivacky OperandList[1].Constraints[0] = 222203954Srdivacky CodeGenInstruction::ConstraintInfo::getTied(0); 223193323Sed } 224201360Srdivacky 225193323Sed // Parse the DisableEncoding field. 226193323Sed std::string DisableEncoding = R->getValueAsString("DisableEncoding"); 227193323Sed while (1) { 228202375Srdivacky std::string OpName; 229202375Srdivacky tie(OpName, DisableEncoding) = getToken(DisableEncoding, " ,\t"); 230193323Sed if (OpName.empty()) break; 231193323Sed 232193323Sed // Figure out which operand this is. 233193323Sed std::pair<unsigned,unsigned> Op = ParseOperandName(OpName, false); 234193323Sed 235193323Sed // Mark the operand as not-to-be encoded. 236193323Sed if (Op.second >= OperandList[Op.first].DoNotEncode.size()) 237193323Sed OperandList[Op.first].DoNotEncode.resize(Op.second+1); 238193323Sed OperandList[Op.first].DoNotEncode[Op.second] = true; 239193323Sed } 240193323Sed} 241193323Sed 242193323Sed/// getOperandNamed - Return the index of the operand with the specified 243193323Sed/// non-empty name. If the instruction does not have an operand with the 244193323Sed/// specified name, throw an exception. 245193323Sed/// 246193323Sedunsigned CodeGenInstruction::getOperandNamed(const std::string &Name) const { 247193323Sed assert(!Name.empty() && "Cannot search for operand with no name!"); 248193323Sed for (unsigned i = 0, e = OperandList.size(); i != e; ++i) 249193323Sed if (OperandList[i].Name == Name) return i; 250193323Sed throw "Instruction '" + TheDef->getName() + 251193323Sed "' does not have an operand named '$" + Name + "'!"; 252193323Sed} 253193323Sed 254201360Srdivackystd::pair<unsigned,unsigned> 255193323SedCodeGenInstruction::ParseOperandName(const std::string &Op, 256193323Sed bool AllowWholeOp) { 257193323Sed if (Op.empty() || Op[0] != '$') 258193323Sed throw TheDef->getName() + ": Illegal operand name: '" + Op + "'"; 259201360Srdivacky 260193323Sed std::string OpName = Op.substr(1); 261193323Sed std::string SubOpName; 262201360Srdivacky 263193323Sed // Check to see if this is $foo.bar. 264193323Sed std::string::size_type DotIdx = OpName.find_first_of("."); 265193323Sed if (DotIdx != std::string::npos) { 266193323Sed SubOpName = OpName.substr(DotIdx+1); 267193323Sed if (SubOpName.empty()) 268193323Sed throw TheDef->getName() + ": illegal empty suboperand name in '" +Op +"'"; 269193323Sed OpName = OpName.substr(0, DotIdx); 270193323Sed } 271201360Srdivacky 272193323Sed unsigned OpIdx = getOperandNamed(OpName); 273193323Sed 274193323Sed if (SubOpName.empty()) { // If no suboperand name was specified: 275193323Sed // If one was needed, throw. 276193323Sed if (OperandList[OpIdx].MINumOperands > 1 && !AllowWholeOp && 277193323Sed SubOpName.empty()) 278193323Sed throw TheDef->getName() + ": Illegal to refer to" 279193323Sed " whole operand part of complex operand '" + Op + "'"; 280201360Srdivacky 281193323Sed // Otherwise, return the operand. 282193323Sed return std::make_pair(OpIdx, 0U); 283193323Sed } 284201360Srdivacky 285193323Sed // Find the suboperand number involved. 286193323Sed DagInit *MIOpInfo = OperandList[OpIdx].MIOperandInfo; 287193323Sed if (MIOpInfo == 0) 288193323Sed throw TheDef->getName() + ": unknown suboperand name in '" + Op + "'"; 289201360Srdivacky 290193323Sed // Find the operand with the right name. 291193323Sed for (unsigned i = 0, e = MIOpInfo->getNumArgs(); i != e; ++i) 292193323Sed if (MIOpInfo->getArgName(i) == SubOpName) 293193323Sed return std::make_pair(OpIdx, i); 294193323Sed 295193323Sed // Otherwise, didn't find it! 296193323Sed throw TheDef->getName() + ": unknown suboperand name in '" + Op + "'"; 297193323Sed} 298206083Srdivacky 299206083Srdivacky 300206083Srdivacky/// HasOneImplicitDefWithKnownVT - If the instruction has at least one 301206083Srdivacky/// implicit def and it has a known VT, return the VT, otherwise return 302206083Srdivacky/// MVT::Other. 303206083SrdivackyMVT::SimpleValueType CodeGenInstruction:: 304206083SrdivackyHasOneImplicitDefWithKnownVT(const CodeGenTarget &TargetInfo) const { 305206083Srdivacky if (ImplicitDefs.empty()) return MVT::Other; 306206083Srdivacky 307206083Srdivacky // Check to see if the first implicit def has a resolvable type. 308206083Srdivacky Record *FirstImplicitDef = ImplicitDefs[0]; 309206083Srdivacky assert(FirstImplicitDef->isSubClassOf("Register")); 310206083Srdivacky const std::vector<MVT::SimpleValueType> &RegVTs = 311206083Srdivacky TargetInfo.getRegisterVTs(FirstImplicitDef); 312206083Srdivacky if (RegVTs.size() == 1) 313206083Srdivacky return RegVTs[0]; 314206083Srdivacky return MVT::Other; 315206083Srdivacky} 316206083Srdivacky 317