Model :upper16: and :lower16: as ARM specific MCTargetExpr. This is a step
[oota-llvm.git] / utils / TableGen / CodeGenInstruction.cpp
index 7428f2c88fe2421bb16ad0425412c0fab58ada6f..a28b1d58d7e914a5a5f5cff21359736d7e5f4cf3 100644 (file)
@@ -15,6 +15,7 @@
 #include "CodeGenTarget.h"
 #include "Record.h"
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/STLExtras.h"
 #include <set>
 using namespace llvm;
@@ -70,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.
@@ -286,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");
@@ -388,8 +389,130 @@ FlattenAsmStringVariants(StringRef Cur, unsigned Variant) {
 /// CodeGenInstAlias Implementation
 //===----------------------------------------------------------------------===//
 
-CodeGenInstAlias::CodeGenInstAlias(Record *R) : 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.
+  DefInit *DI = dynamic_cast<DefInit*>(Result->getOperator());
+  if (DI == 0 || !DI->getDef()->isSubClassOf("Instruction"))
+    throw TGError(R->getLoc(), "result of inst alias should be an instruction");
+
+  ResultInst = &T.getInstruction(DI->getDef());
+  
+  // 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.
+  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(AliasOpNo).empty())
+        throw TGError(R->getLoc(), "result argument #" + utostr(AliasOpNo) +
+                      " must have a name!");
+
+      if (ADI->getDef() != ResultOpRec)
+        throw TGError(R->getLoc(), "result argument #" + utostr(AliasOpNo) +
+                      " declared with class " + ADI->getDef()->getName() +
+                      ", instruction operand is class " + 
+                      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(AliasOpNo)];
+      if (Entry && Entry != ADI->getDef())
+        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(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;
+  }
 }