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_cfi_same_value, 78 kw_cfi_offset, 79 kw_cfi_rel_offset, 80 kw_cfi_def_cfa_register, 81 kw_cfi_def_cfa_offset, 82 kw_cfi_adjust_cfa_offset, 83 kw_cfi_escape, 84 kw_cfi_def_cfa, 85 kw_cfi_register, 86 kw_cfi_remember_state, 87 kw_cfi_restore, 88 kw_cfi_restore_state, 89 kw_cfi_undefined, 90 kw_cfi_window_save, 91 kw_cfi_aarch64_negate_ra_sign_state, 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_custom, 113 kw_liveout, 114 kw_address_taken, 115 kw_landing_pad, 116 kw_ehfunclet_entry, 117 kw_liveins, 118 kw_successors, 119 kw_floatpred, 120 kw_intpred, 121 kw_shufflemask, 122 kw_pre_instr_symbol, 123 kw_post_instr_symbol, 124 kw_heap_alloc_marker, 125 kw_bbsections, 126 kw_unknown_size, 127 128 // Named metadata keywords 129 md_tbaa, 130 md_alias_scope, 131 md_noalias, 132 md_range, 133 md_diexpr, 134 md_dilocation, 135 136 // Identifier tokens 137 Identifier, 138 NamedRegister, 139 NamedVirtualRegister, 140 MachineBasicBlockLabel, 141 MachineBasicBlock, 142 StackObject, 143 FixedStackObject, 144 NamedGlobalValue, 145 GlobalValue, 146 ExternalSymbol, 147 MCSymbol, 148 149 // Other tokens 150 IntegerLiteral, 151 FloatingPointLiteral, 152 HexLiteral, 153 VectorLiteral, 154 VirtualRegister, 155 ConstantPoolItem, 156 JumpTableIndex, 157 NamedIRBlock, 158 IRBlock, 159 NamedIRValue, 160 IRValue, 161 QuotedIRValue, // `<constant value>` 162 SubRegisterIndex, 163 StringConstant 164 }; 165 166 private: 167 TokenKind Kind = Error; 168 StringRef Range; 169 StringRef StringValue; 170 std::string StringValueStorage; 171 APSInt IntVal; 172 173 public: 174 MIToken() = default; 175 176 MIToken &reset(TokenKind Kind, StringRef Range); 177 178 MIToken &setStringValue(StringRef StrVal); 179 MIToken &setOwnedStringValue(std::string StrVal); 180 MIToken &setIntegerValue(APSInt IntVal); 181 182 TokenKind kind() const { return Kind; } 183 184 bool isError() const { return Kind == Error; } 185 186 bool isNewlineOrEOF() const { return Kind == Newline || Kind == Eof; } 187 188 bool isErrorOrEOF() const { return Kind == Error || Kind == Eof; } 189 190 bool isRegister() const { 191 return Kind == NamedRegister || Kind == underscore || 192 Kind == NamedVirtualRegister || Kind == VirtualRegister; 193 } 194 195 bool isRegisterFlag() const { 196 return Kind == kw_implicit || Kind == kw_implicit_define || 197 Kind == kw_def || Kind == kw_dead || Kind == kw_killed || 198 Kind == kw_undef || Kind == kw_internal || 199 Kind == kw_early_clobber || Kind == kw_debug_use || 200 Kind == kw_renamable; 201 } 202 203 bool isMemoryOperandFlag() const { 204 return Kind == kw_volatile || Kind == kw_non_temporal || 205 Kind == kw_dereferenceable || Kind == kw_invariant || 206 Kind == StringConstant; 207 } 208 209 bool is(TokenKind K) const { return Kind == K; } 210 211 bool isNot(TokenKind K) const { return Kind != K; } 212 213 StringRef::iterator location() const { return Range.begin(); } 214 215 StringRef range() const { return Range; } 216 217 /// Return the token's string value. 218 StringRef stringValue() const { return StringValue; } 219 220 const APSInt &integerValue() const { return IntVal; } 221 222 bool hasIntegerValue() const { 223 return Kind == IntegerLiteral || Kind == MachineBasicBlock || 224 Kind == MachineBasicBlockLabel || Kind == StackObject || 225 Kind == FixedStackObject || Kind == GlobalValue || 226 Kind == VirtualRegister || Kind == ConstantPoolItem || 227 Kind == JumpTableIndex || Kind == IRBlock || Kind == IRValue; 228 } 229 }; 230 231 /// Consume a single machine instruction token in the given source and return 232 /// the remaining source string. 233 StringRef lexMIToken( 234 StringRef Source, MIToken &Token, 235 function_ref<void(StringRef::iterator, const Twine &)> ErrorCallback); 236 237 } // end namespace llvm 238 239 #endif // LLVM_LIB_CODEGEN_MIRPARSER_MILEXER_H 240