Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 1 | //===- MCExpr.h - Assembly Level Expressions --------------------*- C++ -*-===// |
2 | // |
||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
||
4 | // See https://llvm.org/LICENSE.txt for license information. |
||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
||
6 | // |
||
7 | //===----------------------------------------------------------------------===// |
||
8 | |||
9 | #ifndef LLVM_MC_MCEXPR_H |
||
10 | #define LLVM_MC_MCEXPR_H |
||
11 | |||
12 | #include "llvm/ADT/DenseMap.h" |
||
13 | #include "llvm/Support/SMLoc.h" |
||
14 | #include <cstdint> |
||
15 | |||
16 | namespace llvm { |
||
17 | |||
18 | class MCAsmInfo; |
||
19 | class MCAsmLayout; |
||
20 | class MCAssembler; |
||
21 | class MCContext; |
||
22 | class MCFixup; |
||
23 | class MCFragment; |
||
24 | class MCSection; |
||
25 | class MCStreamer; |
||
26 | class MCSymbol; |
||
27 | class MCValue; |
||
28 | class raw_ostream; |
||
29 | class StringRef; |
||
30 | |||
31 | using SectionAddrMap = DenseMap<const MCSection *, uint64_t>; |
||
32 | |||
33 | /// Base class for the full range of assembler expressions which are |
||
34 | /// needed for parsing. |
||
35 | class MCExpr { |
||
36 | public: |
||
37 | enum ExprKind : uint8_t { |
||
38 | Binary, ///< Binary expressions. |
||
39 | Constant, ///< Constant expressions. |
||
40 | SymbolRef, ///< References to labels and assigned expressions. |
||
41 | Unary, ///< Unary expressions. |
||
42 | Target ///< Target specific expression. |
||
43 | }; |
||
44 | |||
45 | private: |
||
46 | static const unsigned NumSubclassDataBits = 24; |
||
47 | static_assert( |
||
48 | NumSubclassDataBits == CHAR_BIT * (sizeof(unsigned) - sizeof(ExprKind)), |
||
49 | "ExprKind and SubclassData together should take up one word"); |
||
50 | |||
51 | ExprKind Kind; |
||
52 | /// Field reserved for use by MCExpr subclasses. |
||
53 | unsigned SubclassData : NumSubclassDataBits; |
||
54 | SMLoc Loc; |
||
55 | |||
56 | bool evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm, |
||
57 | const MCAsmLayout *Layout, |
||
58 | const SectionAddrMap *Addrs, bool InSet) const; |
||
59 | |||
60 | protected: |
||
61 | explicit MCExpr(ExprKind Kind, SMLoc Loc, unsigned SubclassData = 0) |
||
62 | : Kind(Kind), SubclassData(SubclassData), Loc(Loc) { |
||
63 | assert(SubclassData < (1 << NumSubclassDataBits) && |
||
64 | "Subclass data too large"); |
||
65 | } |
||
66 | |||
67 | bool evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, |
||
68 | const MCAsmLayout *Layout, |
||
69 | const MCFixup *Fixup, |
||
70 | const SectionAddrMap *Addrs, bool InSet) const; |
||
71 | |||
72 | unsigned getSubclassData() const { return SubclassData; } |
||
73 | |||
74 | public: |
||
75 | MCExpr(const MCExpr &) = delete; |
||
76 | MCExpr &operator=(const MCExpr &) = delete; |
||
77 | |||
78 | /// \name Accessors |
||
79 | /// @{ |
||
80 | |||
81 | ExprKind getKind() const { return Kind; } |
||
82 | SMLoc getLoc() const { return Loc; } |
||
83 | |||
84 | /// @} |
||
85 | /// \name Utility Methods |
||
86 | /// @{ |
||
87 | |||
88 | void print(raw_ostream &OS, const MCAsmInfo *MAI, |
||
89 | bool InParens = false) const; |
||
90 | void dump() const; |
||
91 | |||
92 | /// @} |
||
93 | /// \name Expression Evaluation |
||
94 | /// @{ |
||
95 | |||
96 | /// Try to evaluate the expression to an absolute value. |
||
97 | /// |
||
98 | /// \param Res - The absolute value, if evaluation succeeds. |
||
99 | /// \param Layout - The assembler layout object to use for evaluating symbol |
||
100 | /// values. If not given, then only non-symbolic expressions will be |
||
101 | /// evaluated. |
||
102 | /// \return - True on success. |
||
103 | bool evaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout, |
||
104 | const SectionAddrMap &Addrs) const; |
||
105 | bool evaluateAsAbsolute(int64_t &Res) const; |
||
106 | bool evaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const; |
||
107 | bool evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm) const; |
||
108 | bool evaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout) const; |
||
109 | |||
110 | bool evaluateKnownAbsolute(int64_t &Res, const MCAsmLayout &Layout) const; |
||
111 | |||
112 | /// Try to evaluate the expression to a relocatable value, i.e. an |
||
113 | /// expression of the fixed form (a - b + constant). |
||
114 | /// |
||
115 | /// \param Res - The relocatable value, if evaluation succeeds. |
||
116 | /// \param Layout - The assembler layout object to use for evaluating values. |
||
117 | /// \param Fixup - The Fixup object if available. |
||
118 | /// \return - True on success. |
||
119 | bool evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout, |
||
120 | const MCFixup *Fixup) const; |
||
121 | |||
122 | /// Try to evaluate the expression to the form (a - b + constant) where |
||
123 | /// neither a nor b are variables. |
||
124 | /// |
||
125 | /// This is a more aggressive variant of evaluateAsRelocatable. The intended |
||
126 | /// use is for when relocations are not available, like the .size directive. |
||
127 | bool evaluateAsValue(MCValue &Res, const MCAsmLayout &Layout) const; |
||
128 | |||
129 | /// Find the "associated section" for this expression, which is |
||
130 | /// currently defined as the absolute section for constants, or |
||
131 | /// otherwise the section associated with the first defined symbol in the |
||
132 | /// expression. |
||
133 | MCFragment *findAssociatedFragment() const; |
||
134 | |||
135 | /// @} |
||
136 | }; |
||
137 | |||
138 | inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) { |
||
139 | E.print(OS, nullptr); |
||
140 | return OS; |
||
141 | } |
||
142 | |||
143 | //// Represent a constant integer expression. |
||
144 | class MCConstantExpr : public MCExpr { |
||
145 | int64_t Value; |
||
146 | |||
147 | // Subclass data stores SizeInBytes in bits 0..7 and PrintInHex in bit 8. |
||
148 | static const unsigned SizeInBytesBits = 8; |
||
149 | static const unsigned SizeInBytesMask = (1 << SizeInBytesBits) - 1; |
||
150 | static const unsigned PrintInHexBit = 1 << SizeInBytesBits; |
||
151 | |||
152 | static unsigned encodeSubclassData(bool PrintInHex, unsigned SizeInBytes) { |
||
153 | assert(SizeInBytes <= sizeof(int64_t) && "Excessive size"); |
||
154 | return SizeInBytes | (PrintInHex ? PrintInHexBit : 0); |
||
155 | } |
||
156 | |||
157 | MCConstantExpr(int64_t Value, bool PrintInHex, unsigned SizeInBytes) |
||
158 | : MCExpr(MCExpr::Constant, SMLoc(), |
||
159 | encodeSubclassData(PrintInHex, SizeInBytes)), Value(Value) {} |
||
160 | |||
161 | public: |
||
162 | /// \name Construction |
||
163 | /// @{ |
||
164 | |||
165 | static const MCConstantExpr *create(int64_t Value, MCContext &Ctx, |
||
166 | bool PrintInHex = false, |
||
167 | unsigned SizeInBytes = 0); |
||
168 | |||
169 | /// @} |
||
170 | /// \name Accessors |
||
171 | /// @{ |
||
172 | |||
173 | int64_t getValue() const { return Value; } |
||
174 | unsigned getSizeInBytes() const { |
||
175 | return getSubclassData() & SizeInBytesMask; |
||
176 | } |
||
177 | |||
178 | bool useHexFormat() const { return (getSubclassData() & PrintInHexBit) != 0; } |
||
179 | |||
180 | /// @} |
||
181 | |||
182 | static bool classof(const MCExpr *E) { |
||
183 | return E->getKind() == MCExpr::Constant; |
||
184 | } |
||
185 | }; |
||
186 | |||
187 | /// Represent a reference to a symbol from inside an expression. |
||
188 | /// |
||
189 | /// A symbol reference in an expression may be a use of a label, a use of an |
||
190 | /// assembler variable (defined constant), or constitute an implicit definition |
||
191 | /// of the symbol as external. |
||
192 | class MCSymbolRefExpr : public MCExpr { |
||
193 | public: |
||
194 | enum VariantKind : uint16_t { |
||
195 | VK_None, |
||
196 | VK_Invalid, |
||
197 | |||
198 | VK_GOT, |
||
199 | VK_GOTOFF, |
||
200 | VK_GOTREL, |
||
201 | VK_PCREL, |
||
202 | VK_GOTPCREL, |
||
203 | VK_GOTPCREL_NORELAX, |
||
204 | VK_GOTTPOFF, |
||
205 | VK_INDNTPOFF, |
||
206 | VK_NTPOFF, |
||
207 | VK_GOTNTPOFF, |
||
208 | VK_PLT, |
||
209 | VK_TLSGD, |
||
210 | VK_TLSLD, |
||
211 | VK_TLSLDM, |
||
212 | VK_TPOFF, |
||
213 | VK_DTPOFF, |
||
214 | VK_TLSCALL, // symbol(tlscall) |
||
215 | VK_TLSDESC, // symbol(tlsdesc) |
||
216 | VK_TLVP, // Mach-O thread local variable relocations |
||
217 | VK_TLVPPAGE, |
||
218 | VK_TLVPPAGEOFF, |
||
219 | VK_PAGE, |
||
220 | VK_PAGEOFF, |
||
221 | VK_GOTPAGE, |
||
222 | VK_GOTPAGEOFF, |
||
223 | VK_SECREL, |
||
224 | VK_SIZE, // symbol@SIZE |
||
225 | VK_WEAKREF, // The link between the symbols in .weakref foo, bar |
||
226 | |||
227 | VK_X86_ABS8, |
||
228 | VK_X86_PLTOFF, |
||
229 | |||
230 | VK_ARM_NONE, |
||
231 | VK_ARM_GOT_PREL, |
||
232 | VK_ARM_TARGET1, |
||
233 | VK_ARM_TARGET2, |
||
234 | VK_ARM_PREL31, |
||
235 | VK_ARM_SBREL, // symbol(sbrel) |
||
236 | VK_ARM_TLSLDO, // symbol(tlsldo) |
||
237 | VK_ARM_TLSDESCSEQ, |
||
238 | |||
239 | VK_AVR_NONE, |
||
240 | VK_AVR_LO8, |
||
241 | VK_AVR_HI8, |
||
242 | VK_AVR_HLO8, |
||
243 | VK_AVR_DIFF8, |
||
244 | VK_AVR_DIFF16, |
||
245 | VK_AVR_DIFF32, |
||
246 | VK_AVR_PM, |
||
247 | |||
248 | VK_PPC_LO, // symbol@l |
||
249 | VK_PPC_HI, // symbol@h |
||
250 | VK_PPC_HA, // symbol@ha |
||
251 | VK_PPC_HIGH, // symbol@high |
||
252 | VK_PPC_HIGHA, // symbol@higha |
||
253 | VK_PPC_HIGHER, // symbol@higher |
||
254 | VK_PPC_HIGHERA, // symbol@highera |
||
255 | VK_PPC_HIGHEST, // symbol@highest |
||
256 | VK_PPC_HIGHESTA, // symbol@highesta |
||
257 | VK_PPC_GOT_LO, // symbol@got@l |
||
258 | VK_PPC_GOT_HI, // symbol@got@h |
||
259 | VK_PPC_GOT_HA, // symbol@got@ha |
||
260 | VK_PPC_TOCBASE, // symbol@tocbase |
||
261 | VK_PPC_TOC, // symbol@toc |
||
262 | VK_PPC_TOC_LO, // symbol@toc@l |
||
263 | VK_PPC_TOC_HI, // symbol@toc@h |
||
264 | VK_PPC_TOC_HA, // symbol@toc@ha |
||
265 | VK_PPC_U, // symbol@u |
||
266 | VK_PPC_L, // symbol@l |
||
267 | VK_PPC_DTPMOD, // symbol@dtpmod |
||
268 | VK_PPC_TPREL_LO, // symbol@tprel@l |
||
269 | VK_PPC_TPREL_HI, // symbol@tprel@h |
||
270 | VK_PPC_TPREL_HA, // symbol@tprel@ha |
||
271 | VK_PPC_TPREL_HIGH, // symbol@tprel@high |
||
272 | VK_PPC_TPREL_HIGHA, // symbol@tprel@higha |
||
273 | VK_PPC_TPREL_HIGHER, // symbol@tprel@higher |
||
274 | VK_PPC_TPREL_HIGHERA, // symbol@tprel@highera |
||
275 | VK_PPC_TPREL_HIGHEST, // symbol@tprel@highest |
||
276 | VK_PPC_TPREL_HIGHESTA, // symbol@tprel@highesta |
||
277 | VK_PPC_DTPREL_LO, // symbol@dtprel@l |
||
278 | VK_PPC_DTPREL_HI, // symbol@dtprel@h |
||
279 | VK_PPC_DTPREL_HA, // symbol@dtprel@ha |
||
280 | VK_PPC_DTPREL_HIGH, // symbol@dtprel@high |
||
281 | VK_PPC_DTPREL_HIGHA, // symbol@dtprel@higha |
||
282 | VK_PPC_DTPREL_HIGHER, // symbol@dtprel@higher |
||
283 | VK_PPC_DTPREL_HIGHERA, // symbol@dtprel@highera |
||
284 | VK_PPC_DTPREL_HIGHEST, // symbol@dtprel@highest |
||
285 | VK_PPC_DTPREL_HIGHESTA, // symbol@dtprel@highesta |
||
286 | VK_PPC_GOT_TPREL, // symbol@got@tprel |
||
287 | VK_PPC_GOT_TPREL_LO, // symbol@got@tprel@l |
||
288 | VK_PPC_GOT_TPREL_HI, // symbol@got@tprel@h |
||
289 | VK_PPC_GOT_TPREL_HA, // symbol@got@tprel@ha |
||
290 | VK_PPC_GOT_DTPREL, // symbol@got@dtprel |
||
291 | VK_PPC_GOT_DTPREL_LO, // symbol@got@dtprel@l |
||
292 | VK_PPC_GOT_DTPREL_HI, // symbol@got@dtprel@h |
||
293 | VK_PPC_GOT_DTPREL_HA, // symbol@got@dtprel@ha |
||
294 | VK_PPC_TLS, // symbol@tls |
||
295 | VK_PPC_GOT_TLSGD, // symbol@got@tlsgd |
||
296 | VK_PPC_GOT_TLSGD_LO, // symbol@got@tlsgd@l |
||
297 | VK_PPC_GOT_TLSGD_HI, // symbol@got@tlsgd@h |
||
298 | VK_PPC_GOT_TLSGD_HA, // symbol@got@tlsgd@ha |
||
299 | VK_PPC_TLSGD, // symbol@tlsgd |
||
300 | VK_PPC_AIX_TLSGD, // symbol@gd |
||
301 | VK_PPC_AIX_TLSGDM, // symbol@m |
||
302 | VK_PPC_GOT_TLSLD, // symbol@got@tlsld |
||
303 | VK_PPC_GOT_TLSLD_LO, // symbol@got@tlsld@l |
||
304 | VK_PPC_GOT_TLSLD_HI, // symbol@got@tlsld@h |
||
305 | VK_PPC_GOT_TLSLD_HA, // symbol@got@tlsld@ha |
||
306 | VK_PPC_GOT_PCREL, // symbol@got@pcrel |
||
307 | VK_PPC_GOT_TLSGD_PCREL, // symbol@got@tlsgd@pcrel |
||
308 | VK_PPC_GOT_TLSLD_PCREL, // symbol@got@tlsld@pcrel |
||
309 | VK_PPC_GOT_TPREL_PCREL, // symbol@got@tprel@pcrel |
||
310 | VK_PPC_TLS_PCREL, // symbol@tls@pcrel |
||
311 | VK_PPC_TLSLD, // symbol@tlsld |
||
312 | VK_PPC_LOCAL, // symbol@local |
||
313 | VK_PPC_NOTOC, // symbol@notoc |
||
314 | VK_PPC_PCREL_OPT, // .reloc expr, R_PPC64_PCREL_OPT, expr |
||
315 | |||
316 | VK_COFF_IMGREL32, // symbol@imgrel (image-relative) |
||
317 | |||
318 | VK_Hexagon_LO16, |
||
319 | VK_Hexagon_HI16, |
||
320 | VK_Hexagon_GPREL, |
||
321 | VK_Hexagon_GD_GOT, |
||
322 | VK_Hexagon_LD_GOT, |
||
323 | VK_Hexagon_GD_PLT, |
||
324 | VK_Hexagon_LD_PLT, |
||
325 | VK_Hexagon_IE, |
||
326 | VK_Hexagon_IE_GOT, |
||
327 | |||
328 | VK_WASM_TYPEINDEX, // Reference to a symbol's type (signature) |
||
329 | VK_WASM_TLSREL, // Memory address relative to __tls_base |
||
330 | VK_WASM_MBREL, // Memory address relative to __memory_base |
||
331 | VK_WASM_TBREL, // Table index relative to __table_base |
||
332 | VK_WASM_GOT_TLS, // Wasm global index of TLS symbol. |
||
333 | |||
334 | VK_AMDGPU_GOTPCREL32_LO, // symbol@gotpcrel32@lo |
||
335 | VK_AMDGPU_GOTPCREL32_HI, // symbol@gotpcrel32@hi |
||
336 | VK_AMDGPU_REL32_LO, // symbol@rel32@lo |
||
337 | VK_AMDGPU_REL32_HI, // symbol@rel32@hi |
||
338 | VK_AMDGPU_REL64, // symbol@rel64 |
||
339 | VK_AMDGPU_ABS32_LO, // symbol@abs32@lo |
||
340 | VK_AMDGPU_ABS32_HI, // symbol@abs32@hi |
||
341 | |||
342 | VK_VE_HI32, // symbol@hi |
||
343 | VK_VE_LO32, // symbol@lo |
||
344 | VK_VE_PC_HI32, // symbol@pc_hi |
||
345 | VK_VE_PC_LO32, // symbol@pc_lo |
||
346 | VK_VE_GOT_HI32, // symbol@got_hi |
||
347 | VK_VE_GOT_LO32, // symbol@got_lo |
||
348 | VK_VE_GOTOFF_HI32, // symbol@gotoff_hi |
||
349 | VK_VE_GOTOFF_LO32, // symbol@gotoff_lo |
||
350 | VK_VE_PLT_HI32, // symbol@plt_hi |
||
351 | VK_VE_PLT_LO32, // symbol@plt_lo |
||
352 | VK_VE_TLS_GD_HI32, // symbol@tls_gd_hi |
||
353 | VK_VE_TLS_GD_LO32, // symbol@tls_gd_lo |
||
354 | VK_VE_TPOFF_HI32, // symbol@tpoff_hi |
||
355 | VK_VE_TPOFF_LO32, // symbol@tpoff_lo |
||
356 | |||
357 | VK_TPREL, |
||
358 | VK_DTPREL |
||
359 | }; |
||
360 | |||
361 | private: |
||
362 | /// The symbol being referenced. |
||
363 | const MCSymbol *Symbol; |
||
364 | |||
365 | // Subclass data stores VariantKind in bits 0..15 and HasSubsectionsViaSymbols |
||
366 | // in bit 16. |
||
367 | static const unsigned VariantKindBits = 16; |
||
368 | static const unsigned VariantKindMask = (1 << VariantKindBits) - 1; |
||
369 | |||
370 | // FIXME: Remove this bit. |
||
371 | static const unsigned HasSubsectionsViaSymbolsBit = 1 << VariantKindBits; |
||
372 | |||
373 | static unsigned encodeSubclassData(VariantKind Kind, |
||
374 | bool HasSubsectionsViaSymbols) { |
||
375 | return (unsigned)Kind | |
||
376 | (HasSubsectionsViaSymbols ? HasSubsectionsViaSymbolsBit : 0); |
||
377 | } |
||
378 | |||
379 | explicit MCSymbolRefExpr(const MCSymbol *Symbol, VariantKind Kind, |
||
380 | const MCAsmInfo *MAI, SMLoc Loc = SMLoc()); |
||
381 | |||
382 | public: |
||
383 | /// \name Construction |
||
384 | /// @{ |
||
385 | |||
386 | static const MCSymbolRefExpr *create(const MCSymbol *Symbol, MCContext &Ctx) { |
||
387 | return MCSymbolRefExpr::create(Symbol, VK_None, Ctx); |
||
388 | } |
||
389 | |||
390 | static const MCSymbolRefExpr *create(const MCSymbol *Symbol, VariantKind Kind, |
||
391 | MCContext &Ctx, SMLoc Loc = SMLoc()); |
||
392 | static const MCSymbolRefExpr *create(StringRef Name, VariantKind Kind, |
||
393 | MCContext &Ctx); |
||
394 | |||
395 | /// @} |
||
396 | /// \name Accessors |
||
397 | /// @{ |
||
398 | |||
399 | const MCSymbol &getSymbol() const { return *Symbol; } |
||
400 | |||
401 | VariantKind getKind() const { |
||
402 | return (VariantKind)(getSubclassData() & VariantKindMask); |
||
403 | } |
||
404 | |||
405 | bool hasSubsectionsViaSymbols() const { |
||
406 | return (getSubclassData() & HasSubsectionsViaSymbolsBit) != 0; |
||
407 | } |
||
408 | |||
409 | /// @} |
||
410 | /// \name Static Utility Functions |
||
411 | /// @{ |
||
412 | |||
413 | static StringRef getVariantKindName(VariantKind Kind); |
||
414 | |||
415 | static VariantKind getVariantKindForName(StringRef Name); |
||
416 | |||
417 | /// @} |
||
418 | |||
419 | static bool classof(const MCExpr *E) { |
||
420 | return E->getKind() == MCExpr::SymbolRef; |
||
421 | } |
||
422 | }; |
||
423 | |||
424 | /// Unary assembler expressions. |
||
425 | class MCUnaryExpr : public MCExpr { |
||
426 | public: |
||
427 | enum Opcode { |
||
428 | LNot, ///< Logical negation. |
||
429 | Minus, ///< Unary minus. |
||
430 | Not, ///< Bitwise negation. |
||
431 | Plus ///< Unary plus. |
||
432 | }; |
||
433 | |||
434 | private: |
||
435 | const MCExpr *Expr; |
||
436 | |||
437 | MCUnaryExpr(Opcode Op, const MCExpr *Expr, SMLoc Loc) |
||
438 | : MCExpr(MCExpr::Unary, Loc, Op), Expr(Expr) {} |
||
439 | |||
440 | public: |
||
441 | /// \name Construction |
||
442 | /// @{ |
||
443 | |||
444 | static const MCUnaryExpr *create(Opcode Op, const MCExpr *Expr, |
||
445 | MCContext &Ctx, SMLoc Loc = SMLoc()); |
||
446 | |||
447 | static const MCUnaryExpr *createLNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) { |
||
448 | return create(LNot, Expr, Ctx, Loc); |
||
449 | } |
||
450 | |||
451 | static const MCUnaryExpr *createMinus(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) { |
||
452 | return create(Minus, Expr, Ctx, Loc); |
||
453 | } |
||
454 | |||
455 | static const MCUnaryExpr *createNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) { |
||
456 | return create(Not, Expr, Ctx, Loc); |
||
457 | } |
||
458 | |||
459 | static const MCUnaryExpr *createPlus(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) { |
||
460 | return create(Plus, Expr, Ctx, Loc); |
||
461 | } |
||
462 | |||
463 | /// @} |
||
464 | /// \name Accessors |
||
465 | /// @{ |
||
466 | |||
467 | /// Get the kind of this unary expression. |
||
468 | Opcode getOpcode() const { return (Opcode)getSubclassData(); } |
||
469 | |||
470 | /// Get the child of this unary expression. |
||
471 | const MCExpr *getSubExpr() const { return Expr; } |
||
472 | |||
473 | /// @} |
||
474 | |||
475 | static bool classof(const MCExpr *E) { |
||
476 | return E->getKind() == MCExpr::Unary; |
||
477 | } |
||
478 | }; |
||
479 | |||
480 | /// Binary assembler expressions. |
||
481 | class MCBinaryExpr : public MCExpr { |
||
482 | public: |
||
483 | enum Opcode { |
||
484 | Add, ///< Addition. |
||
485 | And, ///< Bitwise and. |
||
486 | Div, ///< Signed division. |
||
487 | EQ, ///< Equality comparison. |
||
488 | GT, ///< Signed greater than comparison (result is either 0 or some |
||
489 | ///< target-specific non-zero value) |
||
490 | GTE, ///< Signed greater than or equal comparison (result is either 0 or |
||
491 | ///< some target-specific non-zero value). |
||
492 | LAnd, ///< Logical and. |
||
493 | LOr, ///< Logical or. |
||
494 | LT, ///< Signed less than comparison (result is either 0 or |
||
495 | ///< some target-specific non-zero value). |
||
496 | LTE, ///< Signed less than or equal comparison (result is either 0 or |
||
497 | ///< some target-specific non-zero value). |
||
498 | Mod, ///< Signed remainder. |
||
499 | Mul, ///< Multiplication. |
||
500 | NE, ///< Inequality comparison. |
||
501 | Or, ///< Bitwise or. |
||
502 | OrNot, ///< Bitwise or not. |
||
503 | Shl, ///< Shift left. |
||
504 | AShr, ///< Arithmetic shift right. |
||
505 | LShr, ///< Logical shift right. |
||
506 | Sub, ///< Subtraction. |
||
507 | Xor ///< Bitwise exclusive or. |
||
508 | }; |
||
509 | |||
510 | private: |
||
511 | const MCExpr *LHS, *RHS; |
||
512 | |||
513 | MCBinaryExpr(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, |
||
514 | SMLoc Loc = SMLoc()) |
||
515 | : MCExpr(MCExpr::Binary, Loc, Op), LHS(LHS), RHS(RHS) {} |
||
516 | |||
517 | public: |
||
518 | /// \name Construction |
||
519 | /// @{ |
||
520 | |||
521 | static const MCBinaryExpr *create(Opcode Op, const MCExpr *LHS, |
||
522 | const MCExpr *RHS, MCContext &Ctx, |
||
523 | SMLoc Loc = SMLoc()); |
||
524 | |||
525 | static const MCBinaryExpr *createAdd(const MCExpr *LHS, const MCExpr *RHS, |
||
526 | MCContext &Ctx) { |
||
527 | return create(Add, LHS, RHS, Ctx); |
||
528 | } |
||
529 | |||
530 | static const MCBinaryExpr *createAnd(const MCExpr *LHS, const MCExpr *RHS, |
||
531 | MCContext &Ctx) { |
||
532 | return create(And, LHS, RHS, Ctx); |
||
533 | } |
||
534 | |||
535 | static const MCBinaryExpr *createDiv(const MCExpr *LHS, const MCExpr *RHS, |
||
536 | MCContext &Ctx) { |
||
537 | return create(Div, LHS, RHS, Ctx); |
||
538 | } |
||
539 | |||
540 | static const MCBinaryExpr *createEQ(const MCExpr *LHS, const MCExpr *RHS, |
||
541 | MCContext &Ctx) { |
||
542 | return create(EQ, LHS, RHS, Ctx); |
||
543 | } |
||
544 | |||
545 | static const MCBinaryExpr *createGT(const MCExpr *LHS, const MCExpr *RHS, |
||
546 | MCContext &Ctx) { |
||
547 | return create(GT, LHS, RHS, Ctx); |
||
548 | } |
||
549 | |||
550 | static const MCBinaryExpr *createGTE(const MCExpr *LHS, const MCExpr *RHS, |
||
551 | MCContext &Ctx) { |
||
552 | return create(GTE, LHS, RHS, Ctx); |
||
553 | } |
||
554 | |||
555 | static const MCBinaryExpr *createLAnd(const MCExpr *LHS, const MCExpr *RHS, |
||
556 | MCContext &Ctx) { |
||
557 | return create(LAnd, LHS, RHS, Ctx); |
||
558 | } |
||
559 | |||
560 | static const MCBinaryExpr *createLOr(const MCExpr *LHS, const MCExpr *RHS, |
||
561 | MCContext &Ctx) { |
||
562 | return create(LOr, LHS, RHS, Ctx); |
||
563 | } |
||
564 | |||
565 | static const MCBinaryExpr *createLT(const MCExpr *LHS, const MCExpr *RHS, |
||
566 | MCContext &Ctx) { |
||
567 | return create(LT, LHS, RHS, Ctx); |
||
568 | } |
||
569 | |||
570 | static const MCBinaryExpr *createLTE(const MCExpr *LHS, const MCExpr *RHS, |
||
571 | MCContext &Ctx) { |
||
572 | return create(LTE, LHS, RHS, Ctx); |
||
573 | } |
||
574 | |||
575 | static const MCBinaryExpr *createMod(const MCExpr *LHS, const MCExpr *RHS, |
||
576 | MCContext &Ctx) { |
||
577 | return create(Mod, LHS, RHS, Ctx); |
||
578 | } |
||
579 | |||
580 | static const MCBinaryExpr *createMul(const MCExpr *LHS, const MCExpr *RHS, |
||
581 | MCContext &Ctx) { |
||
582 | return create(Mul, LHS, RHS, Ctx); |
||
583 | } |
||
584 | |||
585 | static const MCBinaryExpr *createNE(const MCExpr *LHS, const MCExpr *RHS, |
||
586 | MCContext &Ctx) { |
||
587 | return create(NE, LHS, RHS, Ctx); |
||
588 | } |
||
589 | |||
590 | static const MCBinaryExpr *createOr(const MCExpr *LHS, const MCExpr *RHS, |
||
591 | MCContext &Ctx) { |
||
592 | return create(Or, LHS, RHS, Ctx); |
||
593 | } |
||
594 | |||
595 | static const MCBinaryExpr *createShl(const MCExpr *LHS, const MCExpr *RHS, |
||
596 | MCContext &Ctx) { |
||
597 | return create(Shl, LHS, RHS, Ctx); |
||
598 | } |
||
599 | |||
600 | static const MCBinaryExpr *createAShr(const MCExpr *LHS, const MCExpr *RHS, |
||
601 | MCContext &Ctx) { |
||
602 | return create(AShr, LHS, RHS, Ctx); |
||
603 | } |
||
604 | |||
605 | static const MCBinaryExpr *createLShr(const MCExpr *LHS, const MCExpr *RHS, |
||
606 | MCContext &Ctx) { |
||
607 | return create(LShr, LHS, RHS, Ctx); |
||
608 | } |
||
609 | |||
610 | static const MCBinaryExpr *createSub(const MCExpr *LHS, const MCExpr *RHS, |
||
611 | MCContext &Ctx) { |
||
612 | return create(Sub, LHS, RHS, Ctx); |
||
613 | } |
||
614 | |||
615 | static const MCBinaryExpr *createXor(const MCExpr *LHS, const MCExpr *RHS, |
||
616 | MCContext &Ctx) { |
||
617 | return create(Xor, LHS, RHS, Ctx); |
||
618 | } |
||
619 | |||
620 | /// @} |
||
621 | /// \name Accessors |
||
622 | /// @{ |
||
623 | |||
624 | /// Get the kind of this binary expression. |
||
625 | Opcode getOpcode() const { return (Opcode)getSubclassData(); } |
||
626 | |||
627 | /// Get the left-hand side expression of the binary operator. |
||
628 | const MCExpr *getLHS() const { return LHS; } |
||
629 | |||
630 | /// Get the right-hand side expression of the binary operator. |
||
631 | const MCExpr *getRHS() const { return RHS; } |
||
632 | |||
633 | /// @} |
||
634 | |||
635 | static bool classof(const MCExpr *E) { |
||
636 | return E->getKind() == MCExpr::Binary; |
||
637 | } |
||
638 | }; |
||
639 | |||
640 | /// This is an extension point for target-specific MCExpr subclasses to |
||
641 | /// implement. |
||
642 | /// |
||
643 | /// NOTE: All subclasses are required to have trivial destructors because |
||
644 | /// MCExprs are bump pointer allocated and not destructed. |
||
645 | class MCTargetExpr : public MCExpr { |
||
646 | virtual void anchor(); |
||
647 | |||
648 | protected: |
||
649 | MCTargetExpr() : MCExpr(Target, SMLoc()) {} |
||
650 | virtual ~MCTargetExpr() = default; |
||
651 | |||
652 | public: |
||
653 | virtual void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const = 0; |
||
654 | virtual bool evaluateAsRelocatableImpl(MCValue &Res, |
||
655 | const MCAsmLayout *Layout, |
||
656 | const MCFixup *Fixup) const = 0; |
||
657 | // allow Target Expressions to be checked for equality |
||
658 | virtual bool isEqualTo(const MCExpr *x) const { return false; } |
||
659 | // This should be set when assigned expressions are not valid ".set" |
||
660 | // expressions, e.g. registers, and must be inlined. |
||
661 | virtual bool inlineAssignedExpr() const { return false; } |
||
662 | virtual void visitUsedExpr(MCStreamer& Streamer) const = 0; |
||
663 | virtual MCFragment *findAssociatedFragment() const = 0; |
||
664 | |||
665 | virtual void fixELFSymbolsInTLSFixups(MCAssembler &) const = 0; |
||
666 | |||
667 | static bool classof(const MCExpr *E) { |
||
668 | return E->getKind() == MCExpr::Target; |
||
669 | } |
||
670 | }; |
||
671 | |||
672 | } // end namespace llvm |
||
673 | |||
674 | #endif // LLVM_MC_MCEXPR_H |