[llvm-commits] [llvm] r95697 - in /llvm/trunk/utils/TableGen: AsmWriterEmitter.cpp AsmWriterInst.cpp AsmWriterInst.h

Chris Lattner clattner at apple.com
Tue Feb 9 14:52:29 PST 2010


On Feb 9, 2010, at 1:50 PM, Sean Callanan wrote:

> Author: spyffe
> Date: Tue Feb  9 15:50:41 2010
> New Revision: 95697
>
> URL: http://llvm.org/viewvc/llvm-project?rev=95697&view=rev
> Log:
> Per PR 6219, factored AsmWriterInst and AsmWriterOperand
> out of the AsmWriterEmitter.  This patch does the physical
> code movement, but leaves the implementation unchanged. I'll
> make any changes necessary to generalize the code in a
> separate patch.

Nice!  Please add newlines at the end of files, and watch 80 columns.   
It looks like your editor reindented the code you moved and broke the  
formatting.

-Chris

>
> Added:
>    llvm/trunk/utils/TableGen/AsmWriterInst.cpp
>    llvm/trunk/utils/TableGen/AsmWriterInst.h
> Modified:
>    llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp
>
> Modified: llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp?rev=95697&r1=95696&r2=95697&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp (original)
> +++ llvm/trunk/utils/TableGen/AsmWriterEmitter.cpp Tue Feb  9  
> 15:50:41 2010
> @@ -13,339 +13,15 @@
> // 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
>
> #include "AsmWriterEmitter.h"
> +#include "AsmWriterInst.h"
> #include "CodeGenTarget.h"
> #include "Record.h"
> #include "StringToOffsetTable.h"
> -#include "llvm/ADT/StringExtras.h"
> #include "llvm/Support/Debug.h"
> #include "llvm/Support/MathExtras.h"
> #include <algorithm>
> using namespace llvm;
>
> -
> -static bool isIdentChar(char C) {
> -  return (C >= 'a' && C <= 'z') ||
> -         (C >= 'A' && C <= 'Z') ||
> -         (C >= '0' && C <= '9') ||
> -         C == '_';
> -}
> -
> -// This should be an anon namespace, this works around a GCC warning.
> -namespace llvm {
> -  struct AsmWriterOperand {
> -    enum OpType {
> -      // Output this text surrounded by quotes to the asm.
> -      isLiteralTextOperand,
> -      // This is the name of a routine to call to print the operand.
> -      isMachineInstrOperand,
> -      // Output this text verbatim to the asm writer.  It is code  
> that
> -      // will output some text to the asm.
> -      isLiteralStatementOperand
> -    } OperandType;
> -
> -    /// Str - For isLiteralTextOperand, this IS the literal text.   
> For
> -    /// isMachineInstrOperand, this is the PrinterMethodName for  
> the operand..
> -    /// For isLiteralStatementOperand, this is the code to insert  
> verbatim
> -    /// into the asm writer.
> -    std::string Str;
> -
> -    /// MiOpNo - For isMachineInstrOperand, this is the operand  
> number of the
> -    /// machine instruction.
> -    unsigned MIOpNo;
> -
> -    /// MiModifier - For isMachineInstrOperand, this is the  
> modifier string for
> -    /// an operand, specified with syntax like ${opname:modifier}.
> -    std::string MiModifier;
> -
> -    // To make VS STL happy
> -    AsmWriterOperand(OpType op =  
> isLiteralTextOperand):OperandType(op) {}
> -
> -    AsmWriterOperand(const std::string &LitStr,
> -                     OpType op = isLiteralTextOperand)
> -      : OperandType(op), Str(LitStr) {}
> -
> -    AsmWriterOperand(const std::string &Printer, unsigned OpNo,
> -                     const std::string &Modifier,
> -                     OpType op = isMachineInstrOperand)
> -      : OperandType(op), Str(Printer), MIOpNo(OpNo),
> -      MiModifier(Modifier) {}
> -
> -    bool operator!=(const AsmWriterOperand &Other) const {
> -      if (OperandType != Other.OperandType || Str != Other.Str)  
> return true;
> -      if (OperandType == isMachineInstrOperand)
> -        return MIOpNo != Other.MIOpNo || MiModifier !=  
> Other.MiModifier;
> -      return false;
> -    }
> -    bool operator==(const AsmWriterOperand &Other) const {
> -      return !operator!=(Other);
> -    }
> -
> -    /// getCode - Return the code that prints this operand.
> -    std::string getCode() const;
> -  };
> -}
> -
> -namespace llvm {
> -  class AsmWriterInst {
> -  public:
> -    std::vector<AsmWriterOperand> Operands;
> -    const CodeGenInstruction *CGI;
> -
> -    AsmWriterInst(const CodeGenInstruction &CGI, Record *AsmWriter);
> -
> -    /// MatchesAllButOneOp - If this instruction is exactly  
> identical to the
> -    /// specified instruction except for one differing operand,  
> return the
> -    /// differing operand number.  Otherwise return ~0.
> -    unsigned MatchesAllButOneOp(const AsmWriterInst &Other) const;
> -
> -  private:
> -    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.
> -      if (!Operands.empty() &&
> -          Operands.back().OperandType ==  
> AsmWriterOperand::isLiteralTextOperand)
> -        Operands.back().Str.append(Str);
> -      else
> -        Operands.push_back(AsmWriterOperand(Str));
> -    }
> -  };
> -}
> -
> -
> -std::string AsmWriterOperand::getCode() const {
> -  if (OperandType == isLiteralTextOperand) {
> -    if (Str.size() == 1)
> -      return "O << '" + Str + "'; ";
> -    return "O << \"" + Str + "\"; ";
> -  }
> -
> -  if (OperandType == isLiteralStatementOperand)
> -    return Str;
> -
> -  std::string Result = Str + "(MI";
> -  if (MIOpNo != ~0U)
> -    Result += ", " + utostr(MIOpNo);
> -  if (!MiModifier.empty())
> -    Result += ", \"" + MiModifier + '"';
> -  return Result + "); ";
> -}
> -
> -
> -/// ParseAsmString - Parse the specified Instruction's AsmString  
> into this
> -/// AsmWriterInst.
> -///
> -AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI, Record  
> *AsmWriter) {
> -  this->CGI = &CGI;
> -
> -  unsigned Variant       = AsmWriter->getValueAsInt("Variant");
> -  int FirstOperandColumn = AsmWriter- 
> >getValueAsInt("FirstOperandColumn");
> -  int OperandSpacing     = AsmWriter- 
> >getValueAsInt("OperandSpacing");
> -
> -  unsigned CurVariant = ~0U;  // ~0 if we are outside a {.|.|.}  
> region, other #.
> -
> -  // This is the number of tabs we've seen if we're doing columnar  
> layout.
> -  unsigned CurColumn = 0;
> -
> -
> -  // NOTE: Any extensions to this code need to be mirrored in the
> -  // AsmPrinter::printInlineAsm code that executes as compile time  
> (assuming
> -  // that inline asm strings should also get the new feature)!
> -  const std::string &AsmString = CGI.AsmString;
> -  std::string::size_type LastEmitted = 0;
> -  while (LastEmitted != AsmString.size()) {
> -    std::string::size_type DollarPos =
> -      AsmString.find_first_of("${|}\\", LastEmitted);
> -    if (DollarPos == std::string::npos) DollarPos = AsmString.size();
> -
> -    // Emit a constant string fragment.
> -
> -    if (DollarPos != LastEmitted) {
> -      if (CurVariant == Variant || CurVariant == ~0U) {
> -        for (; LastEmitted != DollarPos; ++LastEmitted)
> -          switch (AsmString[LastEmitted]) {
> -          case '\n':
> -            AddLiteralString("\\n");
> -            break;
> -          case '\t':
> -            // If the asm writer is not using a columnar layout, \t  
> is not
> -            // magic.
> -            if (FirstOperandColumn == -1 || OperandSpacing == -1) {
> -              AddLiteralString("\\t");
> -            } else {
> -              // We recognize a tab as an operand delimeter.
> -              unsigned DestColumn = FirstOperandColumn +
> -                                    CurColumn++ * OperandSpacing;
> -              Operands.push_back(
> -                AsmWriterOperand("O.PadToColumn(" +
> -                                 utostr(DestColumn) + ");\n",
> -                                  
> AsmWriterOperand::isLiteralStatementOperand));
> -            }
> -            break;
> -          case '"':
> -            AddLiteralString("\\\"");
> -            break;
> -          case '\\':
> -            AddLiteralString("\\\\");
> -            break;
> -          default:
> -            AddLiteralString(std::string(1, AsmString[LastEmitted]));
> -            break;
> -          }
> -      } else {
> -        LastEmitted = DollarPos;
> -      }
> -    } else if (AsmString[DollarPos] == '\\') {
> -      if (DollarPos+1 != AsmString.size() &&
> -          (CurVariant == Variant || CurVariant == ~0U)) {
> -        if (AsmString[DollarPos+1] == 'n') {
> -          AddLiteralString("\\n");
> -        } else if (AsmString[DollarPos+1] == 't') {
> -          // If the asm writer is not using a columnar layout, \t  
> is not
> -          // magic.
> -          if (FirstOperandColumn == -1 || OperandSpacing == -1) {
> -            AddLiteralString("\\t");
> -            break;
> -          }
> -
> -          // We recognize a tab as an operand delimeter.
> -          unsigned DestColumn = FirstOperandColumn +
> -                                CurColumn++ * OperandSpacing;
> -          Operands.push_back(
> -            AsmWriterOperand("O.PadToColumn(" + utostr(DestColumn)  
> + ");\n",
> -                              
> AsmWriterOperand::isLiteralStatementOperand));
> -          break;
> -        } else if (std::string("${|}\\").find(AsmString[DollarPos+1])
> -                   != std::string::npos) {
> -          AddLiteralString(std::string(1, AsmString[DollarPos+1]));
> -        } else {
> -          throw "Non-supported escaped character found in  
> instruction '" +
> -            CGI.TheDef->getName() + "'!";
> -        }
> -        LastEmitted = DollarPos+2;
> -        continue;
> -      }
> -    } else if (AsmString[DollarPos] == '{') {
> -      if (CurVariant != ~0U)
> -        throw "Nested variants found for instruction '" +
> -              CGI.TheDef->getName() + "'!";
> -      LastEmitted = DollarPos+1;
> -      CurVariant = 0;   // We are now inside of the variant!
> -    } else if (AsmString[DollarPos] == '|') {
> -      if (CurVariant == ~0U)
> -        throw "'|' character found outside of a variant in  
> instruction '"
> -          + CGI.TheDef->getName() + "'!";
> -      ++CurVariant;
> -      ++LastEmitted;
> -    } else if (AsmString[DollarPos] == '}') {
> -      if (CurVariant == ~0U)
> -        throw "'}' character found outside of a variant in  
> instruction '"
> -          + CGI.TheDef->getName() + "'!";
> -      ++LastEmitted;
> -      CurVariant = ~0U;
> -    } else if (DollarPos+1 != AsmString.size() &&
> -               AsmString[DollarPos+1] == '$') {
> -      if (CurVariant == Variant || CurVariant == ~0U) {
> -        AddLiteralString("$");  // "$$" -> $
> -      }
> -      LastEmitted = DollarPos+2;
> -    } else {
> -      // Get the name of the variable.
> -      std::string::size_type VarEnd = DollarPos+1;
> -
> -      // handle ${foo}bar as $foo by detecting whether the  
> character following
> -      // the dollar sign is a curly brace.  If so, advance VarEnd  
> and DollarPos
> -      // so the variable name does not contain the leading curly  
> brace.
> -      bool hasCurlyBraces = false;
> -      if (VarEnd < AsmString.size() && '{' == AsmString[VarEnd]) {
> -        hasCurlyBraces = true;
> -        ++DollarPos;
> -        ++VarEnd;
> -      }
> -
> -      while (VarEnd < AsmString.size() &&  
> isIdentChar(AsmString[VarEnd]))
> -        ++VarEnd;
> -      std::string VarName(AsmString.begin()+DollarPos+1,
> -                          AsmString.begin()+VarEnd);
> -
> -      // Modifier - Support ${foo:modifier} syntax, where  
> "modifier" is passed
> -      // into printOperand.  Also support ${:feature}, which is  
> passed into
> -      // PrintSpecial.
> -      std::string Modifier;
> -
> -      // In order to avoid starting the next string at the  
> terminating curly
> -      // brace, advance the end position past it if we found an  
> opening curly
> -      // brace.
> -      if (hasCurlyBraces) {
> -        if (VarEnd >= AsmString.size())
> -          throw "Reached end of string before terminating curly  
> brace in '"
> -                + CGI.TheDef->getName() + "'";
> -
> -        // Look for a modifier string.
> -        if (AsmString[VarEnd] == ':') {
> -          ++VarEnd;
> -          if (VarEnd >= AsmString.size())
> -            throw "Reached end of string before terminating curly  
> brace in '"
> -              + CGI.TheDef->getName() + "'";
> -
> -          unsigned ModifierStart = VarEnd;
> -          while (VarEnd < AsmString.size() &&  
> isIdentChar(AsmString[VarEnd]))
> -            ++VarEnd;
> -          Modifier = std::string(AsmString.begin()+ModifierStart,
> -                                 AsmString.begin()+VarEnd);
> -          if (Modifier.empty())
> -            throw "Bad operand modifier name in '"+ CGI.TheDef- 
> >getName() + "'";
> -        }
> -
> -        if (AsmString[VarEnd] != '}')
> -          throw "Variable name beginning with '{' did not end with  
> '}' in '"
> -                + CGI.TheDef->getName() + "'";
> -        ++VarEnd;
> -      }
> -      if (VarName.empty() && Modifier.empty())
> -        throw "Stray '$' in '" + CGI.TheDef->getName() +
> -              "' asm string, maybe you want $$?";
> -
> -      if (VarName.empty()) {
> -        // Just a modifier, pass this into PrintSpecial.
> -        Operands.push_back(AsmWriterOperand("PrintSpecial", ~0U,  
> Modifier));
> -      } else {
> -        // Otherwise, normal operand.
> -        unsigned OpNo = CGI.getOperandNamed(VarName);
> -        CodeGenInstruction::OperandInfo OpInfo =  
> CGI.OperandList[OpNo];
> -
> -        if (CurVariant == Variant || CurVariant == ~0U) {
> -          unsigned MIOp = OpInfo.MIOperandNo;
> -           
> Operands.push_back(AsmWriterOperand(OpInfo.PrinterMethodName, MIOp,
> -                                              Modifier));
> -        }
> -      }
> -      LastEmitted = VarEnd;
> -    }
> -  }
> -
> -  Operands.push_back(AsmWriterOperand("return;",
> -                                   
> AsmWriterOperand::isLiteralStatementOperand));
> -}
> -
> -/// MatchesAllButOneOp - If this instruction is exactly identical  
> to the
> -/// specified instruction except for one differing operand, return  
> the differing
> -/// operand number.  If more than one operand mismatches, return  
> ~1, otherwise
> -/// if the instructions are identical return ~0.
> -unsigned AsmWriterInst::MatchesAllButOneOp(const AsmWriterInst  
> &Other)const{
> -  if (Operands.size() != Other.Operands.size()) return ~1;
> -
> -  unsigned MismatchOperand = ~0U;
> -  for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
> -    if (Operands[i] != Other.Operands[i]) {
> -      if (MismatchOperand != ~0U)  // Already have one mismatch?
> -        return ~1U;
> -      else
> -        MismatchOperand = i;
> -    }
> -  }
> -  return MismatchOperand;
> -}
> -
> static void PrintCases(std::vector<std::pair<std::string,
>                        AsmWriterOperand> > &OpsToPrint, raw_ostream  
> &O) {
>   O << "    case " << OpsToPrint.back().first << ": ";
>
> Added: llvm/trunk/utils/TableGen/AsmWriterInst.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/AsmWriterInst.cpp?rev=95697&view=auto
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/utils/TableGen/AsmWriterInst.cpp (added)
> +++ llvm/trunk/utils/TableGen/AsmWriterInst.cpp Tue Feb  9 15:50:41  
> 2010
> @@ -0,0 +1,259 @@
> +//===- AsmWriterInst.h - Classes encapsulating a printable inst  
> -----------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open  
> Source
> +// License. See LICENSE.TXT for details.
> +//
> +// 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> +//
> +// These classes implement a parser for assembly strings.
> +//
> +// 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> +
> +#include "AsmWriterInst.h"
> +#include "CodeGenTarget.h"
> +#include "Record.h"
> +#include "llvm/ADT/StringExtras.h"
> +
> +using namespace llvm;
> +
> +static bool isIdentChar(char C) {
> +  return (C >= 'a' && C <= 'z') ||
> +  (C >= 'A' && C <= 'Z') ||
> +  (C >= '0' && C <= '9') ||
> +  C == '_';
> +}
> +
> +std::string AsmWriterOperand::getCode() const {
> +  if (OperandType == isLiteralTextOperand) {
> +    if (Str.size() == 1)
> +      return "O << '" + Str + "'; ";
> +    return "O << \"" + Str + "\"; ";
> +  }
> +
> +  if (OperandType == isLiteralStatementOperand)
> +    return Str;
> +
> +  std::string Result = Str + "(MI";
> +  if (MIOpNo != ~0U)
> +    Result += ", " + utostr(MIOpNo);
> +  if (!MiModifier.empty())
> +    Result += ", \"" + MiModifier + '"';
> +  return Result + "); ";
> +}
> +
> +/// ParseAsmString - Parse the specified Instruction's AsmString  
> into this
> +/// AsmWriterInst.
> +///
> +AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI, Record  
> *AsmWriter) {
> +  this->CGI = &CGI;
> +
> +  unsigned Variant       = AsmWriter->getValueAsInt("Variant");
> +  int FirstOperandColumn = AsmWriter- 
> >getValueAsInt("FirstOperandColumn");
> +  int OperandSpacing     = AsmWriter- 
> >getValueAsInt("OperandSpacing");
> +
> +  unsigned CurVariant = ~0U;  // ~0 if we are outside a {.|.|.}  
> region, other #.
> +
> +  // This is the number of tabs we've seen if we're doing columnar  
> layout.
> +  unsigned CurColumn = 0;
> +
> +
> +  // NOTE: Any extensions to this code need to be mirrored in the
> +  // AsmPrinter::printInlineAsm code that executes as compile time  
> (assuming
> +  // that inline asm strings should also get the new feature)!
> +  const std::string &AsmString = CGI.AsmString;
> +  std::string::size_type LastEmitted = 0;
> +  while (LastEmitted != AsmString.size()) {
> +    std::string::size_type DollarPos =
> +    AsmString.find_first_of("${|}\\", LastEmitted);
> +    if (DollarPos == std::string::npos) DollarPos = AsmString.size();
> +
> +    // Emit a constant string fragment.
> +
> +    if (DollarPos != LastEmitted) {
> +      if (CurVariant == Variant || CurVariant == ~0U) {
> +        for (; LastEmitted != DollarPos; ++LastEmitted)
> +          switch (AsmString[LastEmitted]) {
> +            case '\n':
> +              AddLiteralString("\\n");
> +              break;
> +            case '\t':
> +              // If the asm writer is not using a columnar layout,  
> \t is not
> +              // magic.
> +              if (FirstOperandColumn == -1 || OperandSpacing == -1) {
> +                AddLiteralString("\\t");
> +              } else {
> +                // We recognize a tab as an operand delimeter.
> +                unsigned DestColumn = FirstOperandColumn +
> +                CurColumn++ * OperandSpacing;
> +                Operands.push_back(
> +                                    
> AsmWriterOperand("O.PadToColumn(" +
> +                                                     
> utostr(DestColumn) + ");\n",
> +                                                     
> AsmWriterOperand::isLiteralStatementOperand));
> +              }
> +              break;
> +            case '"':
> +              AddLiteralString("\\\"");
> +              break;
> +            case '\\':
> +              AddLiteralString("\\\\");
> +              break;
> +            default:
> +              AddLiteralString(std::string(1,  
> AsmString[LastEmitted]));
> +              break;
> +          }
> +      } else {
> +        LastEmitted = DollarPos;
> +      }
> +    } else if (AsmString[DollarPos] == '\\') {
> +      if (DollarPos+1 != AsmString.size() &&
> +          (CurVariant == Variant || CurVariant == ~0U)) {
> +        if (AsmString[DollarPos+1] == 'n') {
> +          AddLiteralString("\\n");
> +        } else if (AsmString[DollarPos+1] == 't') {
> +          // If the asm writer is not using a columnar layout, \t  
> is not
> +          // magic.
> +          if (FirstOperandColumn == -1 || OperandSpacing == -1) {
> +            AddLiteralString("\\t");
> +            break;
> +          }
> +
> +          // We recognize a tab as an operand delimeter.
> +          unsigned DestColumn = FirstOperandColumn +
> +          CurColumn++ * OperandSpacing;
> +          Operands.push_back(
> +                             AsmWriterOperand("O.PadToColumn(" +  
> utostr(DestColumn) + ");\n",
> +                                               
> AsmWriterOperand::isLiteralStatementOperand));
> +          break;
> +        } else if (std::string("${|}\\").find(AsmString[DollarPos+1])
> +                   != std::string::npos) {
> +          AddLiteralString(std::string(1, AsmString[DollarPos+1]));
> +        } else {
> +          throw "Non-supported escaped character found in  
> instruction '" +
> +          CGI.TheDef->getName() + "'!";
> +        }
> +        LastEmitted = DollarPos+2;
> +        continue;
> +      }
> +    } else if (AsmString[DollarPos] == '{') {
> +      if (CurVariant != ~0U)
> +        throw "Nested variants found for instruction '" +
> +        CGI.TheDef->getName() + "'!";
> +      LastEmitted = DollarPos+1;
> +      CurVariant = 0;   // We are now inside of the variant!
> +    } else if (AsmString[DollarPos] == '|') {
> +      if (CurVariant == ~0U)
> +        throw "'|' character found outside of a variant in  
> instruction '"
> +        + CGI.TheDef->getName() + "'!";
> +      ++CurVariant;
> +      ++LastEmitted;
> +    } else if (AsmString[DollarPos] == '}') {
> +      if (CurVariant == ~0U)
> +        throw "'}' character found outside of a variant in  
> instruction '"
> +        + CGI.TheDef->getName() + "'!";
> +      ++LastEmitted;
> +      CurVariant = ~0U;
> +    } else if (DollarPos+1 != AsmString.size() &&
> +               AsmString[DollarPos+1] == '$') {
> +      if (CurVariant == Variant || CurVariant == ~0U) {
> +        AddLiteralString("$");  // "$$" -> $
> +      }
> +      LastEmitted = DollarPos+2;
> +    } else {
> +      // Get the name of the variable.
> +      std::string::size_type VarEnd = DollarPos+1;
> +
> +      // handle ${foo}bar as $foo by detecting whether the  
> character following
> +      // the dollar sign is a curly brace.  If so, advance VarEnd  
> and DollarPos
> +      // so the variable name does not contain the leading curly  
> brace.
> +      bool hasCurlyBraces = false;
> +      if (VarEnd < AsmString.size() && '{' == AsmString[VarEnd]) {
> +        hasCurlyBraces = true;
> +        ++DollarPos;
> +        ++VarEnd;
> +      }
> +
> +      while (VarEnd < AsmString.size() &&  
> isIdentChar(AsmString[VarEnd]))
> +        ++VarEnd;
> +      std::string VarName(AsmString.begin()+DollarPos+1,
> +                          AsmString.begin()+VarEnd);
> +
> +      // Modifier - Support ${foo:modifier} syntax, where  
> "modifier" is passed
> +      // into printOperand.  Also support ${:feature}, which is  
> passed into
> +      // PrintSpecial.
> +      std::string Modifier;
> +
> +      // In order to avoid starting the next string at the  
> terminating curly
> +      // brace, advance the end position past it if we found an  
> opening curly
> +      // brace.
> +      if (hasCurlyBraces) {
> +        if (VarEnd >= AsmString.size())
> +          throw "Reached end of string before terminating curly  
> brace in '"
> +          + CGI.TheDef->getName() + "'";
> +
> +        // Look for a modifier string.
> +        if (AsmString[VarEnd] == ':') {
> +          ++VarEnd;
> +          if (VarEnd >= AsmString.size())
> +            throw "Reached end of string before terminating curly  
> brace in '"
> +            + CGI.TheDef->getName() + "'";
> +
> +          unsigned ModifierStart = VarEnd;
> +          while (VarEnd < AsmString.size() &&  
> isIdentChar(AsmString[VarEnd]))
> +            ++VarEnd;
> +          Modifier = std::string(AsmString.begin()+ModifierStart,
> +                                 AsmString.begin()+VarEnd);
> +          if (Modifier.empty())
> +            throw "Bad operand modifier name in '"+ CGI.TheDef- 
> >getName() + "'";
> +        }
> +
> +        if (AsmString[VarEnd] != '}')
> +          throw "Variable name beginning with '{' did not end with  
> '}' in '"
> +          + CGI.TheDef->getName() + "'";
> +        ++VarEnd;
> +      }
> +      if (VarName.empty() && Modifier.empty())
> +        throw "Stray '$' in '" + CGI.TheDef->getName() +
> +        "' asm string, maybe you want $$?";
> +
> +      if (VarName.empty()) {
> +        // Just a modifier, pass this into PrintSpecial.
> +        Operands.push_back(AsmWriterOperand("PrintSpecial", ~0U,  
> Modifier));
> +      } else {
> +        // Otherwise, normal operand.
> +        unsigned OpNo = CGI.getOperandNamed(VarName);
> +        CodeGenInstruction::OperandInfo OpInfo =  
> CGI.OperandList[OpNo];
> +
> +        if (CurVariant == Variant || CurVariant == ~0U) {
> +          unsigned MIOp = OpInfo.MIOperandNo;
> +           
> Operands.push_back(AsmWriterOperand(OpInfo.PrinterMethodName, MIOp,
> +                                              Modifier));
> +        }
> +      }
> +      LastEmitted = VarEnd;
> +    }
> +  }
> +
> +  Operands.push_back(AsmWriterOperand("return;",
> +                                       
> AsmWriterOperand::isLiteralStatementOperand));
> +}
> +
> +/// MatchesAllButOneOp - If this instruction is exactly identical  
> to the
> +/// specified instruction except for one differing operand, return  
> the differing
> +/// operand number.  If more than one operand mismatches, return  
> ~1, otherwise
> +/// if the instructions are identical return ~0.
> +unsigned AsmWriterInst::MatchesAllButOneOp(const AsmWriterInst  
> &Other)const{
> +  if (Operands.size() != Other.Operands.size()) return ~1;
> +
> +  unsigned MismatchOperand = ~0U;
> +  for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
> +    if (Operands[i] != Other.Operands[i]) {
> +      if (MismatchOperand != ~0U)  // Already have one mismatch?
> +        return ~1U;
> +      else
> +        MismatchOperand = i;
> +    }
> +  }
> +  return MismatchOperand;
> +}
> \ No newline at end of file
>
> Added: llvm/trunk/utils/TableGen/AsmWriterInst.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/AsmWriterInst.h?rev=95697&view=auto
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/utils/TableGen/AsmWriterInst.h (added)
> +++ llvm/trunk/utils/TableGen/AsmWriterInst.h Tue Feb  9 15:50:41 2010
> @@ -0,0 +1,104 @@
> +//===- AsmWriterInst.h - Classes encapsulating a printable inst -*-  
> C++ -*-===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open  
> Source
> +// License. See LICENSE.TXT for details.
> +//
> +// 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> +//
> +// These classes implement a parser for assembly strings.  The  
> parser splits
> +// the string into operands, which can be literal strings (the  
> constant bits of
> +// the string), actual operands (i.e., operands from the  
> MachineInstr), and
> +// dynamically-generated text, specified by raw C++ code.
> +//
> +// 
> = 
> = 
> = 
> ----------------------------------------------------------------------= 
> ==//
> +
> +#ifndef ASMWRITER_INST_H
> +#define ASMWRITER_INST_H
> +
> +#include <string>
> +#include <vector>
> +
> +namespace llvm {
> +  class CodeGenInstruction;
> +  class Record;
> +
> +  struct AsmWriterOperand {
> +    enum OpType {
> +      // Output this text surrounded by quotes to the asm.
> +      isLiteralTextOperand,
> +      // This is the name of a routine to call to print the operand.
> +      isMachineInstrOperand,
> +      // Output this text verbatim to the asm writer.  It is code  
> that
> +      // will output some text to the asm.
> +      isLiteralStatementOperand
> +    } OperandType;
> +
> +    /// Str - For isLiteralTextOperand, this IS the literal text.   
> For
> +    /// isMachineInstrOperand, this is the PrinterMethodName for  
> the operand..
> +    /// For isLiteralStatementOperand, this is the code to insert  
> verbatim
> +    /// into the asm writer.
> +    std::string Str;
> +
> +    /// MiOpNo - For isMachineInstrOperand, this is the operand  
> number of the
> +    /// machine instruction.
> +    unsigned MIOpNo;
> +
> +    /// MiModifier - For isMachineInstrOperand, this is the  
> modifier string for
> +    /// an operand, specified with syntax like ${opname:modifier}.
> +    std::string MiModifier;
> +
> +    // To make VS STL happy
> +    AsmWriterOperand(OpType op =  
> isLiteralTextOperand):OperandType(op) {}
> +
> +    AsmWriterOperand(const std::string &LitStr,
> +                     OpType op = isLiteralTextOperand)
> +    : OperandType(op), Str(LitStr) {}
> +
> +    AsmWriterOperand(const std::string &Printer, unsigned OpNo,
> +                     const std::string &Modifier,
> +                     OpType op = isMachineInstrOperand)
> +    : OperandType(op), Str(Printer), MIOpNo(OpNo),
> +    MiModifier(Modifier) {}
> +
> +    bool operator!=(const AsmWriterOperand &Other) const {
> +      if (OperandType != Other.OperandType || Str != Other.Str)  
> return true;
> +      if (OperandType == isMachineInstrOperand)
> +        return MIOpNo != Other.MIOpNo || MiModifier !=  
> Other.MiModifier;
> +      return false;
> +    }
> +    bool operator==(const AsmWriterOperand &Other) const {
> +      return !operator!=(Other);
> +    }
> +
> +    /// getCode - Return the code that prints this operand.
> +    std::string getCode() const;
> +  };
> +
> +  class AsmWriterInst {
> +  public:
> +    std::vector<AsmWriterOperand> Operands;
> +    const CodeGenInstruction *CGI;
> +
> +    AsmWriterInst(const CodeGenInstruction &CGI, Record *AsmWriter);
> +
> +    /// MatchesAllButOneOp - If this instruction is exactly  
> identical to the
> +    /// specified instruction except for one differing operand,  
> return the
> +    /// differing operand number.  Otherwise return ~0.
> +    unsigned MatchesAllButOneOp(const AsmWriterInst &Other) const;
> +
> +  private:
> +    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.
> +      if (!Operands.empty() &&
> +          Operands.back().OperandType ==  
> AsmWriterOperand::isLiteralTextOperand)
> +        Operands.back().Str.append(Str);
> +      else
> +        Operands.push_back(AsmWriterOperand(Str));
> +    }
> +  };
> +}
> +
> +#endif
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list