Home | History | Annotate | Download | only in MCParser
      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 &copySTI();
    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