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