Add initial lexer and parser support for shifting values.  Every use of this
will lead to it being rejected though.

llvm-svn: 21335
diff --git a/llvm/utils/TableGen/FileLexer.l b/llvm/utils/TableGen/FileLexer.l
index 08daf2f..a433587 100644
--- a/llvm/utils/TableGen/FileLexer.l
+++ b/llvm/utils/TableGen/FileLexer.l
@@ -195,6 +195,11 @@
 let            { return LET; }
 in             { return IN; }
 
+!sra           { return SRATOK; }
+!srl           { return SRLTOK; }
+!shl           { return SHLTOK; }
+
+
 {Identifier}   { Filelval.StrVal = new std::string(yytext, yytext+yyleng);
                  return ID; }
 ${Identifier}  { Filelval.StrVal = new std::string(yytext+1, yytext+yyleng);
diff --git a/llvm/utils/TableGen/FileParser.y b/llvm/utils/TableGen/FileParser.y
index 8781049..e7d5032 100644
--- a/llvm/utils/TableGen/FileParser.y
+++ b/llvm/utils/TableGen/FileParser.y
@@ -189,6 +189,7 @@
 };
 
 %token INT BIT STRING BITS LIST CODE DAG CLASS DEF FIELD LET IN
+%token SHLTOK SRATOK SRLTOK
 %token <IntVal>      INTVAL
 %token <StrVal>      ID VARNAME STRVAL CODEFRAGMENT
 
@@ -308,6 +309,24 @@
       exit(1);
     }
     delete $3;
+  } | SHLTOK '(' Value ',' Value ')' {
+    $$ = $3->getBinaryOp(Init::SHL, $5);
+    if ($$ == 0) {
+      err() << "Cannot shift values '" << *$3 << "' and '" << *$5 << "'!\n";
+      exit(1);
+    }
+  } | SRATOK '(' Value ',' Value ')' {
+    $$ = $3->getBinaryOp(Init::SRA, $5);
+    if ($$ == 0) {
+      err() << "Cannot shift values '" << *$3 << "' and '" << *$5 << "'!\n";
+      exit(1);
+    }
+  } | SRLTOK '(' Value ',' Value ')' {
+    $$ = $3->getBinaryOp(Init::SRL, $5);
+    if ($$ == 0) {
+      err() << "Cannot shift values '" << *$3 << "' and '" << *$5 << "'!\n";
+      exit(1);
+    }
   };
 
 OptVarName : /* empty */ {
diff --git a/llvm/utils/TableGen/Record.h b/llvm/utils/TableGen/Record.h
index e2b9c0e..9c5166c 100644
--- a/llvm/utils/TableGen/Record.h
+++ b/llvm/utils/TableGen/Record.h
@@ -463,6 +463,11 @@
   virtual Init *getFieldInit(Record &R, const std::string &FieldName) const {
     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.