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