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