1*0b57cec5SDimitry Andric //===- MILexer.h - Lexer for machine instructions ---------------*- C++ -*-===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // This file declares the function that lexes the machine instruction source 10*0b57cec5SDimitry Andric // string. 11*0b57cec5SDimitry Andric // 12*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 13*0b57cec5SDimitry Andric 14*0b57cec5SDimitry Andric #ifndef LLVM_LIB_CODEGEN_MIRPARSER_MILEXER_H 15*0b57cec5SDimitry Andric #define LLVM_LIB_CODEGEN_MIRPARSER_MILEXER_H 16*0b57cec5SDimitry Andric 17*0b57cec5SDimitry Andric #include "llvm/ADT/APSInt.h" 18*0b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 19*0b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 20*0b57cec5SDimitry Andric #include <string> 21*0b57cec5SDimitry Andric 22*0b57cec5SDimitry Andric namespace llvm { 23*0b57cec5SDimitry Andric 24*0b57cec5SDimitry Andric class Twine; 25*0b57cec5SDimitry Andric 26*0b57cec5SDimitry Andric /// A token produced by the machine instruction lexer. 27*0b57cec5SDimitry Andric struct MIToken { 28*0b57cec5SDimitry Andric enum TokenKind { 29*0b57cec5SDimitry Andric // Markers 30*0b57cec5SDimitry Andric Eof, 31*0b57cec5SDimitry Andric Error, 32*0b57cec5SDimitry Andric Newline, 33*0b57cec5SDimitry Andric 34*0b57cec5SDimitry Andric // Tokens with no info. 35*0b57cec5SDimitry Andric comma, 36*0b57cec5SDimitry Andric equal, 37*0b57cec5SDimitry Andric underscore, 38*0b57cec5SDimitry Andric colon, 39*0b57cec5SDimitry Andric coloncolon, 40*0b57cec5SDimitry Andric dot, 41*0b57cec5SDimitry Andric exclaim, 42*0b57cec5SDimitry Andric lparen, 43*0b57cec5SDimitry Andric rparen, 44*0b57cec5SDimitry Andric lbrace, 45*0b57cec5SDimitry Andric rbrace, 46*0b57cec5SDimitry Andric plus, 47*0b57cec5SDimitry Andric minus, 48*0b57cec5SDimitry Andric less, 49*0b57cec5SDimitry Andric greater, 50*0b57cec5SDimitry Andric 51*0b57cec5SDimitry Andric // Keywords 52*0b57cec5SDimitry Andric kw_implicit, 53*0b57cec5SDimitry Andric kw_implicit_define, 54*0b57cec5SDimitry Andric kw_def, 55*0b57cec5SDimitry Andric kw_dead, 56*0b57cec5SDimitry Andric kw_dereferenceable, 57*0b57cec5SDimitry Andric kw_killed, 58*0b57cec5SDimitry Andric kw_undef, 59*0b57cec5SDimitry Andric kw_internal, 60*0b57cec5SDimitry Andric kw_early_clobber, 61*0b57cec5SDimitry Andric kw_debug_use, 62*0b57cec5SDimitry Andric kw_renamable, 63*0b57cec5SDimitry Andric kw_tied_def, 64*0b57cec5SDimitry Andric kw_frame_setup, 65*0b57cec5SDimitry Andric kw_frame_destroy, 66*0b57cec5SDimitry Andric kw_nnan, 67*0b57cec5SDimitry Andric kw_ninf, 68*0b57cec5SDimitry Andric kw_nsz, 69*0b57cec5SDimitry Andric kw_arcp, 70*0b57cec5SDimitry Andric kw_contract, 71*0b57cec5SDimitry Andric kw_afn, 72*0b57cec5SDimitry Andric kw_reassoc, 73*0b57cec5SDimitry Andric kw_nuw, 74*0b57cec5SDimitry Andric kw_nsw, 75*0b57cec5SDimitry Andric kw_exact, 76*0b57cec5SDimitry Andric kw_fpexcept, 77*0b57cec5SDimitry Andric kw_debug_location, 78*0b57cec5SDimitry Andric kw_cfi_same_value, 79*0b57cec5SDimitry Andric kw_cfi_offset, 80*0b57cec5SDimitry Andric kw_cfi_rel_offset, 81*0b57cec5SDimitry Andric kw_cfi_def_cfa_register, 82*0b57cec5SDimitry Andric kw_cfi_def_cfa_offset, 83*0b57cec5SDimitry Andric kw_cfi_adjust_cfa_offset, 84*0b57cec5SDimitry Andric kw_cfi_escape, 85*0b57cec5SDimitry Andric kw_cfi_def_cfa, 86*0b57cec5SDimitry Andric kw_cfi_register, 87*0b57cec5SDimitry Andric kw_cfi_remember_state, 88*0b57cec5SDimitry Andric kw_cfi_restore, 89*0b57cec5SDimitry Andric kw_cfi_restore_state, 90*0b57cec5SDimitry Andric kw_cfi_undefined, 91*0b57cec5SDimitry Andric kw_cfi_window_save, 92*0b57cec5SDimitry Andric kw_cfi_aarch64_negate_ra_sign_state, 93*0b57cec5SDimitry Andric kw_blockaddress, 94*0b57cec5SDimitry Andric kw_intrinsic, 95*0b57cec5SDimitry Andric kw_target_index, 96*0b57cec5SDimitry Andric kw_half, 97*0b57cec5SDimitry Andric kw_float, 98*0b57cec5SDimitry Andric kw_double, 99*0b57cec5SDimitry Andric kw_x86_fp80, 100*0b57cec5SDimitry Andric kw_fp128, 101*0b57cec5SDimitry Andric kw_ppc_fp128, 102*0b57cec5SDimitry Andric kw_target_flags, 103*0b57cec5SDimitry Andric kw_volatile, 104*0b57cec5SDimitry Andric kw_non_temporal, 105*0b57cec5SDimitry Andric kw_invariant, 106*0b57cec5SDimitry Andric kw_align, 107*0b57cec5SDimitry Andric kw_addrspace, 108*0b57cec5SDimitry Andric kw_stack, 109*0b57cec5SDimitry Andric kw_got, 110*0b57cec5SDimitry Andric kw_jump_table, 111*0b57cec5SDimitry Andric kw_constant_pool, 112*0b57cec5SDimitry Andric kw_call_entry, 113*0b57cec5SDimitry Andric kw_liveout, 114*0b57cec5SDimitry Andric kw_address_taken, 115*0b57cec5SDimitry Andric kw_landing_pad, 116*0b57cec5SDimitry Andric kw_liveins, 117*0b57cec5SDimitry Andric kw_successors, 118*0b57cec5SDimitry Andric kw_floatpred, 119*0b57cec5SDimitry Andric kw_intpred, 120*0b57cec5SDimitry Andric kw_pre_instr_symbol, 121*0b57cec5SDimitry Andric kw_post_instr_symbol, 122*0b57cec5SDimitry Andric kw_unknown_size, 123*0b57cec5SDimitry Andric 124*0b57cec5SDimitry Andric // Named metadata keywords 125*0b57cec5SDimitry Andric md_tbaa, 126*0b57cec5SDimitry Andric md_alias_scope, 127*0b57cec5SDimitry Andric md_noalias, 128*0b57cec5SDimitry Andric md_range, 129*0b57cec5SDimitry Andric md_diexpr, 130*0b57cec5SDimitry Andric md_dilocation, 131*0b57cec5SDimitry Andric 132*0b57cec5SDimitry Andric // Identifier tokens 133*0b57cec5SDimitry Andric Identifier, 134*0b57cec5SDimitry Andric NamedRegister, 135*0b57cec5SDimitry Andric NamedVirtualRegister, 136*0b57cec5SDimitry Andric MachineBasicBlockLabel, 137*0b57cec5SDimitry Andric MachineBasicBlock, 138*0b57cec5SDimitry Andric StackObject, 139*0b57cec5SDimitry Andric FixedStackObject, 140*0b57cec5SDimitry Andric NamedGlobalValue, 141*0b57cec5SDimitry Andric GlobalValue, 142*0b57cec5SDimitry Andric ExternalSymbol, 143*0b57cec5SDimitry Andric MCSymbol, 144*0b57cec5SDimitry Andric 145*0b57cec5SDimitry Andric // Other tokens 146*0b57cec5SDimitry Andric IntegerLiteral, 147*0b57cec5SDimitry Andric FloatingPointLiteral, 148*0b57cec5SDimitry Andric HexLiteral, 149*0b57cec5SDimitry Andric VirtualRegister, 150*0b57cec5SDimitry Andric ConstantPoolItem, 151*0b57cec5SDimitry Andric JumpTableIndex, 152*0b57cec5SDimitry Andric NamedIRBlock, 153*0b57cec5SDimitry Andric IRBlock, 154*0b57cec5SDimitry Andric NamedIRValue, 155*0b57cec5SDimitry Andric IRValue, 156*0b57cec5SDimitry Andric QuotedIRValue, // `<constant value>` 157*0b57cec5SDimitry Andric SubRegisterIndex, 158*0b57cec5SDimitry Andric StringConstant 159*0b57cec5SDimitry Andric }; 160*0b57cec5SDimitry Andric 161*0b57cec5SDimitry Andric private: 162*0b57cec5SDimitry Andric TokenKind Kind = Error; 163*0b57cec5SDimitry Andric StringRef Range; 164*0b57cec5SDimitry Andric StringRef StringValue; 165*0b57cec5SDimitry Andric std::string StringValueStorage; 166*0b57cec5SDimitry Andric APSInt IntVal; 167*0b57cec5SDimitry Andric 168*0b57cec5SDimitry Andric public: 169*0b57cec5SDimitry Andric MIToken() = default; 170*0b57cec5SDimitry Andric 171*0b57cec5SDimitry Andric MIToken &reset(TokenKind Kind, StringRef Range); 172*0b57cec5SDimitry Andric 173*0b57cec5SDimitry Andric MIToken &setStringValue(StringRef StrVal); 174*0b57cec5SDimitry Andric MIToken &setOwnedStringValue(std::string StrVal); 175*0b57cec5SDimitry Andric MIToken &setIntegerValue(APSInt IntVal); 176*0b57cec5SDimitry Andric 177*0b57cec5SDimitry Andric TokenKind kind() const { return Kind; } 178*0b57cec5SDimitry Andric 179*0b57cec5SDimitry Andric bool isError() const { return Kind == Error; } 180*0b57cec5SDimitry Andric 181*0b57cec5SDimitry Andric bool isNewlineOrEOF() const { return Kind == Newline || Kind == Eof; } 182*0b57cec5SDimitry Andric 183*0b57cec5SDimitry Andric bool isErrorOrEOF() const { return Kind == Error || Kind == Eof; } 184*0b57cec5SDimitry Andric 185*0b57cec5SDimitry Andric bool isRegister() const { 186*0b57cec5SDimitry Andric return Kind == NamedRegister || Kind == underscore || 187*0b57cec5SDimitry Andric Kind == NamedVirtualRegister || Kind == VirtualRegister; 188*0b57cec5SDimitry Andric } 189*0b57cec5SDimitry Andric 190*0b57cec5SDimitry Andric bool isRegisterFlag() const { 191*0b57cec5SDimitry Andric return Kind == kw_implicit || Kind == kw_implicit_define || 192*0b57cec5SDimitry Andric Kind == kw_def || Kind == kw_dead || Kind == kw_killed || 193*0b57cec5SDimitry Andric Kind == kw_undef || Kind == kw_internal || 194*0b57cec5SDimitry Andric Kind == kw_early_clobber || Kind == kw_debug_use || 195*0b57cec5SDimitry Andric Kind == kw_renamable; 196*0b57cec5SDimitry Andric } 197*0b57cec5SDimitry Andric 198*0b57cec5SDimitry Andric bool isMemoryOperandFlag() const { 199*0b57cec5SDimitry Andric return Kind == kw_volatile || Kind == kw_non_temporal || 200*0b57cec5SDimitry Andric Kind == kw_dereferenceable || Kind == kw_invariant || 201*0b57cec5SDimitry Andric Kind == StringConstant; 202*0b57cec5SDimitry Andric } 203*0b57cec5SDimitry Andric 204*0b57cec5SDimitry Andric bool is(TokenKind K) const { return Kind == K; } 205*0b57cec5SDimitry Andric 206*0b57cec5SDimitry Andric bool isNot(TokenKind K) const { return Kind != K; } 207*0b57cec5SDimitry Andric 208*0b57cec5SDimitry Andric StringRef::iterator location() const { return Range.begin(); } 209*0b57cec5SDimitry Andric 210*0b57cec5SDimitry Andric StringRef range() const { return Range; } 211*0b57cec5SDimitry Andric 212*0b57cec5SDimitry Andric /// Return the token's string value. 213*0b57cec5SDimitry Andric StringRef stringValue() const { return StringValue; } 214*0b57cec5SDimitry Andric 215*0b57cec5SDimitry Andric const APSInt &integerValue() const { return IntVal; } 216*0b57cec5SDimitry Andric 217*0b57cec5SDimitry Andric bool hasIntegerValue() const { 218*0b57cec5SDimitry Andric return Kind == IntegerLiteral || Kind == MachineBasicBlock || 219*0b57cec5SDimitry Andric Kind == MachineBasicBlockLabel || Kind == StackObject || 220*0b57cec5SDimitry Andric Kind == FixedStackObject || Kind == GlobalValue || 221*0b57cec5SDimitry Andric Kind == VirtualRegister || Kind == ConstantPoolItem || 222*0b57cec5SDimitry Andric Kind == JumpTableIndex || Kind == IRBlock || Kind == IRValue; 223*0b57cec5SDimitry Andric } 224*0b57cec5SDimitry Andric }; 225*0b57cec5SDimitry Andric 226*0b57cec5SDimitry Andric /// Consume a single machine instruction token in the given source and return 227*0b57cec5SDimitry Andric /// the remaining source string. 228*0b57cec5SDimitry Andric StringRef lexMIToken( 229*0b57cec5SDimitry Andric StringRef Source, MIToken &Token, 230*0b57cec5SDimitry Andric function_ref<void(StringRef::iterator, const Twine &)> ErrorCallback); 231*0b57cec5SDimitry Andric 232*0b57cec5SDimitry Andric } // end namespace llvm 233*0b57cec5SDimitry Andric 234*0b57cec5SDimitry Andric #endif // LLVM_LIB_CODEGEN_MIRPARSER_MILEXER_H 235