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