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     SubRegisterIndex
123   };
124 
125 private:
126   TokenKind Kind;
127   StringRef Range;
128   StringRef StringValue;
129   std::string StringValueStorage;
130   APSInt IntVal;
131 
132 public:
MITokenMIToken133   MIToken() : Kind(Error) {}
134 
135   MIToken &reset(TokenKind Kind, StringRef Range);
136 
137   MIToken &setStringValue(StringRef StrVal);
138   MIToken &setOwnedStringValue(std::string StrVal);
139   MIToken &setIntegerValue(APSInt IntVal);
140 
kindMIToken141   TokenKind kind() const { return Kind; }
142 
isErrorMIToken143   bool isError() const { return Kind == Error; }
144 
isNewlineOrEOFMIToken145   bool isNewlineOrEOF() const { return Kind == Newline || Kind == Eof; }
146 
isErrorOrEOFMIToken147   bool isErrorOrEOF() const { return Kind == Error || Kind == Eof; }
148 
isRegisterMIToken149   bool isRegister() const {
150     return Kind == NamedRegister || Kind == underscore ||
151            Kind == VirtualRegister;
152   }
153 
isRegisterFlagMIToken154   bool isRegisterFlag() const {
155     return Kind == kw_implicit || Kind == kw_implicit_define ||
156            Kind == kw_def || Kind == kw_dead || Kind == kw_killed ||
157            Kind == kw_undef || Kind == kw_internal ||
158            Kind == kw_early_clobber || Kind == kw_debug_use;
159   }
160 
isMemoryOperandFlagMIToken161   bool isMemoryOperandFlag() const {
162     return Kind == kw_volatile || Kind == kw_non_temporal ||
163            Kind == kw_invariant;
164   }
165 
isMIToken166   bool is(TokenKind K) const { return Kind == K; }
167 
isNotMIToken168   bool isNot(TokenKind K) const { return Kind != K; }
169 
locationMIToken170   StringRef::iterator location() const { return Range.begin(); }
171 
rangeMIToken172   StringRef range() const { return Range; }
173 
174   /// Return the token's string value.
stringValueMIToken175   StringRef stringValue() const { return StringValue; }
176 
integerValueMIToken177   const APSInt &integerValue() const { return IntVal; }
178 
hasIntegerValueMIToken179   bool hasIntegerValue() const {
180     return Kind == IntegerLiteral || Kind == MachineBasicBlock ||
181            Kind == MachineBasicBlockLabel || Kind == StackObject ||
182            Kind == FixedStackObject || Kind == GlobalValue ||
183            Kind == VirtualRegister || Kind == ConstantPoolItem ||
184            Kind == JumpTableIndex || Kind == IRBlock || Kind == IRValue;
185   }
186 };
187 
188 /// Consume a single machine instruction token in the given source and return
189 /// the remaining source string.
190 StringRef lexMIToken(
191     StringRef Source, MIToken &Token,
192     function_ref<void(StringRef::iterator, const Twine &)> ErrorCallback);
193 
194 } // end namespace llvm
195 
196 #endif
197