xref: /freebsd/contrib/llvm-project/llvm/lib/CodeGen/MIRParser/MILexer.h (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric //===- MILexer.h - Lexer for machine instructions ---------------*- C++ -*-===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric //
9*0b57cec5SDimitry Andric // This file declares the function that lexes the machine instruction source
10*0b57cec5SDimitry Andric // string.
11*0b57cec5SDimitry Andric //
12*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
13*0b57cec5SDimitry Andric 
14*0b57cec5SDimitry Andric #ifndef LLVM_LIB_CODEGEN_MIRPARSER_MILEXER_H
15*0b57cec5SDimitry Andric #define LLVM_LIB_CODEGEN_MIRPARSER_MILEXER_H
16*0b57cec5SDimitry Andric 
17*0b57cec5SDimitry Andric #include "llvm/ADT/APSInt.h"
18*0b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
19*0b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
20*0b57cec5SDimitry Andric #include <string>
21*0b57cec5SDimitry Andric 
22*0b57cec5SDimitry Andric namespace llvm {
23*0b57cec5SDimitry Andric 
24*0b57cec5SDimitry Andric class Twine;
25*0b57cec5SDimitry Andric 
26*0b57cec5SDimitry Andric /// A token produced by the machine instruction lexer.
27*0b57cec5SDimitry Andric struct MIToken {
28*0b57cec5SDimitry Andric   enum TokenKind {
29*0b57cec5SDimitry Andric     // Markers
30*0b57cec5SDimitry Andric     Eof,
31*0b57cec5SDimitry Andric     Error,
32*0b57cec5SDimitry Andric     Newline,
33*0b57cec5SDimitry Andric 
34*0b57cec5SDimitry Andric     // Tokens with no info.
35*0b57cec5SDimitry Andric     comma,
36*0b57cec5SDimitry Andric     equal,
37*0b57cec5SDimitry Andric     underscore,
38*0b57cec5SDimitry Andric     colon,
39*0b57cec5SDimitry Andric     coloncolon,
40*0b57cec5SDimitry Andric     dot,
41*0b57cec5SDimitry Andric     exclaim,
42*0b57cec5SDimitry Andric     lparen,
43*0b57cec5SDimitry Andric     rparen,
44*0b57cec5SDimitry Andric     lbrace,
45*0b57cec5SDimitry Andric     rbrace,
46*0b57cec5SDimitry Andric     plus,
47*0b57cec5SDimitry Andric     minus,
48*0b57cec5SDimitry Andric     less,
49*0b57cec5SDimitry Andric     greater,
50*0b57cec5SDimitry Andric 
51*0b57cec5SDimitry Andric     // Keywords
52*0b57cec5SDimitry Andric     kw_implicit,
53*0b57cec5SDimitry Andric     kw_implicit_define,
54*0b57cec5SDimitry Andric     kw_def,
55*0b57cec5SDimitry Andric     kw_dead,
56*0b57cec5SDimitry Andric     kw_dereferenceable,
57*0b57cec5SDimitry Andric     kw_killed,
58*0b57cec5SDimitry Andric     kw_undef,
59*0b57cec5SDimitry Andric     kw_internal,
60*0b57cec5SDimitry Andric     kw_early_clobber,
61*0b57cec5SDimitry Andric     kw_debug_use,
62*0b57cec5SDimitry Andric     kw_renamable,
63*0b57cec5SDimitry Andric     kw_tied_def,
64*0b57cec5SDimitry Andric     kw_frame_setup,
65*0b57cec5SDimitry Andric     kw_frame_destroy,
66*0b57cec5SDimitry Andric     kw_nnan,
67*0b57cec5SDimitry Andric     kw_ninf,
68*0b57cec5SDimitry Andric     kw_nsz,
69*0b57cec5SDimitry Andric     kw_arcp,
70*0b57cec5SDimitry Andric     kw_contract,
71*0b57cec5SDimitry Andric     kw_afn,
72*0b57cec5SDimitry Andric     kw_reassoc,
73*0b57cec5SDimitry Andric     kw_nuw,
74*0b57cec5SDimitry Andric     kw_nsw,
75*0b57cec5SDimitry Andric     kw_exact,
76*0b57cec5SDimitry Andric     kw_fpexcept,
77*0b57cec5SDimitry Andric     kw_debug_location,
78*0b57cec5SDimitry Andric     kw_cfi_same_value,
79*0b57cec5SDimitry Andric     kw_cfi_offset,
80*0b57cec5SDimitry Andric     kw_cfi_rel_offset,
81*0b57cec5SDimitry Andric     kw_cfi_def_cfa_register,
82*0b57cec5SDimitry Andric     kw_cfi_def_cfa_offset,
83*0b57cec5SDimitry Andric     kw_cfi_adjust_cfa_offset,
84*0b57cec5SDimitry Andric     kw_cfi_escape,
85*0b57cec5SDimitry Andric     kw_cfi_def_cfa,
86*0b57cec5SDimitry Andric     kw_cfi_register,
87*0b57cec5SDimitry Andric     kw_cfi_remember_state,
88*0b57cec5SDimitry Andric     kw_cfi_restore,
89*0b57cec5SDimitry Andric     kw_cfi_restore_state,
90*0b57cec5SDimitry Andric     kw_cfi_undefined,
91*0b57cec5SDimitry Andric     kw_cfi_window_save,
92*0b57cec5SDimitry Andric     kw_cfi_aarch64_negate_ra_sign_state,
93*0b57cec5SDimitry Andric     kw_blockaddress,
94*0b57cec5SDimitry Andric     kw_intrinsic,
95*0b57cec5SDimitry Andric     kw_target_index,
96*0b57cec5SDimitry Andric     kw_half,
97*0b57cec5SDimitry Andric     kw_float,
98*0b57cec5SDimitry Andric     kw_double,
99*0b57cec5SDimitry Andric     kw_x86_fp80,
100*0b57cec5SDimitry Andric     kw_fp128,
101*0b57cec5SDimitry Andric     kw_ppc_fp128,
102*0b57cec5SDimitry Andric     kw_target_flags,
103*0b57cec5SDimitry Andric     kw_volatile,
104*0b57cec5SDimitry Andric     kw_non_temporal,
105*0b57cec5SDimitry Andric     kw_invariant,
106*0b57cec5SDimitry Andric     kw_align,
107*0b57cec5SDimitry Andric     kw_addrspace,
108*0b57cec5SDimitry Andric     kw_stack,
109*0b57cec5SDimitry Andric     kw_got,
110*0b57cec5SDimitry Andric     kw_jump_table,
111*0b57cec5SDimitry Andric     kw_constant_pool,
112*0b57cec5SDimitry Andric     kw_call_entry,
113*0b57cec5SDimitry Andric     kw_liveout,
114*0b57cec5SDimitry Andric     kw_address_taken,
115*0b57cec5SDimitry Andric     kw_landing_pad,
116*0b57cec5SDimitry Andric     kw_liveins,
117*0b57cec5SDimitry Andric     kw_successors,
118*0b57cec5SDimitry Andric     kw_floatpred,
119*0b57cec5SDimitry Andric     kw_intpred,
120*0b57cec5SDimitry Andric     kw_pre_instr_symbol,
121*0b57cec5SDimitry Andric     kw_post_instr_symbol,
122*0b57cec5SDimitry Andric     kw_unknown_size,
123*0b57cec5SDimitry Andric 
124*0b57cec5SDimitry Andric     // Named metadata keywords
125*0b57cec5SDimitry Andric     md_tbaa,
126*0b57cec5SDimitry Andric     md_alias_scope,
127*0b57cec5SDimitry Andric     md_noalias,
128*0b57cec5SDimitry Andric     md_range,
129*0b57cec5SDimitry Andric     md_diexpr,
130*0b57cec5SDimitry Andric     md_dilocation,
131*0b57cec5SDimitry Andric 
132*0b57cec5SDimitry Andric     // Identifier tokens
133*0b57cec5SDimitry Andric     Identifier,
134*0b57cec5SDimitry Andric     NamedRegister,
135*0b57cec5SDimitry Andric     NamedVirtualRegister,
136*0b57cec5SDimitry Andric     MachineBasicBlockLabel,
137*0b57cec5SDimitry Andric     MachineBasicBlock,
138*0b57cec5SDimitry Andric     StackObject,
139*0b57cec5SDimitry Andric     FixedStackObject,
140*0b57cec5SDimitry Andric     NamedGlobalValue,
141*0b57cec5SDimitry Andric     GlobalValue,
142*0b57cec5SDimitry Andric     ExternalSymbol,
143*0b57cec5SDimitry Andric     MCSymbol,
144*0b57cec5SDimitry Andric 
145*0b57cec5SDimitry Andric     // Other tokens
146*0b57cec5SDimitry Andric     IntegerLiteral,
147*0b57cec5SDimitry Andric     FloatingPointLiteral,
148*0b57cec5SDimitry Andric     HexLiteral,
149*0b57cec5SDimitry Andric     VirtualRegister,
150*0b57cec5SDimitry Andric     ConstantPoolItem,
151*0b57cec5SDimitry Andric     JumpTableIndex,
152*0b57cec5SDimitry Andric     NamedIRBlock,
153*0b57cec5SDimitry Andric     IRBlock,
154*0b57cec5SDimitry Andric     NamedIRValue,
155*0b57cec5SDimitry Andric     IRValue,
156*0b57cec5SDimitry Andric     QuotedIRValue, // `<constant value>`
157*0b57cec5SDimitry Andric     SubRegisterIndex,
158*0b57cec5SDimitry Andric     StringConstant
159*0b57cec5SDimitry Andric   };
160*0b57cec5SDimitry Andric 
161*0b57cec5SDimitry Andric private:
162*0b57cec5SDimitry Andric   TokenKind Kind = Error;
163*0b57cec5SDimitry Andric   StringRef Range;
164*0b57cec5SDimitry Andric   StringRef StringValue;
165*0b57cec5SDimitry Andric   std::string StringValueStorage;
166*0b57cec5SDimitry Andric   APSInt IntVal;
167*0b57cec5SDimitry Andric 
168*0b57cec5SDimitry Andric public:
169*0b57cec5SDimitry Andric   MIToken() = default;
170*0b57cec5SDimitry Andric 
171*0b57cec5SDimitry Andric   MIToken &reset(TokenKind Kind, StringRef Range);
172*0b57cec5SDimitry Andric 
173*0b57cec5SDimitry Andric   MIToken &setStringValue(StringRef StrVal);
174*0b57cec5SDimitry Andric   MIToken &setOwnedStringValue(std::string StrVal);
175*0b57cec5SDimitry Andric   MIToken &setIntegerValue(APSInt IntVal);
176*0b57cec5SDimitry Andric 
177*0b57cec5SDimitry Andric   TokenKind kind() const { return Kind; }
178*0b57cec5SDimitry Andric 
179*0b57cec5SDimitry Andric   bool isError() const { return Kind == Error; }
180*0b57cec5SDimitry Andric 
181*0b57cec5SDimitry Andric   bool isNewlineOrEOF() const { return Kind == Newline || Kind == Eof; }
182*0b57cec5SDimitry Andric 
183*0b57cec5SDimitry Andric   bool isErrorOrEOF() const { return Kind == Error || Kind == Eof; }
184*0b57cec5SDimitry Andric 
185*0b57cec5SDimitry Andric   bool isRegister() const {
186*0b57cec5SDimitry Andric     return Kind == NamedRegister || Kind == underscore ||
187*0b57cec5SDimitry Andric            Kind == NamedVirtualRegister || Kind == VirtualRegister;
188*0b57cec5SDimitry Andric   }
189*0b57cec5SDimitry Andric 
190*0b57cec5SDimitry Andric   bool isRegisterFlag() const {
191*0b57cec5SDimitry Andric     return Kind == kw_implicit || Kind == kw_implicit_define ||
192*0b57cec5SDimitry Andric            Kind == kw_def || Kind == kw_dead || Kind == kw_killed ||
193*0b57cec5SDimitry Andric            Kind == kw_undef || Kind == kw_internal ||
194*0b57cec5SDimitry Andric            Kind == kw_early_clobber || Kind == kw_debug_use ||
195*0b57cec5SDimitry Andric            Kind == kw_renamable;
196*0b57cec5SDimitry Andric   }
197*0b57cec5SDimitry Andric 
198*0b57cec5SDimitry Andric   bool isMemoryOperandFlag() const {
199*0b57cec5SDimitry Andric     return Kind == kw_volatile || Kind == kw_non_temporal ||
200*0b57cec5SDimitry Andric            Kind == kw_dereferenceable || Kind == kw_invariant ||
201*0b57cec5SDimitry Andric            Kind == StringConstant;
202*0b57cec5SDimitry Andric   }
203*0b57cec5SDimitry Andric 
204*0b57cec5SDimitry Andric   bool is(TokenKind K) const { return Kind == K; }
205*0b57cec5SDimitry Andric 
206*0b57cec5SDimitry Andric   bool isNot(TokenKind K) const { return Kind != K; }
207*0b57cec5SDimitry Andric 
208*0b57cec5SDimitry Andric   StringRef::iterator location() const { return Range.begin(); }
209*0b57cec5SDimitry Andric 
210*0b57cec5SDimitry Andric   StringRef range() const { return Range; }
211*0b57cec5SDimitry Andric 
212*0b57cec5SDimitry Andric   /// Return the token's string value.
213*0b57cec5SDimitry Andric   StringRef stringValue() const { return StringValue; }
214*0b57cec5SDimitry Andric 
215*0b57cec5SDimitry Andric   const APSInt &integerValue() const { return IntVal; }
216*0b57cec5SDimitry Andric 
217*0b57cec5SDimitry Andric   bool hasIntegerValue() const {
218*0b57cec5SDimitry Andric     return Kind == IntegerLiteral || Kind == MachineBasicBlock ||
219*0b57cec5SDimitry Andric            Kind == MachineBasicBlockLabel || Kind == StackObject ||
220*0b57cec5SDimitry Andric            Kind == FixedStackObject || Kind == GlobalValue ||
221*0b57cec5SDimitry Andric            Kind == VirtualRegister || Kind == ConstantPoolItem ||
222*0b57cec5SDimitry Andric            Kind == JumpTableIndex || Kind == IRBlock || Kind == IRValue;
223*0b57cec5SDimitry Andric   }
224*0b57cec5SDimitry Andric };
225*0b57cec5SDimitry Andric 
226*0b57cec5SDimitry Andric /// Consume a single machine instruction token in the given source and return
227*0b57cec5SDimitry Andric /// the remaining source string.
228*0b57cec5SDimitry Andric StringRef lexMIToken(
229*0b57cec5SDimitry Andric     StringRef Source, MIToken &Token,
230*0b57cec5SDimitry Andric     function_ref<void(StringRef::iterator, const Twine &)> ErrorCallback);
231*0b57cec5SDimitry Andric 
232*0b57cec5SDimitry Andric } // end namespace llvm
233*0b57cec5SDimitry Andric 
234*0b57cec5SDimitry Andric #endif // LLVM_LIB_CODEGEN_MIRPARSER_MILEXER_H
235