1//===-- RISCVMCExpr.h - RISCV 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 RISCV-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
19namespace llvm {
20
21class StringRef;
22
23class RISCVMCExpr : public MCTargetExpr {
24public:
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_Invalid
41  };
42
43private:
44  const MCExpr *Expr;
45  const VariantKind Kind;
46
47  int64_t evaluateAsInt64(int64_t Value) const;
48
49  explicit RISCVMCExpr(const MCExpr *Expr, VariantKind Kind)
50      : Expr(Expr), Kind(Kind) {}
51
52public:
53  static const RISCVMCExpr *create(const MCExpr *Expr, VariantKind Kind,
54                                   MCContext &Ctx);
55
56  VariantKind getKind() const { return Kind; }
57
58  const MCExpr *getSubExpr() const { return Expr; }
59
60  /// Get the corresponding PC-relative HI fixup that a VK_RISCV_PCREL_LO
61  /// points to, and optionally the fragment containing it.
62  ///
63  /// \returns nullptr if this isn't a VK_RISCV_PCREL_LO pointing to a
64  /// known PC-relative HI fixup.
65  const MCFixup *getPCRelHiFixup(const MCFragment **DFOut) const;
66
67  void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override;
68  bool evaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout,
69                                 const MCFixup *Fixup) const override;
70  void visitUsedExpr(MCStreamer &Streamer) const override;
71  MCFragment *findAssociatedFragment() const override {
72    return getSubExpr()->findAssociatedFragment();
73  }
74
75  void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const override;
76
77  bool evaluateAsConstant(int64_t &Res) const;
78
79  static bool classof(const MCExpr *E) {
80    return E->getKind() == MCExpr::Target;
81  }
82
83  static bool classof(const RISCVMCExpr *) { return true; }
84
85  static VariantKind getVariantKindForName(StringRef name);
86  static StringRef getVariantKindName(VariantKind Kind);
87};
88
89} // end namespace llvm.
90
91#endif
92