1 | //===-- RISCVMCExpr.h - RISC-V specific MC expression classes----*- 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 | // This file describes RISC-V specific MCExprs, used for modifiers like |
10 | // "%hi" or "%lo" etc., |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVMCEXPR_H |
15 | #define LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVMCEXPR_H |
16 | |
17 | #include "llvm/MC/MCExpr.h" |
18 | |
19 | namespace llvm { |
20 | |
21 | class StringRef; |
22 | |
23 | class RISCVMCExpr : public MCTargetExpr { |
24 | public: |
25 | enum VariantKind { |
26 | VK_RISCV_None, |
27 | VK_RISCV_LO, |
28 | VK_RISCV_HI, |
29 | VK_RISCV_PCREL_LO, |
30 | VK_RISCV_PCREL_HI, |
31 | VK_RISCV_GOT_HI, |
32 | VK_RISCV_TPREL_LO, |
33 | VK_RISCV_TPREL_HI, |
34 | VK_RISCV_TPREL_ADD, |
35 | VK_RISCV_TLS_GOT_HI, |
36 | VK_RISCV_TLS_GD_HI, |
37 | VK_RISCV_CALL, |
38 | VK_RISCV_CALL_PLT, |
39 | VK_RISCV_32_PCREL, |
40 | VK_RISCV_TLSDESC_HI, |
41 | VK_RISCV_TLSDESC_LOAD_LO, |
42 | VK_RISCV_TLSDESC_ADD_LO, |
43 | VK_RISCV_TLSDESC_CALL, |
44 | VK_RISCV_Invalid // Must be the last item |
45 | }; |
46 | |
47 | private: |
48 | const MCExpr *Expr; |
49 | const VariantKind Kind; |
50 | |
51 | int64_t evaluateAsInt64(int64_t Value) const; |
52 | |
53 | explicit RISCVMCExpr(const MCExpr *Expr, VariantKind Kind) |
54 | : Expr(Expr), Kind(Kind) {} |
55 | |
56 | public: |
57 | static const RISCVMCExpr *create(const MCExpr *Expr, VariantKind Kind, |
58 | MCContext &Ctx); |
59 | |
60 | VariantKind getKind() const { return Kind; } |
61 | |
62 | const MCExpr *getSubExpr() const { return Expr; } |
63 | |
64 | /// Get the corresponding PC-relative HI fixup that a VK_RISCV_PCREL_LO |
65 | /// points to, and optionally the fragment containing it. |
66 | /// |
67 | /// \returns nullptr if this isn't a VK_RISCV_PCREL_LO pointing to a |
68 | /// known PC-relative HI fixup. |
69 | const MCFixup *getPCRelHiFixup(const MCFragment **DFOut) const; |
70 | |
71 | void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override; |
72 | bool evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, |
73 | const MCFixup *Fixup) const override; |
74 | void visitUsedExpr(MCStreamer &Streamer) const override; |
75 | MCFragment *findAssociatedFragment() const override { |
76 | return getSubExpr()->findAssociatedFragment(); |
77 | } |
78 | |
79 | void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const override; |
80 | |
81 | bool evaluateAsConstant(int64_t &Res) const; |
82 | |
83 | static bool classof(const MCExpr *E) { |
84 | return E->getKind() == MCExpr::Target; |
85 | } |
86 | |
87 | static VariantKind getVariantKindForName(StringRef name); |
88 | static StringRef getVariantKindName(VariantKind Kind); |
89 | }; |
90 | |
91 | } // end namespace llvm. |
92 | |
93 | #endif |
94 | |