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