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