aboutsummaryrefslogtreecommitdiff
path: root/backend/utils/TableGen
diff options
context:
space:
mode:
Diffstat (limited to 'backend/utils/TableGen')
-rw-r--r--backend/utils/TableGen/Common/CodeGenSelection.cpp54
-rw-r--r--backend/utils/TableGen/Common/CodeGenTarget.h6
-rw-r--r--backend/utils/TableGen/GlobalISelEmitter.cpp12
3 files changed, 68 insertions, 4 deletions
diff --git a/backend/utils/TableGen/Common/CodeGenSelection.cpp b/backend/utils/TableGen/Common/CodeGenSelection.cpp
index df9bf7b..defe98b 100644
--- a/backend/utils/TableGen/Common/CodeGenSelection.cpp
+++ b/backend/utils/TableGen/Common/CodeGenSelection.cpp
@@ -79,6 +79,33 @@ findInstructionBySymbol(const NormalizedTargetModel &Model, std::string_view Sym
return static_cast<std::uint32_t>(Position->second);
}
+[[nodiscard]] std::optional<std::uint32_t>
+floatingPredicateValue(std::string_view Symbol) noexcept {
+ static constexpr std::array<std::pair<std::string_view, FloatingPredicate>, 16> Predicates = {{
+ {"false", FloatingPredicate::AlwaysFalse},
+ {"oeq", FloatingPredicate::OrderedEqual},
+ {"ogt", FloatingPredicate::OrderedGreaterThan},
+ {"oge", FloatingPredicate::OrderedGreaterEqual},
+ {"olt", FloatingPredicate::OrderedLessThan},
+ {"ole", FloatingPredicate::OrderedLessEqual},
+ {"one", FloatingPredicate::OrderedNotEqual},
+ {"ord", FloatingPredicate::Ordered},
+ {"uno", FloatingPredicate::Unordered},
+ {"ueq", FloatingPredicate::UnorderedEqual},
+ {"ugt", FloatingPredicate::UnorderedGreaterThan},
+ {"uge", FloatingPredicate::UnorderedGreaterEqual},
+ {"ult", FloatingPredicate::UnorderedLessThan},
+ {"ule", FloatingPredicate::UnorderedLessEqual},
+ {"une", FloatingPredicate::UnorderedNotEqual},
+ {"true", FloatingPredicate::AlwaysTrue},
+ }};
+ const auto *const Position =
+ std::ranges::find(Predicates, Symbol, &decltype(Predicates)::value_type::first);
+ if (Position == Predicates.end())
+ return std::nullopt;
+ return static_cast<std::uint32_t>(Position->second);
+}
+
[[nodiscard]] const NormalizedRegister *findRegisterBySymbol(const NormalizedTargetModel &Model,
std::string_view Symbol) {
const auto Position = std::ranges::find(Model.Registers, Symbol, &NormalizedRegister::Symbol);
@@ -243,6 +270,33 @@ bool CodeGenTarget::normalizeSelectionRules(NormalizedTargetModel &Result) {
++Normalized.Specificity;
}
+ if (Rule.IntegerPredicate && Rule.FloatingPredicate) {
+ fail(Rule.Range, "selection rule cannot require both integer and floating predicates");
+ return false;
+ }
+ if (Rule.FloatingPredicate) {
+ const auto Predicate = floatingPredicateValue(Rule.FloatingPredicate->Predicate);
+ if (!Predicate) {
+ fail(Rule.FloatingPredicate->Range,
+ "selection floating predicate is not a recognized floating predicate");
+ return false;
+ }
+ if (MatchInstruction != nullptr &&
+ (Rule.FloatingPredicate->OperandIndex >= MatchInstruction->Operands.size() ||
+ !std::ranges::contains(
+ MatchInstruction->Operands[Rule.FloatingPredicate->OperandIndex].Kinds,
+ "Predicate"))) {
+ fail(Rule.FloatingPredicate->Range,
+ "selection floating predicate requires a predicate operand");
+ return false;
+ }
+ Normalized.FloatingPredicate = {
+ .OperandIndex = Rule.FloatingPredicate->OperandIndex,
+ .Predicate = *Predicate,
+ };
+ ++Normalized.Specificity;
+ }
+
std::unordered_set<std::string> TargetPredicateSymbols;
for (const SourceSelectionTargetPredicate &Predicate : Rule.TargetPredicates) {
if (!isIdentifier(Predicate.Symbol) ||
diff --git a/backend/utils/TableGen/Common/CodeGenTarget.h b/backend/utils/TableGen/Common/CodeGenTarget.h
index 9a7c0a2..020bb88 100644
--- a/backend/utils/TableGen/Common/CodeGenTarget.h
+++ b/backend/utils/TableGen/Common/CodeGenTarget.h
@@ -195,6 +195,11 @@ struct NormalizedSelectionIntegerPredicate final {
std::uint32_t Predicate = 0;
};
+struct NormalizedSelectionFloatingPredicate final {
+ std::uint32_t OperandIndex = 0;
+ std::uint32_t Predicate = 0;
+};
+
struct NormalizedSelectionConstantRange final {
std::int64_t Minimum = 0;
std::int64_t Maximum = 0;
@@ -266,6 +271,7 @@ struct NormalizedSelectionRule final {
std::uint32_t MatchOpcode = 0;
std::optional<NormalizedSelectionTypePredicate> ResultType;
std::optional<NormalizedSelectionIntegerPredicate> IntegerPredicate;
+ std::optional<NormalizedSelectionFloatingPredicate> FloatingPredicate;
std::vector<std::string> TargetPredicates;
std::vector<NormalizedSelectionOperandTypePredicate> OperandTypes;
std::vector<NormalizedSelectionOperandBankPredicate> OperandBanks;
diff --git a/backend/utils/TableGen/GlobalISelEmitter.cpp b/backend/utils/TableGen/GlobalISelEmitter.cpp
index d73d691..7390bdf 100644
--- a/backend/utils/TableGen/GlobalISelEmitter.cpp
+++ b/backend/utils/TableGen/GlobalISelEmitter.cpp
@@ -42,10 +42,11 @@ void emitTypePredicate(std::ostream &Output, std::uint32_t OperandIndex,
[[nodiscard]] std::size_t instructionCount(const NormalizedSelectionRule &Rule) noexcept {
std::size_t Count = 2U + (Rule.ResultType ? 1U : 0U) + (Rule.IntegerPredicate ? 1U : 0U) +
- Rule.TargetPredicates.size() + Rule.OperandTypes.size() +
- Rule.OperandBanks.size() + Rule.OperandClasses.size() +
- Rule.OperandImmediates.size() + Rule.OperandDefConstants.size() +
- Rule.Temporaries.size() + Rule.EraseOperandDefinitions.size();
+ (Rule.FloatingPredicate ? 1U : 0U) + Rule.TargetPredicates.size() +
+ Rule.OperandTypes.size() + Rule.OperandBanks.size() +
+ Rule.OperandClasses.size() + Rule.OperandImmediates.size() +
+ Rule.OperandDefConstants.size() + Rule.Temporaries.size() +
+ Rule.EraseOperandDefinitions.size();
for (const NormalizedSelectionDefUsePredicate &Predicate : Rule.DefUsePredicates)
Count += 1U + static_cast<std::size_t>(Predicate.IntegerPredicate.has_value()) +
Predicate.Captures.size() + Predicate.OperandDefConstants.size();
@@ -115,6 +116,9 @@ std::string emitGlobalISel(const NormalizedTargetModel &Model, std::string_view
if (Rule.IntegerPredicate)
emitInstruction(Output, "CheckIntegerPredicate", Rule.IntegerPredicate->OperandIndex,
Rule.IntegerPredicate->Predicate);
+ if (Rule.FloatingPredicate)
+ emitInstruction(Output, "CheckFloatingPredicate", Rule.FloatingPredicate->OperandIndex,
+ Rule.FloatingPredicate->Predicate);
for (const std::string &Predicate : Rule.TargetPredicates)
emitInstruction(Output, "CheckTargetPredicate", 0, 0, "0", 0, Predicate);
for (const NormalizedSelectionOperandTypePredicate &Predicate : Rule.OperandTypes)