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_frame_destroy, 67 kw_nnan, 68 kw_ninf, 69 kw_nsz, 70 kw_arcp, 71 kw_contract, 72 kw_afn, 73 kw_reassoc, 74 kw_nuw, 75 kw_nsw, 76 kw_exact, 77 kw_debug_location, 78 kw_cfi_same_value, 79 kw_cfi_offset, 80 kw_cfi_rel_offset, 81 kw_cfi_def_cfa_register, 82 kw_cfi_def_cfa_offset, 83 kw_cfi_adjust_cfa_offset, 84 kw_cfi_escape, 85 kw_cfi_def_cfa, 86 kw_cfi_register, 87 kw_cfi_remember_state, 88 kw_cfi_restore, 89 kw_cfi_restore_state, 90 kw_cfi_undefined, 91 kw_cfi_window_save, 92 kw_blockaddress, 93 kw_intrinsic, 94 kw_target_index, 95 kw_half, 96 kw_float, 97 kw_double, 98 kw_x86_fp80, 99 kw_fp128, 100 kw_ppc_fp128, 101 kw_target_flags, 102 kw_volatile, 103 kw_non_temporal, 104 kw_invariant, 105 kw_align, 106 kw_addrspace, 107 kw_stack, 108 kw_got, 109 kw_jump_table, 110 kw_constant_pool, 111 kw_call_entry, 112 kw_liveout, 113 kw_address_taken, 114 kw_landing_pad, 115 kw_liveins, 116 kw_successors, 117 kw_floatpred, 118 kw_intpred, 119 kw_pre_instr_symbol, 120 kw_post_instr_symbol, 121 kw_unknown_size, 122 123 // Named metadata keywords 124 md_tbaa, 125 md_alias_scope, 126 md_noalias, 127 md_range, 128 md_diexpr, 129 130 // Identifier tokens 131 Identifier, 132 NamedRegister, 133 NamedVirtualRegister, 134 MachineBasicBlockLabel, 135 MachineBasicBlock, 136 StackObject, 137 FixedStackObject, 138 NamedGlobalValue, 139 GlobalValue, 140 ExternalSymbol, 141 MCSymbol, 142 143 // Other tokens 144 IntegerLiteral, 145 FloatingPointLiteral, 146 HexLiteral, 147 VirtualRegister, 148 ConstantPoolItem, 149 JumpTableIndex, 150 NamedIRBlock, 151 IRBlock, 152 NamedIRValue, 153 IRValue, 154 QuotedIRValue, // `<constant value>` 155 SubRegisterIndex, 156 StringConstant 157 }; 158 159 private: 160 TokenKind Kind = Error; 161 StringRef Range; 162 StringRef StringValue; 163 std::string StringValueStorage; 164 APSInt IntVal; 165 166 public: 167 MIToken() = default; 168 169 MIToken &reset(TokenKind Kind, StringRef Range); 170 171 MIToken &setStringValue(StringRef StrVal); 172 MIToken &setOwnedStringValue(std::string StrVal); 173 MIToken &setIntegerValue(APSInt IntVal); 174 175 TokenKind kind() const { return Kind; } 176 177 bool isError() const { return Kind == Error; } 178 179 bool isNewlineOrEOF() const { return Kind == Newline || Kind == Eof; } 180 181 bool isErrorOrEOF() const { return Kind == Error || Kind == Eof; } 182 183 bool isRegister() const { 184 return Kind == NamedRegister || Kind == underscore || 185 Kind == NamedVirtualRegister || Kind == VirtualRegister; 186 } 187 188 bool isRegisterFlag() const { 189 return Kind == kw_implicit || Kind == kw_implicit_define || 190 Kind == kw_def || Kind == kw_dead || Kind == kw_killed || 191 Kind == kw_undef || Kind == kw_internal || 192 Kind == kw_early_clobber || Kind == kw_debug_use || 193 Kind == kw_renamable; 194 } 195 196 bool isMemoryOperandFlag() const { 197 return Kind == kw_volatile || Kind == kw_non_temporal || 198 Kind == kw_dereferenceable || Kind == kw_invariant || 199 Kind == StringConstant; 200 } 201 202 bool is(TokenKind K) const { return Kind == K; } 203 204 bool isNot(TokenKind K) const { return Kind != K; } 205 206 StringRef::iterator location() const { return Range.begin(); } 207 208 StringRef range() const { return Range; } 209 210 /// Return the token's string value. 211 StringRef stringValue() const { return StringValue; } 212 213 const APSInt &integerValue() const { return IntVal; } 214 215 bool hasIntegerValue() const { 216 return Kind == IntegerLiteral || Kind == MachineBasicBlock || 217 Kind == MachineBasicBlockLabel || Kind == StackObject || 218 Kind == FixedStackObject || Kind == GlobalValue || 219 Kind == VirtualRegister || Kind == ConstantPoolItem || 220 Kind == JumpTableIndex || Kind == IRBlock || Kind == IRValue; 221 } 222 }; 223 224 /// Consume a single machine instruction token in the given source and return 225 /// the remaining source string. 226 StringRef lexMIToken( 227 StringRef Source, MIToken &Token, 228 function_ref<void(StringRef::iterator, const Twine &)> ErrorCallback); 229 230 } // end namespace llvm 231 232 #endif // LLVM_LIB_CODEGEN_MIRPARSER_MILEXER_H 233