1 //===-- llvm/MC/MCTargetAsmParser.h - Target Assembly Parser ----*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef LLVM_MC_MCTARGETASMPARSER_H 11 #define LLVM_MC_MCTARGETASMPARSER_H 12 13 #include "llvm/MC/MCExpr.h" 14 #include "llvm/MC/MCParser/MCAsmParserExtension.h" 15 #include "llvm/MC/MCTargetOptions.h" 16 #include <memory> 17 18 namespace llvm { 19 class AsmToken; 20 class MCInst; 21 class MCParsedAsmOperand; 22 class MCStreamer; 23 class MCSubtargetInfo; 24 class SMLoc; 25 class StringRef; 26 template <typename T> class SmallVectorImpl; 27 28 typedef SmallVectorImpl<std::unique_ptr<MCParsedAsmOperand>> OperandVector; 29 30 enum AsmRewriteKind { 31 AOK_Delete = 0, // Rewrite should be ignored. 32 AOK_Align, // Rewrite align as .align. 33 AOK_EVEN, // Rewrite even as .even. 34 AOK_DotOperator, // Rewrite a dot operator expression as an immediate. 35 // E.g., [eax].foo.bar -> [eax].8 36 AOK_Emit, // Rewrite _emit as .byte. 37 AOK_Imm, // Rewrite as $$N. 38 AOK_ImmPrefix, // Add $$ before a parsed Imm. 39 AOK_Input, // Rewrite in terms of $N. 40 AOK_Output, // Rewrite in terms of $N. 41 AOK_SizeDirective, // Add a sizing directive (e.g., dword ptr). 42 AOK_Label, // Rewrite local labels. 43 AOK_Skip // Skip emission (e.g., offset/type operators). 44 }; 45 46 const char AsmRewritePrecedence [] = { 47 0, // AOK_Delete 48 2, // AOK_Align 49 2, // AOK_EVEN 50 2, // AOK_DotOperator 51 2, // AOK_Emit 52 4, // AOK_Imm 53 4, // AOK_ImmPrefix 54 3, // AOK_Input 55 3, // AOK_Output 56 5, // AOK_SizeDirective 57 1, // AOK_Label 58 2 // AOK_Skip 59 }; 60 61 struct AsmRewrite { 62 AsmRewriteKind Kind; 63 SMLoc Loc; 64 unsigned Len; 65 unsigned Val; 66 StringRef Label; 67 public: 68 AsmRewrite(AsmRewriteKind kind, SMLoc loc, unsigned len = 0, unsigned val = 0) 69 : Kind(kind), Loc(loc), Len(len), Val(val) {} 70 AsmRewrite(AsmRewriteKind kind, SMLoc loc, unsigned len, StringRef label) 71 : Kind(kind), Loc(loc), Len(len), Val(0), Label(label) {} 72 }; 73 74 struct ParseInstructionInfo { 75 76 SmallVectorImpl<AsmRewrite> *AsmRewrites; 77 78 ParseInstructionInfo() : AsmRewrites(nullptr) {} 79 ParseInstructionInfo(SmallVectorImpl<AsmRewrite> *rewrites) 80 : AsmRewrites(rewrites) {} 81 }; 82 83 /// MCTargetAsmParser - Generic interface to target specific assembly parsers. 84 class MCTargetAsmParser : public MCAsmParserExtension { 85 public: 86 enum MatchResultTy { 87 Match_InvalidOperand, 88 Match_MissingFeature, 89 Match_MnemonicFail, 90 Match_Success, 91 FIRST_TARGET_MATCH_RESULT_TY 92 }; 93 94 private: 95 MCTargetAsmParser(const MCTargetAsmParser &) = delete; 96 void operator=(const MCTargetAsmParser &) = delete; 97 protected: // Can only create subclasses. 98 MCTargetAsmParser(MCTargetOptions const &, const MCSubtargetInfo &STI); 99 100 /// Create a copy of STI and return a non-const reference to it. 101 MCSubtargetInfo ©STI(); 102 103 /// AvailableFeatures - The current set of available features. 104 uint64_t AvailableFeatures; 105 106 /// ParsingInlineAsm - Are we parsing ms-style inline assembly? 107 bool ParsingInlineAsm; 108 109 /// SemaCallback - The Sema callback implementation. Must be set when parsing 110 /// ms-style inline assembly. 111 MCAsmParserSemaCallback *SemaCallback; 112 113 /// Set of options which affects instrumentation of inline assembly. 114 MCTargetOptions MCOptions; 115 116 /// Current STI. 117 const MCSubtargetInfo *STI; 118 119 public: 120 ~MCTargetAsmParser() override; 121 122 const MCSubtargetInfo &getSTI() const; 123 124 uint64_t getAvailableFeatures() const { return AvailableFeatures; } 125 void setAvailableFeatures(uint64_t Value) { AvailableFeatures = Value; } 126 127 bool isParsingInlineAsm () { return ParsingInlineAsm; } 128 void setParsingInlineAsm (bool Value) { ParsingInlineAsm = Value; } 129 130 MCTargetOptions getTargetOptions() const { return MCOptions; } 131 132 void setSemaCallback(MCAsmParserSemaCallback *Callback) { 133 SemaCallback = Callback; 134 } 135 136 virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 137 SMLoc &EndLoc) = 0; 138 139 /// Sets frame register corresponding to the current MachineFunction. 140 virtual void SetFrameRegister(unsigned RegNo) {} 141 142 /// ParseInstruction - Parse one assembly instruction. 143 /// 144 /// The parser is positioned following the instruction name. The target 145 /// specific instruction parser should parse the entire instruction and 146 /// construct the appropriate MCInst, or emit an error. On success, the entire 147 /// line should be parsed up to and including the end-of-statement token. On 148 /// failure, the parser is not required to read to the end of the line. 149 // 150 /// \param Name - The instruction name. 151 /// \param NameLoc - The source location of the name. 152 /// \param Operands [out] - The list of parsed operands, this returns 153 /// ownership of them to the caller. 154 /// \return True on failure. 155 virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 156 SMLoc NameLoc, OperandVector &Operands) = 0; 157 virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 158 AsmToken Token, OperandVector &Operands) { 159 return ParseInstruction(Info, Name, Token.getLoc(), Operands); 160 } 161 162 /// ParseDirective - Parse a target specific assembler directive 163 /// 164 /// The parser is positioned following the directive name. The target 165 /// specific directive parser should parse the entire directive doing or 166 /// recording any target specific work, or return true and do nothing if the 167 /// directive is not target specific. If the directive is specific for 168 /// the target, the entire line is parsed up to and including the 169 /// end-of-statement token and false is returned. 170 /// 171 /// \param DirectiveID - the identifier token of the directive. 172 virtual bool ParseDirective(AsmToken DirectiveID) = 0; 173 174 /// mnemonicIsValid - This returns true if this is a valid mnemonic and false 175 /// otherwise. 176 virtual bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) = 0; 177 178 /// MatchAndEmitInstruction - Recognize a series of operands of a parsed 179 /// instruction as an actual MCInst and emit it to the specified MCStreamer. 180 /// This returns false on success and returns true on failure to match. 181 /// 182 /// On failure, the target parser is responsible for emitting a diagnostic 183 /// explaining the match failure. 184 virtual bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 185 OperandVector &Operands, MCStreamer &Out, 186 uint64_t &ErrorInfo, 187 bool MatchingInlineAsm) = 0; 188 189 /// Allows targets to let registers opt out of clobber lists. 190 virtual bool OmitRegisterFromClobberLists(unsigned RegNo) { return false; } 191 192 /// Allow a target to add special case operand matching for things that 193 /// tblgen doesn't/can't handle effectively. For example, literal 194 /// immediates on ARM. TableGen expects a token operand, but the parser 195 /// will recognize them as immediates. 196 virtual unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, 197 unsigned Kind) { 198 return Match_InvalidOperand; 199 } 200 201 /// checkTargetMatchPredicate - Validate the instruction match against 202 /// any complex target predicates not expressible via match classes. 203 virtual unsigned checkTargetMatchPredicate(MCInst &Inst) { 204 return Match_Success; 205 } 206 207 virtual void convertToMapAndConstraints(unsigned Kind, 208 const OperandVector &Operands) = 0; 209 210 // Return whether this parser uses assignment statements with equals tokens 211 virtual bool equalIsAsmAssignment() { return true; }; 212 // Return whether this start of statement identifier is a label 213 virtual bool isLabel(AsmToken &Token) { return true; }; 214 215 virtual const MCExpr *applyModifierToExpr(const MCExpr *E, 216 MCSymbolRefExpr::VariantKind, 217 MCContext &Ctx) { 218 return nullptr; 219 } 220 221 virtual void onLabelParsed(MCSymbol *Symbol) { } 222 }; 223 224 } // End llvm namespace 225 226 #endif 227