1 //===- MILexer.h - Lexer for machine instructions ---------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file declares the function that lexes the machine instruction source
11 // string.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_LIB_CODEGEN_MIRPARSER_MILEXER_H
16 #define LLVM_LIB_CODEGEN_MIRPARSER_MILEXER_H
17 
18 #include "llvm/ADT/APSInt.h"
19 #include "llvm/ADT/STLExtras.h"
20 #include "llvm/ADT/StringRef.h"
21 #include <string>
22 
23 namespace llvm {
24 
25 class Twine;
26 
27 /// A token produced by the machine instruction lexer.
28 struct MIToken {
29   enum TokenKind {
30     // Markers
31     Eof,
32     Error,
33     Newline,
34 
35     // Tokens with no info.
36     comma,
37     equal,
38     underscore,
39     colon,
40     coloncolon,
41     dot,
42     exclaim,
43     lparen,
44     rparen,
45     lbrace,
46     rbrace,
47     plus,
48     minus,
49     less,
50     greater,
51 
52     // Keywords
53     kw_implicit,
54     kw_implicit_define,
55     kw_def,
56     kw_dead,
57     kw_dereferenceable,
58     kw_killed,
59     kw_undef,
60     kw_internal,
61     kw_early_clobber,
62     kw_debug_use,
63     kw_renamable,
64     kw_tied_def,
65     kw_frame_setup,
66     kw_frame_destroy,
67     kw_nnan,
68     kw_ninf,
69     kw_nsz,
70     kw_arcp,
71     kw_contract,
72     kw_afn,
73     kw_reassoc,
74     kw_nuw,
75     kw_nsw,
76     kw_exact,
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_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_liveout,
113     kw_address_taken,
114     kw_landing_pad,
115     kw_liveins,
116     kw_successors,
117     kw_floatpred,
118     kw_intpred,
119     kw_pre_instr_symbol,
120     kw_post_instr_symbol,
121     kw_unknown_size,
122 
123     // Named metadata keywords
124     md_tbaa,
125     md_alias_scope,
126     md_noalias,
127     md_range,
128     md_diexpr,
129 
130     // Identifier tokens
131     Identifier,
132     NamedRegister,
133     NamedVirtualRegister,
134     MachineBasicBlockLabel,
135     MachineBasicBlock,
136     StackObject,
137     FixedStackObject,
138     NamedGlobalValue,
139     GlobalValue,
140     ExternalSymbol,
141     MCSymbol,
142 
143     // Other tokens
144     IntegerLiteral,
145     FloatingPointLiteral,
146     HexLiteral,
147     VirtualRegister,
148     ConstantPoolItem,
149     JumpTableIndex,
150     NamedIRBlock,
151     IRBlock,
152     NamedIRValue,
153     IRValue,
154     QuotedIRValue, // `<constant value>`
155     SubRegisterIndex,
156     StringConstant
157   };
158 
159 private:
160   TokenKind Kind = Error;
161   StringRef Range;
162   StringRef StringValue;
163   std::string StringValueStorage;
164   APSInt IntVal;
165 
166 public:
167   MIToken() = default;
168 
169   MIToken &reset(TokenKind Kind, StringRef Range);
170 
171   MIToken &setStringValue(StringRef StrVal);
172   MIToken &setOwnedStringValue(std::string StrVal);
173   MIToken &setIntegerValue(APSInt IntVal);
174 
175   TokenKind kind() const { return Kind; }
176 
177   bool isError() const { return Kind == Error; }
178 
179   bool isNewlineOrEOF() const { return Kind == Newline || Kind == Eof; }
180 
181   bool isErrorOrEOF() const { return Kind == Error || Kind == Eof; }
182 
183   bool isRegister() const {
184     return Kind == NamedRegister || Kind == underscore ||
185            Kind == NamedVirtualRegister || Kind == VirtualRegister;
186   }
187 
188   bool isRegisterFlag() const {
189     return Kind == kw_implicit || Kind == kw_implicit_define ||
190            Kind == kw_def || Kind == kw_dead || Kind == kw_killed ||
191            Kind == kw_undef || Kind == kw_internal ||
192            Kind == kw_early_clobber || Kind == kw_debug_use ||
193            Kind == kw_renamable;
194   }
195 
196   bool isMemoryOperandFlag() const {
197     return Kind == kw_volatile || Kind == kw_non_temporal ||
198            Kind == kw_dereferenceable || Kind == kw_invariant ||
199            Kind == StringConstant;
200   }
201 
202   bool is(TokenKind K) const { return Kind == K; }
203 
204   bool isNot(TokenKind K) const { return Kind != K; }
205 
206   StringRef::iterator location() const { return Range.begin(); }
207 
208   StringRef range() const { return Range; }
209 
210   /// Return the token's string value.
211   StringRef stringValue() const { return StringValue; }
212 
213   const APSInt &integerValue() const { return IntVal; }
214 
215   bool hasIntegerValue() const {
216     return Kind == IntegerLiteral || Kind == MachineBasicBlock ||
217            Kind == MachineBasicBlockLabel || Kind == StackObject ||
218            Kind == FixedStackObject || Kind == GlobalValue ||
219            Kind == VirtualRegister || Kind == ConstantPoolItem ||
220            Kind == JumpTableIndex || Kind == IRBlock || Kind == IRValue;
221   }
222 };
223 
224 /// Consume a single machine instruction token in the given source and return
225 /// the remaining source string.
226 StringRef lexMIToken(
227     StringRef Source, MIToken &Token,
228     function_ref<void(StringRef::iterator, const Twine &)> ErrorCallback);
229 
230 } // end namespace llvm
231 
232 #endif // LLVM_LIB_CODEGEN_MIRPARSER_MILEXER_H
233