1 //===- MILexer.h - Lexer for machine instructions -------------------------===//
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 <functional>
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_tied_def,
64     kw_frame_setup,
65     kw_debug_location,
66     kw_cfi_same_value,
67     kw_cfi_offset,
68     kw_cfi_def_cfa_register,
69     kw_cfi_def_cfa_offset,
70     kw_cfi_def_cfa,
71     kw_blockaddress,
72     kw_intrinsic,
73     kw_target_index,
74     kw_half,
75     kw_float,
76     kw_double,
77     kw_x86_fp80,
78     kw_fp128,
79     kw_ppc_fp128,
80     kw_target_flags,
81     kw_volatile,
82     kw_non_temporal,
83     kw_invariant,
84     kw_align,
85     kw_stack,
86     kw_got,
87     kw_jump_table,
88     kw_constant_pool,
89     kw_call_entry,
90     kw_liveout,
91     kw_address_taken,
92     kw_landing_pad,
93     kw_liveins,
94     kw_successors,
95     kw_floatpred,
96     kw_intpred,
97 
98     // Named metadata keywords
99     md_tbaa,
100     md_alias_scope,
101     md_noalias,
102     md_range,
103     md_diexpr,
104 
105     // Identifier tokens
106     Identifier,
107     IntegerType,
108     NamedRegister,
109     MachineBasicBlockLabel,
110     MachineBasicBlock,
111     PointerType,
112     ScalarType,
113     StackObject,
114     FixedStackObject,
115     NamedGlobalValue,
116     GlobalValue,
117     ExternalSymbol,
118 
119     // Other tokens
120     IntegerLiteral,
121     FloatingPointLiteral,
122     HexLiteral,
123     VirtualRegister,
124     ConstantPoolItem,
125     JumpTableIndex,
126     NamedIRBlock,
127     IRBlock,
128     NamedIRValue,
129     IRValue,
130     QuotedIRValue, // `<constant value>`
131     SubRegisterIndex,
132     StringConstant
133   };
134 
135 private:
136   TokenKind Kind;
137   StringRef Range;
138   StringRef StringValue;
139   std::string StringValueStorage;
140   APSInt IntVal;
141 
142 public:
143   MIToken() : Kind(Error) {}
144 
145   MIToken &reset(TokenKind Kind, StringRef Range);
146 
147   MIToken &setStringValue(StringRef StrVal);
148   MIToken &setOwnedStringValue(std::string StrVal);
149   MIToken &setIntegerValue(APSInt IntVal);
150 
151   TokenKind kind() const { return Kind; }
152 
153   bool isError() const { return Kind == Error; }
154 
155   bool isNewlineOrEOF() const { return Kind == Newline || Kind == Eof; }
156 
157   bool isErrorOrEOF() const { return Kind == Error || Kind == Eof; }
158 
159   bool isRegister() const {
160     return Kind == NamedRegister || Kind == underscore ||
161            Kind == VirtualRegister;
162   }
163 
164   bool isRegisterFlag() const {
165     return Kind == kw_implicit || Kind == kw_implicit_define ||
166            Kind == kw_def || Kind == kw_dead || Kind == kw_killed ||
167            Kind == kw_undef || Kind == kw_internal ||
168            Kind == kw_early_clobber || Kind == kw_debug_use;
169   }
170 
171   bool isMemoryOperandFlag() const {
172     return Kind == kw_volatile || Kind == kw_non_temporal ||
173            Kind == kw_dereferenceable || Kind == kw_invariant ||
174            Kind == StringConstant;
175   }
176 
177   bool is(TokenKind K) const { return Kind == K; }
178 
179   bool isNot(TokenKind K) const { return Kind != K; }
180 
181   StringRef::iterator location() const { return Range.begin(); }
182 
183   StringRef range() const { return Range; }
184 
185   /// Return the token's string value.
186   StringRef stringValue() const { return StringValue; }
187 
188   const APSInt &integerValue() const { return IntVal; }
189 
190   bool hasIntegerValue() const {
191     return Kind == IntegerLiteral || Kind == MachineBasicBlock ||
192            Kind == MachineBasicBlockLabel || Kind == StackObject ||
193            Kind == FixedStackObject || Kind == GlobalValue ||
194            Kind == VirtualRegister || Kind == ConstantPoolItem ||
195            Kind == JumpTableIndex || Kind == IRBlock || Kind == IRValue;
196   }
197 };
198 
199 /// Consume a single machine instruction token in the given source and return
200 /// the remaining source string.
201 StringRef lexMIToken(
202     StringRef Source, MIToken &Token,
203     function_ref<void(StringRef::iterator, const Twine &)> ErrorCallback);
204 
205 } // end namespace llvm
206 
207 #endif
208