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