Implement !cast.
authorDavid Greene <greened@obbligato.org>
Thu, 14 May 2009 21:22:49 +0000 (21:22 +0000)
committerDavid Greene <greened@obbligato.org>
Thu, 14 May 2009 21:22:49 +0000 (21:22 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@71794 91177308-0d34-0410-b5e6-96231b3b80d8

docs/TableGenFundamentals.html
test/TableGen/cast.td [new file with mode: 0644]
utils/TableGen/Record.cpp
utils/TableGen/Record.h
utils/TableGen/TGLexer.cpp
utils/TableGen/TGLexer.h
utils/TableGen/TGParser.cpp

index 8cc6f90eac904a248c76329d9d3280bf3a363f92..48fdd2a2018fe0ef2f4606784739a4c77007134b 100644 (file)
@@ -398,11 +398,12 @@ supported include:</p>
 <dt><tt>!strconcat(a, b)</tt></dt>
   <dd>A string value that is the result of concatenating the 'a' and 'b'
   strings.</dd>
+<dt><tt>!cast<type>(a)</tt></dt>
+  <dd>A symbol of type <em>type</em> obtained by looking up the string 'a' in
+the symbol table.  If the type of 'a' does not match <em>type</em>, TableGen
+aborts with an error. </dd>
 <dt><tt>!nameconcat&lt;type&gt;(a, b)</tt></dt>
-  <dd>A value that is the result of concatenating the 'a' and 'b'
-  strings and looking up the resulting name in the symbol table.  The symbol type 
-  determines the type of the resulting value.  If the symbol is not found 
-  or the symbol type does not match 'type,' TableGen emits an error and aborts.</dd>
+  <dd>Shorthand for !cast<type>(!strconcat(a, b))</dd>
 </dl>
 
 <p>Note that all of the values have rules specifying how they convert to values
diff --git a/test/TableGen/cast.td b/test/TableGen/cast.td
new file mode 100644 (file)
index 0000000..4a771ae
--- /dev/null
@@ -0,0 +1,90 @@
+// RUN: tblgen %s | grep {add_ps} | count 3
+
+class ValueType<int size, int value> {
+  int Size = size;
+  int Value = value;
+}
+
+def v2i64  : ValueType<128, 22>;   //  2 x i64 vector value
+def v2f64  : ValueType<128, 28>;   //  2 x f64 vector value
+
+class Intrinsic<string name> {
+  string Name = name;
+}
+
+class Inst<bits<8> opcode, dag oopnds, dag iopnds, string asmstr, 
+           list<dag> pattern> {
+  bits<8> Opcode = opcode;
+  dag OutOperands = oopnds;
+  dag InOperands = iopnds;
+  string AssemblyString = asmstr;
+  list<dag> Pattern = pattern;
+}
+
+def ops;
+def outs;
+def ins;
+
+def set;
+
+// Define registers
+class Register<string n> {
+  string Name = n;
+}
+
+class RegisterClass<list<ValueType> regTypes, list<Register> regList> {
+  list<ValueType> RegTypes = regTypes;
+  list<Register> MemberList = regList;
+}
+
+def XMM0: Register<"xmm0">;
+def XMM1: Register<"xmm1">;
+def XMM2: Register<"xmm2">;
+def XMM3: Register<"xmm3">;
+def XMM4: Register<"xmm4">;
+def XMM5: Register<"xmm5">;
+def XMM6: Register<"xmm6">;
+def XMM7: Register<"xmm7">;
+def XMM8:  Register<"xmm8">;
+def XMM9:  Register<"xmm9">;
+def XMM10: Register<"xmm10">;
+def XMM11: Register<"xmm11">;
+def XMM12: Register<"xmm12">;
+def XMM13: Register<"xmm13">;
+def XMM14: Register<"xmm14">;
+def XMM15: Register<"xmm15">;
+
+def VR128 : RegisterClass<[v2i64, v2f64],
+                          [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
+                           XMM8, XMM9, XMM10, XMM11,
+                           XMM12, XMM13, XMM14, XMM15]>;
+
+// Define intrinsics
+def int_x86_sse2_add_ps : Intrinsic<"addps">;
+def int_x86_sse2_add_pd : Intrinsic<"addpd">;
+
+multiclass arith<bits<8> opcode, string asmstr, string Intr> {
+  def PS : Inst<opcode, (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
+                 !strconcat(asmstr, "\t$dst, $src1, $src2"),
+                 [(set VR128:$dst, (!cast<Intrinsic>(!strconcat(Intr, "_ps")) VR128:$src1, VR128:$src2))]>;
+
+  def PD : Inst<opcode, (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
+                 !strconcat(asmstr, "\t$dst, $src1, $src2"),
+                 [(set VR128:$dst, (!cast<Intrinsic>(!strconcat(Intr, "_pd")) VR128:$src1, VR128:$src2))]>;
+}
+
+defm ADD : arith<0x58, "add", "int_x86_sse2_add">;
+
+class IntInst<bits<8> opcode, string asmstr, Intrinsic Intr> :
+  Inst<opcode,(outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
+       !strconcat(asmstr, "\t$dst, $src1, $src2"),
+       [(set VR128:$dst, (Intr VR128:$src1, VR128:$src2))]>;
+
+
+multiclass arith_int<bits<8> opcode, string asmstr, string Intr> {
+  def PS_Int : IntInst<opcode, asmstr, !cast<Intrinsic>(!strconcat(Intr, "_ps"))>;
+
+  def PD_Int : IntInst<opcode, asmstr, !cast<Intrinsic>(!strconcat(Intr, "_pd"))>;
+}
+
+defm ADD : arith_int<0x58, "add", "int_x86_sse2_add">;
index 0f318612691ab28e6292db1118d3ecb78b1e4a12..2a8ddaa42c74cb57f405e95ef9d95b35d25f46f1 100644 (file)
@@ -132,17 +132,17 @@ Init *IntRecTy::convertValue(TypedInit *TI) {
   return 0;
 }
 
-// Init *StringRecTy::convertValue(UnOpInit *BO) {
-//   if (BO->getOpcode() == UnOpInit::CAST) {
-//     Init *L = BO->getOperand()->convertInitializerTo(this);
-//     if (L == 0) return 0;
-//     if (L != BO->getOperand())
-//       return new UnOpInit(UnOpInit::CAST, L, new StringRecTy);
-//     return BO;
-//   }
+Init *StringRecTy::convertValue(UnOpInit *BO) {
+  if (BO->getOpcode() == UnOpInit::CAST) {
+    Init *L = BO->getOperand()->convertInitializerTo(this);
+    if (L == 0) return 0;
+    if (L != BO->getOperand())
+      return new UnOpInit(UnOpInit::CAST, L, new StringRecTy);
+    return BO;
+  }
 
-//   return convertValue((TypedInit*)BO);
-// }
+  return convertValue((TypedInit*)BO);
+}
 
 Init *StringRecTy::convertValue(BinOpInit *BO) {
   if (BO->getOpcode() == BinOpInit::STRCONCAT) {
@@ -212,16 +212,16 @@ Init *DagRecTy::convertValue(TypedInit *TI) {
   return 0;
 }
 
-// Init *DagRecTy::convertValue(UnOpInit *BO) {
-//   if (BO->getOpcode() == UnOpInit::CAST) {
-//     Init *L = BO->getOperand()->convertInitializerTo(this);
-//     if (L == 0) return 0;
-//     if (L != BO->getOperand())
-//       return new UnOpInit(UnOpInit::CAST, L, new DagRecTy);
-//     return BO;
-//   }
-//   return 0;
-// }
+Init *DagRecTy::convertValue(UnOpInit *BO) {
+  if (BO->getOpcode() == UnOpInit::CAST) {
+    Init *L = BO->getOperand()->convertInitializerTo(this);
+    if (L == 0) return 0;
+    if (L != BO->getOperand())
+      return new UnOpInit(UnOpInit::CAST, L, new DagRecTy);
+    return BO;
+  }
+  return 0;
+}
 
 Init *DagRecTy::convertValue(BinOpInit *BO) {
   if (BO->getOpcode() == BinOpInit::CONCAT) {
@@ -467,78 +467,78 @@ Init *OpInit::resolveListElementReference(Record &R, const RecordVal *IRV,
   return 0;
 }
 
-// Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
-//   switch (getOpcode()) {
-//   default: assert(0 && "Unknown unop");
-//   case CAST: {
-//     StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
-//     if (LHSs) {
-//       std::string Name = LHSs->getValue();
-
-//       // From TGParser::ParseIDValue
-//       if (CurRec) {
-//         if (const RecordVal *RV = CurRec->getValue(Name)) {
-//           if (RV->getType() != getType()) {
-//             throw "type mismatch in nameconcat";
-//           }
-//           return new VarInit(Name, RV->getType());
-//         }
+Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
+  switch (getOpcode()) {
+  default: assert(0 && "Unknown unop");
+  case CAST: {
+    StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
+    if (LHSs) {
+      std::string Name = LHSs->getValue();
+
+      // From TGParser::ParseIDValue
+      if (CurRec) {
+        if (const RecordVal *RV = CurRec->getValue(Name)) {
+          if (RV->getType() != getType()) {
+            throw "type mismatch in nameconcat";
+          }
+          return new VarInit(Name, RV->getType());
+        }
         
-//         std::string TemplateArgName = CurRec->getName()+":"+Name;
-//         if (CurRec->isTemplateArg(TemplateArgName)) {
-//           const RecordVal *RV = CurRec->getValue(TemplateArgName);
-//           assert(RV && "Template arg doesn't exist??");
+        std::string TemplateArgName = CurRec->getName()+":"+Name;
+        if (CurRec->isTemplateArg(TemplateArgName)) {
+          const RecordVal *RV = CurRec->getValue(TemplateArgName);
+          assert(RV && "Template arg doesn't exist??");
 
-//           if (RV->getType() != getType()) {
-//             throw "type mismatch in nameconcat";
-//           }
+          if (RV->getType() != getType()) {
+            throw "type mismatch in nameconcat";
+          }
 
-//           return new VarInit(TemplateArgName, RV->getType());
-//         }
-//       }
+          return new VarInit(TemplateArgName, RV->getType());
+        }
+      }
 
-//       if (CurMultiClass) {
-//         std::string MCName = CurMultiClass->Rec.getName()+"::"+Name;
-//         if (CurMultiClass->Rec.isTemplateArg(MCName)) {
-//           const RecordVal *RV = CurMultiClass->Rec.getValue(MCName);
-//           assert(RV && "Template arg doesn't exist??");
+      if (CurMultiClass) {
+        std::string MCName = CurMultiClass->Rec.getName()+"::"+Name;
+        if (CurMultiClass->Rec.isTemplateArg(MCName)) {
+          const RecordVal *RV = CurMultiClass->Rec.getValue(MCName);
+          assert(RV && "Template arg doesn't exist??");
 
-//           if (RV->getType() != getType()) {
-//             throw "type mismatch in nameconcat";
-//           }
+          if (RV->getType() != getType()) {
+            throw "type mismatch in nameconcat";
+          }
           
-//           return new VarInit(MCName, RV->getType());
-//         }
-//       }
+          return new VarInit(MCName, RV->getType());
+        }
+      }
 
-//       if (Record *D = Records.getDef(Name))
-//         return new DefInit(D);
+      if (Record *D = Records.getDef(Name))
+        return new DefInit(D);
 
-//       cerr << "Variable not defined: '" + Name + "'\n";
-//       assert(0 && "Variable not found");
-//       return 0;
-//     }
-//     break;
-//   }
-//   }
-//   return this;
-// }
+      cerr << "Variable not defined: '" + Name + "'\n";
+      assert(0 && "Variable not found");
+      return 0;
+    }
+    break;
+  }
+  }
+  return this;
+}
 
-// Init *UnOpInit::resolveReferences(Record &R, const RecordVal *RV) {
-//   Init *lhs = LHS->resolveReferences(R, RV);
+Init *UnOpInit::resolveReferences(Record &R, const RecordVal *RV) {
+  Init *lhs = LHS->resolveReferences(R, RV);
   
-//   if (LHS != lhs)
-//     return (new UnOpInit(getOpcode(), lhs, getType()))->Fold(&R, 0);
-//   return Fold(&R, 0);
-// }
+  if (LHS != lhs)
+    return (new UnOpInit(getOpcode(), lhs, getType()))->Fold(&R, 0);
+  return Fold(&R, 0);
+}
 
-// std::string UnOpInit::getAsString() const {
-//   std::string Result;
-//   switch (Opc) {
-//   case CAST: Result = "!cast<" + getType()->getAsString() + ">"; break;
-//   }
-//   return Result + "(" + LHS->getAsString() + ")";
-// }
+std::string UnOpInit::getAsString() const {
+  std::string Result;
+  switch (Opc) {
+  case CAST: Result = "!cast<" + getType()->getAsString() + ">"; break;
+  }
+  return Result + "(" + LHS->getAsString() + ")";
+}
 
 Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
   switch (getOpcode()) {
index b0b4ac17b48939e1494e16d276074f6b8b8be9dc..a81b056b170f7a35f8d5da2d74f51b5c82e8f6fb 100644 (file)
@@ -41,7 +41,7 @@ class IntInit;
 class StringInit;
 class CodeInit;
 class ListInit;
-  //class UnOpInit;
+class UnOpInit;
 class BinOpInit;
   //class TernOpInit;
 class DefInit;
@@ -79,9 +79,9 @@ 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( UnOpInit *UI) {
-//     return convertValue((TypedInit*)UI);
-//   }
+  virtual Init *convertValue( UnOpInit *UI) {
+    return convertValue((TypedInit*)UI);
+  }
   virtual Init *convertValue( BinOpInit *UI) {
     return convertValue((TypedInit*)UI);
   }
@@ -133,7 +133,7 @@ public:
   virtual Init *convertValue(VarBitInit *VB) { return (Init*)VB; }
   virtual Init *convertValue(   DefInit *DI) { return 0; }
   virtual Init *convertValue(   DagInit *DI) { return 0; }
-  //  virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
+  virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
   virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
   //virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
   virtual Init *convertValue( TypedInit *TI);
@@ -177,7 +177,7 @@ public:
   virtual Init *convertValue(VarBitInit *VB) { return 0; }
   virtual Init *convertValue(   DefInit *DI) { return 0; }
   virtual Init *convertValue(   DagInit *DI) { return 0; }
-  //virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
+  virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
   virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
   //virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
   virtual Init *convertValue( TypedInit *TI);
@@ -217,7 +217,7 @@ public:
   virtual Init *convertValue(VarBitInit *VB) { return 0; }
   virtual Init *convertValue(   DefInit *DI) { return 0; }
   virtual Init *convertValue(   DagInit *DI) { return 0; }
-  //virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
+  virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
   virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
   //virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
   virtual Init *convertValue( TypedInit *TI);
@@ -251,7 +251,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( UnOpInit *BO);
+  virtual Init *convertValue( UnOpInit *BO);
   virtual Init *convertValue( BinOpInit *BO);
   //virtual Init *convertValue( TernOpInit *BO) { return RecTy::convertValue(BO);}
 
@@ -301,7 +301,7 @@ public:
   virtual Init *convertValue(VarBitInit *VB) { return 0; }
   virtual Init *convertValue(   DefInit *DI) { return 0; }
   virtual Init *convertValue(   DagInit *DI) { return 0; }
-  //virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
+  virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
   virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
   //virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
   virtual Init *convertValue( TypedInit *TI);
@@ -340,7 +340,7 @@ public:
   virtual Init *convertValue(VarBitInit *VB) { return 0; }
   virtual Init *convertValue(   DefInit *DI) { return 0; }
   virtual Init *convertValue(   DagInit *DI) { return 0; }
-  //virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
+  virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
   virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
   //virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
   virtual Init *convertValue( TypedInit *TI);
@@ -375,7 +375,7 @@ public:
   virtual Init *convertValue(  CodeInit *CI) { return 0; }
   virtual Init *convertValue(VarBitInit *VB) { return 0; }
   virtual Init *convertValue(   DefInit *DI) { return 0; }
-  //virtual Init *convertValue( UnOpInit *BO);
+  virtual Init *convertValue( UnOpInit *BO);
   virtual Init *convertValue( BinOpInit *BO);
   //virtual Init *convertValue( TernOpInit *BO) { return RecTy::convertValue(BO);}
   virtual Init *convertValue(   DagInit *CI) { return (Init*)CI; }
@@ -418,7 +418,7 @@ public:
   virtual Init *convertValue(  ListInit *LI) { return 0; }
   virtual Init *convertValue(  CodeInit *CI) { return 0; }
   virtual Init *convertValue(VarBitInit *VB) { return 0; }
-  //virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
+  virtual Init *convertValue( UnOpInit *UI) { return RecTy::convertValue(UI);}
   virtual Init *convertValue( BinOpInit *UI) { return RecTy::convertValue(UI);}
   //virtual Init *convertValue( TernOpInit *UI) { return RecTy::convertValue(UI);}
   virtual Init *convertValue(   DefInit *DI);
@@ -740,40 +740,40 @@ public:
 
 /// UnOpInit - !op (X) - Transform an init.
 ///
-// class UnOpInit : public OpInit {
-// public:
-//   enum UnaryOp { CAST };
-// private:
-//   UnaryOp Opc;
-//   Init *LHS;
-// public:
-//   UnOpInit(UnaryOp opc, Init *lhs, RecTy *Type) :
-//       OpInit(Type), Opc(opc), LHS(lhs) {
-//   }
+class UnOpInit : public OpInit {
+public:
+  enum UnaryOp { CAST };
+private:
+  UnaryOp Opc;
+  Init *LHS;
+public:
+  UnOpInit(UnaryOp opc, Init *lhs, RecTy *Type) :
+      OpInit(Type), Opc(opc), LHS(lhs) {
+  }
 
-//   // Clone - Clone this operator, replacing arguments with the new list
-//   virtual OpInit *clone(std::vector<Init *> &Operands) {
-//     assert(Operands.size() == 1 && "Wrong number of operands for unary operation");
-//     return new UnOpInit(getOpcode(), *Operands.begin(), getType());
-//   }
+  // Clone - Clone this operator, replacing arguments with the new list
+  virtual OpInit *clone(std::vector<Init *> &Operands) {
+    assert(Operands.size() == 1 && "Wrong number of operands for unary operation");
+    return new UnOpInit(getOpcode(), *Operands.begin(), getType());
+  }
 
-//   int getNumOperands(void) const { return 1; }
-//   Init *getOperand(int i) {
-//     assert(i == 0 && "Invalid operand id for unary operator");
-//     return getOperand();
-//   }
+  int getNumOperands(void) const { return 1; }
+  Init *getOperand(int i) {
+    assert(i == 0 && "Invalid operand id for unary operator");
+    return getOperand();
+  }
   
-//   UnaryOp getOpcode() const { return Opc; }
-//   Init *getOperand() const { return LHS; }
+  UnaryOp getOpcode() const { return Opc; }
+  Init *getOperand() const { return LHS; }
 
-//   // Fold - If possible, fold this to a simpler init.  Return this if not
-//   // possible to fold.
-//   Init *Fold(Record *CurRec, MultiClass *CurMultiClass);
+  // Fold - If possible, fold this to a simpler init.  Return this if not
+  // possible to fold.
+  Init *Fold(Record *CurRec, MultiClass *CurMultiClass);
 
-//   virtual Init *resolveReferences(Record &R, const RecordVal *RV);
+  virtual Init *resolveReferences(Record &R, const RecordVal *RV);
   
-//   virtual std::string getAsString() const;
-// };
+  virtual std::string getAsString() const;
+};
 
 /// BinOpInit - !op (X, Y) - Combine two inits.
 ///
index 5e96e50351e7411848720feed0af361b7b28ed34..43afae9f0f21e63dd81a5e36cb9dad5b41244616 100644 (file)
@@ -449,7 +449,7 @@ tgtok::TokKind TGLexer::LexExclaim() {
   if (Len == 10 && !memcmp(Start, "nameconcat", 10)) return tgtok::XNameConcat;
 //   if (Len == 5 && !memcmp(Start, "subst", 5)) return tgtok::XSubst;
 //   if (Len == 7 && !memcmp(Start, "foreach", 7)) return tgtok::XForEach;
-//   if (Len == 4 && !memcmp(Start, "cast", 4)) return tgtok::XCast;
+  if (Len == 4 && !memcmp(Start, "cast", 4)) return tgtok::XCast;
 
   return ReturnError(Start-1, "Unknown operator");
 }
index 0f27308afd0cc89594e6120a2317cab579c06609..b95ca9558cc5368ba56194dbd3326692c4bad5a2 100644 (file)
@@ -45,7 +45,7 @@ namespace tgtok {
     MultiClass, String,
     
     // !keywords.
-    XConcat, XSRA, XSRL, XSHL, XStrConcat, XNameConcat, //XSubst, XCast,
+    XConcat, XSRA, XSRL, XSHL, XStrConcat, XNameConcat, XCast, // XSubst,
     //XForEach,
 
     // Integer value.
index da2a5304ab3dc5d878469333a206b4ffb18eaa3d..6b4c431635cbfc9c7ac8439ba7eb5bcfbcc1f05b 100644 (file)
@@ -680,41 +680,41 @@ Init *TGParser::ParseOperation(Record *CurRec) {
     TokError("unknown operation");
     return 0;
     break;
-//   case tgtok::XCast: {  // Value ::= !unop '(' Value ')'
-//     UnOpInit::UnaryOp Code;
-//     RecTy *Type = 0;
+  case tgtok::XCast: {  // Value ::= !unop '(' Value ')'
+    UnOpInit::UnaryOp Code;
+    RecTy *Type = 0;
 
-//     switch (Lex.getCode()) {
-//     default: assert(0 && "Unhandled code!");
-//     case tgtok::XCast:
-//       Lex.Lex();  // eat the operation
-//       Code = UnOpInit::CAST;
+    switch (Lex.getCode()) {
+    default: assert(0 && "Unhandled code!");
+    case tgtok::XCast:
+      Lex.Lex();  // eat the operation
+      Code = UnOpInit::CAST;
 
-//       Type = ParseOperatorType();
+      Type = ParseOperatorType();
 
-//       if (Type == 0) {
-//         TokError("did not get type for binary operator");
-//         return 0;
-//       }
+      if (Type == 0) {
+        TokError("did not get type for binary operator");
+        return 0;
+      }
 
-//       break;
-//     }
-//     if (Lex.getCode() != tgtok::l_paren) {
-//       TokError("expected '(' after unary operator");
-//       return 0;
-//     }
-//     Lex.Lex();  // eat the '('
+      break;
+    }
+    if (Lex.getCode() != tgtok::l_paren) {
+      TokError("expected '(' after unary operator");
+      return 0;
+    }
+    Lex.Lex();  // eat the '('
 
-//     Init *LHS = ParseValue(CurRec);
-//     if (LHS == 0) return 0;
+    Init *LHS = ParseValue(CurRec);
+    if (LHS == 0) return 0;
 
-//     if (Lex.getCode() != tgtok::r_paren) {
-//       TokError("expected ')' in unary operator");
-//       return 0;
-//     }
-//     Lex.Lex();  // eat the ')'
-//     return (new UnOpInit(Code, LHS, Type))->Fold(CurRec, CurMultiClass);
-//   }
+    if (Lex.getCode() != tgtok::r_paren) {
+      TokError("expected ')' in unary operator");
+      return 0;
+    }
+    Lex.Lex();  // eat the ')'
+    return (new UnOpInit(Code, LHS, Type))->Fold(CurRec, CurMultiClass);
+  }
 
   case tgtok::XConcat:
   case tgtok::XSRA: 
@@ -1029,7 +1029,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) {
   case tgtok::l_paren: {         // Value ::= '(' IDValue DagArgList ')'
     Lex.Lex();   // eat the '('
     if (Lex.getCode() != tgtok::Id
-        //        && Lex.getCode() != tgtok::XCast
+        && Lex.getCode() != tgtok::XCast
         && Lex.getCode() != tgtok::XNameConcat) {
       TokError("expected identifier in dag init");
       return 0;
@@ -1072,7 +1072,7 @@ Init *TGParser::ParseSimpleValue(Record *CurRec) {
     break;
   }
  
-    //  case tgtok::XCast:  // Value ::= !unop '(' Value ')'
+  case tgtok::XCast:  // Value ::= !unop '(' Value ')'
   case tgtok::XConcat:
   case tgtok::XSRA: 
   case tgtok::XSRL: