Converted a1.ll to unittests.
[oota-llvm.git] / utils / TableGen / CodeGenDAGPatterns.cpp
index e987c2bc82e188d352027f01fcfdfaaa937fd455..c5e6bdffcfcda6556c9ed50d11b49f6df7cc9d51 100644 (file)
@@ -471,7 +471,8 @@ bool TreePatternNode::UpdateNodeType(const std::vector<unsigned char> &ExtVTs,
   }
 
   if (getExtTypeNum(0) == MVT::iPTR || getExtTypeNum(0) == MVT::iPTRAny) {
-    if (ExtVTs[0] == MVT::iPTR || ExtVTs[0] == MVT::iPTRAny || ExtVTs[0] == EMVT::isInt)
+    if (ExtVTs[0] == MVT::iPTR || ExtVTs[0] == MVT::iPTRAny ||
+        ExtVTs[0] == EMVT::isInt)
       return false;
     if (EMVT::isExtIntegerInVTs(ExtVTs)) {
       std::vector<unsigned char> FVTs = FilterEVTs(ExtVTs, isInteger);
@@ -481,8 +482,9 @@ bool TreePatternNode::UpdateNodeType(const std::vector<unsigned char> &ExtVTs,
       }
     }
   }
-  
-  if (ExtVTs[0] == EMVT::isInt && EMVT::isExtIntegerInVTs(getExtTypes())) {
+
+  if ((ExtVTs[0] == EMVT::isInt || ExtVTs[0] == MVT::iAny) &&
+      EMVT::isExtIntegerInVTs(getExtTypes())) {
     assert(hasTypeSet() && "should be handled above!");
     std::vector<unsigned char> FVTs = FilterEVTs(getExtTypes(), isInteger);
     if (getExtTypes() == FVTs)
@@ -501,7 +503,8 @@ bool TreePatternNode::UpdateNodeType(const std::vector<unsigned char> &ExtVTs,
       return true;
     }
   }      
-  if (ExtVTs[0] == EMVT::isFP  && EMVT::isExtFloatingPointInVTs(getExtTypes())) {
+  if ((ExtVTs[0] == EMVT::isFP || ExtVTs[0] == MVT::fAny) &&
+      EMVT::isExtFloatingPointInVTs(getExtTypes())) {
     assert(hasTypeSet() && "should be handled above!");
     std::vector<unsigned char> FVTs =
       FilterEVTs(getExtTypes(), isFloatingPoint);
@@ -516,9 +519,9 @@ bool TreePatternNode::UpdateNodeType(const std::vector<unsigned char> &ExtVTs,
   //
   // Similarly, we should probably set the type here to the intersection of
   // {isInt|isFP} and ExtVTs
-  if ((getExtTypeNum(0) == EMVT::isInt &&
+  if (((getExtTypeNum(0) == EMVT::isInt || getExtTypeNum(0) == MVT::iAny) &&
        EMVT::isExtIntegerInVTs(ExtVTs)) ||
-      (getExtTypeNum(0) == EMVT::isFP &&
+      ((getExtTypeNum(0) == EMVT::isFP || getExtTypeNum(0) == MVT::fAny) &&
        EMVT::isExtFloatingPointInVTs(ExtVTs))) {
     setTypes(ExtVTs);
     return true;
@@ -806,7 +809,7 @@ TreePatternNode::isCommutativeIntrinsic(const CodeGenDAGPatterns &CDP) const {
 }
 
 
-/// ApplyTypeConstraints - Apply all of the type constraints relevent to
+/// ApplyTypeConstraints - Apply all of the type constraints relevant to
 /// this node and its children in the tree.  This returns true if it makes a
 /// change, false otherwise.  If a type contradiction is found, throw an
 /// exception.
@@ -839,7 +842,7 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
               // If sign-extended doesn't fit, does it fit as unsigned?
               unsigned ValueMask;
               unsigned UnsignedVal;
-              ValueMask = unsigned(MVT(VT).getIntegerVTBitMask());
+              ValueMask = unsigned(~uint32_t(0UL) >> (32-Size));
               UnsignedVal = unsigned(II->getValue());
 
               if ((ValueMask & UnsignedVal) != UnsignedVal) {
@@ -885,18 +888,22 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
     bool MadeChange = false;
 
     // Apply the result type to the node.
-    MadeChange = UpdateNodeType(Int->ArgVTs[0], TP);
+    unsigned NumRetVTs = Int->IS.RetVTs.size();
+    unsigned NumParamVTs = Int->IS.ParamVTs.size();
 
-    if (getNumChildren() != Int->ArgVTs.size())
+    for (unsigned i = 0, e = NumRetVTs; i != e; ++i)
+      MadeChange |= UpdateNodeType(Int->IS.RetVTs[i], TP);
+
+    if (getNumChildren() != NumParamVTs + NumRetVTs)
       TP.error("Intrinsic '" + Int->Name + "' expects " +
-               utostr(Int->ArgVTs.size()-1) + " operands, not " +
-               utostr(getNumChildren()-1) + " operands!");
+               utostr(NumParamVTs + NumRetVTs - 1) + " operands, not " +
+               utostr(getNumChildren() - 1) + " operands!");
 
     // Apply type info to the intrinsic ID.
     MadeChange |= getChild(0)->UpdateNodeType(MVT::iPTR, TP);
     
-    for (unsigned i = 1, e = getNumChildren(); i != e; ++i) {
-      MVT::SimpleValueType OpVT = Int->ArgVTs[i];
+    for (unsigned i = NumRetVTs, e = getNumChildren(); i != e; ++i) {
+      MVT::SimpleValueType OpVT = Int->IS.ParamVTs[i - NumRetVTs];
       MadeChange |= getChild(i)->UpdateNodeType(OpVT, TP);
       MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters);
     }
@@ -1106,7 +1113,7 @@ TreePattern::TreePattern(Record *TheRec, TreePatternNode *Pat, bool isInput,
 
 void TreePattern::error(const std::string &Msg) const {
   dump();
-  throw "In " + TheRecord->getName() + ": " + Msg;
+  throw TGError(TheRecord->getLoc(), "In " + TheRecord->getName() + ": " + Msg);
 }
 
 TreePatternNode *TreePattern::ParseTreePattern(DagInit *Dag) {
@@ -1125,7 +1132,7 @@ TreePatternNode *TreePattern::ParseTreePattern(DagInit *Dag) {
     if (DefInit *DI = dynamic_cast<DefInit*>(Arg)) {
       Record *R = DI->getDef();
       if (R->isSubClassOf("SDNode") || R->isSubClassOf("PatFrag")) {
-        Dag->setArg(0, new DagInit(DI,
+        Dag->setArg(0, new DagInit(DI, "",
                                 std::vector<std::pair<Init*, std::string> >()));
         return ParseTreePattern(Dag);
       }
@@ -1153,12 +1160,14 @@ TreePatternNode *TreePattern::ParseTreePattern(DagInit *Dag) {
     
     // Apply the type cast.
     New->UpdateNodeType(getValueType(Operator), *this);
-    New->setName(Dag->getArgName(0));
+    if (New->getNumChildren() == 0)
+      New->setName(Dag->getArgName(0));
     return New;
   }
   
   // Verify that this is something that makes sense for an operator.
-  if (!Operator->isSubClassOf("PatFrag") && !Operator->isSubClassOf("SDNode") &&
+  if (!Operator->isSubClassOf("PatFrag") && 
+      !Operator->isSubClassOf("SDNode") &&
       !Operator->isSubClassOf("Instruction") && 
       !Operator->isSubClassOf("SDNodeXForm") &&
       !Operator->isSubClassOf("Intrinsic") &&
@@ -1185,7 +1194,7 @@ TreePatternNode *TreePattern::ParseTreePattern(DagInit *Dag) {
       // Direct reference to a leaf DagNode or PatFrag?  Turn it into a
       // TreePatternNode if its own.
       if (R->isSubClassOf("SDNode") || R->isSubClassOf("PatFrag")) {
-        Dag->setArg(i, new DagInit(DefI,
+        Dag->setArg(i, new DagInit(DefI, "",
                               std::vector<std::pair<Init*, std::string> >()));
         --i;  // Revisit this node...
       } else {
@@ -1232,7 +1241,7 @@ TreePatternNode *TreePattern::ParseTreePattern(DagInit *Dag) {
 
     // If this intrinsic returns void, it must have side-effects and thus a
     // chain.
-    if (Int.ArgVTs[0] == MVT::isVoid) {
+    if (Int.IS.RetVTs[0] == MVT::isVoid) {
       Operator = getDAGPatterns().get_intrinsic_void_sdnode();
     } else if (Int.ModRef != CodeGenIntrinsic::NoMem) {
       // Has side-effects, requires chain.
@@ -1246,7 +1255,9 @@ TreePatternNode *TreePattern::ParseTreePattern(DagInit *Dag) {
     Children.insert(Children.begin(), IIDNode);
   }
   
-  return new TreePatternNode(Operator, Children);
+  TreePatternNode *Result = new TreePatternNode(Operator, Children);
+  Result->setName(Dag->getName());
+  return Result;
 }
 
 /// InferAllTypes - Infer/propagate as many types throughout the expression
@@ -1296,7 +1307,8 @@ void TreePattern::dump() const { print(*cerr.stream()); }
 
 // FIXME: REMOVE OSTREAM ARGUMENT
 CodeGenDAGPatterns::CodeGenDAGPatterns(RecordKeeper &R) : Records(R) {
-  Intrinsics = LoadIntrinsics(Records);
+  Intrinsics = LoadIntrinsics(Records, false);
+  TgtIntrinsics = LoadIntrinsics(Records, true);
   ParseNodeInfo();
   ParseNodeTransforms();
   ParseComplexPatterns();
@@ -1474,7 +1486,7 @@ void CodeGenDAGPatterns::ParseDefaultOperands() {
       for (unsigned op = 0, e = DefaultInfo->getNumArgs(); op != e; ++op)
         Ops.push_back(std::make_pair(DefaultInfo->getArg(op),
                                      DefaultInfo->getArgName(op)));
-      DagInit *DI = new DagInit(SomeSDNode, Ops);
+      DagInit *DI = new DagInit(SomeSDNode, "", Ops);
     
       // Create a TreePattern to parse this.
       TreePattern P(DefaultOps[iter][i], DI, false, *this);
@@ -1519,7 +1531,6 @@ static bool HandleUse(TreePattern *I, TreePatternNode *Pat,
         I->error("Input " + DI->getDef()->getName() + " must be named!");
       else if (DI && DI->getDef()->isSubClassOf("Register")) 
         InstImpInputs.push_back(DI->getDef());
-        ;
     }
     return false;
   }
@@ -1530,7 +1541,6 @@ static bool HandleUse(TreePattern *I, TreePatternNode *Pat,
     if (!DI) I->error("Input $" + Pat->getName() + " must be an identifier!");
     Rec = DI->getDef();
   } else {
-    assert(Pat->getNumChildren() == 0 && "can't be a use with children!");
     Rec = Pat->getOperator();
   }
 
@@ -1597,9 +1607,7 @@ FindPatternInputsAndOutputs(TreePattern *I, TreePatternNode *Pat,
     
     // If this is a non-leaf node with no children, treat it basically as if
     // it were a leaf.  This handles nodes like (imm).
-    bool isUse = false;
-    if (Pat->getNumChildren() == 0)
-      isUse = HandleUse(I, Pat, InstInputs, InstImpInputs);
+    bool isUse = HandleUse(I, Pat, InstInputs, InstImpInputs);
     
     if (!isUse && Pat->getTransformFn())
       I->error("Cannot specify a transform function for a non-input value!");