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