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
23namespace llvm {
24
25class Twine;
26
27/// A token produced by the machine instruction lexer.
28struct 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
125private:
126  TokenKind Kind;
127  StringRef Range;
128  StringRef StringValue;
129  std::string StringValueStorage;
130  APSInt IntVal;
131
132public:
133  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
141  TokenKind kind() const { return Kind; }
142
143  bool isError() const { return Kind == Error; }
144
145  bool isNewlineOrEOF() const { return Kind == Newline || Kind == Eof; }
146
147  bool isErrorOrEOF() const { return Kind == Error || Kind == Eof; }
148
149  bool isRegister() const {
150    return Kind == NamedRegister || Kind == underscore ||
151           Kind == VirtualRegister;
152  }
153
154  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
161  bool isMemoryOperandFlag() const {
162    return Kind == kw_volatile || Kind == kw_non_temporal ||
163           Kind == kw_invariant;
164  }
165
166  bool is(TokenKind K) const { return Kind == K; }
167
168  bool isNot(TokenKind K) const { return Kind != K; }
169
170  StringRef::iterator location() const { return Range.begin(); }
171
172  StringRef range() const { return Range; }
173
174  /// Return the token's string value.
175  StringRef stringValue() const { return StringValue; }
176
177  const APSInt &integerValue() const { return IntVal; }
178
179  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.
190StringRef lexMIToken(
191    StringRef Source, MIToken &Token,
192    function_ref<void(StringRef::iterator, const Twine &)> ErrorCallback);
193
194} // end namespace llvm
195
196#endif
197