[llvm-commits] [llvm] r76177 - in /llvm/trunk: include/llvm/Target/TargetAsmInfo.h lib/Target/TargetAsmInfo.cpp utils/TableGen/AsmWriterEmitter.cpp

David Greene greened at obbligato.org
Fri Jul 17 07:25:14 PDT 2009


Author: greened
Date: Fri Jul 17 09:24:46 2009
New Revision: 76177

URL: http://llvm.org/viewvc/llvm-project?rev=76177&view=rev
Log:

Add logic to align instruction operands to columns for pretty-printing.
No target uses this currently.  This patch only adds the mechanism so
that local installations can choose to enable this.

Modified:
    llvm/trunk/include/llvm/Target/TargetAsmInfo.h
    llvm/trunk/lib/Target/TargetAsmInfo.cpp
    llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp

Modified: llvm/trunk/include/llvm/Target/TargetAsmInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetAsmInfo.h?rev=76177&r1=76176&r2=76177&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Target/TargetAsmInfo.h (original)
+++ llvm/trunk/include/llvm/Target/TargetAsmInfo.h Fri Jul 17 09:24:46 2009
@@ -222,6 +222,14 @@
     /// assembler.
     const char *CommentString;            // Defaults to "#"
 
+    /// FirstOperandColumn - The output column where the first operand
+    /// should be printed
+    unsigned FirstOperandColumn;          // Defaults to 0 (ignored)
+
+    /// MaxOperandLength - The maximum length of any printed asm
+    /// operand
+    unsigned MaxOperandLength;            // Defaults to 0 (ignored)
+
     /// GlobalPrefix - If this is set to a non-empty string, it is prepended
     /// onto all global symbols.  This is often used for "_" or ".".
     const char *GlobalPrefix;             // Defaults to ""
@@ -697,6 +705,9 @@
     const char *getCommentString() const {
       return CommentString;
     }
+    unsigned getOperandColumn(unsigned Operand) const {
+      return FirstOperandColumn + (MaxOperandLength+1)*(Operand-1);
+    }
     const char *getGlobalPrefix() const {
       return GlobalPrefix;
     }

Modified: llvm/trunk/lib/Target/TargetAsmInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetAsmInfo.cpp?rev=76177&r1=76176&r2=76177&view=diff

==============================================================================
--- llvm/trunk/lib/Target/TargetAsmInfo.cpp (original)
+++ llvm/trunk/lib/Target/TargetAsmInfo.cpp Fri Jul 17 09:24:46 2009
@@ -45,6 +45,8 @@
   SeparatorChar = ';';
   CommentColumn = 60;
   CommentString = "#";
+  FirstOperandColumn = 0;
+  MaxOperandLength = 0;
   GlobalPrefix = "";
   PrivateGlobalPrefix = ".";
   LessPrivateGlobalPrefix = "";

Modified: llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp?rev=76177&r1=76176&r2=76177&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp Fri Jul 17 09:24:46 2009
@@ -19,6 +19,7 @@
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/MathExtras.h"
 #include <algorithm>
+#include <sstream>
 #include <iostream>
 using namespace llvm;
 
@@ -32,7 +33,11 @@
 // This should be an anon namespace, this works around a GCC warning.
 namespace llvm {  
   struct AsmWriterOperand {
-    enum { isLiteralTextOperand, isMachineInstrOperand } OperandType;
+    enum OpType { 
+      isLiteralTextOperand, 
+      isMachineInstrOperand,
+      isLiteralStatementOperand
+    } OperandType;
 
     /// Str - For isLiteralTextOperand, this IS the literal text.  For
     /// isMachineInstrOperand, this is the PrinterMethodName for the operand.
@@ -47,14 +52,16 @@
     std::string MiModifier;
 
     // To make VS STL happy
-    AsmWriterOperand():OperandType(isLiteralTextOperand) {}
+    AsmWriterOperand(OpType op = isLiteralTextOperand):OperandType(op) {}
 
-    explicit AsmWriterOperand(const std::string &LitStr)
-      : OperandType(isLiteralTextOperand), Str(LitStr) {}
+    AsmWriterOperand(const std::string &LitStr,
+                     OpType op = isLiteralTextOperand)
+      : OperandType(op), Str(LitStr) {}
 
     AsmWriterOperand(const std::string &Printer, unsigned OpNo, 
-                     const std::string &Modifier) 
-      : OperandType(isMachineInstrOperand), Str(Printer), MIOpNo(OpNo),
+                     const std::string &Modifier,
+                     OpType op = isMachineInstrOperand) 
+      : OperandType(op), Str(Printer), MIOpNo(OpNo),
       MiModifier(Modifier) {}
 
     bool operator!=(const AsmWriterOperand &Other) const {
@@ -78,6 +85,22 @@
     std::vector<AsmWriterOperand> Operands;
     const CodeGenInstruction *CGI;
 
+    /// MAX_GROUP_NESTING_LEVEL - The maximum number of group nesting
+    /// levels we ever expect to see in an asm operand.
+    static const int MAX_GROUP_NESTING_LEVEL = 10;
+
+    /// GroupLevel - The level of nesting of the current operand
+    /// group, such as [reg + (reg + offset)].  -1 means we are not in
+    /// a group.
+    int GroupLevel;
+
+    /// GroupDelim - Remember the delimeter for a group operand.
+    char GroupDelim[MAX_GROUP_NESTING_LEVEL];
+
+    /// InGroup - Determine whether we are in the middle of an
+    /// operand group.
+    bool InGroup() const { return GroupLevel != -1; }
+
     AsmWriterInst(const CodeGenInstruction &CGI, unsigned Variant);
 
     /// MatchesAllButOneOp - If this instruction is exactly identical to the
@@ -89,6 +112,70 @@
     void AddLiteralString(const std::string &Str) {
       // If the last operand was already a literal text string, append this to
       // it, otherwise add a new operand.
+
+      std::string::size_type SearchStart = 0;
+      std::string::size_type SpaceStartPos = std::string::npos;
+      do {
+        // Search for whitespace and replace with calls to set the
+        // output column.
+        SpaceStartPos = Str.find_first_of(" \t", SearchStart);
+        // Assume grouped text is one operand.
+        std::string::size_type StartDelimPos = Str.find_first_of("[{(", SearchStart);
+
+        SearchStart = std::string::npos;
+
+        if (StartDelimPos != std::string::npos) {
+          ++GroupLevel;
+          assert(GroupLevel < MAX_GROUP_NESTING_LEVEL
+                 && "Exceeded maximum operand group nesting level");
+          GroupDelim[GroupLevel] = Str[StartDelimPos];
+          if (SpaceStartPos != std::string::npos &&
+              SpaceStartPos > StartDelimPos) {
+            // This space doesn't count.
+            SpaceStartPos = std::string::npos;
+          }
+        }
+
+        if (InGroup()) {
+          // Find the end delimiter.
+          char EndDelim = (GroupDelim[GroupLevel] == '{' ? '}' : 
+                           (GroupDelim[GroupLevel] == '(' ? ')' : ']'));
+          std::string::size_type EndDelimSearchStart =
+            StartDelimPos == std::string::npos ? 0 : StartDelimPos+1;
+          std::string::size_type EndDelimPos = Str.find(EndDelim,
+                                                        EndDelimSearchStart);
+          SearchStart = EndDelimPos;
+          if (EndDelimPos != std::string::npos) {
+            // Iterate.
+            SearchStart = EndDelimPos + 1;
+            --GroupLevel;
+            assert(GroupLevel > -2 && "Too many end delimeters!");
+          }
+          if (InGroup())
+            SpaceStartPos = std::string::npos;
+        }
+      } while (SearchStart != std::string::npos);
+
+
+      if (SpaceStartPos != std::string::npos) {
+        std::string::size_type SpaceEndPos = 
+          Str.find_first_not_of(" \t", SpaceStartPos+1);
+        if (SpaceStartPos != 0) {
+          // Emit the first part of the string.
+          AddLiteralString(Str.substr(0, SpaceStartPos));
+        }
+        Operands.push_back(
+          AsmWriterOperand(
+            "O.PadToColumn(TAI->getOperandColumn(OperandColumn++), 1);\n",
+            AsmWriterOperand::isLiteralStatementOperand));
+        if (SpaceEndPos != std::string::npos) {
+          // Emit the last part of the string.
+          AddLiteralString(Str.substr(SpaceEndPos));
+        }
+        // We've emitted the whole string.
+        return;
+      }
+      
       if (!Operands.empty() &&
           Operands.back().OperandType == AsmWriterOperand::isLiteralTextOperand)
         Operands.back().Str.append(Str);
@@ -103,6 +190,18 @@
   if (OperandType == isLiteralTextOperand)
     return "O << \"" + Str + "\"; ";
 
+  if (OperandType == isLiteralStatementOperand) {
+    return Str;
+  }
+
+  if (OperandType == isLiteralStatementOperand) {
+    return Str;
+  }
+
+  if (OperandType == isLiteralStatementOperand) {
+    return Str;
+  }
+
   std::string Result = Str + "(MI";
   if (MIOpNo != ~0U)
     Result += ", " + utostr(MIOpNo);
@@ -115,7 +214,8 @@
 /// ParseAsmString - Parse the specified Instruction's AsmString into this
 /// AsmWriterInst.
 ///
-AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI, unsigned Variant) {
+AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI, unsigned Variant)
+    : GroupLevel(-1) {
   this->CGI = &CGI;
   unsigned CurVariant = ~0U;  // ~0 if we are outside a {.|.|.} region, other #.
 
@@ -355,6 +455,9 @@
     }
     O << "\n";
   }
+  O << "    EmitComments(*MI);\n";
+  // Print the final newline
+  O << "    O << \"\\n\";\n";
   O << "    break;\n";
 }
 
@@ -681,8 +784,16 @@
 
   O << "  // Emit the opcode for the instruction.\n"
     << "  unsigned Bits = OpInfo[MI->getOpcode()];\n"
-    << "  if (Bits == 0) return false;\n"
-    << "  O << AsmStrs+(Bits & " << (1 << AsmStrBits)-1 << ");\n\n";
+    << "  if (Bits == 0) return false;\n\n";
+
+  O << "  std::string OpStr(AsmStrs+(Bits & " << (1 << AsmStrBits)-1 << "));\n"
+    << "  unsigned OperandColumn = 1;\n"
+    << "  O << OpStr;\n\n";
+
+  O << "  if (OpStr.find_last_of(\" \\t\") == OpStr.size()-1) {\n"
+    << "    O.PadToColumn(TAI->getOperandColumn(1));\n"
+    << "    OperandColumn = 2;\n"
+    << "  }\n\n";
 
   // Output the table driven operand information.
   BitsLeft = 32-AsmStrBits;
@@ -746,10 +857,10 @@
 
     O << "  }\n";
     O << "  EmitComments(*MI);\n";
-    // Print the final newline
-    O << "  O << \"\\n\";\n";
-    O << "  return true;\n";
   }
+  // Print the final newline
+  O << "  O << \"\\n\";\n";
+  O << "  return true;\n";
   
   O << "}\n";
 }





More information about the llvm-commits mailing list