[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