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