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