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