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
21namespace llvm {
22
23class Twine;
24
25/// A token produced by the machine instruction lexer.
26struct 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_nusw,
73 kw_nuw,
74 kw_nsw,
75 kw_exact,
76 kw_nofpexcept,
77 kw_unpredictable,
78 kw_nneg,
79 kw_disjoint,
80 kw_samesign,
81 kw_inbounds,
82 kw_debug_location,
83 kw_debug_instr_number,
84 kw_dbg_instr_ref,
85 kw_cfi_same_value,
86 kw_cfi_offset,
87 kw_cfi_rel_offset,
88 kw_cfi_def_cfa_register,
89 kw_cfi_def_cfa_offset,
90 kw_cfi_adjust_cfa_offset,
91 kw_cfi_escape,
92 kw_cfi_def_cfa,
93 kw_cfi_llvm_def_aspace_cfa,
94 kw_cfi_register,
95 kw_cfi_remember_state,
96 kw_cfi_restore,
97 kw_cfi_restore_state,
98 kw_cfi_undefined,
99 kw_cfi_window_save,
100 kw_cfi_aarch64_negate_ra_sign_state,
101 kw_cfi_aarch64_negate_ra_sign_state_with_pc,
102 kw_cfi_set_ra_state,
103 kw_cfi_llvm_register_pair,
104 kw_cfi_llvm_vector_registers,
105 kw_cfi_llvm_vector_offset,
106 kw_cfi_llvm_vector_register_mask,
107 kw_blockaddress,
108 kw_intrinsic,
109 kw_target_index,
110 kw_half,
111 kw_bfloat,
112 kw_float,
113 kw_double,
114 kw_x86_fp80,
115 kw_fp128,
116 kw_ppc_fp128,
117 kw_target_flags,
118 kw_volatile,
119 kw_non_temporal,
120 kw_invariant,
121 kw_align,
122 kw_basealign,
123 kw_addrspace,
124 kw_stack,
125 kw_got,
126 kw_jump_table,
127 kw_constant_pool,
128 kw_call_entry,
129 kw_custom,
130 kw_lanemask,
131 kw_liveout,
132 kw_landing_pad,
133 kw_inlineasm_br_indirect_target,
134 kw_ehscope_entry,
135 kw_ehfunclet_entry,
136 kw_liveins,
137 kw_successors,
138 kw_floatpred,
139 kw_intpred,
140 kw_shufflemask,
141 kw_pre_instr_symbol,
142 kw_post_instr_symbol,
143 kw_heap_alloc_marker,
144 kw_pcsections,
145 kw_cfi_type,
146 kw_deactivation_symbol,
147 kw_bbsections,
148 kw_bb_id,
149 kw_unknown_size,
150 kw_unknown_address,
151 kw_ir_block_address_taken,
152 kw_machine_block_address_taken,
153 kw_call_frame_size,
154 kw_noconvergent,
155 kw_mmra,
156 kw_lr_split,
157
158 // Metadata types.
159 kw_distinct,
160
161 // Named metadata keywords
162 md_tbaa,
163 md_alias_scope,
164 md_noalias,
165 md_noalias_addrspace,
166 md_range,
167 md_mem_cache_hint,
168 md_diexpr,
169 md_dilocation,
170
171 // Identifier tokens
172 Identifier,
173 NamedRegister,
174 NamedVirtualRegister,
175 MachineBasicBlockLabel,
176 MachineBasicBlock,
177 StackObject,
178 FixedStackObject,
179 NamedGlobalValue,
180 GlobalValue,
181 ExternalSymbol,
182 MCSymbol,
183
184 // Other tokens
185 IntegerLiteral,
186 FloatingPointLiteral,
187 HexLiteral,
188 VectorLiteral,
189 VirtualRegister,
190 ConstantPoolItem,
191 JumpTableIndex,
192 NamedIRBlock,
193 IRBlock,
194 NamedIRValue,
195 IRValue,
196 QuotedIRValue, // `<constant value>`
197 SubRegisterIndex,
198 StringConstant
199 };
200
201private:
202 TokenKind Kind = Error;
203 StringRef Range;
204 StringRef StringValue;
205 std::string StringValueStorage;
206 APSInt IntVal;
207
208public:
209 MIToken() = default;
210
211 MIToken &reset(TokenKind Kind, StringRef Range);
212
213 MIToken &setStringValue(StringRef StrVal);
214 MIToken &setOwnedStringValue(std::string StrVal);
215 MIToken &setIntegerValue(APSInt IntVal);
216
217 TokenKind kind() const { return Kind; }
218
219 bool isError() const { return Kind == Error; }
220
221 bool isNewlineOrEOF() const { return Kind == Newline || Kind == Eof; }
222
223 bool isErrorOrEOF() const { return Kind == Error || Kind == Eof; }
224
225 bool isRegister() const {
226 return Kind == NamedRegister || Kind == underscore ||
227 Kind == NamedVirtualRegister || Kind == VirtualRegister;
228 }
229
230 bool isRegisterFlag() const {
231 return Kind == kw_implicit || Kind == kw_implicit_define ||
232 Kind == kw_def || Kind == kw_dead || Kind == kw_killed ||
233 Kind == kw_undef || Kind == kw_internal ||
234 Kind == kw_early_clobber || Kind == kw_debug_use ||
235 Kind == kw_renamable;
236 }
237
238 bool isMemoryOperandFlag() const {
239 return Kind == kw_volatile || Kind == kw_non_temporal ||
240 Kind == kw_dereferenceable || Kind == kw_invariant ||
241 Kind == StringConstant;
242 }
243
244 bool is(TokenKind K) const { return Kind == K; }
245
246 bool isNot(TokenKind K) const { return Kind != K; }
247
248 StringRef::iterator location() const { return Range.begin(); }
249
250 StringRef range() const { return Range; }
251
252 /// Return the token's string value.
253 StringRef stringValue() const { return StringValue; }
254
255 const APSInt &integerValue() const { return IntVal; }
256
257 bool hasIntegerValue() const {
258 return Kind == IntegerLiteral || Kind == MachineBasicBlock ||
259 Kind == MachineBasicBlockLabel || Kind == StackObject ||
260 Kind == FixedStackObject || Kind == GlobalValue ||
261 Kind == VirtualRegister || Kind == ConstantPoolItem ||
262 Kind == JumpTableIndex || Kind == IRBlock || Kind == IRValue;
263 }
264};
265
266/// Consume a single machine instruction token in the given source and return
267/// the remaining source string.
268StringRef lexMIToken(
269 StringRef Source, MIToken &Token,
270 function_ref<void(StringRef::iterator, const Twine &)> ErrorCallback);
271
272} // end namespace llvm
273
274#endif // LLVM_LIB_CODEGEN_MIRPARSER_MILEXER_H
275