summaryrefslogtreecommitdiff
path: root/utils/TableGen/SetTheory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/TableGen/SetTheory.cpp')
-rw-r--r--utils/TableGen/SetTheory.cpp19
1 files changed, 19 insertions, 0 deletions
diff --git a/utils/TableGen/SetTheory.cpp b/utils/TableGen/SetTheory.cpp
index 838b9246aa..0649fd1cfa 100644
--- a/utils/TableGen/SetTheory.cpp
+++ b/utils/TableGen/SetTheory.cpp
@@ -139,6 +139,24 @@ struct DecimateOp : public SetIntBinOp {
}
};
+// (interleave S1, S2, ...) Interleave elements of the arguments.
+struct InterleaveOp : public SetTheory::Operator {
+ void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts) {
+ // Evaluate the arguments individually.
+ SmallVector<RecSet, 4> Args(Expr->getNumArgs());
+ unsigned MaxSize = 0;
+ for (unsigned i = 0, e = Expr->getNumArgs(); i != e; ++i) {
+ ST.evaluate(Expr->getArg(i), Args[i]);
+ MaxSize = std::max(MaxSize, unsigned(Args[i].size()));
+ }
+ // Interleave arguments into Elts.
+ for (unsigned n = 0; n != MaxSize; ++n)
+ for (unsigned i = 0, e = Expr->getNumArgs(); i != e; ++i)
+ if (n < Args[i].size())
+ Elts.insert(Args[i][n]);
+ }
+};
+
// (sequence "Format", From, To) Generate a sequence of records by name.
struct SequenceOp : public SetTheory::Operator {
void apply(SetTheory &ST, DagInit *Expr, RecSet &Elts) {
@@ -211,6 +229,7 @@ SetTheory::SetTheory() {
addOperator("rotl", new RotOp(false));
addOperator("rotr", new RotOp(true));
addOperator("decimate", new DecimateOp);
+ addOperator("interleave", new InterleaveOp);
addOperator("sequence", new SequenceOp);
}