184f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan//===- AsmWriterInst.h - Classes encapsulating a printable inst -*- C++ -*-===//
284f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan//
384f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan//                     The LLVM Compiler Infrastructure
484f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan//
584f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan// This file is distributed under the University of Illinois Open Source
684f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan// License. See LICENSE.TXT for details.
784f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan//
884f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan//===----------------------------------------------------------------------===//
984f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan//
1084f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan// These classes implement a parser for assembly strings.  The parser splits
1184f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan// the string into operands, which can be literal strings (the constant bits of
1284f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan// the string), actual operands (i.e., operands from the MachineInstr), and
1384f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan// dynamically-generated text, specified by raw C++ code.
1484f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan//
1584f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan//===----------------------------------------------------------------------===//
1684f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan
1784f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan#ifndef ASMWRITER_INST_H
1884f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan#define ASMWRITER_INST_H
1984f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan
2084f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan#include <string>
2184f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan#include <vector>
2284f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan
2384f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanannamespace llvm {
2484f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan  class CodeGenInstruction;
2584f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan  class Record;
2600b85abee3a453babe9dcfb8a80bf0c793565039Jim Grosbach
2784f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan  struct AsmWriterOperand {
2884f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan    enum OpType {
2984f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan      // Output this text surrounded by quotes to the asm.
3000b85abee3a453babe9dcfb8a80bf0c793565039Jim Grosbach      isLiteralTextOperand,
3184f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan      // This is the name of a routine to call to print the operand.
3284f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan      isMachineInstrOperand,
3384f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan      // Output this text verbatim to the asm writer.  It is code that
3484f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan      // will output some text to the asm.
3584f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan      isLiteralStatementOperand
3684f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan    } OperandType;
3700b85abee3a453babe9dcfb8a80bf0c793565039Jim Grosbach
3884f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan    /// Str - For isLiteralTextOperand, this IS the literal text.  For
3984f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan    /// isMachineInstrOperand, this is the PrinterMethodName for the operand..
4000b85abee3a453babe9dcfb8a80bf0c793565039Jim Grosbach    /// For isLiteralStatementOperand, this is the code to insert verbatim
4184f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan    /// into the asm writer.
4284f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan    std::string Str;
4300b85abee3a453babe9dcfb8a80bf0c793565039Jim Grosbach
44241052eecb099f1d480ecebed325201a97ba4bc8Sean Callanan    /// CGIOpNo - For isMachineInstrOperand, this is the index of the operand in
45241052eecb099f1d480ecebed325201a97ba4bc8Sean Callanan    /// the CodeGenInstruction.
46241052eecb099f1d480ecebed325201a97ba4bc8Sean Callanan    unsigned CGIOpNo;
4700b85abee3a453babe9dcfb8a80bf0c793565039Jim Grosbach
4884f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan    /// MiOpNo - For isMachineInstrOperand, this is the operand number of the
4984f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan    /// machine instruction.
5084f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan    unsigned MIOpNo;
5100b85abee3a453babe9dcfb8a80bf0c793565039Jim Grosbach
5284f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan    /// MiModifier - For isMachineInstrOperand, this is the modifier string for
5384f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan    /// an operand, specified with syntax like ${opname:modifier}.
5484f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan    std::string MiModifier;
5500b85abee3a453babe9dcfb8a80bf0c793565039Jim Grosbach
5684f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan    // To make VS STL happy
5784f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan    AsmWriterOperand(OpType op = isLiteralTextOperand):OperandType(op) {}
5800b85abee3a453babe9dcfb8a80bf0c793565039Jim Grosbach
5984f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan    AsmWriterOperand(const std::string &LitStr,
6084f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan                     OpType op = isLiteralTextOperand)
6184f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan    : OperandType(op), Str(LitStr) {}
6200b85abee3a453babe9dcfb8a80bf0c793565039Jim Grosbach
63241052eecb099f1d480ecebed325201a97ba4bc8Sean Callanan    AsmWriterOperand(const std::string &Printer,
64241052eecb099f1d480ecebed325201a97ba4bc8Sean Callanan                     unsigned _CGIOpNo,
65241052eecb099f1d480ecebed325201a97ba4bc8Sean Callanan                     unsigned _MIOpNo,
6684f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan                     const std::string &Modifier,
6700b85abee3a453babe9dcfb8a80bf0c793565039Jim Grosbach                     OpType op = isMachineInstrOperand)
68241052eecb099f1d480ecebed325201a97ba4bc8Sean Callanan    : OperandType(op), Str(Printer), CGIOpNo(_CGIOpNo), MIOpNo(_MIOpNo),
6984f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan    MiModifier(Modifier) {}
7000b85abee3a453babe9dcfb8a80bf0c793565039Jim Grosbach
7184f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan    bool operator!=(const AsmWriterOperand &Other) const {
7284f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan      if (OperandType != Other.OperandType || Str != Other.Str) return true;
7384f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan      if (OperandType == isMachineInstrOperand)
7484f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan        return MIOpNo != Other.MIOpNo || MiModifier != Other.MiModifier;
7584f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan      return false;
7684f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan    }
7784f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan    bool operator==(const AsmWriterOperand &Other) const {
7884f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan      return !operator!=(Other);
7984f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan    }
8000b85abee3a453babe9dcfb8a80bf0c793565039Jim Grosbach
8184f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan    /// getCode - Return the code that prints this operand.
8284f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan    std::string getCode() const;
8384f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan  };
8400b85abee3a453babe9dcfb8a80bf0c793565039Jim Grosbach
8584f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan  class AsmWriterInst {
8684f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan  public:
8784f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan    std::vector<AsmWriterOperand> Operands;
8884f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan    const CodeGenInstruction *CGI;
8900b85abee3a453babe9dcfb8a80bf0c793565039Jim Grosbach
9000b85abee3a453babe9dcfb8a80bf0c793565039Jim Grosbach    AsmWriterInst(const CodeGenInstruction &CGI,
91f44462e6ab4521214c088cc8610e9471d23e1a89Sean Callanan                  unsigned Variant,
92f44462e6ab4521214c088cc8610e9471d23e1a89Sean Callanan                  int FirstOperandColumn,
93f44462e6ab4521214c088cc8610e9471d23e1a89Sean Callanan                  int OperandSpacing);
9400b85abee3a453babe9dcfb8a80bf0c793565039Jim Grosbach
9584f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan    /// MatchesAllButOneOp - If this instruction is exactly identical to the
9684f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan    /// specified instruction except for one differing operand, return the
9784f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan    /// differing operand number.  Otherwise return ~0.
9884f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan    unsigned MatchesAllButOneOp(const AsmWriterInst &Other) const;
9900b85abee3a453babe9dcfb8a80bf0c793565039Jim Grosbach
10084f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan  private:
10184f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan    void AddLiteralString(const std::string &Str) {
10284f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan      // If the last operand was already a literal text string, append this to
10384f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan      // it, otherwise add a new operand.
10484f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan      if (!Operands.empty() &&
10584f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan          Operands.back().OperandType == AsmWriterOperand::isLiteralTextOperand)
10684f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan        Operands.back().Str.append(Str);
10784f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan      else
10884f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan        Operands.push_back(AsmWriterOperand(Str));
10984f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan    }
11084f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan  };
11184f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan}
11284f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan
11384f676c1e5908ca286e27759ec6be0dfb310e637Sean Callanan#endif
114