diff options
Diffstat (limited to 'llvm/utils/TableGen/RISCVCompressInstEmitter.cpp')
-rw-r--r-- | llvm/utils/TableGen/RISCVCompressInstEmitter.cpp | 87 |
1 files changed, 59 insertions, 28 deletions
diff --git a/llvm/utils/TableGen/RISCVCompressInstEmitter.cpp b/llvm/utils/TableGen/RISCVCompressInstEmitter.cpp index 96e4f95937b2..f298e639bf7f 100644 --- a/llvm/utils/TableGen/RISCVCompressInstEmitter.cpp +++ b/llvm/utils/TableGen/RISCVCompressInstEmitter.cpp @@ -85,7 +85,7 @@ class RISCVCompressInstEmitter { MapKind Kind; union { unsigned Operand; // Operand number mapped to. - uint64_t Imm; // Integer immediate value. + int64_t Imm; // Integer immediate value. Record *Reg; // Physical register. } Data; int TiedOpIdx = -1; // Tied operand index within the instruction. @@ -141,7 +141,7 @@ bool RISCVCompressInstEmitter::validateRegister(Record *Reg, Record *RegClass) { assert(Reg->isSubClassOf("Register") && "Reg record should be a Register\n"); assert(RegClass->isSubClassOf("RegisterClass") && "RegClass record should be" " a RegisterClass\n"); - CodeGenRegisterClass RC = Target.getRegisterClass(RegClass); + const CodeGenRegisterClass &RC = Target.getRegisterClass(RegClass); const CodeGenRegister *R = Target.getRegisterByName(Reg->getName().lower()); assert((R != nullptr) && ("Register" + Reg->getName().str() + " not defined!!\n").c_str()); @@ -160,8 +160,8 @@ bool RISCVCompressInstEmitter::validateTypes(Record *DagOpType, if (DagOpType->isSubClassOf("RegisterClass") && InstOpType->isSubClassOf("RegisterClass")) { - CodeGenRegisterClass RC = Target.getRegisterClass(InstOpType); - CodeGenRegisterClass SubRC = Target.getRegisterClass(DagOpType); + const CodeGenRegisterClass &RC = Target.getRegisterClass(InstOpType); + const CodeGenRegisterClass &SubRC = Target.getRegisterClass(DagOpType); return RC.hasSubClass(&SubRC); } @@ -474,19 +474,40 @@ void RISCVCompressInstEmitter::evaluateCompressPat(Record *Rec) { SourceOperandMap, DestOperandMap)); } -static void getReqFeatures(std::set<StringRef> &FeaturesSet, - const std::vector<Record *> &ReqFeatures) { +static void +getReqFeatures(std::set<std::pair<bool, StringRef>> &FeaturesSet, + std::set<std::set<std::pair<bool, StringRef>>> &AnyOfFeatureSets, + const std::vector<Record *> &ReqFeatures) { for (auto &R : ReqFeatures) { - StringRef AsmCondString = R->getValueAsString("AssemblerCondString"); - - // AsmCondString has syntax [!]F(,[!]F)* - SmallVector<StringRef, 4> Ops; - SplitString(AsmCondString, Ops, ","); - assert(!Ops.empty() && "AssemblerCondString cannot be empty"); - for (auto &Op : Ops) { - assert(!Op.empty() && "Empty operator"); - FeaturesSet.insert(Op); + const DagInit *D = R->getValueAsDag("AssemblerCondDag"); + std::string CombineType = D->getOperator()->getAsString(); + if (CombineType != "any_of" && CombineType != "all_of") + PrintFatalError(R->getLoc(), "Invalid AssemblerCondDag!"); + if (D->getNumArgs() == 0) + PrintFatalError(R->getLoc(), "Invalid AssemblerCondDag!"); + bool IsOr = CombineType == "any_of"; + std::set<std::pair<bool, StringRef>> AnyOfSet; + + for (auto *Arg : D->getArgs()) { + bool IsNot = false; + if (auto *NotArg = dyn_cast<DagInit>(Arg)) { + if (NotArg->getOperator()->getAsString() != "not" || + NotArg->getNumArgs() != 1) + PrintFatalError(R->getLoc(), "Invalid AssemblerCondDag!"); + Arg = NotArg->getArg(0); + IsNot = true; + } + if (!isa<DefInit>(Arg) || + !cast<DefInit>(Arg)->getDef()->isSubClassOf("SubtargetFeature")) + PrintFatalError(R->getLoc(), "Invalid AssemblerCondDag!"); + if (IsOr) + AnyOfSet.insert({IsNot, cast<DefInit>(Arg)->getDef()->getName()}); + else + FeaturesSet.insert({IsNot, cast<DefInit>(Arg)->getDef()->getName()}); } + + if (IsOr) + AnyOfFeatureSets.insert(AnyOfSet); } } @@ -547,7 +568,7 @@ void RISCVCompressInstEmitter::emitCompressInstEmitter(raw_ostream &o, "'PassSubtarget' is false. SubTargetInfo object is needed " "for target features.\n"); - std::string Namespace = Target.getName(); + std::string Namespace = std::string(Target.getName()); // Sort entries in CompressPatterns to handle instructions that can have more // than one candidate for compression\uncompression, e.g ADD can be @@ -651,9 +672,10 @@ void RISCVCompressInstEmitter::emitCompressInstEmitter(raw_ostream &o, CaseStream.indent(4) << "case " + Namespace + "::" + CurOp + ": {\n"; } - std::set<StringRef> FeaturesSet; + std::set<std::pair<bool, StringRef>> FeaturesSet; + std::set<std::set<std::pair<bool, StringRef>>> AnyOfFeatureSets; // Add CompressPat required features. - getReqFeatures(FeaturesSet, CompressPat.PatReqFeatures); + getReqFeatures(FeaturesSet, AnyOfFeatureSets, CompressPat.PatReqFeatures); // Add Dest instruction required features. std::vector<Record *> ReqFeatures; @@ -661,19 +683,28 @@ void RISCVCompressInstEmitter::emitCompressInstEmitter(raw_ostream &o, copy_if(RF, std::back_inserter(ReqFeatures), [](Record *R) { return R->getValueAsBit("AssemblerMatcherPredicate"); }); - getReqFeatures(FeaturesSet, ReqFeatures); + getReqFeatures(FeaturesSet, AnyOfFeatureSets, ReqFeatures); // Emit checks for all required features. for (auto &Op : FeaturesSet) { - if (Op[0] == '!') - CondStream.indent(6) << ("!STI.getFeatureBits()[" + Namespace + - "::" + Op.substr(1) + "]") - .str() + - " &&\n"; - else - CondStream.indent(6) - << ("STI.getFeatureBits()[" + Namespace + "::" + Op + "]").str() + - " &&\n"; + StringRef Not = Op.first ? "!" : ""; + CondStream.indent(6) + << Not << ("STI.getFeatureBits()[" + Namespace + "::" + Op.second + "]").str() + + " &&\n"; + } + + // Emit checks for all required feature groups. + for (auto &Set : AnyOfFeatureSets) { + CondStream.indent(6) << "("; + for (auto &Op : Set) { + bool isLast = &Op == &*Set.rbegin(); + StringRef Not = Op.first ? "!" : ""; + CondStream << Not << ("STI.getFeatureBits()[" + Namespace + "::" + Op.second + + "]").str(); + if (!isLast) + CondStream << " || "; + } + CondStream << ") &&\n"; } // Start Source Inst operands validation. |