Introduce a new CodeGenInstruction::ConstraintInfo class
authorChris Lattner <sabre@nondot.org>
Wed, 10 Feb 2010 01:45:28 +0000 (01:45 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 10 Feb 2010 01:45:28 +0000 (01:45 +0000)
for representing constraint info semantically instead of
as a c expression that will be blatted out to the .inc
file.  Fix X86RecognizableInstr to use this instead of
parsing C code :).

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@95753 91177308-0d34-0410-b5e6-96231b3b80d8

utils/TableGen/CodeGenInstruction.cpp
utils/TableGen/CodeGenInstruction.h
utils/TableGen/InstrInfoEmitter.cpp
utils/TableGen/X86RecognizableInstr.cpp

index 684431a6f49f6d74dd1f5c4317eab5b5d4adfd32..d31502b1acb6a00a2574ddc9cb4de4d73b31d5b5 100644 (file)
@@ -33,10 +33,10 @@ static void ParseConstraint(const std::string &CStr, CodeGenInstruction *I) {
       I->ParseOperandName(Name, false);
 
     // Build the string for the operand
-    std::string OpConstraint = "(1 << TOI::EARLY_CLOBBER)";
-    if (!I->OperandList[Op.first].Constraints[Op.second].empty())
+    if (!I->OperandList[Op.first].Constraints[Op.second].isNone())
       throw "Operand '" + Name + "' cannot have multiple constraints!";
-    I->OperandList[Op.first].Constraints[Op.second] = OpConstraint;
+    I->OperandList[Op.first].Constraints[Op.second] =
+      CodeGenInstruction::ConstraintInfo::getEarlyClobber();
     return;
   }
 
@@ -65,13 +65,11 @@ static void ParseConstraint(const std::string &CStr, CodeGenInstruction *I) {
 
 
   unsigned FlatOpNo = I->getFlattenedOperandNumber(SrcOp);
-  // Build the string for the operand.
-  std::string OpConstraint =
-  "((" + utostr(FlatOpNo) + " << 16) | (1 << TOI::TIED_TO))";
 
-  if (!I->OperandList[DestOp.first].Constraints[DestOp.second].empty())
+  if (!I->OperandList[DestOp.first].Constraints[DestOp.second].isNone())
     throw "Operand '" + DestOpName + "' cannot have multiple constraints!";
-  I->OperandList[DestOp.first].Constraints[DestOp.second] = OpConstraint;
+  I->OperandList[DestOp.first].Constraints[DestOp.second] =
+    CodeGenInstruction::ConstraintInfo::getTied(FlatOpNo);
 }
 
 static void ParseConstraints(const std::string &CStr, CodeGenInstruction *I) {
@@ -210,18 +208,13 @@ CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr)
   // For backward compatibility: isTwoAddress means operand 1 is tied to
   // operand 0.
   if (isTwoAddress) {
-    if (!OperandList[1].Constraints[0].empty())
+    if (!OperandList[1].Constraints[0].isNone())
       throw R->getName() + ": cannot use isTwoAddress property: instruction "
             "already has constraint set!";
-    OperandList[1].Constraints[0] = "((0 << 16) | (1 << TOI::TIED_TO))";
+    OperandList[1].Constraints[0] =
+      CodeGenInstruction::ConstraintInfo::getTied(0);
   }
 
-  // Any operands with unset constraints get 0 as their constraint.
-  for (unsigned op = 0, e = OperandList.size(); op != e; ++op)
-    for (unsigned j = 0, e = OperandList[op].MINumOperands; j != e; ++j)
-      if (OperandList[op].Constraints[j].empty())
-        OperandList[op].Constraints[j] = "0";
-
   // Parse the DisableEncoding field.
   std::string DisableEncoding = R->getValueAsString("DisableEncoding");
   while (1) {
index d22ac3e13fedd934ecfd4d20125cb570816893f5..e81e7f43bf3d4c9b890ce8c29b03c9d9c5462405 100644 (file)
@@ -32,6 +32,35 @@ namespace llvm {
     /// instruction.
     std::string AsmString;
     
+    class ConstraintInfo {
+      enum { None, EarlyClobber, Tied } Kind;
+      unsigned OtherTiedOperand;
+    public:
+      ConstraintInfo() : Kind(None) {}
+
+      static ConstraintInfo getEarlyClobber() {
+        ConstraintInfo I;
+        I.Kind = EarlyClobber;
+        return I;
+      }
+      
+      static ConstraintInfo getTied(unsigned Op) {
+        ConstraintInfo I;
+        I.Kind = Tied;
+        I.OtherTiedOperand = Op;
+        return I;
+      }
+      
+      bool isNone() const { return Kind == None; }
+      bool isEarlyClobber() const { return Kind == EarlyClobber; }
+      bool isTied() const { return Kind == Tied; }
+      
+      unsigned getTiedOperand() const {
+        assert(isTied());
+        return OtherTiedOperand;
+      }
+    };
+    
     /// OperandInfo - The information we keep track of for each operand in the
     /// operand list for a tablegen instruction.
     struct OperandInfo {
@@ -67,7 +96,7 @@ namespace llvm {
       
       /// Constraint info for this operand.  This operand can have pieces, so we
       /// track constraint info for each.
-      std::vector<std::string> Constraints;
+      std::vector<ConstraintInfo> Constraints;
 
       OperandInfo(Record *R, const std::string &N, const std::string &PMN, 
                   unsigned MION, unsigned MINO, DagInit *MIOI)
index 21d97c3878b25a03802f60966d6c59e2b4408646..898c92af8da905258b36aa0bb3da0ede00ca8aa7 100644 (file)
@@ -118,7 +118,20 @@ InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) {
         Res += "|(1<<TOI::OptionalDef)";
 
       // Fill in constraint info.
-      Res += ", " + Inst.OperandList[i].Constraints[j];
+      Res += ", ";
+      
+      const CodeGenInstruction::ConstraintInfo &Constraint =
+        Inst.OperandList[i].Constraints[j];
+      if (Constraint.isNone())
+        Res += "0";
+      else if (Constraint.isEarlyClobber())
+        Res += "(1 << TOI::EARLY_CLOBBER)";
+      else {
+        assert(Constraint.isTied());
+        Res += "((" + utostr(Constraint.getTiedOperand()) +
+                    " << 16) | (1 << TOI::TIED_TO))";
+      }
+        
       Result.push_back(Res);
     }
   }
index 2b6e30d93d73109f84d7f8c1e39ec1552b4be7f4..da2de6b3200bb5b1480a9c748a3e9b287a37a3e5 100644 (file)
@@ -402,13 +402,10 @@ void RecognizableInstr::emitInstructionSpecifier(DisassemblerTables &tables) {
   
   for (operandIndex = 0; operandIndex < numOperands; ++operandIndex) {
     if (OperandList[operandIndex].Constraints.size()) {
-      const std::string &constraint = OperandList[operandIndex].Constraints[0];
-      std::string::size_type tiedToPos;
-
-      if ((tiedToPos = constraint.find(" << 16) | (1 << TOI::TIED_TO))")) !=
-         constraint.npos) {
-        tiedToPos--;
-        operandMapping[operandIndex] = constraint[tiedToPos] - '0';
+      const CodeGenInstruction::ConstraintInfo &Constraint =
+        OperandList[operandIndex].Constraints[0];
+      if (Constraint.isTied()) {
+        operandMapping[operandIndex] = Constraint.getTiedOperand();
       } else {
         ++numPhysicalOperands;
         operandMapping[operandIndex] = operandIndex;