1*9880d681SAndroid Build Coastguard Worker //=--- AArch64MCExpr.h - AArch64 specific MC expression classes ---*- C++ -*-=// 2*9880d681SAndroid Build Coastguard Worker // 3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker // 5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker // 8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker // 10*9880d681SAndroid Build Coastguard Worker // This file describes AArch64-specific MCExprs, used for modifiers like 11*9880d681SAndroid Build Coastguard Worker // ":lo12:" or ":gottprel_g1:". 12*9880d681SAndroid Build Coastguard Worker // 13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 14*9880d681SAndroid Build Coastguard Worker 15*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_LIB_TARGET_AARCH64_MCTARGETDESC_AARCH64MCEXPR_H 16*9880d681SAndroid Build Coastguard Worker #define LLVM_LIB_TARGET_AARCH64_MCTARGETDESC_AARCH64MCEXPR_H 17*9880d681SAndroid Build Coastguard Worker 18*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCExpr.h" 19*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h" 20*9880d681SAndroid Build Coastguard Worker 21*9880d681SAndroid Build Coastguard Worker namespace llvm { 22*9880d681SAndroid Build Coastguard Worker 23*9880d681SAndroid Build Coastguard Worker class AArch64MCExpr : public MCTargetExpr { 24*9880d681SAndroid Build Coastguard Worker public: 25*9880d681SAndroid Build Coastguard Worker enum VariantKind { 26*9880d681SAndroid Build Coastguard Worker VK_NONE = 0x000, 27*9880d681SAndroid Build Coastguard Worker 28*9880d681SAndroid Build Coastguard Worker // Symbol locations specifying (roughly speaking) what calculation should be 29*9880d681SAndroid Build Coastguard Worker // performed to construct the final address for the relocated 30*9880d681SAndroid Build Coastguard Worker // symbol. E.g. direct, via the GOT, ... 31*9880d681SAndroid Build Coastguard Worker VK_ABS = 0x001, 32*9880d681SAndroid Build Coastguard Worker VK_SABS = 0x002, 33*9880d681SAndroid Build Coastguard Worker VK_GOT = 0x003, 34*9880d681SAndroid Build Coastguard Worker VK_DTPREL = 0x004, 35*9880d681SAndroid Build Coastguard Worker VK_GOTTPREL = 0x005, 36*9880d681SAndroid Build Coastguard Worker VK_TPREL = 0x006, 37*9880d681SAndroid Build Coastguard Worker VK_TLSDESC = 0x007, 38*9880d681SAndroid Build Coastguard Worker VK_SymLocBits = 0x00f, 39*9880d681SAndroid Build Coastguard Worker 40*9880d681SAndroid Build Coastguard Worker // Variants specifying which part of the final address calculation is 41*9880d681SAndroid Build Coastguard Worker // used. E.g. the low 12 bits for an ADD/LDR, the middle 16 bits for a 42*9880d681SAndroid Build Coastguard Worker // MOVZ/MOVK. 43*9880d681SAndroid Build Coastguard Worker VK_PAGE = 0x010, 44*9880d681SAndroid Build Coastguard Worker VK_PAGEOFF = 0x020, 45*9880d681SAndroid Build Coastguard Worker VK_HI12 = 0x030, 46*9880d681SAndroid Build Coastguard Worker VK_G0 = 0x040, 47*9880d681SAndroid Build Coastguard Worker VK_G1 = 0x050, 48*9880d681SAndroid Build Coastguard Worker VK_G2 = 0x060, 49*9880d681SAndroid Build Coastguard Worker VK_G3 = 0x070, 50*9880d681SAndroid Build Coastguard Worker VK_AddressFragBits = 0x0f0, 51*9880d681SAndroid Build Coastguard Worker 52*9880d681SAndroid Build Coastguard Worker // Whether the final relocation is a checked one (where a linker should 53*9880d681SAndroid Build Coastguard Worker // perform a range-check on the final address) or not. Note that this field 54*9880d681SAndroid Build Coastguard Worker // is unfortunately sometimes omitted from the assembly syntax. E.g. :lo12: 55*9880d681SAndroid Build Coastguard Worker // on its own is a non-checked relocation. We side with ELF on being 56*9880d681SAndroid Build Coastguard Worker // explicit about this! 57*9880d681SAndroid Build Coastguard Worker VK_NC = 0x100, 58*9880d681SAndroid Build Coastguard Worker 59*9880d681SAndroid Build Coastguard Worker // Convenience definitions for referring to specific textual representations 60*9880d681SAndroid Build Coastguard Worker // of relocation specifiers. Note that this means the "_NC" is sometimes 61*9880d681SAndroid Build Coastguard Worker // omitted in line with assembly syntax here (VK_LO12 rather than VK_LO12_NC 62*9880d681SAndroid Build Coastguard Worker // since a user would write ":lo12:"). 63*9880d681SAndroid Build Coastguard Worker VK_CALL = VK_ABS, 64*9880d681SAndroid Build Coastguard Worker VK_ABS_PAGE = VK_ABS | VK_PAGE, 65*9880d681SAndroid Build Coastguard Worker VK_ABS_G3 = VK_ABS | VK_G3, 66*9880d681SAndroid Build Coastguard Worker VK_ABS_G2 = VK_ABS | VK_G2, 67*9880d681SAndroid Build Coastguard Worker VK_ABS_G2_S = VK_SABS | VK_G2, 68*9880d681SAndroid Build Coastguard Worker VK_ABS_G2_NC = VK_ABS | VK_G2 | VK_NC, 69*9880d681SAndroid Build Coastguard Worker VK_ABS_G1 = VK_ABS | VK_G1, 70*9880d681SAndroid Build Coastguard Worker VK_ABS_G1_S = VK_SABS | VK_G1, 71*9880d681SAndroid Build Coastguard Worker VK_ABS_G1_NC = VK_ABS | VK_G1 | VK_NC, 72*9880d681SAndroid Build Coastguard Worker VK_ABS_G0 = VK_ABS | VK_G0, 73*9880d681SAndroid Build Coastguard Worker VK_ABS_G0_S = VK_SABS | VK_G0, 74*9880d681SAndroid Build Coastguard Worker VK_ABS_G0_NC = VK_ABS | VK_G0 | VK_NC, 75*9880d681SAndroid Build Coastguard Worker VK_LO12 = VK_ABS | VK_PAGEOFF | VK_NC, 76*9880d681SAndroid Build Coastguard Worker VK_GOT_LO12 = VK_GOT | VK_PAGEOFF | VK_NC, 77*9880d681SAndroid Build Coastguard Worker VK_GOT_PAGE = VK_GOT | VK_PAGE, 78*9880d681SAndroid Build Coastguard Worker VK_DTPREL_G2 = VK_DTPREL | VK_G2, 79*9880d681SAndroid Build Coastguard Worker VK_DTPREL_G1 = VK_DTPREL | VK_G1, 80*9880d681SAndroid Build Coastguard Worker VK_DTPREL_G1_NC = VK_DTPREL | VK_G1 | VK_NC, 81*9880d681SAndroid Build Coastguard Worker VK_DTPREL_G0 = VK_DTPREL | VK_G0, 82*9880d681SAndroid Build Coastguard Worker VK_DTPREL_G0_NC = VK_DTPREL | VK_G0 | VK_NC, 83*9880d681SAndroid Build Coastguard Worker VK_DTPREL_HI12 = VK_DTPREL | VK_HI12, 84*9880d681SAndroid Build Coastguard Worker VK_DTPREL_LO12 = VK_DTPREL | VK_PAGEOFF, 85*9880d681SAndroid Build Coastguard Worker VK_DTPREL_LO12_NC = VK_DTPREL | VK_PAGEOFF | VK_NC, 86*9880d681SAndroid Build Coastguard Worker VK_GOTTPREL_PAGE = VK_GOTTPREL | VK_PAGE, 87*9880d681SAndroid Build Coastguard Worker VK_GOTTPREL_LO12_NC = VK_GOTTPREL | VK_PAGEOFF | VK_NC, 88*9880d681SAndroid Build Coastguard Worker VK_GOTTPREL_G1 = VK_GOTTPREL | VK_G1, 89*9880d681SAndroid Build Coastguard Worker VK_GOTTPREL_G0_NC = VK_GOTTPREL | VK_G0 | VK_NC, 90*9880d681SAndroid Build Coastguard Worker VK_TPREL_G2 = VK_TPREL | VK_G2, 91*9880d681SAndroid Build Coastguard Worker VK_TPREL_G1 = VK_TPREL | VK_G1, 92*9880d681SAndroid Build Coastguard Worker VK_TPREL_G1_NC = VK_TPREL | VK_G1 | VK_NC, 93*9880d681SAndroid Build Coastguard Worker VK_TPREL_G0 = VK_TPREL | VK_G0, 94*9880d681SAndroid Build Coastguard Worker VK_TPREL_G0_NC = VK_TPREL | VK_G0 | VK_NC, 95*9880d681SAndroid Build Coastguard Worker VK_TPREL_HI12 = VK_TPREL | VK_HI12, 96*9880d681SAndroid Build Coastguard Worker VK_TPREL_LO12 = VK_TPREL | VK_PAGEOFF, 97*9880d681SAndroid Build Coastguard Worker VK_TPREL_LO12_NC = VK_TPREL | VK_PAGEOFF | VK_NC, 98*9880d681SAndroid Build Coastguard Worker VK_TLSDESC_LO12 = VK_TLSDESC | VK_PAGEOFF | VK_NC, 99*9880d681SAndroid Build Coastguard Worker VK_TLSDESC_PAGE = VK_TLSDESC | VK_PAGE, 100*9880d681SAndroid Build Coastguard Worker 101*9880d681SAndroid Build Coastguard Worker VK_INVALID = 0xfff 102*9880d681SAndroid Build Coastguard Worker }; 103*9880d681SAndroid Build Coastguard Worker 104*9880d681SAndroid Build Coastguard Worker private: 105*9880d681SAndroid Build Coastguard Worker const MCExpr *Expr; 106*9880d681SAndroid Build Coastguard Worker const VariantKind Kind; 107*9880d681SAndroid Build Coastguard Worker AArch64MCExpr(const MCExpr * Expr,VariantKind Kind)108*9880d681SAndroid Build Coastguard Worker explicit AArch64MCExpr(const MCExpr *Expr, VariantKind Kind) 109*9880d681SAndroid Build Coastguard Worker : Expr(Expr), Kind(Kind) {} 110*9880d681SAndroid Build Coastguard Worker 111*9880d681SAndroid Build Coastguard Worker public: 112*9880d681SAndroid Build Coastguard Worker /// @name Construction 113*9880d681SAndroid Build Coastguard Worker /// @{ 114*9880d681SAndroid Build Coastguard Worker 115*9880d681SAndroid Build Coastguard Worker static const AArch64MCExpr *create(const MCExpr *Expr, VariantKind Kind, 116*9880d681SAndroid Build Coastguard Worker MCContext &Ctx); 117*9880d681SAndroid Build Coastguard Worker 118*9880d681SAndroid Build Coastguard Worker /// @} 119*9880d681SAndroid Build Coastguard Worker /// @name Accessors 120*9880d681SAndroid Build Coastguard Worker /// @{ 121*9880d681SAndroid Build Coastguard Worker 122*9880d681SAndroid Build Coastguard Worker /// Get the kind of this expression. getKind()123*9880d681SAndroid Build Coastguard Worker VariantKind getKind() const { return Kind; } 124*9880d681SAndroid Build Coastguard Worker 125*9880d681SAndroid Build Coastguard Worker /// Get the expression this modifier applies to. getSubExpr()126*9880d681SAndroid Build Coastguard Worker const MCExpr *getSubExpr() const { return Expr; } 127*9880d681SAndroid Build Coastguard Worker 128*9880d681SAndroid Build Coastguard Worker /// @} 129*9880d681SAndroid Build Coastguard Worker /// @name VariantKind information extractors. 130*9880d681SAndroid Build Coastguard Worker /// @{ 131*9880d681SAndroid Build Coastguard Worker getSymbolLoc(VariantKind Kind)132*9880d681SAndroid Build Coastguard Worker static VariantKind getSymbolLoc(VariantKind Kind) { 133*9880d681SAndroid Build Coastguard Worker return static_cast<VariantKind>(Kind & VK_SymLocBits); 134*9880d681SAndroid Build Coastguard Worker } 135*9880d681SAndroid Build Coastguard Worker getAddressFrag(VariantKind Kind)136*9880d681SAndroid Build Coastguard Worker static VariantKind getAddressFrag(VariantKind Kind) { 137*9880d681SAndroid Build Coastguard Worker return static_cast<VariantKind>(Kind & VK_AddressFragBits); 138*9880d681SAndroid Build Coastguard Worker } 139*9880d681SAndroid Build Coastguard Worker isNotChecked(VariantKind Kind)140*9880d681SAndroid Build Coastguard Worker static bool isNotChecked(VariantKind Kind) { return Kind & VK_NC; } 141*9880d681SAndroid Build Coastguard Worker 142*9880d681SAndroid Build Coastguard Worker /// @} 143*9880d681SAndroid Build Coastguard Worker 144*9880d681SAndroid Build Coastguard Worker /// Convert the variant kind into an ELF-appropriate modifier 145*9880d681SAndroid Build Coastguard Worker /// (e.g. ":got:", ":lo12:"). 146*9880d681SAndroid Build Coastguard Worker StringRef getVariantKindName() const; 147*9880d681SAndroid Build Coastguard Worker 148*9880d681SAndroid Build Coastguard Worker void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override; 149*9880d681SAndroid Build Coastguard Worker 150*9880d681SAndroid Build Coastguard Worker void visitUsedExpr(MCStreamer &Streamer) const override; 151*9880d681SAndroid Build Coastguard Worker 152*9880d681SAndroid Build Coastguard Worker MCFragment *findAssociatedFragment() const override; 153*9880d681SAndroid Build Coastguard Worker 154*9880d681SAndroid Build Coastguard Worker bool evaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout, 155*9880d681SAndroid Build Coastguard Worker const MCFixup *Fixup) const override; 156*9880d681SAndroid Build Coastguard Worker 157*9880d681SAndroid Build Coastguard Worker void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const override; 158*9880d681SAndroid Build Coastguard Worker classof(const MCExpr * E)159*9880d681SAndroid Build Coastguard Worker static bool classof(const MCExpr *E) { 160*9880d681SAndroid Build Coastguard Worker return E->getKind() == MCExpr::Target; 161*9880d681SAndroid Build Coastguard Worker } 162*9880d681SAndroid Build Coastguard Worker classof(const AArch64MCExpr *)163*9880d681SAndroid Build Coastguard Worker static bool classof(const AArch64MCExpr *) { return true; } 164*9880d681SAndroid Build Coastguard Worker }; 165*9880d681SAndroid Build Coastguard Worker } // end namespace llvm 166*9880d681SAndroid Build Coastguard Worker 167*9880d681SAndroid Build Coastguard Worker #endif 168