mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-10-09 12:24:08 +00:00
[TableGen] Change !getop and !setop to !getdagop and !setdagop.
Differential Revision: https://reviews.llvm.org/D89814
This commit is contained in:
parent
8a59d4b654
commit
876af264c1
@ -545,8 +545,8 @@ multiclass Reduction<Type Accumulator, string basename, list<Type> basetypes,
|
|||||||
defvar intArgsUnpred = !con(intArgsBase,
|
defvar intArgsUnpred = !con(intArgsBase,
|
||||||
!if(needSign, (? (unsignedflag Scalar)), (?)));
|
!if(needSign, (? (unsignedflag Scalar)), (?)));
|
||||||
defvar intArgsPred = !con(intArgsUnpred, (? $pred));
|
defvar intArgsPred = !con(intArgsUnpred, (? $pred));
|
||||||
defvar intUnpred = !setop(intArgsUnpred, IRInt<basename, basetypes>);
|
defvar intUnpred = !setdagop(intArgsUnpred, IRInt<basename, basetypes>);
|
||||||
defvar intPred = !setop(intArgsPred, IRInt<
|
defvar intPred = !setdagop(intArgsPred, IRInt<
|
||||||
basename#"_predicated", !listconcat(basetypes, [Predicate])>);
|
basename#"_predicated", !listconcat(basetypes, [Predicate])>);
|
||||||
|
|
||||||
def "": Intrinsic<
|
def "": Intrinsic<
|
||||||
|
@ -206,13 +206,13 @@ TableGen provides "bang operators" that have a wide variety of uses:
|
|||||||
|
|
||||||
.. productionlist::
|
.. productionlist::
|
||||||
BangOperator: one of
|
BangOperator: one of
|
||||||
: !add !and !cast !con !dag
|
: !add !and !cast !con !dag
|
||||||
: !empty !eq !foldl !foreach !ge
|
: !empty !eq !foldl !foreach !ge
|
||||||
: !getop !gt !head !if !isa
|
: !getdagop !gt !head !if !isa
|
||||||
: !le !listconcat !listsplat !lt !mul
|
: !le !listconcat !listsplat !lt !mul
|
||||||
: !ne !not !or !setop !shl
|
: !ne !not !or !setdagop !shl
|
||||||
: !size !sra !srl !strconcat !subst
|
: !size !sra !srl !strconcat !subst
|
||||||
: !tail !xor
|
: !tail !xor
|
||||||
|
|
||||||
The ``!cond`` operator has a slightly different
|
The ``!cond`` operator has a slightly different
|
||||||
syntax compared to other bang operators, so it is defined separately:
|
syntax compared to other bang operators, so it is defined separately:
|
||||||
@ -1243,7 +1243,7 @@ or to associate an argument in one DAG with a like-named argument in another
|
|||||||
DAG.
|
DAG.
|
||||||
|
|
||||||
The following bang operators are useful for working with DAGs:
|
The following bang operators are useful for working with DAGs:
|
||||||
``!con``, ``!dag``, ``!empty``, ``!foreach``, ``!getop``, ``!setop``, ``!size``.
|
``!con``, ``!dag``, ``!empty``, ``!foreach``, ``!getdagop``, ``!setdagop``, ``!size``.
|
||||||
|
|
||||||
Defvar in a record body
|
Defvar in a record body
|
||||||
-----------------------
|
-----------------------
|
||||||
@ -1445,6 +1445,10 @@ operator produces a boolean result, the result value will be 1 for true or 0
|
|||||||
for false. When an operator tests a boolean argument, it interprets 0 as false
|
for false. When an operator tests a boolean argument, it interprets 0 as false
|
||||||
and non-0 as true.
|
and non-0 as true.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
The ``!getop`` and ``!setop`` bang operators are deprecated in favor of
|
||||||
|
``!getdagop`` and ``!setdagop``.
|
||||||
|
|
||||||
``!add(``\ *a*\ ``,`` *b*\ ``, ...)``
|
``!add(``\ *a*\ ``,`` *b*\ ``, ...)``
|
||||||
This operator adds *a*, *b*, etc., and produces the sum.
|
This operator adds *a*, *b*, etc., and produces the sum.
|
||||||
|
|
||||||
@ -1544,26 +1548,27 @@ and non-0 as true.
|
|||||||
The arguments must be ``bit``, ``int``, or ``string`` values.
|
The arguments must be ``bit``, ``int``, or ``string`` values.
|
||||||
Use ``!cast<string>`` to compare other types of objects.
|
Use ``!cast<string>`` to compare other types of objects.
|
||||||
|
|
||||||
``!getop(``\ *dag*\ ``)`` --or-- ``!getop<``\ *type*\ ``>(``\ *dag*\ ``)``
|
``!getdagop(``\ *dag*\ ``)`` --or-- ``!getdagop<``\ *type*\ ``>(``\ *dag*\ ``)``
|
||||||
This operator produces the operator of the given *dag* node.
|
This operator produces the operator of the given *dag* node.
|
||||||
Example: ``!getop((foo 1, 2))`` results in ``foo``.
|
Example: ``!getdagop((foo 1, 2))`` results in ``foo``. Recall that
|
||||||
|
DAG operators are always records.
|
||||||
|
|
||||||
The result of ``!getop`` can be used directly in a context where
|
The result of ``!getdagop`` can be used directly in a context where
|
||||||
any record value at all is acceptable (typically placing it into
|
any record class at all is acceptable (typically placing it into
|
||||||
another dag value). But in other contexts, it must be explicitly
|
another dag value). But in other contexts, it must be explicitly
|
||||||
cast to a particular class type. The ``<``\ *type*\ ``>`` syntax is
|
cast to a particular class. The ``<``\ *type*\ ``>`` syntax is
|
||||||
provided to make this easy.
|
provided to make this easy.
|
||||||
|
|
||||||
For example, to assign the result to a value of type ``BaseClass``, you
|
For example, to assign the result to a value of type ``BaseClass``, you
|
||||||
could write either of these::
|
could write either of these::
|
||||||
|
|
||||||
BaseClass b = !getop<BaseClass>(someDag);
|
BaseClass b = !getdagop<BaseClass>(someDag);
|
||||||
BaseClass b = !cast<BaseClass>(!getop(someDag));
|
BaseClass b = !cast<BaseClass>(!getdagop(someDag));
|
||||||
|
|
||||||
But to create a new DAG node that reuses the operator from another, no
|
But to create a new DAG node that reuses the operator from another, no
|
||||||
cast is necessary::
|
cast is necessary::
|
||||||
|
|
||||||
dag d = !dag(!getop(someDag), args, names);
|
dag d = !dag(!getdagop(someDag), args, names);
|
||||||
|
|
||||||
``!gt(``\ *a*\ `,` *b*\ ``)``
|
``!gt(``\ *a*\ `,` *b*\ ``)``
|
||||||
This operator produces 1 if *a* is greater than *b*; 0 otherwise.
|
This operator produces 1 if *a* is greater than *b*; 0 otherwise.
|
||||||
@ -1620,11 +1625,11 @@ and non-0 as true.
|
|||||||
result. A logical OR can be performed if all the arguments are either
|
result. A logical OR can be performed if all the arguments are either
|
||||||
0 or 1.
|
0 or 1.
|
||||||
|
|
||||||
``!setop(``\ *dag*\ ``,`` *op*\ ``)``
|
``!setdagop(``\ *dag*\ ``,`` *op*\ ``)``
|
||||||
This operator produces a DAG node with the same arguments as *dag*, but with its
|
This operator produces a DAG node with the same arguments as *dag*, but with its
|
||||||
operator replaced with *op*.
|
operator replaced with *op*.
|
||||||
|
|
||||||
Example: ``!setop((foo 1, 2), bar)`` results in ``(bar 1, 2)``.
|
Example: ``!setdagop((foo 1, 2), bar)`` results in ``(bar 1, 2)``.
|
||||||
|
|
||||||
``!shl(``\ *a*\ ``,`` *count*\ ``)``
|
``!shl(``\ *a*\ ``,`` *count*\ ``)``
|
||||||
This operator shifts *a* left logically by *count* bits and produces the resulting
|
This operator shifts *a* left logically by *count* bits and produces the resulting
|
||||||
|
@ -759,7 +759,7 @@ public:
|
|||||||
///
|
///
|
||||||
class UnOpInit : public OpInit, public FoldingSetNode {
|
class UnOpInit : public OpInit, public FoldingSetNode {
|
||||||
public:
|
public:
|
||||||
enum UnaryOp : uint8_t { CAST, NOT, HEAD, TAIL, SIZE, EMPTY, GETOP };
|
enum UnaryOp : uint8_t { CAST, NOT, HEAD, TAIL, SIZE, EMPTY, GETDAGOP };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Init *LHS;
|
Init *LHS;
|
||||||
@ -810,7 +810,7 @@ class BinOpInit : public OpInit, public FoldingSetNode {
|
|||||||
public:
|
public:
|
||||||
enum BinaryOp : uint8_t { ADD, MUL, AND, OR, XOR, 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,
|
LISTSPLAT, STRCONCAT, CONCAT, EQ, NE, LE, LT, GE,
|
||||||
GT, SETOP };
|
GT, SETDAGOP };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Init *LHS, *RHS;
|
Init *LHS, *RHS;
|
||||||
|
@ -801,7 +801,7 @@ Init *UnOpInit::Fold(Record *CurRec, bool IsFinal) const {
|
|||||||
return IntInit::get(LHSs->getValue().empty());
|
return IntInit::get(LHSs->getValue().empty());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GETOP:
|
case GETDAGOP:
|
||||||
if (DagInit *Dag = dyn_cast<DagInit>(LHS)) {
|
if (DagInit *Dag = dyn_cast<DagInit>(LHS)) {
|
||||||
DefInit *DI = DefInit::get(Dag->getOperatorAsDef({}));
|
DefInit *DI = DefInit::get(Dag->getOperatorAsDef({}));
|
||||||
if (!DI->getType()->typeIsA(getType())) {
|
if (!DI->getType()->typeIsA(getType())) {
|
||||||
@ -837,7 +837,7 @@ std::string UnOpInit::getAsString() const {
|
|||||||
case TAIL: Result = "!tail"; break;
|
case TAIL: Result = "!tail"; break;
|
||||||
case SIZE: Result = "!size"; break;
|
case SIZE: Result = "!size"; break;
|
||||||
case EMPTY: Result = "!empty"; break;
|
case EMPTY: Result = "!empty"; break;
|
||||||
case GETOP: Result = "!getop"; break;
|
case GETDAGOP: Result = "!getdagop"; break;
|
||||||
}
|
}
|
||||||
return Result + "(" + LHS->getAsString() + ")";
|
return Result + "(" + LHS->getAsString() + ")";
|
||||||
}
|
}
|
||||||
@ -1009,7 +1009,7 @@ Init *BinOpInit::Fold(Record *CurRec) const {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SETOP: {
|
case SETDAGOP: {
|
||||||
DagInit *Dag = dyn_cast<DagInit>(LHS);
|
DagInit *Dag = dyn_cast<DagInit>(LHS);
|
||||||
DefInit *Op = dyn_cast<DefInit>(RHS);
|
DefInit *Op = dyn_cast<DefInit>(RHS);
|
||||||
if (Dag && Op) {
|
if (Dag && Op) {
|
||||||
@ -1088,7 +1088,7 @@ std::string BinOpInit::getAsString() const {
|
|||||||
case LISTCONCAT: Result = "!listconcat"; break;
|
case LISTCONCAT: Result = "!listconcat"; break;
|
||||||
case LISTSPLAT: Result = "!listsplat"; break;
|
case LISTSPLAT: Result = "!listsplat"; break;
|
||||||
case STRCONCAT: Result = "!strconcat"; break;
|
case STRCONCAT: Result = "!strconcat"; break;
|
||||||
case SETOP: Result = "!setop"; break;
|
case SETDAGOP: Result = "!setdagop"; break;
|
||||||
}
|
}
|
||||||
return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")";
|
return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")";
|
||||||
}
|
}
|
||||||
|
@ -578,8 +578,8 @@ tgtok::TokKind TGLexer::LexExclaim() {
|
|||||||
.Case("listconcat", tgtok::XListConcat)
|
.Case("listconcat", tgtok::XListConcat)
|
||||||
.Case("listsplat", tgtok::XListSplat)
|
.Case("listsplat", tgtok::XListSplat)
|
||||||
.Case("strconcat", tgtok::XStrConcat)
|
.Case("strconcat", tgtok::XStrConcat)
|
||||||
.Case("setop", tgtok::XSetOp)
|
.Cases("setdagop", "setop", tgtok::XSetDagOp) // !setop is deprecated.
|
||||||
.Case("getop", tgtok::XGetOp)
|
.Cases("getdagop", "getop", tgtok::XGetDagOp) // !getop is deprecated.
|
||||||
.Default(tgtok::Error);
|
.Default(tgtok::Error);
|
||||||
|
|
||||||
return Kind != tgtok::Error ? Kind : ReturnError(Start-1, "Unknown operator");
|
return Kind != tgtok::Error ? Kind : ReturnError(Start-1, "Unknown operator");
|
||||||
|
@ -54,7 +54,7 @@ namespace tgtok {
|
|||||||
XConcat, XADD, XMUL, XNOT, XAND, XOR, XXOR, XSRA, XSRL, XSHL,
|
XConcat, XADD, XMUL, XNOT, XAND, XOR, XXOR, XSRA, XSRL, XSHL,
|
||||||
XListConcat, XListSplat, XStrConcat, XCast, XSubst, XForEach, XFoldl,
|
XListConcat, XListSplat, XStrConcat, XCast, XSubst, XForEach, XFoldl,
|
||||||
XHead, XTail, XSize, XEmpty, XIf, XCond, XEq, XIsA, XDag, XNe, XLe,
|
XHead, XTail, XSize, XEmpty, XIf, XCond, XEq, XIsA, XDag, XNe, XLe,
|
||||||
XLt, XGe, XGt, XSetOp, XGetOp,
|
XLt, XGe, XGt, XSetDagOp, XGetDagOp,
|
||||||
|
|
||||||
// Integer value.
|
// Integer value.
|
||||||
IntVal,
|
IntVal,
|
||||||
|
@ -813,12 +813,12 @@ RecTy *TGParser::ParseType() {
|
|||||||
TokError("expected '<' after bits type");
|
TokError("expected '<' after bits type");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (Lex.Lex() != tgtok::IntVal) { // Eat '<'
|
if (Lex.Lex() != tgtok::IntVal) { // Eat '<'
|
||||||
TokError("expected integer in bits<n> type");
|
TokError("expected integer in bits<n> type");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
uint64_t Val = Lex.getCurIntVal();
|
uint64_t Val = Lex.getCurIntVal();
|
||||||
if (Lex.Lex() != tgtok::greater) { // Eat count.
|
if (Lex.Lex() != tgtok::greater) { // Eat count.
|
||||||
TokError("expected '>' at end of bits<n> type");
|
TokError("expected '>' at end of bits<n> type");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -914,7 +914,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
|
|||||||
case tgtok::XSize:
|
case tgtok::XSize:
|
||||||
case tgtok::XEmpty:
|
case tgtok::XEmpty:
|
||||||
case tgtok::XCast:
|
case tgtok::XCast:
|
||||||
case tgtok::XGetOp: { // Value ::= !unop '(' Value ')'
|
case tgtok::XGetDagOp: { // Value ::= !unop '(' Value ')'
|
||||||
UnOpInit::UnaryOp Code;
|
UnOpInit::UnaryOp Code;
|
||||||
RecTy *Type = nullptr;
|
RecTy *Type = nullptr;
|
||||||
|
|
||||||
@ -955,12 +955,12 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
|
|||||||
Code = UnOpInit::EMPTY;
|
Code = UnOpInit::EMPTY;
|
||||||
Type = IntRecTy::get();
|
Type = IntRecTy::get();
|
||||||
break;
|
break;
|
||||||
case tgtok::XGetOp:
|
case tgtok::XGetDagOp:
|
||||||
Lex.Lex(); // eat the operation
|
Lex.Lex(); // eat the operation
|
||||||
if (Lex.getCode() == tgtok::less) {
|
if (Lex.getCode() == tgtok::less) {
|
||||||
// Parse an optional type suffix, so that you can say
|
// Parse an optional type suffix, so that you can say
|
||||||
// !getop<BaseClass>(someDag) as a shorthand for
|
// !getdagop<BaseClass>(someDag) as a shorthand for
|
||||||
// !cast<BaseClass>(!getop(someDag)).
|
// !cast<BaseClass>(!getdagop(someDag)).
|
||||||
Type = ParseOperatorType();
|
Type = ParseOperatorType();
|
||||||
|
|
||||||
if (!Type) {
|
if (!Type) {
|
||||||
@ -969,13 +969,13 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isa<RecordRecTy>(Type)) {
|
if (!isa<RecordRecTy>(Type)) {
|
||||||
TokError("type for !getop must be a record type");
|
TokError("type for !getdagop must be a record type");
|
||||||
// but keep parsing, to consume the operand
|
// but keep parsing, to consume the operand
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Type = RecordRecTy::get({});
|
Type = RecordRecTy::get({});
|
||||||
}
|
}
|
||||||
Code = UnOpInit::GETOP;
|
Code = UnOpInit::GETDAGOP;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!consume(tgtok::l_paren)) {
|
if (!consume(tgtok::l_paren)) {
|
||||||
@ -1091,7 +1091,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
|
|||||||
case tgtok::XListConcat:
|
case tgtok::XListConcat:
|
||||||
case tgtok::XListSplat:
|
case tgtok::XListSplat:
|
||||||
case tgtok::XStrConcat:
|
case tgtok::XStrConcat:
|
||||||
case tgtok::XSetOp: { // Value ::= !binop '(' Value ',' Value ')'
|
case tgtok::XSetDagOp: { // Value ::= !binop '(' Value ',' Value ')'
|
||||||
tgtok::TokKind OpTok = Lex.getCode();
|
tgtok::TokKind OpTok = Lex.getCode();
|
||||||
SMLoc OpLoc = Lex.getLoc();
|
SMLoc OpLoc = Lex.getLoc();
|
||||||
Lex.Lex(); // eat the operation
|
Lex.Lex(); // eat the operation
|
||||||
@ -1115,9 +1115,9 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
|
|||||||
case tgtok::XGe: Code = BinOpInit::GE; break;
|
case tgtok::XGe: Code = BinOpInit::GE; break;
|
||||||
case tgtok::XGt: Code = BinOpInit::GT; break;
|
case tgtok::XGt: Code = BinOpInit::GT; break;
|
||||||
case tgtok::XListConcat: Code = BinOpInit::LISTCONCAT; break;
|
case tgtok::XListConcat: Code = BinOpInit::LISTCONCAT; break;
|
||||||
case tgtok::XListSplat: Code = BinOpInit::LISTSPLAT; break;
|
case tgtok::XListSplat: Code = BinOpInit::LISTSPLAT; break;
|
||||||
case tgtok::XStrConcat: Code = BinOpInit::STRCONCAT; break;
|
case tgtok::XStrConcat: Code = BinOpInit::STRCONCAT; break;
|
||||||
case tgtok::XSetOp: Code = BinOpInit::SETOP; break;
|
case tgtok::XSetDagOp: Code = BinOpInit::SETDAGOP; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
RecTy *Type = nullptr;
|
RecTy *Type = nullptr;
|
||||||
@ -1126,7 +1126,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
|
|||||||
default:
|
default:
|
||||||
llvm_unreachable("Unhandled code!");
|
llvm_unreachable("Unhandled code!");
|
||||||
case tgtok::XConcat:
|
case tgtok::XConcat:
|
||||||
case tgtok::XSetOp:
|
case tgtok::XSetDagOp:
|
||||||
Type = DagRecTy::get();
|
Type = DagRecTy::get();
|
||||||
ArgType = DagRecTy::get();
|
ArgType = DagRecTy::get();
|
||||||
break;
|
break;
|
||||||
@ -1259,7 +1259,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
|
|||||||
// Deal with BinOps whose arguments have different types, by
|
// Deal with BinOps whose arguments have different types, by
|
||||||
// rewriting ArgType in between them.
|
// rewriting ArgType in between them.
|
||||||
switch (Code) {
|
switch (Code) {
|
||||||
case BinOpInit::SETOP:
|
case BinOpInit::SETDAGOP:
|
||||||
// After parsing the first dag argument, switch to expecting
|
// After parsing the first dag argument, switch to expecting
|
||||||
// a record, with no restriction on its superclasses.
|
// a record, with no restriction on its superclasses.
|
||||||
ArgType = RecordRecTy::get({});
|
ArgType = RecordRecTy::get({});
|
||||||
@ -1417,7 +1417,7 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
|
|||||||
|
|
||||||
case tgtok::XDag:
|
case tgtok::XDag:
|
||||||
case tgtok::XIf:
|
case tgtok::XIf:
|
||||||
case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')'
|
case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')'
|
||||||
TernOpInit::TernaryOp Code;
|
TernOpInit::TernaryOp Code;
|
||||||
RecTy *Type = nullptr;
|
RecTy *Type = nullptr;
|
||||||
|
|
||||||
@ -2051,7 +2051,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
|
|||||||
case tgtok::l_paren: { // Value ::= '(' IDValue DagArgList ')'
|
case tgtok::l_paren: { // Value ::= '(' IDValue DagArgList ')'
|
||||||
Lex.Lex(); // eat the '('
|
Lex.Lex(); // eat the '('
|
||||||
if (Lex.getCode() != tgtok::Id && Lex.getCode() != tgtok::XCast &&
|
if (Lex.getCode() != tgtok::Id && Lex.getCode() != tgtok::XCast &&
|
||||||
Lex.getCode() != tgtok::question && Lex.getCode() != tgtok::XGetOp) {
|
Lex.getCode() != tgtok::question && Lex.getCode() != tgtok::XGetDagOp) {
|
||||||
TokError("expected identifier in dag init");
|
TokError("expected identifier in dag init");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -2089,7 +2089,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
|
|||||||
case tgtok::XSize:
|
case tgtok::XSize:
|
||||||
case tgtok::XEmpty:
|
case tgtok::XEmpty:
|
||||||
case tgtok::XCast:
|
case tgtok::XCast:
|
||||||
case tgtok::XGetOp: // Value ::= !unop '(' Value ')'
|
case tgtok::XGetDagOp: // Value ::= !unop '(' Value ')'
|
||||||
case tgtok::XIsA:
|
case tgtok::XIsA:
|
||||||
case tgtok::XConcat:
|
case tgtok::XConcat:
|
||||||
case tgtok::XDag:
|
case tgtok::XDag:
|
||||||
@ -2111,12 +2111,12 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
|
|||||||
case tgtok::XListConcat:
|
case tgtok::XListConcat:
|
||||||
case tgtok::XListSplat:
|
case tgtok::XListSplat:
|
||||||
case tgtok::XStrConcat:
|
case tgtok::XStrConcat:
|
||||||
case tgtok::XSetOp: // Value ::= !binop '(' Value ',' Value ')'
|
case tgtok::XSetDagOp: // Value ::= !binop '(' Value ',' Value ')'
|
||||||
case tgtok::XIf:
|
case tgtok::XIf:
|
||||||
case tgtok::XCond:
|
case tgtok::XCond:
|
||||||
case tgtok::XFoldl:
|
case tgtok::XFoldl:
|
||||||
case tgtok::XForEach:
|
case tgtok::XForEach:
|
||||||
case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')'
|
case tgtok::XSubst: { // Value ::= !ternop '(' Value ',' Value ',' Value ')'
|
||||||
return ParseOperation(CurRec, ItemType);
|
return ParseOperation(CurRec, ItemType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2186,7 +2186,7 @@ Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case tgtok::dot: {
|
case tgtok::dot: {
|
||||||
if (Lex.Lex() != tgtok::Id) { // eat the .
|
if (Lex.Lex() != tgtok::Id) { // eat the .
|
||||||
TokError("expected field identifier after '.'");
|
TokError("expected field identifier after '.'");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -3033,7 +3033,7 @@ multiclass MVE_VSHRN_patterns<MVE_shift_imm_partial inst,
|
|||||||
defvar outparams = (inst (OutVTI.Vec MQPR:$QdSrc), (InVTI.Vec MQPR:$Qm),
|
defvar outparams = (inst (OutVTI.Vec MQPR:$QdSrc), (InVTI.Vec MQPR:$Qm),
|
||||||
(imm:$imm));
|
(imm:$imm));
|
||||||
|
|
||||||
def : Pat<(OutVTI.Vec !setop(inparams, int_arm_mve_vshrn)),
|
def : Pat<(OutVTI.Vec !setdagop(inparams, int_arm_mve_vshrn)),
|
||||||
(OutVTI.Vec outparams)>;
|
(OutVTI.Vec outparams)>;
|
||||||
def : Pat<(OutVTI.Vec !con(inparams, (int_arm_mve_vshrn_predicated
|
def : Pat<(OutVTI.Vec !con(inparams, (int_arm_mve_vshrn_predicated
|
||||||
(InVTI.Pred VCCR:$pred)))),
|
(InVTI.Pred VCCR:$pred)))),
|
||||||
@ -3235,7 +3235,7 @@ multiclass MVE_VSxI_patterns<MVE_VSxI_imm inst, string name,
|
|||||||
defvar unpred_int = !cast<Intrinsic>("int_arm_mve_" # name);
|
defvar unpred_int = !cast<Intrinsic>("int_arm_mve_" # name);
|
||||||
defvar pred_int = !cast<Intrinsic>("int_arm_mve_" # name # "_predicated");
|
defvar pred_int = !cast<Intrinsic>("int_arm_mve_" # name # "_predicated");
|
||||||
|
|
||||||
def : Pat<(VTI.Vec !setop(inparams, unpred_int)),
|
def : Pat<(VTI.Vec !setdagop(inparams, unpred_int)),
|
||||||
(VTI.Vec outparams)>;
|
(VTI.Vec outparams)>;
|
||||||
def : Pat<(VTI.Vec !con(inparams, (pred_int (VTI.Pred VCCR:$pred)))),
|
def : Pat<(VTI.Vec !con(inparams, (pred_int (VTI.Pred VCCR:$pred)))),
|
||||||
(VTI.Vec !con(outparams, (? ARMVCCThen, VCCR:$pred)))>;
|
(VTI.Vec !con(outparams, (? ARMVCCThen, VCCR:$pred)))>;
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
// RUN: not llvm-tblgen -DERROR2 %s 2>&1 | FileCheck --check-prefix=ERROR2 %s
|
// RUN: not llvm-tblgen -DERROR2 %s 2>&1 | FileCheck --check-prefix=ERROR2 %s
|
||||||
// RUN: not llvm-tblgen -DERROR3 %s 2>&1 | FileCheck --check-prefix=ERROR3 %s
|
// RUN: not llvm-tblgen -DERROR3 %s 2>&1 | FileCheck --check-prefix=ERROR3 %s
|
||||||
|
|
||||||
|
// !setop and !getop are deprecated in favor of !setdagop and !getdagop.
|
||||||
|
// Two tests retain the old names just to be sure they are still supported.
|
||||||
|
|
||||||
class Base;
|
class Base;
|
||||||
class OtherBase;
|
class OtherBase;
|
||||||
|
|
||||||
@ -18,28 +21,28 @@ def test {
|
|||||||
dag replaceWithBar = !setop(orig, bar);
|
dag replaceWithBar = !setop(orig, bar);
|
||||||
|
|
||||||
// CHECK: dag replaceWithBaz = (qux 1, 2:$a, ?:$b);
|
// CHECK: dag replaceWithBaz = (qux 1, 2:$a, ?:$b);
|
||||||
dag replaceWithBaz = !setop(orig, qux);
|
dag replaceWithBaz = !setdagop(orig, qux);
|
||||||
|
|
||||||
// CHECK: Base getopWithCast = foo;
|
// CHECK: Base getopWithCast = foo;
|
||||||
Base getopWithCast = !getop<Base>(orig);
|
Base getopWithCast = !getop<Base>(orig);
|
||||||
|
|
||||||
// CHECK: dag getopToSetop = (foo "hello", ?:$world);
|
// CHECK: dag getopToSetop = (foo "hello", ?:$world);
|
||||||
dag getopToSetop = !setop(another, !getop(orig));
|
dag getopToSetop = !setdagop(another, !getdagop(orig));
|
||||||
|
|
||||||
// CHECK: dag getopToBangDag = (foo 1:$a, 2:$b, 3:$c);
|
// CHECK: dag getopToBangDag = (foo 1:$a, 2:$b, 3:$c);
|
||||||
dag getopToBangDag = !dag(!getop(orig), [1, 2, 3], ["a", "b", "c"]);
|
dag getopToBangDag = !dag(!getdagop(orig), [1, 2, 3], ["a", "b", "c"]);
|
||||||
|
|
||||||
// CHECK: dag getopToDagInit = (foo "it worked");
|
// CHECK: dag getopToDagInit = (foo "it worked");
|
||||||
dag getopToDagInit = (!getop(orig) "it worked");
|
dag getopToDagInit = (!getdagop(orig) "it worked");
|
||||||
|
|
||||||
#ifdef ERROR1
|
#ifdef ERROR1
|
||||||
// !getop(...) has a static type of 'any record at all, with no
|
// !getdagop(...) has a static type of 'any record at all, with no
|
||||||
// required superclasses'. That's too general to use in an
|
// required superclasses'. That's too general to use in an
|
||||||
// assignment whose LHS demands an instance of Base, so we expect a
|
// assignment whose LHS demands an instance of Base, so we expect a
|
||||||
// static (parse-time) type-checking error.
|
// static (parse-time) type-checking error.
|
||||||
|
|
||||||
// ERROR1: error: Field 'noCast' of type 'Base' is incompatible with value '!getop(orig)' of type '{}'
|
// ERROR1: error: Field 'noCast' of type 'Base' is incompatible with value '!getdagop(orig)' of type '{}'
|
||||||
Base noCast = !getop(orig);
|
Base noCast = !getdagop(orig);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ERROR2
|
#ifdef ERROR2
|
||||||
@ -47,15 +50,15 @@ def test {
|
|||||||
// evaluation time that the operator of 'another' is a record that
|
// evaluation time that the operator of 'another' is a record that
|
||||||
// isn't an instance of the specified base class.
|
// isn't an instance of the specified base class.
|
||||||
|
|
||||||
// ERROR2: error: Expected type 'Base', got 'OtherBase' in: !getop((qux "hello", ?:$world))
|
// ERROR2: error: Expected type 'Base', got 'OtherBase' in: !getdagop((qux "hello", ?:$world))
|
||||||
Base badCast = !getop<Base>(another);
|
Base badCast = !getdagop<Base>(another);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ERROR3
|
#ifdef ERROR3
|
||||||
// Obviously, you shouldn't be able to give any type to !getop that
|
// Obviously, you shouldn't be able to give any type to !getdagop that
|
||||||
// isn't a class type.
|
// isn't a class type.
|
||||||
|
|
||||||
// ERROR3: error: type for !getop must be a record type
|
// ERROR3: error: type for !getdagop must be a record type
|
||||||
int ridiculousCast = !getop<int>(orig);
|
int ridiculousCast = !getdagop<int>(orig);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user