diff options
author | Chris Lattner <sabre@nondot.org> | 2008-01-06 01:35:39 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-01-06 01:35:39 +0000 |
commit | 6cc654b27a9d392ac7660afcb23e3c8136e9ab28 (patch) | |
tree | 571842880726553487235ebf32fc28eeea46c62a /utils/TableGen/CodeGenTarget.cpp | |
parent | 5fbe27530415dcacd7afd591c4ba1d6df4374873 (diff) |
Split the impl of CodeGenInstruction out to its own .cpp file, add a getName() accessor.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45645 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils/TableGen/CodeGenTarget.cpp')
-rw-r--r-- | utils/TableGen/CodeGenTarget.cpp | 266 |
1 files changed, 2 insertions, 264 deletions
diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp index 2688914d1e..53dbbf86f1 100644 --- a/utils/TableGen/CodeGenTarget.cpp +++ b/utils/TableGen/CodeGenTarget.cpp @@ -1,4 +1,4 @@ -//===- CodeGenTarget.cpp - CodeGen Target Class Wrapper ---------*- C++ -*-===// +//===- CodeGenTarget.cpp - CodeGen Target Class Wrapper -------------------===// // // The LLVM Compiler Infrastructure // @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// This class wrap target description classes used by the various code +// This class wraps target description classes used by the various code // generation TableGen backends. This makes it easier to access the data and // provides a single place that needs to check it for validity. All of these // classes throw exceptions on error conditions. @@ -20,7 +20,6 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Streams.h" -#include <set> #include <algorithm> using namespace llvm; @@ -324,267 +323,6 @@ bool CodeGenTarget::isLittleEndianEncoding() const { return getInstructionSet()->getValueAsBit("isLittleEndianEncoding"); } - - -static void ParseConstraint(const std::string &CStr, CodeGenInstruction *I) { - // FIXME: Only supports TIED_TO for now. - std::string::size_type pos = CStr.find_first_of('='); - assert(pos != std::string::npos && "Unrecognized constraint"); - std::string Name = CStr.substr(0, pos); - - // TIED_TO: $src1 = $dst - std::string::size_type wpos = Name.find_first_of(" \t"); - if (wpos == std::string::npos) - throw "Illegal format for tied-to constraint: '" + CStr + "'"; - std::string DestOpName = Name.substr(0, wpos); - std::pair<unsigned,unsigned> DestOp = I->ParseOperandName(DestOpName, false); - - Name = CStr.substr(pos+1); - wpos = Name.find_first_not_of(" \t"); - if (wpos == std::string::npos) - throw "Illegal format for tied-to constraint: '" + CStr + "'"; - - std::pair<unsigned,unsigned> SrcOp = - I->ParseOperandName(Name.substr(wpos), false); - if (SrcOp > DestOp) - throw "Illegal tied-to operand constraint '" + CStr + "'"; - - - unsigned FlatOpNo = I->getFlattenedOperandNumber(SrcOp); - // Build the string for the operand. - std::string OpConstraint = - "((" + utostr(FlatOpNo) + " << 16) | (1 << TOI::TIED_TO))"; - - - if (!I->OperandList[DestOp.first].Constraints[DestOp.second].empty()) - throw "Operand '" + DestOpName + "' cannot have multiple constraints!"; - I->OperandList[DestOp.first].Constraints[DestOp.second] = OpConstraint; -} - -static void ParseConstraints(const std::string &CStr, CodeGenInstruction *I) { - // Make sure the constraints list for each operand is large enough to hold - // constraint info, even if none is present. - for (unsigned i = 0, e = I->OperandList.size(); i != e; ++i) - I->OperandList[i].Constraints.resize(I->OperandList[i].MINumOperands); - - if (CStr.empty()) return; - - const std::string delims(","); - std::string::size_type bidx, eidx; - - bidx = CStr.find_first_not_of(delims); - while (bidx != std::string::npos) { - eidx = CStr.find_first_of(delims, bidx); - if (eidx == std::string::npos) - eidx = CStr.length(); - - ParseConstraint(CStr.substr(bidx, eidx), I); - bidx = CStr.find_first_not_of(delims, eidx); - } -} - -CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr) - : TheDef(R), AsmString(AsmStr) { - Name = R->getValueAsString("Name"); - Namespace = R->getValueAsString("Namespace"); - - isReturn = R->getValueAsBit("isReturn"); - isBranch = R->getValueAsBit("isBranch"); - isIndirectBranch = R->getValueAsBit("isIndirectBranch"); - isBarrier = R->getValueAsBit("isBarrier"); - isCall = R->getValueAsBit("isCall"); - isLoad = R->getValueAsBit("isLoad"); - isStore = R->getValueAsBit("isStore"); - isImplicitDef= R->getValueAsBit("isImplicitDef"); - bool isTwoAddress = R->getValueAsBit("isTwoAddress"); - isPredicable = R->getValueAsBit("isPredicable"); - isConvertibleToThreeAddress = R->getValueAsBit("isConvertibleToThreeAddress"); - isCommutable = R->getValueAsBit("isCommutable"); - isTerminator = R->getValueAsBit("isTerminator"); - isReMaterializable = R->getValueAsBit("isReMaterializable"); - hasDelaySlot = R->getValueAsBit("hasDelaySlot"); - usesCustomDAGSchedInserter = R->getValueAsBit("usesCustomDAGSchedInserter"); - hasCtrlDep = R->getValueAsBit("hasCtrlDep"); - isNotDuplicable = R->getValueAsBit("isNotDuplicable"); - mayHaveSideEffects = R->getValueAsBit("mayHaveSideEffects"); - neverHasSideEffects = R->getValueAsBit("neverHasSideEffects"); - hasOptionalDef = false; - hasVariableNumberOfOperands = false; - - if (mayHaveSideEffects && neverHasSideEffects) - throw R->getName() + - ": cannot have both 'mayHaveSideEffects' and 'neverHasSideEffects' set!"; - - DagInit *DI; - try { - DI = R->getValueAsDag("OutOperandList"); - } catch (...) { - // Error getting operand list, just ignore it (sparcv9). - AsmString.clear(); - OperandList.clear(); - return; - } - NumDefs = DI->getNumArgs(); - - DagInit *IDI; - try { - IDI = R->getValueAsDag("InOperandList"); - } catch (...) { - // Error getting operand list, just ignore it (sparcv9). - AsmString.clear(); - OperandList.clear(); - return; - } - DI = (DagInit*)(new BinOpInit(BinOpInit::CONCAT, DI, IDI))->Fold(); - - unsigned MIOperandNo = 0; - std::set<std::string> OperandNames; - for (unsigned i = 0, e = DI->getNumArgs(); i != e; ++i) { - DefInit *Arg = dynamic_cast<DefInit*>(DI->getArg(i)); - if (!Arg) - throw "Illegal operand for the '" + R->getName() + "' instruction!"; - - Record *Rec = Arg->getDef(); - std::string PrintMethod = "printOperand"; - unsigned NumOps = 1; - DagInit *MIOpInfo = 0; - if (Rec->isSubClassOf("Operand")) { - PrintMethod = Rec->getValueAsString("PrintMethod"); - MIOpInfo = Rec->getValueAsDag("MIOperandInfo"); - - // Verify that MIOpInfo has an 'ops' root value. - if (!dynamic_cast<DefInit*>(MIOpInfo->getOperator()) || - dynamic_cast<DefInit*>(MIOpInfo->getOperator()) - ->getDef()->getName() != "ops") - throw "Bad value for MIOperandInfo in operand '" + Rec->getName() + - "'\n"; - - // If we have MIOpInfo, then we have #operands equal to number of entries - // in MIOperandInfo. - if (unsigned NumArgs = MIOpInfo->getNumArgs()) - NumOps = NumArgs; - - if (Rec->isSubClassOf("PredicateOperand")) - isPredicable = true; - else if (Rec->isSubClassOf("OptionalDefOperand")) - hasOptionalDef = true; - } else if (Rec->getName() == "variable_ops") { - hasVariableNumberOfOperands = true; - continue; - } else if (!Rec->isSubClassOf("RegisterClass") && - Rec->getName() != "ptr_rc") - throw "Unknown operand class '" + Rec->getName() + - "' in instruction '" + R->getName() + "' instruction!"; - - // Check that the operand has a name and that it's unique. - if (DI->getArgName(i).empty()) - throw "In instruction '" + R->getName() + "', operand #" + utostr(i) + - " has no name!"; - if (!OperandNames.insert(DI->getArgName(i)).second) - throw "In instruction '" + R->getName() + "', operand #" + utostr(i) + - " has the same name as a previous operand!"; - - OperandList.push_back(OperandInfo(Rec, DI->getArgName(i), PrintMethod, - MIOperandNo, NumOps, MIOpInfo)); - MIOperandNo += NumOps; - } - - // Parse Constraints. - ParseConstraints(R->getValueAsString("Constraints"), this); - - // For backward compatibility: isTwoAddress means operand 1 is tied to - // operand 0. - if (isTwoAddress) { - if (!OperandList[1].Constraints[0].empty()) - throw R->getName() + ": cannot use isTwoAddress property: instruction " - "already has constraint set!"; - OperandList[1].Constraints[0] = "((0 << 16) | (1 << TOI::TIED_TO))"; - } - - // Any operands with unset constraints get 0 as their constraint. - for (unsigned op = 0, e = OperandList.size(); op != e; ++op) - for (unsigned j = 0, e = OperandList[op].MINumOperands; j != e; ++j) - if (OperandList[op].Constraints[j].empty()) - OperandList[op].Constraints[j] = "0"; - - // Parse the DisableEncoding field. - std::string DisableEncoding = R->getValueAsString("DisableEncoding"); - while (1) { - std::string OpName = getToken(DisableEncoding, " ,\t"); - if (OpName.empty()) break; - - // Figure out which operand this is. - std::pair<unsigned,unsigned> Op = ParseOperandName(OpName, false); - - // Mark the operand as not-to-be encoded. - if (Op.second >= OperandList[Op.first].DoNotEncode.size()) - OperandList[Op.first].DoNotEncode.resize(Op.second+1); - OperandList[Op.first].DoNotEncode[Op.second] = true; - } -} - - - -/// getOperandNamed - Return the index of the operand with the specified -/// non-empty name. If the instruction does not have an operand with the -/// specified name, throw an exception. -/// -unsigned CodeGenInstruction::getOperandNamed(const std::string &Name) const { - assert(!Name.empty() && "Cannot search for operand with no name!"); - for (unsigned i = 0, e = OperandList.size(); i != e; ++i) - if (OperandList[i].Name == Name) return i; - throw "Instruction '" + TheDef->getName() + - "' does not have an operand named '$" + Name + "'!"; -} - -std::pair<unsigned,unsigned> -CodeGenInstruction::ParseOperandName(const std::string &Op, - bool AllowWholeOp) { - if (Op.empty() || Op[0] != '$') - throw TheDef->getName() + ": Illegal operand name: '" + Op + "'"; - - std::string OpName = Op.substr(1); - std::string SubOpName; - - // Check to see if this is $foo.bar. - std::string::size_type DotIdx = OpName.find_first_of("."); - if (DotIdx != std::string::npos) { - SubOpName = OpName.substr(DotIdx+1); - if (SubOpName.empty()) - throw TheDef->getName() + ": illegal empty suboperand name in '" +Op +"'"; - OpName = OpName.substr(0, DotIdx); - } - - unsigned OpIdx = getOperandNamed(OpName); - - if (SubOpName.empty()) { // If no suboperand name was specified: - // If one was needed, throw. - if (OperandList[OpIdx].MINumOperands > 1 && !AllowWholeOp && - SubOpName.empty()) - throw TheDef->getName() + ": Illegal to refer to" - " whole operand part of complex operand '" + Op + "'"; - - // Otherwise, return the operand. - return std::make_pair(OpIdx, 0U); - } - - // Find the suboperand number involved. - DagInit *MIOpInfo = OperandList[OpIdx].MIOperandInfo; - if (MIOpInfo == 0) - throw TheDef->getName() + ": unknown suboperand name in '" + Op + "'"; - - // Find the operand with the right name. - for (unsigned i = 0, e = MIOpInfo->getNumArgs(); i != e; ++i) - if (MIOpInfo->getArgName(i) == SubOpName) - return std::make_pair(OpIdx, i); - - // Otherwise, didn't find it! - throw TheDef->getName() + ": unknown suboperand name in '" + Op + "'"; -} - - - - //===----------------------------------------------------------------------===// // ComplexPattern implementation // |