[llvm] 4767bb2 - [TableGen] Add the !not and !xor operators.
Paul C. Anagnostopoulos via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 15 07:13:28 PDT 2020
Author: Paul C. Anagnostopoulos
Date: 2020-10-15T10:12:59-04:00
New Revision: 4767bb2c0c746eaf146927c8bcb0528bd36c7b8f
URL: https://github.com/llvm/llvm-project/commit/4767bb2c0c746eaf146927c8bcb0528bd36c7b8f
DIFF: https://github.com/llvm/llvm-project/commit/4767bb2c0c746eaf146927c8bcb0528bd36c7b8f.diff
LOG: [TableGen] Add the !not and !xor operators.
Update the TableGen Programmer's Reference.
Added:
Modified:
llvm/docs/TableGen/ProgRef.rst
llvm/include/llvm/TableGen/Record.h
llvm/lib/TableGen/Record.cpp
llvm/lib/TableGen/TGLexer.cpp
llvm/lib/TableGen/TGLexer.h
llvm/lib/TableGen/TGParser.cpp
llvm/test/TableGen/arithmetic.td
llvm/test/TableGen/if.td
llvm/test/TableGen/math.td
Removed:
################################################################################
diff --git a/llvm/docs/TableGen/ProgRef.rst b/llvm/docs/TableGen/ProgRef.rst
index d59dc1b54d76..0454d5abbba6 100644
--- a/llvm/docs/TableGen/ProgRef.rst
+++ b/llvm/docs/TableGen/ProgRef.rst
@@ -206,12 +206,13 @@ TableGen provides "bang operators" that have a wide variety of uses:
.. productionlist::
BangOperator: one of
- : !add !and !cast !con !dag
- : !empty !eq !foldl !foreach !ge
- : !getop !gt !head !if !isa
- : !le !listconcat !listsplat !lt !mul
- : !ne !or !setop !shl !size
- : !sra !srl !strconcat !subst !tail
+ : !add !and !cast !con !dag
+ : !empty !eq !foldl !foreach !ge
+ : !getop !gt !head !if !isa
+ : !le !listconcat !listsplat !lt !mul
+ : !ne !not !or !setop !shl
+ : !size !sra !srl !strconcat !subst
+ : !tail !xor
The ``!cond`` operator has a slightly
diff erent
syntax compared to other bang operators, so it is defined separately:
@@ -1447,7 +1448,8 @@ and non-0 as true.
``!and(``\ *a*\ ``,`` *b*\ ``, ...)``
This operator does a bitwise AND on *a*, *b*, etc., and produces the
- result.
+ result. A logical AND can be performed if all the arguments are either
+ 0 or 1.
``!cast<``\ *type*\ ``>(``\ *a*\ ``)``
This operator performs a cast on *a* and produces the result.
@@ -1605,9 +1607,15 @@ and non-0 as true.
The arguments must be ``bit``, ``int``, or ``string`` values.
Use ``!cast<string>`` to compare other types of objects.
+``!not(``\ *a*\ ``)``
+ This operator performs a logical NOT on *a*, which must be
+ an integer. The argument 0 results in 1 (true); any other
+ argument results in 0 (false).
+
``!or(``\ *a*\ ``,`` *b*\ ``, ...)``
This operator does a bitwise OR on *a*, *b*, etc., and produces the
- result.
+ result. A logical OR can be performed if all the arguments are either
+ 0 or 1.
``!setop(``\ *dag*\ ``,`` *op*\ ``)``
This operator produces a DAG node with the same arguments as *dag*, but with its
@@ -1655,6 +1663,11 @@ and non-0 as true.
This operator produces a new list with all the elements
of the list *a* except for the zeroth one. (See also ``!head``.)
+``!xor(``\ *a*\ ``,`` *b*\ ``, ...)``
+ This operator does a bitwise EXCLUSIVE OR on *a*, *b*, etc., and produces
+ the result. A logical XOR can be performed if all the arguments are either
+ 0 or 1.
+
Appendix B: Sample Record
=========================
diff --git a/llvm/include/llvm/TableGen/Record.h b/llvm/include/llvm/TableGen/Record.h
index c7009e400ebc..c0eb88b56be3 100644
--- a/llvm/include/llvm/TableGen/Record.h
+++ b/llvm/include/llvm/TableGen/Record.h
@@ -753,7 +753,7 @@ class OpInit : public TypedInit {
///
class UnOpInit : public OpInit, public FoldingSetNode {
public:
- enum UnaryOp : uint8_t { CAST, HEAD, TAIL, SIZE, EMPTY, GETOP };
+ enum UnaryOp : uint8_t { CAST, NOT, HEAD, TAIL, SIZE, EMPTY, GETOP };
private:
Init *LHS;
@@ -802,7 +802,7 @@ class UnOpInit : public OpInit, public FoldingSetNode {
/// !op (X, Y) - Combine two inits.
class BinOpInit : public OpInit, public FoldingSetNode {
public:
- enum BinaryOp : uint8_t { ADD, MUL, AND, OR, SHL, SRA, SRL, LISTCONCAT,
+ enum BinaryOp : uint8_t { ADD, MUL, AND, OR, XOR, SHL, SRA, SRL, LISTCONCAT,
LISTSPLAT, STRCONCAT, CONCAT, EQ, NE, LE, LT, GE,
GT, SETOP };
diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index 2a46449b213f..f191638083c4 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -761,6 +761,12 @@ Init *UnOpInit::Fold(Record *CurRec, bool IsFinal) const {
return NewInit;
break;
+ case NOT:
+ if (IntInit *LHSi =
+ dyn_cast_or_null<IntInit>(LHS->convertInitializerTo(IntRecTy::get())))
+ return IntInit::get(LHSi->getValue() ? 0 : 1);
+ break;
+
case HEAD:
if (ListInit *LHSl = dyn_cast<ListInit>(LHS)) {
assert(!LHSl->empty() && "Empty list in head");
@@ -820,6 +826,7 @@ std::string UnOpInit::getAsString() const {
std::string Result;
switch (getOpcode()) {
case CAST: Result = "!cast<" + getType()->getAsString() + ">"; break;
+ case NOT: Result = "!not"; break;
case HEAD: Result = "!head"; break;
case TAIL: Result = "!tail"; break;
case SIZE: Result = "!size"; break;
@@ -1014,6 +1021,7 @@ Init *BinOpInit::Fold(Record *CurRec) const {
case MUL:
case AND:
case OR:
+ case XOR:
case SHL:
case SRA:
case SRL: {
@@ -1029,7 +1037,8 @@ Init *BinOpInit::Fold(Record *CurRec) const {
case ADD: Result = LHSv + RHSv; break;
case MUL: Result = LHSv * RHSv; break;
case AND: Result = LHSv & RHSv; break;
- case OR: Result = LHSv | RHSv; break;
+ case OR: Result = LHSv | RHSv; break;
+ case XOR: Result = LHSv ^ RHSv; break;
case SHL: Result = (uint64_t)LHSv << (uint64_t)RHSv; break;
case SRA: Result = LHSv >> RHSv; break;
case SRL: Result = (uint64_t)LHSv >> (uint64_t)RHSv; break;
@@ -1060,6 +1069,7 @@ std::string BinOpInit::getAsString() const {
case MUL: Result = "!mul"; break;
case AND: Result = "!and"; break;
case OR: Result = "!or"; break;
+ case XOR: Result = "!xor"; break;
case SHL: Result = "!shl"; break;
case SRA: Result = "!sra"; break;
case SRL: Result = "!srl"; break;
diff --git a/llvm/lib/TableGen/TGLexer.cpp b/llvm/lib/TableGen/TGLexer.cpp
index d9111f0068c2..5db0ecb4b0ed 100644
--- a/llvm/lib/TableGen/TGLexer.cpp
+++ b/llvm/lib/TableGen/TGLexer.cpp
@@ -563,8 +563,10 @@ tgtok::TokKind TGLexer::LexExclaim() {
.Case("dag", tgtok::XDag)
.Case("add", tgtok::XADD)
.Case("mul", tgtok::XMUL)
+ .Case("not", tgtok::XNOT)
.Case("and", tgtok::XAND)
.Case("or", tgtok::XOR)
+ .Case("xor", tgtok::XXOR)
.Case("shl", tgtok::XSHL)
.Case("sra", tgtok::XSRA)
.Case("srl", tgtok::XSRL)
diff --git a/llvm/lib/TableGen/TGLexer.h b/llvm/lib/TableGen/TGLexer.h
index 49f37890043f..534c31382f63 100644
--- a/llvm/lib/TableGen/TGLexer.h
+++ b/llvm/lib/TableGen/TGLexer.h
@@ -51,9 +51,10 @@ namespace tgtok {
MultiClass, String, Defset, Defvar, If, Then, ElseKW,
// !keywords.
- XConcat, XADD, XMUL, XAND, XOR, XSRA, XSRL, XSHL, XListConcat, XListSplat,
- XStrConcat, XCast, XSubst, XForEach, XFoldl, XHead, XTail, XSize, XEmpty,
- XIf, XCond, XEq, XIsA, XDag, XNe, XLe, XLt, XGe, XGt, XSetOp, XGetOp,
+ XConcat, XADD, XMUL, XNOT, XAND, XOR, XXOR, XSRA, XSRL, XSHL,
+ XListConcat, XListSplat, XStrConcat, XCast, XSubst, XForEach, XFoldl,
+ XHead, XTail, XSize, XEmpty, XIf, XCond, XEq, XIsA, XDag, XNe, XLe,
+ XLt, XGe, XGt, XSetOp, XGetOp,
// Integer value.
IntVal,
diff --git a/llvm/lib/TableGen/TGParser.cpp b/llvm/lib/TableGen/TGParser.cpp
index eb5053b9c480..98443c97a159 100644
--- a/llvm/lib/TableGen/TGParser.cpp
+++ b/llvm/lib/TableGen/TGParser.cpp
@@ -908,6 +908,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
default:
TokError("unknown operation");
return nullptr;
+ case tgtok::XNOT:
case tgtok::XHead:
case tgtok::XTail:
case tgtok::XSize:
@@ -930,6 +931,11 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
return nullptr;
}
+ break;
+ case tgtok::XNOT:
+ Lex.Lex(); // eat the operation
+ Code = UnOpInit::NOT;
+ Type = IntRecTy::get();
break;
case tgtok::XHead:
Lex.Lex(); // eat the operation
@@ -1070,6 +1076,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
case tgtok::XMUL:
case tgtok::XAND:
case tgtok::XOR:
+ case tgtok::XXOR:
case tgtok::XSRA:
case tgtok::XSRL:
case tgtok::XSHL:
@@ -1095,6 +1102,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
case tgtok::XMUL: Code = BinOpInit::MUL; break;
case tgtok::XAND: Code = BinOpInit::AND; break;
case tgtok::XOR: Code = BinOpInit::OR; break;
+ case tgtok::XXOR: Code = BinOpInit::XOR; break;
case tgtok::XSRA: Code = BinOpInit::SRA; break;
case tgtok::XSRL: Code = BinOpInit::SRL; break;
case tgtok::XSHL: Code = BinOpInit::SHL; break;
@@ -1122,6 +1130,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
break;
case tgtok::XAND:
case tgtok::XOR:
+ case tgtok::XXOR:
case tgtok::XSRA:
case tgtok::XSRL:
case tgtok::XSHL:
@@ -1239,9 +1248,9 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
return nullptr;
}
if (Code != BinOpInit::ADD && Code != BinOpInit::AND &&
- Code != BinOpInit::OR && Code != BinOpInit::SRA &&
- Code != BinOpInit::SRL && Code != BinOpInit::SHL &&
- Code != BinOpInit::MUL)
+ Code != BinOpInit::OR && Code != BinOpInit::XOR &&
+ Code != BinOpInit::SRA && Code != BinOpInit::SRL &&
+ Code != BinOpInit::SHL && Code != BinOpInit::MUL)
ArgType = Resolved;
}
@@ -1278,7 +1287,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
if (Code == BinOpInit::STRCONCAT || Code == BinOpInit::LISTCONCAT ||
Code == BinOpInit::CONCAT || Code == BinOpInit::ADD ||
Code == BinOpInit::AND || Code == BinOpInit::OR ||
- Code == BinOpInit::MUL) {
+ Code == BinOpInit::XOR || Code == BinOpInit::MUL) {
while (InitList.size() > 2) {
Init *RHS = InitList.pop_back_val();
RHS = (BinOpInit::get(Code, InitList.back(), RHS, Type))->Fold(CurRec);
@@ -2084,8 +2093,10 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
case tgtok::XDag:
case tgtok::XADD:
case tgtok::XMUL:
+ case tgtok::XNOT:
case tgtok::XAND:
case tgtok::XOR:
+ case tgtok::XXOR:
case tgtok::XSRA:
case tgtok::XSRL:
case tgtok::XSHL:
diff --git a/llvm/test/TableGen/arithmetic.td b/llvm/test/TableGen/arithmetic.td
index 50007c5f18a2..db268eef2f85 100644
--- a/llvm/test/TableGen/arithmetic.td
+++ b/llvm/test/TableGen/arithmetic.td
@@ -7,6 +7,7 @@
// CHECK: bits<8> add = { 0, 1, 0, 0, 0, 0, 0, 0 };
// CHECK: bits<8> and = { 0, 0, 0, 0, 0, 0, 0, 1 };
// CHECK: bits<8> or = { 0, 0, 1, 1, 1, 1, 1, 1 };
+// CHECK: bits<8> xor = { 0, 0, 1, 1, 1, 1, 1, 0 };
// CHECK: bits<8> srl = { 0, 0, 0, 1, 1, 1, 1, 1 };
// CHECK: bits<8> sra = { 0, 0, 0, 1, 1, 1, 1, 1 };
// CHECK: bits<8> shl = { 0, 1, 1, 1, 1, 1, 1, 0 };
@@ -17,6 +18,7 @@ class A<bits<8> a, bits<2> b> {
bits<8> add = !add(a, b);
bits<8> and = !and(a, b);
bits<8> or = !or(a, b);
+ bits<8> xor = !xor(a, b);
bits<8> srl = !srl(a, b);
bits<8> sra = !sra(a, b);
bits<8> shl = !shl(a, b);
diff --git a/llvm/test/TableGen/if.td b/llvm/test/TableGen/if.td
index 1fbee6966ff3..a3148494dd13 100644
--- a/llvm/test/TableGen/if.td
+++ b/llvm/test/TableGen/if.td
@@ -97,6 +97,39 @@ def E2d : E2<0>;
def EXd1 : EX<1, E1d, E2d>;
def EXd2 : EX<0, E1d, E2d>;
+// CHECK: def Not1
+// CHECK: Result1a = "OK"
+// CHECK: Result1b = "OK"
+// CHECK: Result1c = "OK"
+// CHECK: Result1d = "OK"
+// CHECK: Result1e = "OK"
+// CHECK: def Not2
+// CHECK: Result2a = "OK"
+// CHECK: Result2b = "OK"
+// CHECK: Result2c = "OK"
+// CHECK: Result2d = "OK"
+
+def Not1 {
+ bit true = 1;
+ string Result1a = !if(true, "OK", "not OK");
+ string Result1b = !if(!not(true), "not OK", "OK");
+
+ bit false = 0;
+ string Result1c = !if(false, "not OK", "OK");
+ string Result1d = !if(!not(false), "OK", "not OK");
+ string Result1e = !if(!not(!not(false)), "not OK", "OK");
+}
+
+def Not2 {
+ int one = 1;
+ string Result2a = !if(one, "OK", "not OK");
+ string Result2b = !if(!not(one), "not OK", "OK");
+
+ int zero = 0;
+ string Result2c = !if(zero, "not OK", "OK");
+ string Result2d = !if(!not(zero), "OK", "not OK");
+}
+
// CHECK: def One
// CHECK-NEXT: list<int> first = [1, 2, 3];
// CHECK-NEXT: list<int> rest = [1, 2, 3];
diff --git a/llvm/test/TableGen/math.td b/llvm/test/TableGen/math.td
index f7bda1ed1377..24a0e53a7916 100644
--- a/llvm/test/TableGen/math.td
+++ b/llvm/test/TableGen/math.td
@@ -71,6 +71,12 @@ def v1a : Int<!and(v7.Value, 5, v1.Value)>;
// CHECK: Value = 84
def v84 : Int<!mul(v12.Value, v7.Value)>;
+// CHECK: def v9
+// CHECK: Value = 9
+def v9 : Int<!xor(v7.Value, 0x0E)>;
+
// CHECK: def v924
// CHECK: Value = 924
def v924 : Int<!mul(v84.Value, 11)>;
+
+
More information about the llvm-commits
mailing list