blob: 22882802966170a30be7a545b02f3dad804a1702 [file] [log] [blame]
//===-- PPCMCExpr.h - PPC specific MC expression classes --------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_TARGET_POWERPC_MCTARGETDESC_PPCMCEXPR_H
#define LLVM_LIB_TARGET_POWERPC_MCTARGETDESC_PPCMCEXPR_H
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCValue.h"
#include <optional>
namespace llvm {
class PPCMCExpr : public MCTargetExpr {
public:
enum Specifier {
VK_None,
// We currently use both MCSymbolRefExpr::VariantKind and
// PPCMCExpr::Specifier. Start at a larger number to avoid conflicts.
VK_LO = 200,
VK_HI,
VK_HA,
VK_HIGH,
VK_HIGHA,
VK_HIGHER,
VK_HIGHERA,
VK_HIGHEST,
VK_HIGHESTA,
VK_AIX_TLSGD, // symbol@gd
VK_AIX_TLSGDM, // symbol@m
VK_AIX_TLSIE, // symbol@ie
VK_AIX_TLSLD, // symbol@ld
VK_AIX_TLSLE, // symbol@le
VK_AIX_TLSML, // symbol@ml
VK_DTPMOD, // symbol@dtpmod
VK_DTPREL, // symbol@dprel
VK_DTPREL_HA, // symbol@dtprel@ha
VK_DTPREL_HI, // symbol@dtprel@h
VK_DTPREL_HIGH, // symbol@dtprel@high
VK_DTPREL_HIGHA, // symbol@dtprel@higha
VK_DTPREL_HIGHER, // symbol@dtprel@higher
VK_DTPREL_HIGHERA, // symbol@dtprel@highera
VK_DTPREL_HIGHEST, // symbol@dtprel@highest
VK_DTPREL_HIGHESTA, // symbol@dtprel@highesta
VK_DTPREL_LO, // symbol@dtprel@l
VK_GOT, // symbol@got
VK_GOT_DTPREL, // symbol@got@dtprel
VK_GOT_DTPREL_HA, // symbol@got@dtprel@ha
VK_GOT_DTPREL_HI, // symbol@got@dtprel@h
VK_GOT_DTPREL_LO, // symbol@got@dtprel@l
VK_GOT_HA, // symbol@got@ha
VK_GOT_HI, // symbol@got@h
VK_GOT_LO, // symbol@got@l
VK_GOT_PCREL, // symbol@got@pcrel
VK_GOT_TLSGD, // symbol@got@tlsgd
VK_GOT_TLSGD_HA, // symbol@got@tlsgd@ha
VK_GOT_TLSGD_HI, // symbol@got@tlsgd@h
VK_GOT_TLSGD_LO, // symbol@got@tlsgd@l
VK_GOT_TLSGD_PCREL, // symbol@got@tlsgd@pcrel
VK_GOT_TLSLD, // symbol@got@tlsld
VK_GOT_TLSLD_HA, // symbol@got@tlsld@ha
VK_GOT_TLSLD_HI, // symbol@got@tlsld@h
VK_GOT_TLSLD_LO, // symbol@got@tlsld@l
VK_GOT_TLSLD_PCREL, // symbol@got@tlsld@pcrel
VK_GOT_TPREL, // symbol@got@tprel
VK_GOT_TPREL_HA, // symbol@got@tprel@ha
VK_GOT_TPREL_HI, // symbol@got@tprel@h
VK_GOT_TPREL_LO, // symbol@got@tprel@l
VK_GOT_TPREL_PCREL, // symbol@got@tprel@pcrel
VK_L, // symbol@l
VK_LOCAL, // symbol@local
VK_NOTOC, // symbol@notoc
VK_PCREL,
VK_PCREL_OPT, // .reloc expr, R_PPC64_PCREL_OPT, expr
VK_PLT, // symbol@plt
VK_TLS, // symbol@tls
VK_TLSGD, // symbol@tlsgd
VK_TLSLD, // symbol@tlsld
VK_TLS_PCREL, // symbol@tls@pcrel
VK_TOC, // symbol@toc
VK_TOCBASE, // symbol@tocbase
VK_TOC_HA, // symbol@toc@ha
VK_TOC_HI, // symbol@toc@h
VK_TOC_LO, // symbol@toc@l
VK_TPREL, // symbol@tprel
VK_TPREL_HA, // symbol@tprel@ha
VK_TPREL_HI, // symbol@tprel@h
VK_TPREL_HIGH, // symbol@tprel@high
VK_TPREL_HIGHA, // symbol@tprel@higha
VK_TPREL_HIGHER, // symbol@tprel@higher
VK_TPREL_HIGHERA, // symbol@tprel@highera
VK_TPREL_HIGHEST, // symbol@tprel@highest
VK_TPREL_HIGHESTA, // symbol@tprel@highesta
VK_TPREL_LO, // symbol@tprel@l
VK_U, // symbol@u
};
private:
const Specifier specifier;
const MCExpr *Expr;
std::optional<int64_t> evaluateAsInt64(int64_t Value) const;
explicit PPCMCExpr(Specifier S, const MCExpr *Expr)
: specifier(S), Expr(Expr) {}
public:
/// @name Construction
/// @{
static const PPCMCExpr *create(Specifier S, const MCExpr *Expr,
MCContext &Ctx);
static const PPCMCExpr *createLo(const MCExpr *Expr, MCContext &Ctx) {
return create(VK_LO, Expr, Ctx);
}
static const PPCMCExpr *createHi(const MCExpr *Expr, MCContext &Ctx) {
return create(VK_HI, Expr, Ctx);
}
static const PPCMCExpr *createHa(const MCExpr *Expr, MCContext &Ctx) {
return create(VK_HA, Expr, Ctx);
}
/// @}
/// @name Accessors
/// @{
Specifier getKind() const { return specifier; }
/// getSubExpr - Get the child of this expression.
const MCExpr *getSubExpr() const { return Expr; }
/// @}
void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override;
bool evaluateAsRelocatableImpl(MCValue &Res,
const MCAssembler *Asm) const override;
void visitUsedExpr(MCStreamer &Streamer) const override;
MCFragment *findAssociatedFragment() const override {
return getSubExpr()->findAssociatedFragment();
}
bool evaluateAsConstant(int64_t &Res) const;
static bool classof(const MCExpr *E) {
return E->getKind() == MCExpr::Target;
}
};
static inline PPCMCExpr::Specifier getSpecifier(const MCSymbolRefExpr *SRE) {
return PPCMCExpr::Specifier(SRE->getKind());
}
} // end namespace llvm
#endif