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