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