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/StringRef.h"
20 #include "llvm/ADT/STLExtras.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 
104     // Identifier tokens
105     Identifier,
106     IntegerType,
107     NamedRegister,
108     MachineBasicBlockLabel,
109     MachineBasicBlock,
110     PointerType,
111     ScalarType,
112     StackObject,
113     FixedStackObject,
114     NamedGlobalValue,
115     GlobalValue,
116     ExternalSymbol,
117 
118     // Other tokens
119     IntegerLiteral,
120     FloatingPointLiteral,
121     HexLiteral,
122     VirtualRegister,
123     ConstantPoolItem,
124     JumpTableIndex,
125     NamedIRBlock,
126     IRBlock,
127     NamedIRValue,
128     IRValue,
129     QuotedIRValue, // `<constant value>`
130     SubRegisterIndex
131   };
132 
133 private:
134   TokenKind Kind;
135   StringRef Range;
136   StringRef StringValue;
137   std::string StringValueStorage;
138   APSInt IntVal;
139 
140 public:
141   MIToken() : Kind(Error) {}
142 
143   MIToken &reset(TokenKind Kind, StringRef Range);
144 
145   MIToken &setStringValue(StringRef StrVal);
146   MIToken &setOwnedStringValue(std::string StrVal);
147   MIToken &setIntegerValue(APSInt IntVal);
148 
149   TokenKind kind() const { return Kind; }
150 
151   bool isError() const { return Kind == Error; }
152 
153   bool isNewlineOrEOF() const { return Kind == Newline || Kind == Eof; }
154 
155   bool isErrorOrEOF() const { return Kind == Error || Kind == Eof; }
156 
157   bool isRegister() const {
158     return Kind == NamedRegister || Kind == underscore ||
159            Kind == VirtualRegister;
160   }
161 
162   bool isRegisterFlag() const {
163     return Kind == kw_implicit || Kind == kw_implicit_define ||
164            Kind == kw_def || Kind == kw_dead || Kind == kw_killed ||
165            Kind == kw_undef || Kind == kw_internal ||
166            Kind == kw_early_clobber || Kind == kw_debug_use;
167   }
168 
169   bool isMemoryOperandFlag() const {
170     return Kind == kw_volatile || Kind == kw_non_temporal ||
171            Kind == kw_dereferenceable || Kind == kw_invariant;
172   }
173 
174   bool is(TokenKind K) const { return Kind == K; }
175 
176   bool isNot(TokenKind K) const { return Kind != K; }
177 
178   StringRef::iterator location() const { return Range.begin(); }
179 
180   StringRef range() const { return Range; }
181 
182   /// Return the token's string value.
183   StringRef stringValue() const { return StringValue; }
184 
185   const APSInt &integerValue() const { return IntVal; }
186 
187   bool hasIntegerValue() const {
188     return Kind == IntegerLiteral || Kind == MachineBasicBlock ||
189            Kind == MachineBasicBlockLabel || Kind == StackObject ||
190            Kind == FixedStackObject || Kind == GlobalValue ||
191            Kind == VirtualRegister || Kind == ConstantPoolItem ||
192            Kind == JumpTableIndex || Kind == IRBlock || Kind == IRValue;
193   }
194 };
195 
196 /// Consume a single machine instruction token in the given source and return
197 /// the remaining source string.
198 StringRef lexMIToken(
199     StringRef Source, MIToken &Token,
200     function_ref<void(StringRef::iterator, const Twine &)> ErrorCallback);
201 
202 } // end namespace llvm
203 
204 #endif
205