Model :upper16: and :lower16: as ARM specific MCTargetExpr. This is a step
[oota-llvm.git] / utils / TableGen / CodeGenInstruction.cpp
index a2989b116d886ecc4adcc934a1f30ee51499548e..a28b1d58d7e914a5a5f5cff21359736d7e5f4cf3 100644 (file)
@@ -71,8 +71,7 @@ CGIOperandList::CGIOperandList(Record *R) : TheDef(R) {
     if (Rec->isSubClassOf("Operand")) {
       PrintMethod = Rec->getValueAsString("PrintMethod");
       // If there is an explicit encoder method, use it.
-      if (Rec->getValue("EncoderMethod"))
-        EncoderMethod = Rec->getValueAsString("EncoderMethod");
+      EncoderMethod = Rec->getValueAsString("EncoderMethod");
       MIOpInfo = Rec->getValueAsDag("MIOperandInfo");
       
       // Verify that MIOpInfo has an 'ops' root value.
@@ -287,6 +286,7 @@ CodeGenInstruction::CodeGenInstruction(Record *R) : TheDef(R), Operands(R) {
   isBranch     = R->getValueAsBit("isBranch");
   isIndirectBranch = R->getValueAsBit("isIndirectBranch");
   isCompare    = R->getValueAsBit("isCompare");
+  isMoveImm    = R->getValueAsBit("isMoveImm");
   isBarrier    = R->getValueAsBit("isBarrier");
   isCall       = R->getValueAsBit("isCall");
   canFoldAsLoad = R->getValueAsBit("canFoldAsLoad");
@@ -389,10 +389,8 @@ FlattenAsmStringVariants(StringRef Cur, unsigned Variant) {
 /// CodeGenInstAlias Implementation
 //===----------------------------------------------------------------------===//
 
-CodeGenInstAlias::CodeGenInstAlias(Record *R, CodeGenTarget &T)
-  : TheDef(R), Operands(R) {
+CodeGenInstAlias::CodeGenInstAlias(Record *R, CodeGenTarget &T) : TheDef(R) {
   AsmString = R->getValueAsString("AsmString");
-
   Result = R->getValueAsDag("ResultInst");
 
   // Verify that the root of the result is an instruction.
@@ -402,49 +400,119 @@ CodeGenInstAlias::CodeGenInstAlias(Record *R, CodeGenTarget &T)
 
   ResultInst = &T.getInstruction(DI->getDef());
   
-  // Check number of arguments in the result.
-  if (ResultInst->Operands.size() != Result->getNumArgs())
-    throw TGError(R->getLoc(), "result has " + utostr(Result->getNumArgs()) +
-                  " arguments, but " + ResultInst->TheDef->getName() +
-                  " instruction expects " + utostr(ResultInst->Operands.size())+
-                  " operands!");
-  
   // NameClass - If argument names are repeated, we need to verify they have
   // the same class.
   StringMap<Record*> NameClass;
     
   // Decode and validate the arguments of the result.
-  for (unsigned i = 0, e = Result->getNumArgs(); i != e; ++i) {
-    Init *Arg = Result->getArg(i);
+  unsigned AliasOpNo = 0;
+  for (unsigned i = 0, e = ResultInst->Operands.size(); i != e; ++i) {
+    // Tied registers don't have an entry in the result dag.
+    if (ResultInst->Operands[i].getTiedRegister() != -1)
+      continue;
+
+    if (AliasOpNo >= Result->getNumArgs())
+      throw TGError(R->getLoc(), "result has " + utostr(Result->getNumArgs()) +
+                    " arguments, but " + ResultInst->TheDef->getName() +
+                    " instruction expects " +
+                    utostr(ResultInst->Operands.size()) + " operands!");
+    
+    
+    Init *Arg = Result->getArg(AliasOpNo);
+    Record *ResultOpRec = ResultInst->Operands[i].Rec;
+
+    // Handle explicit registers.
+    if (DefInit *ADI = dynamic_cast<DefInit*>(Arg)) {
+      if (ADI->getDef()->isSubClassOf("Register")) {
+        if (!Result->getArgName(AliasOpNo).empty())
+          throw TGError(R->getLoc(), "result fixed register argument must "
+                        "not have a name!");
+        
+        if (!ResultOpRec->isSubClassOf("RegisterClass"))
+          throw TGError(R->getLoc(), "result fixed register argument is not "
+                        "passed to a RegisterClass operand!");
+        
+        if (!T.getRegisterClass(ResultOpRec).containsRegister(ADI->getDef()))
+          throw TGError(R->getLoc(), "fixed register " +ADI->getDef()->getName()
+                        + " is not a member of the " + ResultOpRec->getName() +
+                        " register class!");
+                                                                              
+        // Now that it is validated, add it.
+        ResultOperands.push_back(ResultOperand(ADI->getDef()));
+        ++AliasOpNo;
+        continue;
+      }
+    }
     
     // If the operand is a record, it must have a name, and the record type must
     // match up with the instruction's argument type.
     if (DefInit *ADI = dynamic_cast<DefInit*>(Arg)) {
-      if (Result->getArgName(i).empty())
-        throw TGError(R->getLoc(), "result argument #" + utostr(i) +
+      if (Result->getArgName(AliasOpNo).empty())
+        throw TGError(R->getLoc(), "result argument #" + utostr(AliasOpNo) +
                       " must have a name!");
 
-      if (ADI->getDef() != ResultInst->Operands[i].Rec)
-        throw TGError(R->getLoc(), "result argument #" + utostr(i) +
+      if (ADI->getDef() != ResultOpRec)
+        throw TGError(R->getLoc(), "result argument #" + utostr(AliasOpNo) +
                       " declared with class " + ADI->getDef()->getName() +
                       ", instruction operand is class " + 
-                      ResultInst->Operands[i].Rec->getName());
+                      ResultOpRec->getName());
       
       // Verify we don't have something like: (someinst GR16:$foo, GR32:$foo)
       // $foo can exist multiple times in the result list, but it must have the
       // same type.
-      Record *&Entry = NameClass[Result->getArgName(i)];
+      Record *&Entry = NameClass[Result->getArgName(AliasOpNo)];
       if (Entry && Entry != ADI->getDef())
-        throw TGError(R->getLoc(), "result value $" + Result->getArgName(i) +
+        throw TGError(R->getLoc(), "result value $" +
+                      Result->getArgName(AliasOpNo) +
                       " is both " + Entry->getName() + " and " +
                       ADI->getDef()->getName() + "!");
       
       // Now that it is validated, add it.
-      ResultOperands.push_back(ResultOperand(Result->getArgName(i),
+      ResultOperands.push_back(ResultOperand(Result->getArgName(AliasOpNo),
                                              ADI->getDef()));
+      ++AliasOpNo;
+      continue;
+    }
+    
+    if (IntInit *II = dynamic_cast<IntInit*>(Arg)) {
+      // Integer arguments can't have names.
+      if (!Result->getArgName(AliasOpNo).empty())
+        throw TGError(R->getLoc(), "result argument #" + utostr(AliasOpNo) +
+                      " must not have a name!");
+      if (ResultInst->Operands[i].MINumOperands != 1 ||
+          !ResultOpRec->isSubClassOf("Operand"))
+        throw TGError(R->getLoc(), "invalid argument class " + 
+                      ResultOpRec->getName() +
+                      " for integer result operand!");
+      ResultOperands.push_back(ResultOperand(II->getValue()));
+      ++AliasOpNo;
       continue;
     }
 
     throw TGError(R->getLoc(), "result of inst alias has unknown operand type");
   }
+  
+  if (AliasOpNo != Result->getNumArgs())
+    throw TGError(R->getLoc(), "result has " + utostr(Result->getNumArgs()) +
+                  " arguments, but " + ResultInst->TheDef->getName() +
+                  " instruction expects " + utostr(ResultInst->Operands.size())+
+                  " operands!");
+}
+
+/// getResultInstOperandIndexForResultOperandIndex - Given an index into the
+/// ResultOperands array, translate it to a valid index in ResultInst's
+/// operand list.
+unsigned CodeGenInstAlias::
+getResultInstOperandIndexForResultOperandIndex(unsigned OpNo) const {
+  unsigned OpIdx = 0;
+  
+  for (unsigned i = 0;; ++i) {
+    assert(i != ResultInst->Operands.size() && "Didn't find entry");
+    if (ResultInst->Operands[i].getTiedRegister() != -1)
+      continue;
+
+    if (OpIdx == OpNo) return i;
+
+    ++OpIdx;
+  }
 }