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