summaryrefslogtreecommitdiff
path: root/utils/TableGen
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-10-05 23:58:18 +0000
committerChris Lattner <sabre@nondot.org>2010-10-05 23:58:18 +0000
commit8d978a75b477c0e4861d937096518eebba639e72 (patch)
tree6f3d80445489a8265336dd12af682f5d4b5d3d40 /utils/TableGen
parent3729d0052bda365d04fee900c6f3d09460f1e108 (diff)
downloadllvm-8d978a75b477c0e4861d937096518eebba639e72.tar.gz
llvm-8d978a75b477c0e4861d937096518eebba639e72.tar.bz2
llvm-8d978a75b477c0e4861d937096518eebba639e72.tar.xz
allow !strconcat to take more than two operands to eliminate
!strconcat(!strconcat(!strconcat(!strconcat Simplify some x86 td files to use it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@115719 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils/TableGen')
-rw-r--r--utils/TableGen/TGParser.cpp57
1 files changed, 34 insertions, 23 deletions
diff --git a/utils/TableGen/TGParser.cpp b/utils/TableGen/TGParser.cpp
index d3bd5cd710..0c46a814c2 100644
--- a/utils/TableGen/TGParser.cpp
+++ b/utils/TableGen/TGParser.cpp
@@ -16,6 +16,7 @@
#include "llvm/ADT/StringExtras.h"
#include <algorithm>
#include <sstream>
+#include "llvm/ADT/SmallVector.h"
using namespace llvm;
//===----------------------------------------------------------------------===//
@@ -798,53 +799,46 @@ Init *TGParser::ParseOperation(Record *CurRec) {
case tgtok::XEq:
case tgtok::XStrConcat:
case tgtok::XNameConcat: { // Value ::= !binop '(' Value ',' Value ')'
+ tgtok::TokKind OpTok = Lex.getCode();
+ SMLoc OpLoc = Lex.getLoc();
+ Lex.Lex(); // eat the operation
+
BinOpInit::BinaryOp Code;
RecTy *Type = 0;
-
- switch (Lex.getCode()) {
+ switch (OpTok) {
default: assert(0 && "Unhandled code!");
case tgtok::XConcat:
- Lex.Lex(); // eat the operation
Code = BinOpInit::CONCAT;
Type = new DagRecTy();
break;
case tgtok::XSRA:
- Lex.Lex(); // eat the operation
Code = BinOpInit::SRA;
Type = new IntRecTy();
break;
case tgtok::XSRL:
- Lex.Lex(); // eat the operation
Code = BinOpInit::SRL;
Type = new IntRecTy();
break;
case tgtok::XSHL:
- Lex.Lex(); // eat the operation
Code = BinOpInit::SHL;
Type = new IntRecTy();
break;
case tgtok::XEq:
- Lex.Lex(); // eat the operation
Code = BinOpInit::EQ;
Type = new IntRecTy();
break;
case tgtok::XStrConcat:
- Lex.Lex(); // eat the operation
Code = BinOpInit::STRCONCAT;
Type = new StringRecTy();
break;
case tgtok::XNameConcat:
- Lex.Lex(); // eat the operation
Code = BinOpInit::NAMECONCAT;
-
Type = ParseOperatorType();
-
if (Type == 0) {
TokError("did not get type for binary operator");
return 0;
}
-
break;
}
if (Lex.getCode() != tgtok::l_paren) {
@@ -853,24 +847,41 @@ Init *TGParser::ParseOperation(Record *CurRec) {
}
Lex.Lex(); // eat the '('
- Init *LHS = ParseValue(CurRec);
- if (LHS == 0) return 0;
+ SmallVector<Init*, 2> InitList;
+
+ InitList.push_back(ParseValue(CurRec));
+ if (InitList.back() == 0) return 0;
- if (Lex.getCode() != tgtok::comma) {
- TokError("expected ',' in binary operator");
- return 0;
- }
- Lex.Lex(); // eat the ','
+ while (Lex.getCode() == tgtok::comma) {
+ Lex.Lex(); // eat the ','
- Init *RHS = ParseValue(CurRec);
- if (RHS == 0) return 0;
+ InitList.push_back(ParseValue(CurRec));
+ if (InitList.back() == 0) return 0;
+ }
if (Lex.getCode() != tgtok::r_paren) {
- TokError("expected ')' in binary operator");
+ TokError("expected ')' in operator");
return 0;
}
Lex.Lex(); // eat the ')'
- return (new BinOpInit(Code, LHS, RHS, Type))->Fold(CurRec, CurMultiClass);
+
+ // We allow multiple operands to associative operators like !strconcat as
+ // shorthand for nesting them.
+ if (Code == BinOpInit::STRCONCAT) {
+ while (InitList.size() > 2) {
+ Init *RHS = InitList.pop_back_val();
+ RHS = (new BinOpInit(Code, InitList.back(), RHS, Type))
+ ->Fold(CurRec, CurMultiClass);
+ InitList.back() = RHS;
+ }
+ }
+
+ if (InitList.size() == 2)
+ return (new BinOpInit(Code, InitList[0], InitList[1], Type))
+ ->Fold(CurRec, CurMultiClass);
+
+ Error(OpLoc, "expected two operands to operator");
+ return 0;
}
case tgtok::XIf: