@@ -1408,7 +1408,6 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
1408
1408
case tgtok::XListConcat:
1409
1409
case tgtok::XListSplat:
1410
1410
case tgtok::XListRemove:
1411
- case tgtok::XRange:
1412
1411
case tgtok::XStrConcat:
1413
1412
case tgtok::XInterleave:
1414
1413
case tgtok::XGetDagArg:
@@ -1440,8 +1439,9 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
1440
1439
case tgtok::XGt: Code = BinOpInit::GT; break ;
1441
1440
case tgtok::XListConcat: Code = BinOpInit::LISTCONCAT; break ;
1442
1441
case tgtok::XListSplat: Code = BinOpInit::LISTSPLAT; break ;
1443
- case tgtok::XListRemove: Code = BinOpInit::LISTREMOVE; break ;
1444
- case tgtok::XRange: Code = BinOpInit::RANGE; break ;
1442
+ case tgtok::XListRemove:
1443
+ Code = BinOpInit::LISTREMOVE;
1444
+ break ;
1445
1445
case tgtok::XStrConcat: Code = BinOpInit::STRCONCAT; break ;
1446
1446
case tgtok::XInterleave: Code = BinOpInit::INTERLEAVE; break ;
1447
1447
case tgtok::XSetDagOp: Code = BinOpInit::SETDAGOP; break ;
@@ -1508,10 +1508,6 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
1508
1508
// We don't know the list type until we parse the first argument.
1509
1509
ArgType = ItemType;
1510
1510
break ;
1511
- case tgtok::XRange:
1512
- Type = IntRecTy::get (Records)->getListTy ();
1513
- // ArgType may be either Int or List.
1514
- break ;
1515
1511
case tgtok::XStrConcat:
1516
1512
Type = StringRecTy::get (Records);
1517
1513
ArgType = StringRecTy::get (Records);
@@ -1596,27 +1592,6 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
1596
1592
return nullptr ;
1597
1593
}
1598
1594
break ;
1599
- case BinOpInit::RANGE:
1600
- if (InitList.size () == 1 ) {
1601
- if (isa<ListRecTy>(ArgType)) {
1602
- ArgType = nullptr ; // Detect error if 2nd arg were present.
1603
- } else if (isa<IntRecTy>(ArgType)) {
1604
- // Assume 2nd arg should be IntRecTy
1605
- } else {
1606
- Error (InitLoc,
1607
- Twine (" expected list or int, got value of type '" ) +
1608
- ArgType->getAsString () + " '" );
1609
- return nullptr ;
1610
- }
1611
- } else {
1612
- // Don't come here unless 1st arg is ListRecTy.
1613
- assert (isa<ListRecTy>(cast<TypedInit>(InitList[0 ])->getType ()));
1614
- Error (InitLoc,
1615
- Twine (" expected one list, got extra value of type '" ) +
1616
- ArgType->getAsString () + " '" );
1617
- return nullptr ;
1618
- }
1619
- break ;
1620
1595
case BinOpInit::EQ:
1621
1596
case BinOpInit::NE:
1622
1597
if (!ArgType->typeIsConvertibleTo (IntRecTy::get (Records)) &&
@@ -1726,37 +1701,6 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
1726
1701
if (Code == BinOpInit::LISTREMOVE)
1727
1702
Type = ArgType;
1728
1703
1729
- if (Code == BinOpInit::RANGE) {
1730
- Init *LHS, *RHS;
1731
- auto ArgCount = InitList.size ();
1732
- assert (ArgCount >= 1 );
1733
- auto *Arg0 = cast<TypedInit>(InitList[0 ]);
1734
- auto *Arg0Ty = Arg0->getType ();
1735
- if (ArgCount == 1 ) {
1736
- if (isa<ListRecTy>(Arg0Ty)) {
1737
- // (0, !size(arg))
1738
- LHS = IntInit::get (Records, 0 );
1739
- RHS = UnOpInit::get (UnOpInit::SIZE, Arg0, IntRecTy::get (Records))
1740
- ->Fold (CurRec);
1741
- } else {
1742
- assert (isa<IntRecTy>(Arg0Ty));
1743
- // (0, arg)
1744
- LHS = IntInit::get (Records, 0 );
1745
- RHS = Arg0;
1746
- }
1747
- } else if (ArgCount == 2 ) {
1748
- assert (isa<IntRecTy>(Arg0Ty));
1749
- auto *Arg1 = cast<TypedInit>(InitList[1 ]);
1750
- assert (isa<IntRecTy>(Arg1->getType ()));
1751
- LHS = Arg0;
1752
- RHS = Arg1;
1753
- } else {
1754
- Error (OpLoc, " expected at most two values of integer" );
1755
- return nullptr ;
1756
- }
1757
- return BinOpInit::get (Code, LHS, RHS, Type)->Fold (CurRec);
1758
- }
1759
-
1760
1704
// We allow multiple operands to associative operators like !strconcat as
1761
1705
// shorthand for nesting them.
1762
1706
if (Code == BinOpInit::STRCONCAT || Code == BinOpInit::LISTCONCAT ||
@@ -1783,6 +1727,105 @@ Init *TGParser::ParseOperation(Record *CurRec, RecTy *ItemType) {
1783
1727
return ParseOperationForEachFilter (CurRec, ItemType);
1784
1728
}
1785
1729
1730
+ case tgtok::XRange: {
1731
+ SMLoc OpLoc = Lex.getLoc ();
1732
+ Lex.Lex (); // eat the operation
1733
+
1734
+ if (!consume (tgtok::l_paren)) {
1735
+ TokError (" expected '(' after !range operator" );
1736
+ return nullptr ;
1737
+ }
1738
+
1739
+ SmallVector<Init *, 2 > Args;
1740
+ bool FirstArgIsList = false ;
1741
+ for (;;) {
1742
+ if (Args.size () >= 3 ) {
1743
+ TokError (" expected at most three values of integer" );
1744
+ return nullptr ;
1745
+ }
1746
+
1747
+ SMLoc InitLoc = Lex.getLoc ();
1748
+ Args.push_back (ParseValue (CurRec));
1749
+ if (!Args.back ())
1750
+ return nullptr ;
1751
+
1752
+ TypedInit *ArgBack = dyn_cast<TypedInit>(Args.back ());
1753
+ if (!ArgBack) {
1754
+ Error (OpLoc, Twine (" expected value to be a typed value, got '" +
1755
+ Args.back ()->getAsString () + " '" ));
1756
+ return nullptr ;
1757
+ }
1758
+
1759
+ RecTy *ArgBackType = ArgBack->getType ();
1760
+ if (!FirstArgIsList || Args.size () == 1 ) {
1761
+ if (Args.size () == 1 && isa<ListRecTy>(ArgBackType)) {
1762
+ FirstArgIsList = true ; // Detect error if 2nd arg were present.
1763
+ } else if (isa<IntRecTy>(ArgBackType)) {
1764
+ // Assume 2nd arg should be IntRecTy
1765
+ } else {
1766
+ if (Args.size () != 1 )
1767
+ Error (InitLoc, Twine (" expected value of type 'int', got '" +
1768
+ ArgBackType->getAsString () + " '" ));
1769
+ else
1770
+ Error (InitLoc, Twine (" expected list or int, got value of type '" ) +
1771
+ ArgBackType->getAsString () + " '" );
1772
+ return nullptr ;
1773
+ }
1774
+ } else {
1775
+ // Don't come here unless 1st arg is ListRecTy.
1776
+ assert (isa<ListRecTy>(cast<TypedInit>(Args[0 ])->getType ()));
1777
+ Error (InitLoc, Twine (" expected one list, got extra value of type '" ) +
1778
+ ArgBackType->getAsString () + " '" );
1779
+ return nullptr ;
1780
+ }
1781
+ if (!consume (tgtok::comma))
1782
+ break ;
1783
+ }
1784
+
1785
+ if (!consume (tgtok::r_paren)) {
1786
+ TokError (" expected ')' in operator" );
1787
+ return nullptr ;
1788
+ }
1789
+
1790
+ Init *LHS, *MHS, *RHS;
1791
+ auto ArgCount = Args.size ();
1792
+ assert (ArgCount >= 1 );
1793
+ auto *Arg0 = cast<TypedInit>(Args[0 ]);
1794
+ auto *Arg0Ty = Arg0->getType ();
1795
+ if (ArgCount == 1 ) {
1796
+ if (isa<ListRecTy>(Arg0Ty)) {
1797
+ // (0, !size(arg), 1)
1798
+ LHS = IntInit::get (Records, 0 );
1799
+ MHS = UnOpInit::get (UnOpInit::SIZE, Arg0, IntRecTy::get (Records))
1800
+ ->Fold (CurRec);
1801
+ RHS = IntInit::get (Records, 1 );
1802
+ } else {
1803
+ assert (isa<IntRecTy>(Arg0Ty));
1804
+ // (0, arg, 1)
1805
+ LHS = IntInit::get (Records, 0 );
1806
+ MHS = Arg0;
1807
+ RHS = IntInit::get (Records, 1 );
1808
+ }
1809
+ } else {
1810
+ assert (isa<IntRecTy>(Arg0Ty));
1811
+ auto *Arg1 = cast<TypedInit>(Args[1 ]);
1812
+ assert (isa<IntRecTy>(Arg1->getType ()));
1813
+ LHS = Arg0;
1814
+ MHS = Arg1;
1815
+ if (ArgCount == 3 ) {
1816
+ // (start, end, step)
1817
+ auto *Arg2 = cast<TypedInit>(Args[2 ]);
1818
+ assert (isa<IntRecTy>(Arg2->getType ()));
1819
+ RHS = Arg2;
1820
+ } else
1821
+ // (start, end, 1)
1822
+ RHS = IntInit::get (Records, 1 );
1823
+ }
1824
+ return TernOpInit::get (TernOpInit::RANGE, LHS, MHS, RHS,
1825
+ IntRecTy::get (Records)->getListTy ())
1826
+ ->Fold (CurRec);
1827
+ }
1828
+
1786
1829
case tgtok::XSetDagArg:
1787
1830
case tgtok::XSetDagName:
1788
1831
case tgtok::XDag:
@@ -2534,6 +2577,7 @@ Init *TGParser::ParseOperationCond(Record *CurRec, RecTy *ItemType) {
2534
2577
// / SimpleValue ::= LISTREMOVETOK '(' Value ',' Value ')'
2535
2578
// / SimpleValue ::= RANGE '(' Value ')'
2536
2579
// / SimpleValue ::= RANGE '(' Value ',' Value ')'
2580
+ // / SimpleValue ::= RANGE '(' Value ',' Value ',' Value ')'
2537
2581
// / SimpleValue ::= STRCONCATTOK '(' Value ',' Value ')'
2538
2582
// / SimpleValue ::= COND '(' [Value ':' Value,]+ ')'
2539
2583
// /
0 commit comments