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, MAI: 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_AIX_TLSIE, // symbol@ie |
303 | VK_PPC_AIX_TLSLE, // symbol@le |
304 | VK_PPC_GOT_TLSLD, // symbol@got@tlsld |
305 | VK_PPC_GOT_TLSLD_LO, // symbol@got@tlsld@l |
306 | VK_PPC_GOT_TLSLD_HI, // symbol@got@tlsld@h |
307 | VK_PPC_GOT_TLSLD_HA, // symbol@got@tlsld@ha |
308 | VK_PPC_GOT_PCREL, // symbol@got@pcrel |
309 | VK_PPC_GOT_TLSGD_PCREL, // symbol@got@tlsgd@pcrel |
310 | VK_PPC_GOT_TLSLD_PCREL, // symbol@got@tlsld@pcrel |
311 | VK_PPC_GOT_TPREL_PCREL, // symbol@got@tprel@pcrel |
312 | VK_PPC_TLS_PCREL, // symbol@tls@pcrel |
313 | VK_PPC_TLSLD, // symbol@tlsld |
314 | VK_PPC_LOCAL, // symbol@local |
315 | VK_PPC_NOTOC, // symbol@notoc |
316 | VK_PPC_PCREL_OPT, // .reloc expr, R_PPC64_PCREL_OPT, expr |
317 | |
318 | VK_COFF_IMGREL32, // symbol@imgrel (image-relative) |
319 | |
320 | VK_Hexagon_LO16, |
321 | VK_Hexagon_HI16, |
322 | VK_Hexagon_GPREL, |
323 | VK_Hexagon_GD_GOT, |
324 | VK_Hexagon_LD_GOT, |
325 | VK_Hexagon_GD_PLT, |
326 | VK_Hexagon_LD_PLT, |
327 | VK_Hexagon_IE, |
328 | VK_Hexagon_IE_GOT, |
329 | |
330 | VK_WASM_TYPEINDEX, // Reference to a symbol's type (signature) |
331 | VK_WASM_TLSREL, // Memory address relative to __tls_base |
332 | VK_WASM_MBREL, // Memory address relative to __memory_base |
333 | VK_WASM_TBREL, // Table index relative to __table_base |
334 | VK_WASM_GOT_TLS, // Wasm global index of TLS symbol. |
335 | VK_WASM_FUNCINDEX, // Wasm function index. |
336 | |
337 | VK_AMDGPU_GOTPCREL32_LO, // symbol@gotpcrel32@lo |
338 | VK_AMDGPU_GOTPCREL32_HI, // symbol@gotpcrel32@hi |
339 | VK_AMDGPU_REL32_LO, // symbol@rel32@lo |
340 | VK_AMDGPU_REL32_HI, // symbol@rel32@hi |
341 | VK_AMDGPU_REL64, // symbol@rel64 |
342 | VK_AMDGPU_ABS32_LO, // symbol@abs32@lo |
343 | VK_AMDGPU_ABS32_HI, // symbol@abs32@hi |
344 | |
345 | VK_VE_HI32, // symbol@hi |
346 | VK_VE_LO32, // symbol@lo |
347 | VK_VE_PC_HI32, // symbol@pc_hi |
348 | VK_VE_PC_LO32, // symbol@pc_lo |
349 | VK_VE_GOT_HI32, // symbol@got_hi |
350 | VK_VE_GOT_LO32, // symbol@got_lo |
351 | VK_VE_GOTOFF_HI32, // symbol@gotoff_hi |
352 | VK_VE_GOTOFF_LO32, // symbol@gotoff_lo |
353 | VK_VE_PLT_HI32, // symbol@plt_hi |
354 | VK_VE_PLT_LO32, // symbol@plt_lo |
355 | VK_VE_TLS_GD_HI32, // symbol@tls_gd_hi |
356 | VK_VE_TLS_GD_LO32, // symbol@tls_gd_lo |
357 | VK_VE_TPOFF_HI32, // symbol@tpoff_hi |
358 | VK_VE_TPOFF_LO32, // symbol@tpoff_lo |
359 | |
360 | VK_TPREL, |
361 | VK_DTPREL |
362 | }; |
363 | |
364 | private: |
365 | /// The symbol being referenced. |
366 | const MCSymbol *Symbol; |
367 | |
368 | // Subclass data stores VariantKind in bits 0..15 and HasSubsectionsViaSymbols |
369 | // in bit 16. |
370 | static const unsigned VariantKindBits = 16; |
371 | static const unsigned VariantKindMask = (1 << VariantKindBits) - 1; |
372 | |
373 | // FIXME: Remove this bit. |
374 | static const unsigned HasSubsectionsViaSymbolsBit = 1 << VariantKindBits; |
375 | |
376 | static unsigned encodeSubclassData(VariantKind Kind, |
377 | bool HasSubsectionsViaSymbols) { |
378 | return (unsigned)Kind | |
379 | (HasSubsectionsViaSymbols ? HasSubsectionsViaSymbolsBit : 0); |
380 | } |
381 | |
382 | explicit MCSymbolRefExpr(const MCSymbol *Symbol, VariantKind Kind, |
383 | const MCAsmInfo *MAI, SMLoc Loc = SMLoc()); |
384 | |
385 | public: |
386 | /// \name Construction |
387 | /// @{ |
388 | |
389 | static const MCSymbolRefExpr *create(const MCSymbol *Symbol, MCContext &Ctx) { |
390 | return MCSymbolRefExpr::create(Symbol, Kind: VK_None, Ctx); |
391 | } |
392 | |
393 | static const MCSymbolRefExpr *create(const MCSymbol *Symbol, VariantKind Kind, |
394 | MCContext &Ctx, SMLoc Loc = SMLoc()); |
395 | static const MCSymbolRefExpr *create(StringRef Name, VariantKind Kind, |
396 | MCContext &Ctx); |
397 | |
398 | /// @} |
399 | /// \name Accessors |
400 | /// @{ |
401 | |
402 | const MCSymbol &getSymbol() const { return *Symbol; } |
403 | |
404 | VariantKind getKind() const { |
405 | return (VariantKind)(getSubclassData() & VariantKindMask); |
406 | } |
407 | |
408 | bool hasSubsectionsViaSymbols() const { |
409 | return (getSubclassData() & HasSubsectionsViaSymbolsBit) != 0; |
410 | } |
411 | |
412 | /// @} |
413 | /// \name Static Utility Functions |
414 | /// @{ |
415 | |
416 | static StringRef getVariantKindName(VariantKind Kind); |
417 | |
418 | static VariantKind getVariantKindForName(StringRef Name); |
419 | |
420 | /// @} |
421 | |
422 | static bool classof(const MCExpr *E) { |
423 | return E->getKind() == MCExpr::SymbolRef; |
424 | } |
425 | }; |
426 | |
427 | /// Unary assembler expressions. |
428 | class MCUnaryExpr : public MCExpr { |
429 | public: |
430 | enum Opcode { |
431 | LNot, ///< Logical negation. |
432 | Minus, ///< Unary minus. |
433 | Not, ///< Bitwise negation. |
434 | Plus ///< Unary plus. |
435 | }; |
436 | |
437 | private: |
438 | const MCExpr *Expr; |
439 | |
440 | MCUnaryExpr(Opcode Op, const MCExpr *Expr, SMLoc Loc) |
441 | : MCExpr(MCExpr::Unary, Loc, Op), Expr(Expr) {} |
442 | |
443 | public: |
444 | /// \name Construction |
445 | /// @{ |
446 | |
447 | static const MCUnaryExpr *create(Opcode Op, const MCExpr *Expr, |
448 | MCContext &Ctx, SMLoc Loc = SMLoc()); |
449 | |
450 | static const MCUnaryExpr *createLNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) { |
451 | return create(Op: LNot, Expr, Ctx, Loc); |
452 | } |
453 | |
454 | static const MCUnaryExpr *createMinus(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) { |
455 | return create(Op: Minus, Expr, Ctx, Loc); |
456 | } |
457 | |
458 | static const MCUnaryExpr *createNot(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) { |
459 | return create(Op: Not, Expr, Ctx, Loc); |
460 | } |
461 | |
462 | static const MCUnaryExpr *createPlus(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc = SMLoc()) { |
463 | return create(Op: Plus, Expr, Ctx, Loc); |
464 | } |
465 | |
466 | /// @} |
467 | /// \name Accessors |
468 | /// @{ |
469 | |
470 | /// Get the kind of this unary expression. |
471 | Opcode getOpcode() const { return (Opcode)getSubclassData(); } |
472 | |
473 | /// Get the child of this unary expression. |
474 | const MCExpr *getSubExpr() const { return Expr; } |
475 | |
476 | /// @} |
477 | |
478 | static bool classof(const MCExpr *E) { |
479 | return E->getKind() == MCExpr::Unary; |
480 | } |
481 | }; |
482 | |
483 | /// Binary assembler expressions. |
484 | class MCBinaryExpr : public MCExpr { |
485 | public: |
486 | enum Opcode { |
487 | Add, ///< Addition. |
488 | And, ///< Bitwise and. |
489 | Div, ///< Signed division. |
490 | EQ, ///< Equality comparison. |
491 | GT, ///< Signed greater than comparison (result is either 0 or some |
492 | ///< target-specific non-zero value) |
493 | GTE, ///< Signed greater than or equal comparison (result is either 0 or |
494 | ///< some target-specific non-zero value). |
495 | LAnd, ///< Logical and. |
496 | LOr, ///< Logical or. |
497 | LT, ///< Signed less than comparison (result is either 0 or |
498 | ///< some target-specific non-zero value). |
499 | LTE, ///< Signed less than or equal comparison (result is either 0 or |
500 | ///< some target-specific non-zero value). |
501 | Mod, ///< Signed remainder. |
502 | Mul, ///< Multiplication. |
503 | NE, ///< Inequality comparison. |
504 | Or, ///< Bitwise or. |
505 | OrNot, ///< Bitwise or not. |
506 | Shl, ///< Shift left. |
507 | AShr, ///< Arithmetic shift right. |
508 | LShr, ///< Logical shift right. |
509 | Sub, ///< Subtraction. |
510 | Xor ///< Bitwise exclusive or. |
511 | }; |
512 | |
513 | private: |
514 | const MCExpr *LHS, *RHS; |
515 | |
516 | MCBinaryExpr(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, |
517 | SMLoc Loc = SMLoc()) |
518 | : MCExpr(MCExpr::Binary, Loc, Op), LHS(LHS), RHS(RHS) {} |
519 | |
520 | public: |
521 | /// \name Construction |
522 | /// @{ |
523 | |
524 | static const MCBinaryExpr *create(Opcode Op, const MCExpr *LHS, |
525 | const MCExpr *RHS, MCContext &Ctx, |
526 | SMLoc Loc = SMLoc()); |
527 | |
528 | static const MCBinaryExpr *createAdd(const MCExpr *LHS, const MCExpr *RHS, |
529 | MCContext &Ctx) { |
530 | return create(Op: Add, LHS, RHS, Ctx); |
531 | } |
532 | |
533 | static const MCBinaryExpr *createAnd(const MCExpr *LHS, const MCExpr *RHS, |
534 | MCContext &Ctx) { |
535 | return create(Op: And, LHS, RHS, Ctx); |
536 | } |
537 | |
538 | static const MCBinaryExpr *createDiv(const MCExpr *LHS, const MCExpr *RHS, |
539 | MCContext &Ctx) { |
540 | return create(Op: Div, LHS, RHS, Ctx); |
541 | } |
542 | |
543 | static const MCBinaryExpr *createEQ(const MCExpr *LHS, const MCExpr *RHS, |
544 | MCContext &Ctx) { |
545 | return create(Op: EQ, LHS, RHS, Ctx); |
546 | } |
547 | |
548 | static const MCBinaryExpr *createGT(const MCExpr *LHS, const MCExpr *RHS, |
549 | MCContext &Ctx) { |
550 | return create(Op: GT, LHS, RHS, Ctx); |
551 | } |
552 | |
553 | static const MCBinaryExpr *createGTE(const MCExpr *LHS, const MCExpr *RHS, |
554 | MCContext &Ctx) { |
555 | return create(Op: GTE, LHS, RHS, Ctx); |
556 | } |
557 | |
558 | static const MCBinaryExpr *createLAnd(const MCExpr *LHS, const MCExpr *RHS, |
559 | MCContext &Ctx) { |
560 | return create(Op: LAnd, LHS, RHS, Ctx); |
561 | } |
562 | |
563 | static const MCBinaryExpr *createLOr(const MCExpr *LHS, const MCExpr *RHS, |
564 | MCContext &Ctx) { |
565 | return create(Op: LOr, LHS, RHS, Ctx); |
566 | } |
567 | |
568 | static const MCBinaryExpr *createLT(const MCExpr *LHS, const MCExpr *RHS, |
569 | MCContext &Ctx) { |
570 | return create(Op: LT, LHS, RHS, Ctx); |
571 | } |
572 | |
573 | static const MCBinaryExpr *createLTE(const MCExpr *LHS, const MCExpr *RHS, |
574 | MCContext &Ctx) { |
575 | return create(Op: LTE, LHS, RHS, Ctx); |
576 | } |
577 | |
578 | static const MCBinaryExpr *createMod(const MCExpr *LHS, const MCExpr *RHS, |
579 | MCContext &Ctx) { |
580 | return create(Op: Mod, LHS, RHS, Ctx); |
581 | } |
582 | |
583 | static const MCBinaryExpr *createMul(const MCExpr *LHS, const MCExpr *RHS, |
584 | MCContext &Ctx) { |
585 | return create(Op: Mul, LHS, RHS, Ctx); |
586 | } |
587 | |
588 | static const MCBinaryExpr *createNE(const MCExpr *LHS, const MCExpr *RHS, |
589 | MCContext &Ctx) { |
590 | return create(Op: NE, LHS, RHS, Ctx); |
591 | } |
592 | |
593 | static const MCBinaryExpr *createOr(const MCExpr *LHS, const MCExpr *RHS, |
594 | MCContext &Ctx) { |
595 | return create(Op: Or, LHS, RHS, Ctx); |
596 | } |
597 | |
598 | static const MCBinaryExpr *createShl(const MCExpr *LHS, const MCExpr *RHS, |
599 | MCContext &Ctx) { |
600 | return create(Op: Shl, LHS, RHS, Ctx); |
601 | } |
602 | |
603 | static const MCBinaryExpr *createAShr(const MCExpr *LHS, const MCExpr *RHS, |
604 | MCContext &Ctx) { |
605 | return create(Op: AShr, LHS, RHS, Ctx); |
606 | } |
607 | |
608 | static const MCBinaryExpr *createLShr(const MCExpr *LHS, const MCExpr *RHS, |
609 | MCContext &Ctx) { |
610 | return create(Op: LShr, LHS, RHS, Ctx); |
611 | } |
612 | |
613 | static const MCBinaryExpr *createSub(const MCExpr *LHS, const MCExpr *RHS, |
614 | MCContext &Ctx) { |
615 | return create(Op: Sub, LHS, RHS, Ctx); |
616 | } |
617 | |
618 | static const MCBinaryExpr *createXor(const MCExpr *LHS, const MCExpr *RHS, |
619 | MCContext &Ctx) { |
620 | return create(Op: Xor, LHS, RHS, Ctx); |
621 | } |
622 | |
623 | /// @} |
624 | /// \name Accessors |
625 | /// @{ |
626 | |
627 | /// Get the kind of this binary expression. |
628 | Opcode getOpcode() const { return (Opcode)getSubclassData(); } |
629 | |
630 | /// Get the left-hand side expression of the binary operator. |
631 | const MCExpr *getLHS() const { return LHS; } |
632 | |
633 | /// Get the right-hand side expression of the binary operator. |
634 | const MCExpr *getRHS() const { return RHS; } |
635 | |
636 | /// @} |
637 | |
638 | static bool classof(const MCExpr *E) { |
639 | return E->getKind() == MCExpr::Binary; |
640 | } |
641 | }; |
642 | |
643 | /// This is an extension point for target-specific MCExpr subclasses to |
644 | /// implement. |
645 | /// |
646 | /// NOTE: All subclasses are required to have trivial destructors because |
647 | /// MCExprs are bump pointer allocated and not destructed. |
648 | class MCTargetExpr : public MCExpr { |
649 | virtual void anchor(); |
650 | |
651 | protected: |
652 | MCTargetExpr() : MCExpr(Target, SMLoc()) {} |
653 | virtual ~MCTargetExpr() = default; |
654 | |
655 | public: |
656 | virtual void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const = 0; |
657 | virtual bool evaluateAsRelocatableImpl(MCValue &Res, |
658 | const MCAsmLayout *Layout, |
659 | const MCFixup *Fixup) const = 0; |
660 | // allow Target Expressions to be checked for equality |
661 | virtual bool isEqualTo(const MCExpr *x) const { return false; } |
662 | // This should be set when assigned expressions are not valid ".set" |
663 | // expressions, e.g. registers, and must be inlined. |
664 | virtual bool inlineAssignedExpr() const { return false; } |
665 | virtual void visitUsedExpr(MCStreamer& Streamer) const = 0; |
666 | virtual MCFragment *findAssociatedFragment() const = 0; |
667 | |
668 | virtual void fixELFSymbolsInTLSFixups(MCAssembler &) const = 0; |
669 | |
670 | static bool classof(const MCExpr *E) { |
671 | return E->getKind() == MCExpr::Target; |
672 | } |
673 | }; |
674 | |
675 | } // end namespace llvm |
676 | |
677 | #endif // LLVM_MC_MCEXPR_H |
678 | |