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