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