OSDN Git Service

Add a new field to MCOperandInfo that contains information about the type of the...
authorBenjamin Kramer <benny.kra@googlemail.com>
Thu, 14 Jul 2011 21:47:18 +0000 (21:47 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Thu, 14 Jul 2011 21:47:18 +0000 (21:47 +0000)
- The actual values are from the MCOI::OperandType enum.
- Teach tblgen to read it from the instruction definition.
- This is a better implementation of the hacks in edis.

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

include/llvm/MC/MCInstrDesc.h
include/llvm/Target/Target.td
utils/TableGen/CodeGenInstruction.cpp
utils/TableGen/CodeGenInstruction.h
utils/TableGen/InstrInfoEmitter.cpp

index c7a7235..4996914 100644 (file)
@@ -38,6 +38,15 @@ namespace MCOI {
     Predicate,
     OptionalDef
   };
+
+  /// Operand Type - Operands are tagged with one of the values of this enum.
+  enum OperandType {
+    OPERAND_UNKNOWN,
+    OPERAND_IMMEDIATE,
+    OPERAND_REGISTER,
+    OPERAND_MEMORY,
+    OPERAND_PCREL
+  };
 }
 
 /// MCOperandInfo - This holds information about one operand of a machine
@@ -57,6 +66,9 @@ public:
   /// Lower 16 bits are used to specify which constraints are set. The higher 16
   /// bits are used to specify the value of constraints (4 bits each).
   unsigned Constraints;
+
+  /// OperandType - Information about the type of the operand.
+  MCOI::OperandType OperandType;
   /// Currently no other information.
   
   /// isLookupPtrRegClass - Set if this operand is a pointer value and it
index 360eea3..018ccbd 100644 (file)
@@ -500,6 +500,7 @@ class Operand<ValueType ty> {
   string EncoderMethod = "";
   string DecoderMethod = "";
   string AsmOperandLowerMethod = ?;
+  string OperandType = "OPERAND_UNKNOWN";
   dag MIOperandInfo = (ops);
 
   // ParserMatchClass - The "match class" that operands of this type fit
@@ -531,6 +532,7 @@ class RegisterOperand<RegisterClass regclass, string pm = "printOperand"> {
   AsmOperandClass ParserMatchClass;
 }
 
+let OperandType = "OPERAND_IMMEDIATE" in {
 def i1imm  : Operand<i1>;
 def i8imm  : Operand<i8>;
 def i16imm : Operand<i16>;
@@ -539,6 +541,7 @@ def i64imm : Operand<i64>;
 
 def f32imm : Operand<f32>;
 def f64imm : Operand<f64>;
+}
 
 /// zero_reg definition - Special node to stand for the zero register.
 ///
index d1e63a9..a52ce86 100644 (file)
@@ -67,12 +67,14 @@ CGIOperandList::CGIOperandList(Record *R) : TheDef(R) {
     Record *Rec = Arg->getDef();
     std::string PrintMethod = "printOperand";
     std::string EncoderMethod;
+    std::string OperandType = "OPERAND_UNKNOWN";
     unsigned NumOps = 1;
     DagInit *MIOpInfo = 0;
     if (Rec->isSubClassOf("RegisterOperand")) {
       PrintMethod = Rec->getValueAsString("PrintMethod");
     } else if (Rec->isSubClassOf("Operand")) {
       PrintMethod = Rec->getValueAsString("PrintMethod");
+      OperandType = Rec->getValueAsString("OperandType");
       // If there is an explicit encoder method, use it.
       EncoderMethod = Rec->getValueAsString("EncoderMethod");
       MIOpInfo = Rec->getValueAsDag("MIOperandInfo");
@@ -96,8 +98,9 @@ CGIOperandList::CGIOperandList(Record *R) : TheDef(R) {
     } else if (Rec->getName() == "variable_ops") {
       isVariadic = true;
       continue;
-    } else if (!Rec->isSubClassOf("RegisterClass") &&
-               !Rec->isSubClassOf("PointerLikeRegClass") &&
+    } else if (Rec->isSubClassOf("RegisterClass")) {
+      OperandType = "OPERAND_REGISTER";
+    } else if (!Rec->isSubClassOf("PointerLikeRegClass") &&
                Rec->getName() != "unknown")
       throw "Unknown operand class '" + Rec->getName() +
       "' in '" + R->getName() + "' instruction!";
@@ -111,7 +114,8 @@ CGIOperandList::CGIOperandList(Record *R) : TheDef(R) {
       " has the same name as a previous operand!";
 
     OperandList.push_back(OperandInfo(Rec, ArgName, PrintMethod, EncoderMethod,
-                                      MIOperandNo, NumOps, MIOpInfo));
+                                      OperandType, MIOperandNo, NumOps,
+                                      MIOpInfo));
     MIOperandNo += NumOps;
   }
 
index e00b631..8d7669a 100644 (file)
@@ -78,6 +78,10 @@ namespace llvm {
       /// for binary encoding. "getMachineOpValue" by default.
       std::string EncoderMethodName;
 
+      /// OperandType - A value from MCOI::OperandType representing the type of
+      /// the operand.
+      std::string OperandType;
+
       /// MIOperandNo - Currently (this is meant to be phased out), some logical
       /// operands correspond to multiple MachineInstr operands.  In the X86
       /// target for example, one address operand is represented as 4
@@ -101,10 +105,11 @@ namespace llvm {
       std::vector<ConstraintInfo> Constraints;
 
       OperandInfo(Record *R, const std::string &N, const std::string &PMN,
-                  const std::string &EMN, unsigned MION, unsigned MINO,
-                  DagInit *MIOI)
+                  const std::string &EMN, const std::string &OT, unsigned MION,
+                  unsigned MINO, DagInit *MIOI)
       : Rec(R), Name(N), PrinterMethodName(PMN), EncoderMethodName(EMN),
-        MIOperandNo(MION), MINumOperands(MINO), MIOperandInfo(MIOI) {}
+        OperandType(OT), MIOperandNo(MION), MINumOperands(MINO),
+        MIOperandInfo(MIOI) {}
 
 
       /// getTiedOperand - If this operand is tied to another one, return the
index b27e497..d3c2d63 100644 (file)
@@ -121,6 +121,11 @@ InstrInfoEmitter::GetOperandInfo(const CodeGenInstruction &Inst) {
                     " << 16) | (1 << MCOI::TIED_TO))";
       }
 
+      // Fill in operand type.
+      Res += ", MCOI::";
+      assert(!Inst.Operands[i].OperandType.empty() && "Invalid operand type.");
+      Res += Inst.Operands[i].OperandType;
+
       Result.push_back(Res);
     }
   }