| //===-- HexagonMCExpr.cpp - Hexagon specific MC expression classes | |
| //----------===// | |
| // | |
| // The LLVM Compiler Infrastructure | |
| // | |
| // This file is distributed under the University of Illinois Open Source | |
| // License. See LICENSE.TXT for details. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "HexagonMCExpr.h" | |
| #include "llvm/MC/MCContext.h" | |
| #include "llvm/MC/MCStreamer.h" | |
| #include "llvm/MC/MCSymbolELF.h" | |
| #include "llvm/MC/MCValue.h" | |
| #include "llvm/Object/ELF.h" | |
| #include "llvm/Support/raw_ostream.h" | |
| using namespace llvm; | |
| #define DEBUG_TYPE "hexagon-mcexpr" | |
| HexagonMCExpr *HexagonMCExpr::create(MCExpr const *Expr, MCContext &Ctx) { | |
| return new (Ctx) HexagonMCExpr(Expr); | |
| } | |
| bool HexagonMCExpr::evaluateAsRelocatableImpl(MCValue &Res, | |
| MCAsmLayout const *Layout, | |
| MCFixup const *Fixup) const { | |
| return Expr->evaluateAsRelocatable(Res, Layout, Fixup); | |
| } | |
| void HexagonMCExpr::visitUsedExpr(MCStreamer &Streamer) const { | |
| Streamer.visitUsedExpr(*Expr); | |
| } | |
| MCFragment *llvm::HexagonMCExpr::findAssociatedFragment() const { | |
| return Expr->findAssociatedFragment(); | |
| } | |
| static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) { | |
| switch (Expr->getKind()) { | |
| case MCExpr::Target: | |
| llvm_unreachable("Cannot handle nested target MCExpr"); | |
| break; | |
| case MCExpr::Constant: | |
| break; | |
| case MCExpr::Binary: { | |
| const MCBinaryExpr *be = cast<MCBinaryExpr>(Expr); | |
| fixELFSymbolsInTLSFixupsImpl(be->getLHS(), Asm); | |
| fixELFSymbolsInTLSFixupsImpl(be->getRHS(), Asm); | |
| break; | |
| } | |
| case MCExpr::SymbolRef: { | |
| const MCSymbolRefExpr &symRef = *cast<MCSymbolRefExpr>(Expr); | |
| switch (symRef.getKind()) { | |
| default: | |
| return; | |
| case MCSymbolRefExpr::VK_Hexagon_GD_GOT: | |
| case MCSymbolRefExpr::VK_Hexagon_LD_GOT: | |
| case MCSymbolRefExpr::VK_Hexagon_GD_PLT: | |
| case MCSymbolRefExpr::VK_Hexagon_LD_PLT: | |
| case MCSymbolRefExpr::VK_Hexagon_IE: | |
| case MCSymbolRefExpr::VK_Hexagon_IE_GOT: | |
| case MCSymbolRefExpr::VK_TPREL: | |
| break; | |
| } | |
| cast<MCSymbolELF>(symRef.getSymbol()).setType(ELF::STT_TLS); | |
| break; | |
| } | |
| case MCExpr::Unary: | |
| fixELFSymbolsInTLSFixupsImpl(cast<MCUnaryExpr>(Expr)->getSubExpr(), Asm); | |
| break; | |
| } | |
| } | |
| void HexagonMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const { | |
| auto expr = getExpr(); | |
| fixELFSymbolsInTLSFixupsImpl(expr, Asm); | |
| } | |
| MCExpr const *HexagonMCExpr::getExpr() const { return Expr; } | |
| void HexagonMCExpr::setMustExtend(bool Val) { | |
| assert((!Val || !MustNotExtend) && "Extension contradiction"); | |
| MustExtend = Val; | |
| } | |
| bool HexagonMCExpr::mustExtend() const { return MustExtend; } | |
| void HexagonMCExpr::setMustNotExtend(bool Val) { | |
| assert((!Val || !MustExtend) && "Extension contradiction"); | |
| MustNotExtend = Val; | |
| } | |
| bool HexagonMCExpr::mustNotExtend() const { return MustNotExtend; } | |
| bool HexagonMCExpr::s27_2_reloc() const { return S27_2_reloc; } | |
| void HexagonMCExpr::setS27_2_reloc(bool Val) { | |
| S27_2_reloc = Val; | |
| } | |
| bool HexagonMCExpr::classof(MCExpr const *E) { | |
| return E->getKind() == MCExpr::Target; | |
| } | |
| HexagonMCExpr::HexagonMCExpr(MCExpr const *Expr) | |
| : Expr(Expr), MustNotExtend(false), MustExtend(false), S27_2_reloc(false), | |
| SignMismatch(false) {} | |
| void HexagonMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const { | |
| Expr->print(OS, MAI); | |
| } | |
| void HexagonMCExpr::setSignMismatch(bool Val) { | |
| SignMismatch = Val; | |
| } | |
| bool HexagonMCExpr::signMismatch() const { | |
| return SignMismatch; | |
| } |