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 
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     StringConstant
132   };
133 
134 private:
135   TokenKind Kind;
136   StringRef Range;
137   StringRef StringValue;
138   std::string StringValueStorage;
139   APSInt IntVal;
140 
141 public:
142   MIToken() : Kind(Error) {}
143 
144   MIToken &reset(TokenKind Kind, StringRef Range);
145 
146   MIToken &setStringValue(StringRef StrVal);
147   MIToken &setOwnedStringValue(std::string StrVal);
148   MIToken &setIntegerValue(APSInt IntVal);
149 
150   TokenKind kind() const { return Kind; }
151 
152   bool isError() const { return Kind == Error; }
153 
154   bool isNewlineOrEOF() const { return Kind == Newline || Kind == Eof; }
155 
156   bool isErrorOrEOF() const { return Kind == Error || Kind == Eof; }
157 
158   bool isRegister() const {
159     return Kind == NamedRegister || Kind == underscore ||
160            Kind == VirtualRegister;
161   }
162 
163   bool isRegisterFlag() const {
164     return Kind == kw_implicit || Kind == kw_implicit_define ||
165            Kind == kw_def || Kind == kw_dead || Kind == kw_killed ||
166            Kind == kw_undef || Kind == kw_internal ||
167            Kind == kw_early_clobber || Kind == kw_debug_use;
168   }
169 
170   bool isMemoryOperandFlag() const {
171     return Kind == kw_volatile || Kind == kw_non_temporal ||
172            Kind == kw_dereferenceable || Kind == kw_invariant ||
173            Kind == StringConstant;
174   }
175 
176   bool is(TokenKind K) const { return Kind == K; }
177 
178   bool isNot(TokenKind K) const { return Kind != K; }
179 
180   StringRef::iterator location() const { return Range.begin(); }
181 
182   StringRef range() const { return Range; }
183 
184   /// Return the token's string value.
185   StringRef stringValue() const { return StringValue; }
186 
187   const APSInt &integerValue() const { return IntVal; }
188 
189   bool hasIntegerValue() const {
190     return Kind == IntegerLiteral || Kind == MachineBasicBlock ||
191            Kind == MachineBasicBlockLabel || Kind == StackObject ||
192            Kind == FixedStackObject || Kind == GlobalValue ||
193            Kind == VirtualRegister || Kind == ConstantPoolItem ||
194            Kind == JumpTableIndex || Kind == IRBlock || Kind == IRValue;
195   }
196 };
197 
198 /// Consume a single machine instruction token in the given source and return
199 /// the remaining source string.
200 StringRef lexMIToken(
201     StringRef Source, MIToken &Token,
202     function_ref<void(StringRef::iterator, const Twine &)> ErrorCallback);
203 
204 } // end namespace llvm
205 
206 #endif
207