aboutsummaryrefslogtreecommitdiff
path: root/llvm/utils/TableGen/RISCVCompressInstEmitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/utils/TableGen/RISCVCompressInstEmitter.cpp')
-rw-r--r--llvm/utils/TableGen/RISCVCompressInstEmitter.cpp87
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.