[llvm-commits] [llvm] r136405 - in /llvm/trunk/utils/TableGen: FixedLenDecoderEmitter.cpp FixedLenDecoderEmitter.h

Owen Anderson resistor at mac.com
Thu Jul 28 14:54:31 PDT 2011


Author: resistor
Date: Thu Jul 28 16:54:31 2011
New Revision: 136405

URL: http://llvm.org/viewvc/llvm-project?rev=136405&view=rev
Log:
Enhance the fixed-length decoder emitter to support parsing scattered fields.

Modified:
    llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp
    llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.h

Modified: llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp?rev=136405&r1=136404&r2=136405&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp Thu Jul 28 16:54:31 2011
@@ -331,6 +331,9 @@
   // Emits code to decode the singleton, and then to decode the rest.
   void emitSingletonDecoder(raw_ostream &o, unsigned &Indentation,Filter &Best);
 
+  void emitBinaryParser(raw_ostream &o , unsigned &Indentation,
+                        OperandInfo &OpInfo);
+
   // Assign a single filter and run with it.
   void runSingleFilter(FilterChooser &owner, unsigned startBit, unsigned numBit,
       bool mixed);
@@ -563,7 +566,7 @@
     "static bool decode" << Namespace << "Instruction" << BitWidth
     << "(MCInst &MI, uint" << BitWidth << "_t insn, uint64_t Address, "
     << "const void *Decoder) {\n";
-  o.indent(Indentation) << "  unsigned tmp = 0;\n";
+  o.indent(Indentation) << "  unsigned tmp = 0;\n(void)tmp;\n";
 
   ++Indentation; ++Indentation;
   // Emits code to decode the instructions.
@@ -721,6 +724,33 @@
   return Num;
 }
 
+void FilterChooser::emitBinaryParser(raw_ostream &o, unsigned &Indentation,
+                         OperandInfo &OpInfo) {
+  std::string &Decoder = OpInfo.Decoder;
+
+  if (OpInfo.numFields() == 1) {
+    OperandInfo::iterator OI = OpInfo.begin();
+    o.indent(Indentation) << "  tmp = fieldFromInstruction" << BitWidth
+                            << "(insn, " << OI->Base << ", " << OI->Width
+                            << ");\n";
+  } else {
+    o.indent(Indentation) << "  tmp = 0;\n";
+    for (OperandInfo::iterator OI = OpInfo.begin(), OE = OpInfo.end();
+         OI != OE; ++OI) {
+      o.indent(Indentation) << "  tmp |= (fieldFromInstruction" << BitWidth
+                            << "(insn, " << OI->Base << ", " << OI->Width 
+                            << ") << " << OI->Offset << ");\n";
+    }
+  }
+
+  if (Decoder != "")
+    o.indent(Indentation) << "  " << Decoder
+                          << "(MI, tmp, Address, Decoder);\n";
+  else
+    o.indent(Indentation) << "  MI.addOperand(MCOperand::CreateImm(tmp));\n";
+
+}
+
 // Emits code to decode the singleton.  Return true if we have matched all the
 // well-known bits.
 bool FilterChooser::emitSingletonDecoder(raw_ostream &o, unsigned &Indentation,
@@ -745,22 +775,13 @@
     for (std::vector<OperandInfo>::iterator
          I = InsnOperands.begin(), E = InsnOperands.end(); I != E; ++I) {
       // If a custom instruction decoder was specified, use that.
-      if (I->FieldBase == ~0U && I->FieldLength == ~0U) {
+      if (I->numFields() == 0 && I->Decoder.size()) {
         o.indent(Indentation) << "  " << I->Decoder
                               << "(MI, insn, Address, Decoder);\n";
         break;
       }
 
-      o.indent(Indentation)
-        << "  tmp = fieldFromInstruction" << BitWidth
-        << "(insn, " << I->FieldBase << ", " << I->FieldLength << ");\n";
-      if (I->Decoder != "") {
-        o.indent(Indentation) << "  " << I->Decoder
-                              << "(MI, tmp, Address, Decoder);\n";
-      } else {
-        o.indent(Indentation)
-          << "  MI.addOperand(MCOperand::CreateImm(tmp));\n";
-      }
+      emitBinaryParser(o, Indentation, *I);
     }
 
     o.indent(Indentation) << "  return true; // " << nameWithID(Opc)
@@ -799,23 +820,13 @@
   for (std::vector<OperandInfo>::iterator
        I = InsnOperands.begin(), E = InsnOperands.end(); I != E; ++I) {
     // If a custom instruction decoder was specified, use that.
-    if (I->FieldBase == ~0U && I->FieldLength == ~0U) {
+    if (I->numFields() == 0 && I->Decoder.size()) {
       o.indent(Indentation) << "  " << I->Decoder
                             << "(MI, insn, Address, Decoder);\n";
       break;
     }
 
-    o.indent(Indentation)
-      << "  tmp = fieldFromInstruction" << BitWidth
-      << "(insn, " << I->FieldBase
-      << ", " << I->FieldLength << ");\n";
-    if (I->Decoder != "") {
-      o.indent(Indentation) << "  " << I->Decoder
-                            << "(MI, tmp, Address, Decoder);\n";
-    } else {
-      o.indent(Indentation)
-        << "  MI.addOperand(MCOperand::CreateImm(tmp));\n";
-    }
+    emitBinaryParser(o, Indentation, *I);
   }
   o.indent(Indentation) << "  return true; // " << nameWithID(Opc)
                         << '\n';
@@ -1192,7 +1203,7 @@
   // of trying to auto-generate the decoder.
   std::string InstDecoder = Def.getValueAsString("DecoderMethod");
   if (InstDecoder != "") {
-    InsnOperands.push_back(OperandInfo(~0U, ~0U, InstDecoder));
+    InsnOperands.push_back(OperandInfo(InstDecoder));
     Operands[Opc] = InsnOperands;
     return true;
   }
@@ -1215,69 +1226,73 @@
   // For each operand, see if we can figure out where it is encoded.
   for (std::vector<std::pair<Init*, std::string> >::iterator
        NI = InOutOperands.begin(), NE = InOutOperands.end(); NI != NE; ++NI) {
-    unsigned PrevBit = ~0;
-    unsigned Base = ~0;
-    unsigned PrevPos = ~0;
     std::string Decoder = "";
 
+    // At this point, we can locate the field, but we need to know how to
+    // interpret it.  As a first step, require the target to provide callbacks
+    // for decoding register classes.
+    // FIXME: This need to be extended to handle instructions with custom
+    // decoder methods, and operands with (simple) MIOperandInfo's.
+    TypedInit *TI = dynamic_cast<TypedInit*>(NI->first);
+    RecordRecTy *Type = dynamic_cast<RecordRecTy*>(TI->getType());
+    Record *TypeRecord = Type->getRecord();
+    bool isReg = false;
+    if (TypeRecord->isSubClassOf("RegisterOperand"))
+      TypeRecord = TypeRecord->getValueAsDef("RegClass");
+    if (TypeRecord->isSubClassOf("RegisterClass")) {
+      Decoder = "Decode" + TypeRecord->getName() + "RegisterClass";
+      isReg = true;
+    }
+
+    RecordVal *DecoderString = TypeRecord->getValue("DecoderMethod");
+    StringInit *String = DecoderString ?
+      dynamic_cast<StringInit*>(DecoderString->getValue()) : 0;
+    if (!isReg && String && String->getValue() != "")
+      Decoder = String->getValue();
+
+    OperandInfo OpInfo(Decoder);
+    unsigned Base = ~0U;
+    unsigned Width = 0;
+    unsigned Offset = 0;
+
     for (unsigned bi = 0; bi < Bits.getNumBits(); ++bi) {
       VarBitInit *BI = dynamic_cast<VarBitInit*>(Bits.getBit(bi));
-      if (!BI) continue;
+      if (!BI) {
+        if (Base != ~0U) {
+          OpInfo.addField(Base, Width, Offset);
+          Base = ~0U;
+          Width = 0;
+          Offset = 0;
+        }
+        continue;
+      }
 
       VarInit *Var = dynamic_cast<VarInit*>(BI->getVariable());
       assert(Var);
-      unsigned CurrBit = BI->getBitNum();
-      if (Var->getName() != NI->second) continue;
-
-      // Figure out the lowest bit of the value, and the width of the field.
-      // Deliberately don't try to handle cases where the field is scattered,
-      // or where not all bits of the the field are explicit.
-      if (Base == ~0U && PrevBit == ~0U && PrevPos == ~0U) {
-        if (CurrBit == 0)
-          Base = bi;
-        else
-          continue;
+      if (Var->getName() != NI->second) {
+        if (Base != ~0U) {
+          OpInfo.addField(Base, Width, Offset);
+          Base = ~0U;
+          Width = 0;
+          Offset = 0;
+        }
+        continue;
       }
 
-      if ((PrevPos != ~0U && bi-1 != PrevPos) ||
-          (CurrBit != ~0U && CurrBit-1 != PrevBit)) {
-        PrevBit = ~0;
-        Base = ~0;
-        PrevPos = ~0;
-      }
-
-      PrevPos = bi;
-      PrevBit = CurrBit;
-
-      // At this point, we can locate the field, but we need to know how to
-      // interpret it.  As a first step, require the target to provide callbacks
-      // for decoding register classes.
-      // FIXME: This need to be extended to handle instructions with custom
-      // decoder methods, and operands with (simple) MIOperandInfo's.
-      TypedInit *TI = dynamic_cast<TypedInit*>(NI->first);
-      RecordRecTy *Type = dynamic_cast<RecordRecTy*>(TI->getType());
-      Record *TypeRecord = Type->getRecord();
-      bool isReg = false;
-      if (TypeRecord->isSubClassOf("RegisterOperand"))
-        TypeRecord = TypeRecord->getValueAsDef("RegClass");
-      if (TypeRecord->isSubClassOf("RegisterClass")) {
-        Decoder = "Decode" + TypeRecord->getName() + "RegisterClass";
-        isReg = true;
+      if (Base == ~0U) {
+        Base = bi;
+        Width = 1;
+        Offset = BI->getBitNum();
+      } else {
+        ++Width;
       }
-
-      RecordVal *DecoderString = TypeRecord->getValue("DecoderMethod");
-      StringInit *String = DecoderString ?
-        dynamic_cast<StringInit*>(DecoderString->getValue()) :
-        0;
-      if (!isReg && String && String->getValue() != "")
-        Decoder = String->getValue();
     }
 
-    if (Base != ~0U) {
-      InsnOperands.push_back(OperandInfo(Base, PrevBit+1, Decoder));
-      DEBUG(errs() << "ENCODED OPERAND: $" << NI->second << " @ ("
-                   << utostr(Base+PrevBit) << ", " << utostr(Base) << ")\n");
-    }
+    if (Base != ~0U)
+      OpInfo.addField(Base, Width, Offset);
+
+    if (OpInfo.numFields() > 0)
+      InsnOperands.push_back(OpInfo);
   }
 
   Operands[Opc] = InsnOperands;

Modified: llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.h?rev=136405&r1=136404&r2=136405&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.h (original)
+++ llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.h Thu Jul 28 16:54:31 2011
@@ -22,13 +22,29 @@
 
 namespace llvm {
 
+struct EncodingField {
+  unsigned Base, Width, Offset;
+  EncodingField(unsigned B, unsigned W, unsigned O)
+    : Base(B), Width(W), Offset(O) { }
+};
+
 struct OperandInfo {
-  unsigned FieldBase;
-  unsigned FieldLength;
+  std::vector<EncodingField> Fields;
   std::string Decoder;
 
-  OperandInfo(unsigned FB, unsigned FL, std::string D)
-    : FieldBase(FB), FieldLength(FL), Decoder(D) { }
+  OperandInfo(std::string D)
+    : Decoder(D) { }
+
+  void addField(unsigned Base, unsigned Width, unsigned Offset) {
+    Fields.push_back(EncodingField(Base, Width, Offset));
+  }
+
+  unsigned numFields() { return Fields.size(); }
+
+  typedef std::vector<EncodingField>::iterator iterator;
+
+  iterator begin() { return Fields.begin(); }
+  iterator end()   { return Fields.end();   }
 };
 
 class FixedLenDecoderEmitter : public TableGenBackend {





More information about the llvm-commits mailing list