xref: /freebsd-src/contrib/llvm-project/llvm/utils/TableGen/Common/AsmWriterInst.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1*0fca6ea1SDimitry Andric //===- AsmWriterInst.h - Classes encapsulating a printable inst -*- C++ -*-===//
2*0fca6ea1SDimitry Andric //
3*0fca6ea1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0fca6ea1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0fca6ea1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0fca6ea1SDimitry Andric //
7*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===//
8*0fca6ea1SDimitry Andric //
9*0fca6ea1SDimitry Andric // These classes implement a parser for assembly strings.  The parser splits
10*0fca6ea1SDimitry Andric // the string into operands, which can be literal strings (the constant bits of
11*0fca6ea1SDimitry Andric // the string), actual operands (i.e., operands from the MachineInstr), and
12*0fca6ea1SDimitry Andric // dynamically-generated text, specified by raw C++ code.
13*0fca6ea1SDimitry Andric //
14*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===//
15*0fca6ea1SDimitry Andric 
16*0fca6ea1SDimitry Andric #ifndef LLVM_UTILS_TABLEGEN_ASMWRITERINST_H
17*0fca6ea1SDimitry Andric #define LLVM_UTILS_TABLEGEN_ASMWRITERINST_H
18*0fca6ea1SDimitry Andric 
19*0fca6ea1SDimitry Andric #include <string>
20*0fca6ea1SDimitry Andric #include <vector>
21*0fca6ea1SDimitry Andric 
22*0fca6ea1SDimitry Andric namespace llvm {
23*0fca6ea1SDimitry Andric class CodeGenInstruction;
24*0fca6ea1SDimitry Andric 
25*0fca6ea1SDimitry Andric struct AsmWriterOperand {
26*0fca6ea1SDimitry Andric   enum OpType {
27*0fca6ea1SDimitry Andric     // Output this text surrounded by quotes to the asm.
28*0fca6ea1SDimitry Andric     isLiteralTextOperand,
29*0fca6ea1SDimitry Andric     // This is the name of a routine to call to print the operand.
30*0fca6ea1SDimitry Andric     isMachineInstrOperand,
31*0fca6ea1SDimitry Andric     // Output this text verbatim to the asm writer.  It is code that
32*0fca6ea1SDimitry Andric     // will output some text to the asm.
33*0fca6ea1SDimitry Andric     isLiteralStatementOperand
34*0fca6ea1SDimitry Andric   } OperandType;
35*0fca6ea1SDimitry Andric 
36*0fca6ea1SDimitry Andric   /// MiOpNo - For isMachineInstrOperand, this is the operand number of the
37*0fca6ea1SDimitry Andric   /// machine instruction.
38*0fca6ea1SDimitry Andric   unsigned MIOpNo = 0;
39*0fca6ea1SDimitry Andric 
40*0fca6ea1SDimitry Andric   /// Str - For isLiteralTextOperand, this IS the literal text.  For
41*0fca6ea1SDimitry Andric   /// isMachineInstrOperand, this is the PrinterMethodName for the operand..
42*0fca6ea1SDimitry Andric   /// For isLiteralStatementOperand, this is the code to insert verbatim
43*0fca6ea1SDimitry Andric   /// into the asm writer.
44*0fca6ea1SDimitry Andric   std::string Str;
45*0fca6ea1SDimitry Andric 
46*0fca6ea1SDimitry Andric   /// MiModifier - For isMachineInstrOperand, this is the modifier string for
47*0fca6ea1SDimitry Andric   /// an operand, specified with syntax like ${opname:modifier}.
48*0fca6ea1SDimitry Andric   std::string MiModifier;
49*0fca6ea1SDimitry Andric 
50*0fca6ea1SDimitry Andric   bool PCRel = false;
51*0fca6ea1SDimitry Andric 
52*0fca6ea1SDimitry Andric   // To make VS STL happy
53*0fca6ea1SDimitry Andric   AsmWriterOperand(OpType op = isLiteralTextOperand) : OperandType(op) {}
54*0fca6ea1SDimitry Andric 
55*0fca6ea1SDimitry Andric   AsmWriterOperand(const std::string &LitStr, OpType op = isLiteralTextOperand)
56*0fca6ea1SDimitry Andric       : OperandType(op), Str(LitStr) {}
57*0fca6ea1SDimitry Andric 
58*0fca6ea1SDimitry Andric   AsmWriterOperand(const std::string &Printer, unsigned _MIOpNo,
59*0fca6ea1SDimitry Andric                    const std::string &Modifier,
60*0fca6ea1SDimitry Andric                    OpType op = isMachineInstrOperand, bool PCRel = false)
61*0fca6ea1SDimitry Andric       : OperandType(op), MIOpNo(_MIOpNo), Str(Printer), MiModifier(Modifier),
62*0fca6ea1SDimitry Andric         PCRel(PCRel) {}
63*0fca6ea1SDimitry Andric 
64*0fca6ea1SDimitry Andric   bool operator!=(const AsmWriterOperand &Other) const {
65*0fca6ea1SDimitry Andric     if (OperandType != Other.OperandType || Str != Other.Str)
66*0fca6ea1SDimitry Andric       return true;
67*0fca6ea1SDimitry Andric     if (OperandType == isMachineInstrOperand)
68*0fca6ea1SDimitry Andric       return MIOpNo != Other.MIOpNo || MiModifier != Other.MiModifier ||
69*0fca6ea1SDimitry Andric              PCRel != Other.PCRel;
70*0fca6ea1SDimitry Andric     return false;
71*0fca6ea1SDimitry Andric   }
72*0fca6ea1SDimitry Andric   bool operator==(const AsmWriterOperand &Other) const {
73*0fca6ea1SDimitry Andric     return !operator!=(Other);
74*0fca6ea1SDimitry Andric   }
75*0fca6ea1SDimitry Andric 
76*0fca6ea1SDimitry Andric   /// getCode - Return the code that prints this operand.
77*0fca6ea1SDimitry Andric   std::string getCode(bool PassSubtarget) const;
78*0fca6ea1SDimitry Andric };
79*0fca6ea1SDimitry Andric 
80*0fca6ea1SDimitry Andric class AsmWriterInst {
81*0fca6ea1SDimitry Andric public:
82*0fca6ea1SDimitry Andric   std::vector<AsmWriterOperand> Operands;
83*0fca6ea1SDimitry Andric   const CodeGenInstruction *CGI;
84*0fca6ea1SDimitry Andric   unsigned CGIIndex;
85*0fca6ea1SDimitry Andric 
86*0fca6ea1SDimitry Andric   AsmWriterInst(const CodeGenInstruction &CGI, unsigned CGIIndex,
87*0fca6ea1SDimitry Andric                 unsigned Variant);
88*0fca6ea1SDimitry Andric 
89*0fca6ea1SDimitry Andric   /// MatchesAllButOneOp - If this instruction is exactly identical to the
90*0fca6ea1SDimitry Andric   /// specified instruction except for one differing operand, return the
91*0fca6ea1SDimitry Andric   /// differing operand number.  Otherwise return ~0.
92*0fca6ea1SDimitry Andric   unsigned MatchesAllButOneOp(const AsmWriterInst &Other) const;
93*0fca6ea1SDimitry Andric 
94*0fca6ea1SDimitry Andric private:
95*0fca6ea1SDimitry Andric   void AddLiteralString(const std::string &Str) {
96*0fca6ea1SDimitry Andric     // If the last operand was already a literal text string, append this to
97*0fca6ea1SDimitry Andric     // it, otherwise add a new operand.
98*0fca6ea1SDimitry Andric     if (!Operands.empty() &&
99*0fca6ea1SDimitry Andric         Operands.back().OperandType == AsmWriterOperand::isLiteralTextOperand)
100*0fca6ea1SDimitry Andric       Operands.back().Str.append(Str);
101*0fca6ea1SDimitry Andric     else
102*0fca6ea1SDimitry Andric       Operands.push_back(AsmWriterOperand(Str));
103*0fca6ea1SDimitry Andric   }
104*0fca6ea1SDimitry Andric };
105*0fca6ea1SDimitry Andric } // namespace llvm
106*0fca6ea1SDimitry Andric 
107*0fca6ea1SDimitry Andric #endif
108