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