summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-03-31 21:53:49 +0000
committerChris Lattner <sabre@nondot.org>2006-03-31 21:53:49 +0000
commit711e5d96aa648ebe96b09483d0775f3b16283e3d (patch)
tree2f9b38953979af429047da5341e9d5a42a8d28fd /utils
parentfd2ae97ac3f317523a93d9037a8fe0ea6800eaca (diff)
downloadllvm-711e5d96aa648ebe96b09483d0775f3b16283e3d.tar.gz
llvm-711e5d96aa648ebe96b09483d0775f3b16283e3d.tar.bz2
llvm-711e5d96aa648ebe96b09483d0775f3b16283e3d.tar.xz
Generalize the previous binary operator support and add a string concatenation
operation. This implements Regression/TableGen/strconcat.td. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@27312 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/FileLexer.l1
-rw-r--r--utils/TableGen/FileParser.y22
-rw-r--r--utils/TableGen/Record.cpp84
-rw-r--r--utils/TableGen/Record.h40
4 files changed, 109 insertions, 38 deletions
diff --git a/utils/TableGen/FileLexer.l b/utils/TableGen/FileLexer.l
index 020a356b0b..3b60099bc1 100644
--- a/utils/TableGen/FileLexer.l
+++ b/utils/TableGen/FileLexer.l
@@ -202,6 +202,7 @@ in { return IN; }
!sra { return SRATOK; }
!srl { return SRLTOK; }
!shl { return SHLTOK; }
+!strconcat { return STRCONCATTOK; }
{Identifier} { Filelval.StrVal = new std::string(yytext, yytext+yyleng);
diff --git a/utils/TableGen/FileParser.y b/utils/TableGen/FileParser.y
index 11fda1ded0..aa8613952f 100644
--- a/utils/TableGen/FileParser.y
+++ b/utils/TableGen/FileParser.y
@@ -200,7 +200,7 @@ using namespace llvm;
};
%token INT BIT STRING BITS LIST CODE DAG CLASS DEF FIELD LET IN
-%token SHLTOK SRATOK SRLTOK
+%token SHLTOK SRATOK SRLTOK STRCONCATTOK
%token <IntVal> INTVAL
%token <StrVal> ID VARNAME STRVAL CODEFRAGMENT
@@ -352,23 +352,13 @@ Value : IDValue {
}
delete $3;
} | SHLTOK '(' Value ',' Value ')' {
- $$ = $3->getBinaryOp(Init::SHL, $5);
- if ($$ == 0) {
- err() << "Cannot shift values '" << *$3 << "' and '" << *$5 << "'!\n";
- exit(1);
- }
+ $$ = (new BinOpInit(BinOpInit::SHL, $3, $5))->Fold();
} | SRATOK '(' Value ',' Value ')' {
- $$ = $3->getBinaryOp(Init::SRA, $5);
- if ($$ == 0) {
- err() << "Cannot shift values '" << *$3 << "' and '" << *$5 << "'!\n";
- exit(1);
- }
+ $$ = (new BinOpInit(BinOpInit::SRA, $3, $5))->Fold();
} | SRLTOK '(' Value ',' Value ')' {
- $$ = $3->getBinaryOp(Init::SRL, $5);
- if ($$ == 0) {
- err() << "Cannot shift values '" << *$3 << "' and '" << *$5 << "'!\n";
- exit(1);
- }
+ $$ = (new BinOpInit(BinOpInit::SRL, $3, $5))->Fold();
+ } | STRCONCATTOK '(' Value ',' Value ')' {
+ $$ = (new BinOpInit(BinOpInit::STRCONCAT, $3, $5))->Fold();
};
OptVarName : /* empty */ {
diff --git a/utils/TableGen/Record.cpp b/utils/TableGen/Record.cpp
index 251b7a9d92..254ec78423 100644
--- a/utils/TableGen/Record.cpp
+++ b/utils/TableGen/Record.cpp
@@ -7,6 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
+// Implement the tablegen record classes.
//
//===----------------------------------------------------------------------===//
@@ -125,6 +126,19 @@ Init *IntRecTy::convertValue(TypedInit *TI) {
return 0;
}
+Init *StringRecTy::convertValue(BinOpInit *BO) {
+ if (BO->getOpcode() == BinOpInit::STRCONCAT) {
+ Init *L = BO->getLHS()->convertInitializerTo(this);
+ Init *R = BO->getRHS()->convertInitializerTo(this);
+ if (L == 0 || R == 0) return 0;
+ if (L != BO->getLHS() || R != BO->getRHS())
+ return new BinOpInit(BinOpInit::STRCONCAT, L, R);
+ return BO;
+ }
+ return 0;
+}
+
+
Init *StringRecTy::convertValue(TypedInit *TI) {
if (dynamic_cast<StringRecTy*>(TI->getType()))
return TI; // Accept variable if already of the right type!
@@ -299,21 +313,6 @@ Init *BitsInit::resolveReferences(Record &R, const RecordVal *RV) {
return this;
}
-Init *IntInit::getBinaryOp(BinaryOp Op, Init *RHS) {
- IntInit *RHSi = dynamic_cast<IntInit*>(RHS);
- if (RHSi == 0) return 0;
-
- int NewValue;
- switch (Op) {
- default: assert(0 && "Unknown binop");
- case SHL: NewValue = Value << RHSi->getValue(); break;
- case SRA: NewValue = Value >> RHSi->getValue(); break;
- case SRL: NewValue = (unsigned)Value >> (unsigned)RHSi->getValue(); break;
- }
- return new IntInit(NewValue);
-}
-
-
Init *IntInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) {
BitsInit *BI = new BitsInit(Bits.size());
@@ -368,6 +367,61 @@ void ListInit::print(std::ostream &OS) const {
OS << "]";
}
+Init *BinOpInit::Fold() {
+ switch (getOpcode()) {
+ default: assert(0 && "Unknown binop");
+ case STRCONCAT: {
+ StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
+ StringInit *RHSs = dynamic_cast<StringInit*>(RHS);
+ if (LHSs && RHSs)
+ return new StringInit(LHSs->getValue() + RHSs->getValue());
+ break;
+ }
+ case SHL:
+ case SRA:
+ case SRL: {
+ IntInit *LHSi = dynamic_cast<IntInit*>(LHS);
+ IntInit *RHSi = dynamic_cast<IntInit*>(RHS);
+ if (LHSi && RHSi) {
+ int LHSv = LHSi->getValue(), RHSv = RHSi->getValue();
+ int Result;
+ switch (getOpcode()) {
+ default: assert(0 && "Bad opcode!");
+ case SHL: Result = LHSv << RHSv; break;
+ case SRA: Result = LHSv >> RHSv; break;
+ case SRL: Result = (unsigned)LHSv >> (unsigned)RHSv; break;
+ }
+ return new IntInit(Result);
+ }
+ break;
+ }
+ }
+ return this;
+}
+
+Init *BinOpInit::resolveReferences(Record &R, const RecordVal *RV) {
+ Init *lhs = LHS->resolveReferences(R, RV);
+ Init *rhs = RHS->resolveReferences(R, RV);
+
+ if (LHS != lhs || RHS != rhs)
+ return (new BinOpInit(getOpcode(), lhs, rhs))->Fold();
+ return Fold();
+}
+
+void BinOpInit::print(std::ostream &OS) const {
+ switch (Opc) {
+ case SHL: OS << "!shl"; break;
+ case SRA: OS << "!sra"; break;
+ case SRL: OS << "!srl"; break;
+ case STRCONCAT: OS << "!strconcat"; break;
+ }
+ OS << "(";
+ LHS->print(OS);
+ OS << ", ";
+ RHS->print(OS);
+ OS << ")";
+}
+
Init *TypedInit::convertInitializerBitRange(const std::vector<unsigned> &Bits) {
BitsRecTy *T = dynamic_cast<BitsRecTy*>(getType());
if (T == 0) return 0; // Cannot subscript a non-bits variable...
diff --git a/utils/TableGen/Record.h b/utils/TableGen/Record.h
index 26a97013d7..f8a3c35b98 100644
--- a/utils/TableGen/Record.h
+++ b/utils/TableGen/Record.h
@@ -42,6 +42,7 @@ class IntInit;
class StringInit;
class CodeInit;
class ListInit;
+class BinOpInit;
class DefInit;
class DagInit;
class TypedInit;
@@ -75,6 +76,7 @@ public: // These methods should only be called from subclasses of Init
virtual Init *convertValue( IntInit *II) { return 0; }
virtual Init *convertValue(StringInit *SI) { return 0; }
virtual Init *convertValue( ListInit *LI) { return 0; }
+ virtual Init *convertValue( BinOpInit *UI) { return 0; }
virtual Init *convertValue( CodeInit *CI) { return 0; }
virtual Init *convertValue(VarBitInit *VB) { return 0; }
virtual Init *convertValue( DefInit *DI) { return 0; }
@@ -231,6 +233,7 @@ public:
virtual Init *convertValue( IntInit *II) { return 0; }
virtual Init *convertValue(StringInit *SI) { return (Init*)SI; }
virtual Init *convertValue( ListInit *LI) { return 0; }
+ virtual Init *convertValue( BinOpInit *BO);
virtual Init *convertValue( CodeInit *CI) { return 0; }
virtual Init *convertValue(VarBitInit *VB) { return 0; }
virtual Init *convertValue( DefInit *DI) { return 0; }
@@ -465,11 +468,6 @@ struct Init {
return 0;
}
- enum BinaryOp { SHL, SRA, SRL };
- virtual Init *getBinaryOp(BinaryOp Op, Init *RHS) {
- return 0;
- }
-
/// resolveReferences - This method is used by classes that refer to other
/// variables which may not be defined at the time they expression is formed.
/// If a value is set for the variable later, this method will be called on
@@ -570,8 +568,6 @@ public:
}
virtual Init *convertInitializerBitRange(const std::vector<unsigned> &Bits);
- virtual Init *getBinaryOp(BinaryOp Op, Init *RHS);
-
virtual void print(std::ostream &OS) const { OS << Value; }
};
@@ -639,6 +635,36 @@ public:
virtual void print(std::ostream &OS) const;
};
+/// BinOpInit - !op (X, Y) - Combine two inits.
+///
+class BinOpInit : public Init {
+public:
+ enum BinaryOp { SHL, SRA, SRL, STRCONCAT };
+private:
+ BinaryOp Opc;
+ Init *LHS, *RHS;
+public:
+ BinOpInit(BinaryOp opc, Init *lhs, Init *rhs) : Opc(opc), LHS(lhs), RHS(rhs) {
+ }
+
+ BinaryOp getOpcode() const { return Opc; }
+ Init *getLHS() const { return LHS; }
+ Init *getRHS() const { return RHS; }
+
+ // Fold - If possible, fold this to a simpler init. Return this if not
+ // possible to fold.
+ Init *Fold();
+
+ virtual Init *convertInitializerTo(RecTy *Ty) {
+ return Ty->convertValue(this);
+ }
+
+ virtual Init *resolveReferences(Record &R, const RecordVal *RV);
+
+ virtual void print(std::ostream &OS) const;
+};
+
+
/// TypedInit - This is the common super-class of types that have a specific,
/// explicit, type.