LLVM API Documentation
00001 //===-- AArch64MCExpr.cpp - AArch64 specific MC expression classes --------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file contains the implementation of the assembly expression modifiers 00011 // accepted by the AArch64 architecture (e.g. ":lo12:", ":gottprel_g1:", ...). 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "AArch64MCExpr.h" 00016 #include "llvm/MC/MCAssembler.h" 00017 #include "llvm/MC/MCContext.h" 00018 #include "llvm/MC/MCELF.h" 00019 #include "llvm/MC/MCSymbol.h" 00020 #include "llvm/MC/MCValue.h" 00021 #include "llvm/Object/ELF.h" 00022 #include "llvm/Support/ErrorHandling.h" 00023 00024 using namespace llvm; 00025 00026 #define DEBUG_TYPE "aarch64symbolrefexpr" 00027 00028 const AArch64MCExpr *AArch64MCExpr::Create(const MCExpr *Expr, VariantKind Kind, 00029 MCContext &Ctx) { 00030 return new (Ctx) AArch64MCExpr(Expr, Kind); 00031 } 00032 00033 StringRef AArch64MCExpr::getVariantKindName() const { 00034 switch (static_cast<uint32_t>(getKind())) { 00035 case VK_CALL: return ""; 00036 case VK_LO12: return ":lo12:"; 00037 case VK_ABS_G3: return ":abs_g3:"; 00038 case VK_ABS_G2: return ":abs_g2:"; 00039 case VK_ABS_G2_S: return ":abs_g2_s:"; 00040 case VK_ABS_G2_NC: return ":abs_g2_nc:"; 00041 case VK_ABS_G1: return ":abs_g1:"; 00042 case VK_ABS_G1_S: return ":abs_g1_s:"; 00043 case VK_ABS_G1_NC: return ":abs_g1_nc:"; 00044 case VK_ABS_G0: return ":abs_g0:"; 00045 case VK_ABS_G0_S: return ":abs_g0_s:"; 00046 case VK_ABS_G0_NC: return ":abs_g0_nc:"; 00047 case VK_DTPREL_G2: return ":dtprel_g2:"; 00048 case VK_DTPREL_G1: return ":dtprel_g1:"; 00049 case VK_DTPREL_G1_NC: return ":dtprel_g1_nc:"; 00050 case VK_DTPREL_G0: return ":dtprel_g0:"; 00051 case VK_DTPREL_G0_NC: return ":dtprel_g0_nc:"; 00052 case VK_DTPREL_HI12: return ":dtprel_hi12:"; 00053 case VK_DTPREL_LO12: return ":dtprel_lo12:"; 00054 case VK_DTPREL_LO12_NC: return ":dtprel_lo12_nc:"; 00055 case VK_TPREL_G2: return ":tprel_g2:"; 00056 case VK_TPREL_G1: return ":tprel_g1:"; 00057 case VK_TPREL_G1_NC: return ":tprel_g1_nc:"; 00058 case VK_TPREL_G0: return ":tprel_g0:"; 00059 case VK_TPREL_G0_NC: return ":tprel_g0_nc:"; 00060 case VK_TPREL_HI12: return ":tprel_hi12:"; 00061 case VK_TPREL_LO12: return ":tprel_lo12:"; 00062 case VK_TPREL_LO12_NC: return ":tprel_lo12_nc:"; 00063 case VK_TLSDESC_LO12: return ":tlsdesc_lo12:"; 00064 case VK_ABS_PAGE: return ""; 00065 case VK_GOT_PAGE: return ":got:"; 00066 case VK_GOT_LO12: return ":got_lo12:"; 00067 case VK_GOTTPREL_PAGE: return ":gottprel:"; 00068 case VK_GOTTPREL_LO12_NC: return ":gottprel_lo12:"; 00069 case VK_GOTTPREL_G1: return ":gottprel_g1:"; 00070 case VK_GOTTPREL_G0_NC: return ":gottprel_g0_nc:"; 00071 case VK_TLSDESC: return ""; 00072 case VK_TLSDESC_PAGE: return ":tlsdesc:"; 00073 default: 00074 llvm_unreachable("Invalid ELF symbol kind"); 00075 } 00076 } 00077 00078 void AArch64MCExpr::PrintImpl(raw_ostream &OS) const { 00079 if (getKind() != VK_NONE) 00080 OS << getVariantKindName(); 00081 OS << *Expr; 00082 } 00083 00084 void AArch64MCExpr::visitUsedExpr(MCStreamer &Streamer) const { 00085 Streamer.visitUsedExpr(*getSubExpr()); 00086 } 00087 00088 const MCSection *AArch64MCExpr::FindAssociatedSection() const { 00089 llvm_unreachable("FIXME: what goes here?"); 00090 } 00091 00092 bool AArch64MCExpr::EvaluateAsRelocatableImpl(MCValue &Res, 00093 const MCAsmLayout *Layout, 00094 const MCFixup *Fixup) const { 00095 if (!getSubExpr()->EvaluateAsRelocatable(Res, Layout, Fixup)) 00096 return false; 00097 00098 Res = 00099 MCValue::get(Res.getSymA(), Res.getSymB(), Res.getConstant(), getKind()); 00100 00101 return true; 00102 } 00103 00104 static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) { 00105 switch (Expr->getKind()) { 00106 case MCExpr::Target: 00107 llvm_unreachable("Can't handle nested target expression"); 00108 break; 00109 case MCExpr::Constant: 00110 break; 00111 00112 case MCExpr::Binary: { 00113 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr); 00114 fixELFSymbolsInTLSFixupsImpl(BE->getLHS(), Asm); 00115 fixELFSymbolsInTLSFixupsImpl(BE->getRHS(), Asm); 00116 break; 00117 } 00118 00119 case MCExpr::SymbolRef: { 00120 // We're known to be under a TLS fixup, so any symbol should be 00121 // modified. There should be only one. 00122 const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr); 00123 MCSymbolData &SD = Asm.getOrCreateSymbolData(SymRef.getSymbol()); 00124 MCELF::SetType(SD, ELF::STT_TLS); 00125 break; 00126 } 00127 00128 case MCExpr::Unary: 00129 fixELFSymbolsInTLSFixupsImpl(cast<MCUnaryExpr>(Expr)->getSubExpr(), Asm); 00130 break; 00131 } 00132 } 00133 00134 void AArch64MCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const { 00135 switch (getSymbolLoc(Kind)) { 00136 default: 00137 return; 00138 case VK_DTPREL: 00139 case VK_GOTTPREL: 00140 case VK_TPREL: 00141 case VK_TLSDESC: 00142 break; 00143 } 00144 00145 fixELFSymbolsInTLSFixupsImpl(getSubExpr(), Asm); 00146 }