| Tim Northover | 3b0846e | 2014-05-24 12:50:23 +0000 | [diff] [blame] | 1 | //===-- AArch64MCExpr.cpp - AArch64 specific MC expression classes --------===// | 
|  | 2 | // | 
|  | 3 | //                     The LLVM Compiler Infrastructure | 
|  | 4 | // | 
|  | 5 | // This file is distributed under the University of Illinois Open Source | 
|  | 6 | // License. See LICENSE.TXT for details. | 
|  | 7 | // | 
|  | 8 | //===----------------------------------------------------------------------===// | 
|  | 9 | // | 
|  | 10 | // This file contains the implementation of the assembly expression modifiers | 
|  | 11 | // accepted by the AArch64 architecture (e.g. ":lo12:", ":gottprel_g1:", ...). | 
|  | 12 | // | 
|  | 13 | //===----------------------------------------------------------------------===// | 
|  | 14 |  | 
|  | 15 | #include "AArch64MCExpr.h" | 
| Tim Northover | 3b0846e | 2014-05-24 12:50:23 +0000 | [diff] [blame] | 16 | #include "llvm/MC/MCContext.h" | 
| Pete Cooper | ef21bd4 | 2015-03-04 01:24:11 +0000 | [diff] [blame] | 17 | #include "llvm/MC/MCStreamer.h" | 
| Rafael Espindola | 95fb9b9 | 2015-06-02 20:38:46 +0000 | [diff] [blame] | 18 | #include "llvm/MC/MCSymbolELF.h" | 
| Tim Northover | 3b0846e | 2014-05-24 12:50:23 +0000 | [diff] [blame] | 19 | #include "llvm/MC/MCValue.h" | 
|  | 20 | #include "llvm/Object/ELF.h" | 
|  | 21 | #include "llvm/Support/ErrorHandling.h" | 
|  | 22 |  | 
|  | 23 | using namespace llvm; | 
|  | 24 |  | 
|  | 25 | #define DEBUG_TYPE "aarch64symbolrefexpr" | 
|  | 26 |  | 
| Jim Grosbach | 13760bd | 2015-05-30 01:25:56 +0000 | [diff] [blame] | 27 | const AArch64MCExpr *AArch64MCExpr::create(const MCExpr *Expr, VariantKind Kind, | 
| Tim Northover | 3b0846e | 2014-05-24 12:50:23 +0000 | [diff] [blame] | 28 | MCContext &Ctx) { | 
|  | 29 | return new (Ctx) AArch64MCExpr(Expr, Kind); | 
|  | 30 | } | 
|  | 31 |  | 
|  | 32 | StringRef AArch64MCExpr::getVariantKindName() const { | 
|  | 33 | switch (static_cast<uint32_t>(getKind())) { | 
|  | 34 | case VK_CALL:                return ""; | 
|  | 35 | case VK_LO12:                return ":lo12:"; | 
|  | 36 | case VK_ABS_G3:              return ":abs_g3:"; | 
|  | 37 | case VK_ABS_G2:              return ":abs_g2:"; | 
|  | 38 | case VK_ABS_G2_S:            return ":abs_g2_s:"; | 
|  | 39 | case VK_ABS_G2_NC:           return ":abs_g2_nc:"; | 
|  | 40 | case VK_ABS_G1:              return ":abs_g1:"; | 
|  | 41 | case VK_ABS_G1_S:            return ":abs_g1_s:"; | 
|  | 42 | case VK_ABS_G1_NC:           return ":abs_g1_nc:"; | 
|  | 43 | case VK_ABS_G0:              return ":abs_g0:"; | 
|  | 44 | case VK_ABS_G0_S:            return ":abs_g0_s:"; | 
|  | 45 | case VK_ABS_G0_NC:           return ":abs_g0_nc:"; | 
|  | 46 | case VK_DTPREL_G2:           return ":dtprel_g2:"; | 
|  | 47 | case VK_DTPREL_G1:           return ":dtprel_g1:"; | 
|  | 48 | case VK_DTPREL_G1_NC:        return ":dtprel_g1_nc:"; | 
|  | 49 | case VK_DTPREL_G0:           return ":dtprel_g0:"; | 
|  | 50 | case VK_DTPREL_G0_NC:        return ":dtprel_g0_nc:"; | 
|  | 51 | case VK_DTPREL_HI12:         return ":dtprel_hi12:"; | 
|  | 52 | case VK_DTPREL_LO12:         return ":dtprel_lo12:"; | 
|  | 53 | case VK_DTPREL_LO12_NC:      return ":dtprel_lo12_nc:"; | 
|  | 54 | case VK_TPREL_G2:            return ":tprel_g2:"; | 
|  | 55 | case VK_TPREL_G1:            return ":tprel_g1:"; | 
|  | 56 | case VK_TPREL_G1_NC:         return ":tprel_g1_nc:"; | 
|  | 57 | case VK_TPREL_G0:            return ":tprel_g0:"; | 
|  | 58 | case VK_TPREL_G0_NC:         return ":tprel_g0_nc:"; | 
|  | 59 | case VK_TPREL_HI12:          return ":tprel_hi12:"; | 
|  | 60 | case VK_TPREL_LO12:          return ":tprel_lo12:"; | 
|  | 61 | case VK_TPREL_LO12_NC:       return ":tprel_lo12_nc:"; | 
|  | 62 | case VK_TLSDESC_LO12:        return ":tlsdesc_lo12:"; | 
|  | 63 | case VK_ABS_PAGE:            return ""; | 
| Joel Jones | 6513405 | 2017-05-02 22:01:48 +0000 | [diff] [blame] | 64 | case VK_ABS_PAGE_NC:         return ":pg_hi21_nc:"; | 
| Tim Northover | 3b0846e | 2014-05-24 12:50:23 +0000 | [diff] [blame] | 65 | case VK_GOT_PAGE:            return ":got:"; | 
|  | 66 | case VK_GOT_LO12:            return ":got_lo12:"; | 
|  | 67 | case VK_GOTTPREL_PAGE:       return ":gottprel:"; | 
|  | 68 | case VK_GOTTPREL_LO12_NC:    return ":gottprel_lo12:"; | 
|  | 69 | case VK_GOTTPREL_G1:         return ":gottprel_g1:"; | 
|  | 70 | case VK_GOTTPREL_G0_NC:      return ":gottprel_g0_nc:"; | 
|  | 71 | case VK_TLSDESC:             return ""; | 
|  | 72 | case VK_TLSDESC_PAGE:        return ":tlsdesc:"; | 
| Martin Storsjo | c61ff3b | 2018-03-01 20:42:28 +0000 | [diff] [blame] | 73 | case VK_SECREL_LO12:         return ":secrel_lo12:"; | 
|  | 74 | case VK_SECREL_HI12:         return ":secrel_hi12:"; | 
| Tim Northover | 3b0846e | 2014-05-24 12:50:23 +0000 | [diff] [blame] | 75 | default: | 
|  | 76 | llvm_unreachable("Invalid ELF symbol kind"); | 
|  | 77 | } | 
|  | 78 | } | 
|  | 79 |  | 
| Matt Arsenault | 8b64355 | 2015-06-09 00:31:39 +0000 | [diff] [blame] | 80 | void AArch64MCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const { | 
| Tim Northover | 3b0846e | 2014-05-24 12:50:23 +0000 | [diff] [blame] | 81 | if (getKind() != VK_NONE) | 
|  | 82 | OS << getVariantKindName(); | 
| Matt Arsenault | 8b64355 | 2015-06-09 00:31:39 +0000 | [diff] [blame] | 83 | Expr->print(OS, MAI); | 
| Tim Northover | 3b0846e | 2014-05-24 12:50:23 +0000 | [diff] [blame] | 84 | } | 
|  | 85 |  | 
| Rafael Espindola | e2c6624 | 2014-06-25 15:45:33 +0000 | [diff] [blame] | 86 | void AArch64MCExpr::visitUsedExpr(MCStreamer &Streamer) const { | 
| Rafael Espindola | 2be1281 | 2014-06-25 15:29:54 +0000 | [diff] [blame] | 87 | Streamer.visitUsedExpr(*getSubExpr()); | 
| Tim Northover | 3b0846e | 2014-05-24 12:50:23 +0000 | [diff] [blame] | 88 | } | 
|  | 89 |  | 
| Rafael Espindola | e3a20f5 | 2015-10-05 12:07:05 +0000 | [diff] [blame] | 90 | MCFragment *AArch64MCExpr::findAssociatedFragment() const { | 
| Tim Northover | 3b0846e | 2014-05-24 12:50:23 +0000 | [diff] [blame] | 91 | llvm_unreachable("FIXME: what goes here?"); | 
|  | 92 | } | 
|  | 93 |  | 
| Jim Grosbach | 13760bd | 2015-05-30 01:25:56 +0000 | [diff] [blame] | 94 | bool AArch64MCExpr::evaluateAsRelocatableImpl(MCValue &Res, | 
| NAKAMURA Takumi | 0a7d0ad | 2015-09-22 11:15:07 +0000 | [diff] [blame] | 95 | const MCAsmLayout *Layout, | 
|  | 96 | const MCFixup *Fixup) const { | 
| Jim Grosbach | 13760bd | 2015-05-30 01:25:56 +0000 | [diff] [blame] | 97 | if (!getSubExpr()->evaluateAsRelocatable(Res, Layout, Fixup)) | 
| Tim Northover | 3b0846e | 2014-05-24 12:50:23 +0000 | [diff] [blame] | 98 | return false; | 
|  | 99 |  | 
|  | 100 | Res = | 
|  | 101 | MCValue::get(Res.getSymA(), Res.getSymB(), Res.getConstant(), getKind()); | 
|  | 102 |  | 
|  | 103 | return true; | 
|  | 104 | } | 
|  | 105 |  | 
|  | 106 | static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) { | 
|  | 107 | switch (Expr->getKind()) { | 
|  | 108 | case MCExpr::Target: | 
|  | 109 | llvm_unreachable("Can't handle nested target expression"); | 
|  | 110 | break; | 
|  | 111 | case MCExpr::Constant: | 
|  | 112 | break; | 
|  | 113 |  | 
|  | 114 | case MCExpr::Binary: { | 
|  | 115 | const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr); | 
|  | 116 | fixELFSymbolsInTLSFixupsImpl(BE->getLHS(), Asm); | 
|  | 117 | fixELFSymbolsInTLSFixupsImpl(BE->getRHS(), Asm); | 
|  | 118 | break; | 
|  | 119 | } | 
|  | 120 |  | 
|  | 121 | case MCExpr::SymbolRef: { | 
|  | 122 | // We're known to be under a TLS fixup, so any symbol should be | 
|  | 123 | // modified. There should be only one. | 
|  | 124 | const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr); | 
| Rafael Espindola | 95fb9b9 | 2015-06-02 20:38:46 +0000 | [diff] [blame] | 125 | cast<MCSymbolELF>(SymRef.getSymbol()).setType(ELF::STT_TLS); | 
| Tim Northover | 3b0846e | 2014-05-24 12:50:23 +0000 | [diff] [blame] | 126 | break; | 
|  | 127 | } | 
|  | 128 |  | 
|  | 129 | case MCExpr::Unary: | 
|  | 130 | fixELFSymbolsInTLSFixupsImpl(cast<MCUnaryExpr>(Expr)->getSubExpr(), Asm); | 
|  | 131 | break; | 
|  | 132 | } | 
|  | 133 | } | 
|  | 134 |  | 
|  | 135 | void AArch64MCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const { | 
|  | 136 | switch (getSymbolLoc(Kind)) { | 
|  | 137 | default: | 
|  | 138 | return; | 
|  | 139 | case VK_DTPREL: | 
|  | 140 | case VK_GOTTPREL: | 
|  | 141 | case VK_TPREL: | 
|  | 142 | case VK_TLSDESC: | 
|  | 143 | break; | 
|  | 144 | } | 
|  | 145 |  | 
|  | 146 | fixELFSymbolsInTLSFixupsImpl(getSubExpr(), Asm); | 
|  | 147 | } |