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