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