From 4962e6143186f6168f5d0ee979bf047651a13124 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Mon, 21 Mar 2011 08:40:31 +0000 Subject: [PATCH] Add the IAPrinter class. This is a helper class that will make it easier to say which InstAliases can be printed and which cannot (because of ambiguity). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@127990 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/AsmWriterEmitter.cpp | 97 +++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp index 1bf7f3ed6c0..3bbefef6b65 100644 --- a/utils/TableGen/AsmWriterEmitter.cpp +++ b/utils/TableGen/AsmWriterEmitter.cpp @@ -601,6 +601,103 @@ struct AsmWriterInfo { } }; +// IAPrinter - Holds information about an InstAlias. Two InstAliases match if +// they both have the same conditionals. In which case, we cannot print out the +// alias for that pattern. +class IAPrinter { + AsmWriterInfo &AWI; + std::vector Conds; + std::map OpMap; + std::string Result; + std::string AsmString; + std::vector ReqFeatures; +public: + IAPrinter(AsmWriterInfo &Info, std::string R, std::string AS) + : AWI(Info), Result(R), AsmString(AS) {} + + void addCond(const std::string &C) { Conds.push_back(C); } + void addReqFeatures(const std::vector &Features) { + AWI.addReqFeatures(Features); + ReqFeatures = Features; + } + + void addOperand(StringRef Op, unsigned Idx) { OpMap[Op] = Idx; } + unsigned getOpIndex(StringRef Op) { return OpMap[Op]; } + bool isOpMapped(StringRef Op) { return OpMap.find(Op) != OpMap.end(); } + + void print(raw_ostream &O, bool IncIndent) { + unsigned Indent = 8 + (IncIndent ? 7 : 0); + + for (std::vector::iterator + I = Conds.begin(), E = Conds.end(); I != E; ++I) { + if (I != Conds.begin()) { + O << " &&\n"; + O.indent(Indent); + } else { + O << "if ("; + } + O << *I; + } + + if (Conds.begin() != Conds.end()) + O << " &&\n"; + else + O << "if ("; + + if (!ReqFeatures.empty()) { + std::string Req; + raw_string_ostream ReqO(Req); + + for (std::vector::iterator + I = ReqFeatures.begin(), E = ReqFeatures.end(); I != E; ++I) { + if (I != ReqFeatures.begin()) ReqO << " | "; + ReqO << AWI.getFeatureInfo(*I)->getEnumName(); + } + + if (Conds.begin() != Conds.end()) O.indent(Indent); + O << "(AvailableFeatures & (" << ReqO.str() << ")) == (" + << ReqO.str() << ')'; + } + + O << ") {\n"; + O.indent(6) << "// " << Result << "\n"; + O.indent(6) << "AsmString = \"" << AsmString << "\";\n"; + + for (std::map::iterator + I = OpMap.begin(), E = OpMap.end(); I != E; ++I) + O.indent(6) << "OpMap[\"" << I->first << "\"] = " + << I->second << ";\n"; + + O.indent(4) << '}'; + } + + bool operator==(const IAPrinter &RHS) { + if (Conds.size() != RHS.Conds.size()) + return false; + + unsigned Idx = 0; + for (std::vector::iterator + I = Conds.begin(), E = Conds.end(); I != E; ++I) + if (*I != RHS.Conds[Idx++]) + return false; + + return true; + } + + bool operator()(const IAPrinter &RHS) { + if (Conds.size() < RHS.Conds.size()) + return true; + + unsigned Idx = 0; + for (std::vector::iterator + I = Conds.begin(), E = Conds.end(); I != E; ++I) + if (*I != RHS.Conds[Idx++]) + return *I < RHS.Conds[Idx++]; + + return false; + } +}; + } // end anonymous namespace /// EmitSubtargetFeatureFlagEnumeration - Emit the subtarget feature flag