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