106c3fb27SDimitry Andric //===-- RISCVMCExpr.cpp - RISC-V specific MC expression classes -----------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file contains the implementation of the assembly expression modifiers 1006c3fb27SDimitry Andric // accepted by the RISC-V architecture (e.g. ":lo12:", ":gottprel_g1:", ...). 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #include "RISCVMCExpr.h" 150b57cec5SDimitry Andric #include "MCTargetDesc/RISCVAsmBackend.h" 160b57cec5SDimitry Andric #include "RISCVFixupKinds.h" 170b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELF.h" 180b57cec5SDimitry Andric #include "llvm/MC/MCAssembler.h" 190b57cec5SDimitry Andric #include "llvm/MC/MCContext.h" 200b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h" 210b57cec5SDimitry Andric #include "llvm/MC/MCSymbolELF.h" 220b57cec5SDimitry Andric #include "llvm/MC/MCValue.h" 2381ad6265SDimitry Andric #include "llvm/Support/Casting.h" 240b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric using namespace llvm; 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric #define DEBUG_TYPE "riscvmcexpr" 290b57cec5SDimitry Andric 300b57cec5SDimitry Andric const RISCVMCExpr *RISCVMCExpr::create(const MCExpr *Expr, VariantKind Kind, 310b57cec5SDimitry Andric MCContext &Ctx) { 320b57cec5SDimitry Andric return new (Ctx) RISCVMCExpr(Expr, Kind); 330b57cec5SDimitry Andric } 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric void RISCVMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const { 360b57cec5SDimitry Andric VariantKind Kind = getKind(); 370b57cec5SDimitry Andric bool HasVariant = ((Kind != VK_RISCV_None) && (Kind != VK_RISCV_CALL) && 380b57cec5SDimitry Andric (Kind != VK_RISCV_CALL_PLT)); 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric if (HasVariant) 410b57cec5SDimitry Andric OS << '%' << getVariantKindName(getKind()) << '('; 420b57cec5SDimitry Andric Expr->print(OS, MAI); 430b57cec5SDimitry Andric if (HasVariant) 440b57cec5SDimitry Andric OS << ')'; 450b57cec5SDimitry Andric } 460b57cec5SDimitry Andric 4755e4f9d5SDimitry Andric const MCFixup *RISCVMCExpr::getPCRelHiFixup(const MCFragment **DFOut) const { 480b57cec5SDimitry Andric MCValue AUIPCLoc; 490b57cec5SDimitry Andric if (!getSubExpr()->evaluateAsRelocatable(AUIPCLoc, nullptr, nullptr)) 500b57cec5SDimitry Andric return nullptr; 510b57cec5SDimitry Andric 520b57cec5SDimitry Andric const MCSymbolRefExpr *AUIPCSRE = AUIPCLoc.getSymA(); 530b57cec5SDimitry Andric if (!AUIPCSRE) 540b57cec5SDimitry Andric return nullptr; 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric const MCSymbol *AUIPCSymbol = &AUIPCSRE->getSymbol(); 570b57cec5SDimitry Andric const auto *DF = dyn_cast_or_null<MCDataFragment>(AUIPCSymbol->getFragment()); 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric if (!DF) 600b57cec5SDimitry Andric return nullptr; 610b57cec5SDimitry Andric 620b57cec5SDimitry Andric uint64_t Offset = AUIPCSymbol->getOffset(); 630b57cec5SDimitry Andric if (DF->getContents().size() == Offset) { 64*0fca6ea1SDimitry Andric DF = dyn_cast_or_null<MCDataFragment>(DF->getNext()); 650b57cec5SDimitry Andric if (!DF) 660b57cec5SDimitry Andric return nullptr; 670b57cec5SDimitry Andric Offset = 0; 680b57cec5SDimitry Andric } 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric for (const MCFixup &F : DF->getFixups()) { 710b57cec5SDimitry Andric if (F.getOffset() != Offset) 720b57cec5SDimitry Andric continue; 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric switch ((unsigned)F.getKind()) { 750b57cec5SDimitry Andric default: 760b57cec5SDimitry Andric continue; 770b57cec5SDimitry Andric case RISCV::fixup_riscv_got_hi20: 780b57cec5SDimitry Andric case RISCV::fixup_riscv_tls_got_hi20: 790b57cec5SDimitry Andric case RISCV::fixup_riscv_tls_gd_hi20: 800b57cec5SDimitry Andric case RISCV::fixup_riscv_pcrel_hi20: 817a6dacacSDimitry Andric case RISCV::fixup_riscv_tlsdesc_hi20: 8255e4f9d5SDimitry Andric if (DFOut) 8355e4f9d5SDimitry Andric *DFOut = DF; 840b57cec5SDimitry Andric return &F; 850b57cec5SDimitry Andric } 860b57cec5SDimitry Andric } 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric return nullptr; 890b57cec5SDimitry Andric } 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric bool RISCVMCExpr::evaluateAsRelocatableImpl(MCValue &Res, 92*0fca6ea1SDimitry Andric const MCAssembler *Asm, 930b57cec5SDimitry Andric const MCFixup *Fixup) const { 94fe6060f1SDimitry Andric // Explicitly drop the layout and assembler to prevent any symbolic folding in 95fe6060f1SDimitry Andric // the expression handling. This is required to preserve symbolic difference 96fe6060f1SDimitry Andric // expressions to emit the paired relocations. 97fe6060f1SDimitry Andric if (!getSubExpr()->evaluateAsRelocatable(Res, nullptr, nullptr)) 980b57cec5SDimitry Andric return false; 990b57cec5SDimitry Andric 100fe6060f1SDimitry Andric Res = 101fe6060f1SDimitry Andric MCValue::get(Res.getSymA(), Res.getSymB(), Res.getConstant(), getKind()); 102fe6060f1SDimitry Andric // Custom fixup types are not valid with symbol difference expressions. 103fe6060f1SDimitry Andric return Res.getSymB() ? getKind() == VK_RISCV_None : true; 1040b57cec5SDimitry Andric } 1050b57cec5SDimitry Andric 1060b57cec5SDimitry Andric void RISCVMCExpr::visitUsedExpr(MCStreamer &Streamer) const { 1070b57cec5SDimitry Andric Streamer.visitUsedExpr(*getSubExpr()); 1080b57cec5SDimitry Andric } 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andric RISCVMCExpr::VariantKind RISCVMCExpr::getVariantKindForName(StringRef name) { 1110b57cec5SDimitry Andric return StringSwitch<RISCVMCExpr::VariantKind>(name) 1120b57cec5SDimitry Andric .Case("lo", VK_RISCV_LO) 1130b57cec5SDimitry Andric .Case("hi", VK_RISCV_HI) 1140b57cec5SDimitry Andric .Case("pcrel_lo", VK_RISCV_PCREL_LO) 1150b57cec5SDimitry Andric .Case("pcrel_hi", VK_RISCV_PCREL_HI) 1160b57cec5SDimitry Andric .Case("got_pcrel_hi", VK_RISCV_GOT_HI) 1170b57cec5SDimitry Andric .Case("tprel_lo", VK_RISCV_TPREL_LO) 1180b57cec5SDimitry Andric .Case("tprel_hi", VK_RISCV_TPREL_HI) 1190b57cec5SDimitry Andric .Case("tprel_add", VK_RISCV_TPREL_ADD) 1200b57cec5SDimitry Andric .Case("tls_ie_pcrel_hi", VK_RISCV_TLS_GOT_HI) 1210b57cec5SDimitry Andric .Case("tls_gd_pcrel_hi", VK_RISCV_TLS_GD_HI) 1227a6dacacSDimitry Andric .Case("tlsdesc_hi", VK_RISCV_TLSDESC_HI) 1237a6dacacSDimitry Andric .Case("tlsdesc_load_lo", VK_RISCV_TLSDESC_LOAD_LO) 1247a6dacacSDimitry Andric .Case("tlsdesc_add_lo", VK_RISCV_TLSDESC_ADD_LO) 1257a6dacacSDimitry Andric .Case("tlsdesc_call", VK_RISCV_TLSDESC_CALL) 1260b57cec5SDimitry Andric .Default(VK_RISCV_Invalid); 1270b57cec5SDimitry Andric } 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andric StringRef RISCVMCExpr::getVariantKindName(VariantKind Kind) { 1300b57cec5SDimitry Andric switch (Kind) { 131fe6060f1SDimitry Andric case VK_RISCV_Invalid: 132fe6060f1SDimitry Andric case VK_RISCV_None: 1330b57cec5SDimitry Andric llvm_unreachable("Invalid ELF symbol kind"); 1340b57cec5SDimitry Andric case VK_RISCV_LO: 1350b57cec5SDimitry Andric return "lo"; 1360b57cec5SDimitry Andric case VK_RISCV_HI: 1370b57cec5SDimitry Andric return "hi"; 1380b57cec5SDimitry Andric case VK_RISCV_PCREL_LO: 1390b57cec5SDimitry Andric return "pcrel_lo"; 1400b57cec5SDimitry Andric case VK_RISCV_PCREL_HI: 1410b57cec5SDimitry Andric return "pcrel_hi"; 1420b57cec5SDimitry Andric case VK_RISCV_GOT_HI: 1430b57cec5SDimitry Andric return "got_pcrel_hi"; 1440b57cec5SDimitry Andric case VK_RISCV_TPREL_LO: 1450b57cec5SDimitry Andric return "tprel_lo"; 1460b57cec5SDimitry Andric case VK_RISCV_TPREL_HI: 1470b57cec5SDimitry Andric return "tprel_hi"; 1480b57cec5SDimitry Andric case VK_RISCV_TPREL_ADD: 1490b57cec5SDimitry Andric return "tprel_add"; 1500b57cec5SDimitry Andric case VK_RISCV_TLS_GOT_HI: 1510b57cec5SDimitry Andric return "tls_ie_pcrel_hi"; 1527a6dacacSDimitry Andric case VK_RISCV_TLSDESC_HI: 1537a6dacacSDimitry Andric return "tlsdesc_hi"; 1547a6dacacSDimitry Andric case VK_RISCV_TLSDESC_LOAD_LO: 1557a6dacacSDimitry Andric return "tlsdesc_load_lo"; 1567a6dacacSDimitry Andric case VK_RISCV_TLSDESC_ADD_LO: 1577a6dacacSDimitry Andric return "tlsdesc_add_lo"; 1587a6dacacSDimitry Andric case VK_RISCV_TLSDESC_CALL: 1597a6dacacSDimitry Andric return "tlsdesc_call"; 1600b57cec5SDimitry Andric case VK_RISCV_TLS_GD_HI: 1610b57cec5SDimitry Andric return "tls_gd_pcrel_hi"; 162fe6060f1SDimitry Andric case VK_RISCV_CALL: 163fe6060f1SDimitry Andric return "call"; 164fe6060f1SDimitry Andric case VK_RISCV_CALL_PLT: 165fe6060f1SDimitry Andric return "call_plt"; 166fe6060f1SDimitry Andric case VK_RISCV_32_PCREL: 167fe6060f1SDimitry Andric return "32_pcrel"; 1680b57cec5SDimitry Andric } 169fe6060f1SDimitry Andric llvm_unreachable("Invalid ELF symbol kind"); 1700b57cec5SDimitry Andric } 1710b57cec5SDimitry Andric 1720b57cec5SDimitry Andric static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) { 1730b57cec5SDimitry Andric switch (Expr->getKind()) { 1740b57cec5SDimitry Andric case MCExpr::Target: 1750b57cec5SDimitry Andric llvm_unreachable("Can't handle nested target expression"); 1760b57cec5SDimitry Andric break; 1770b57cec5SDimitry Andric case MCExpr::Constant: 1780b57cec5SDimitry Andric break; 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andric case MCExpr::Binary: { 1810b57cec5SDimitry Andric const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr); 1820b57cec5SDimitry Andric fixELFSymbolsInTLSFixupsImpl(BE->getLHS(), Asm); 1830b57cec5SDimitry Andric fixELFSymbolsInTLSFixupsImpl(BE->getRHS(), Asm); 1840b57cec5SDimitry Andric break; 1850b57cec5SDimitry Andric } 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric case MCExpr::SymbolRef: { 1880b57cec5SDimitry Andric // We're known to be under a TLS fixup, so any symbol should be 1890b57cec5SDimitry Andric // modified. There should be only one. 1900b57cec5SDimitry Andric const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr); 1910b57cec5SDimitry Andric cast<MCSymbolELF>(SymRef.getSymbol()).setType(ELF::STT_TLS); 1920b57cec5SDimitry Andric break; 1930b57cec5SDimitry Andric } 1940b57cec5SDimitry Andric 1950b57cec5SDimitry Andric case MCExpr::Unary: 1960b57cec5SDimitry Andric fixELFSymbolsInTLSFixupsImpl(cast<MCUnaryExpr>(Expr)->getSubExpr(), Asm); 1970b57cec5SDimitry Andric break; 1980b57cec5SDimitry Andric } 1990b57cec5SDimitry Andric } 2000b57cec5SDimitry Andric 2010b57cec5SDimitry Andric void RISCVMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const { 2020b57cec5SDimitry Andric switch (getKind()) { 2030b57cec5SDimitry Andric default: 2040b57cec5SDimitry Andric return; 2050b57cec5SDimitry Andric case VK_RISCV_TPREL_HI: 2060b57cec5SDimitry Andric case VK_RISCV_TLS_GOT_HI: 2070b57cec5SDimitry Andric case VK_RISCV_TLS_GD_HI: 2087a6dacacSDimitry Andric case VK_RISCV_TLSDESC_HI: 2090b57cec5SDimitry Andric break; 2100b57cec5SDimitry Andric } 2110b57cec5SDimitry Andric 2120b57cec5SDimitry Andric fixELFSymbolsInTLSFixupsImpl(getSubExpr(), Asm); 2130b57cec5SDimitry Andric } 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric bool RISCVMCExpr::evaluateAsConstant(int64_t &Res) const { 2160b57cec5SDimitry Andric MCValue Value; 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric if (Kind == VK_RISCV_PCREL_HI || Kind == VK_RISCV_PCREL_LO || 2190b57cec5SDimitry Andric Kind == VK_RISCV_GOT_HI || Kind == VK_RISCV_TPREL_HI || 2200b57cec5SDimitry Andric Kind == VK_RISCV_TPREL_LO || Kind == VK_RISCV_TPREL_ADD || 2210b57cec5SDimitry Andric Kind == VK_RISCV_TLS_GOT_HI || Kind == VK_RISCV_TLS_GD_HI || 2227a6dacacSDimitry Andric Kind == VK_RISCV_TLSDESC_HI || Kind == VK_RISCV_TLSDESC_LOAD_LO || 2237a6dacacSDimitry Andric Kind == VK_RISCV_TLSDESC_ADD_LO || Kind == VK_RISCV_TLSDESC_CALL || 2240b57cec5SDimitry Andric Kind == VK_RISCV_CALL || Kind == VK_RISCV_CALL_PLT) 2250b57cec5SDimitry Andric return false; 2260b57cec5SDimitry Andric 2270b57cec5SDimitry Andric if (!getSubExpr()->evaluateAsRelocatable(Value, nullptr, nullptr)) 2280b57cec5SDimitry Andric return false; 2290b57cec5SDimitry Andric 2300b57cec5SDimitry Andric if (!Value.isAbsolute()) 2310b57cec5SDimitry Andric return false; 2320b57cec5SDimitry Andric 2330b57cec5SDimitry Andric Res = evaluateAsInt64(Value.getConstant()); 2340b57cec5SDimitry Andric return true; 2350b57cec5SDimitry Andric } 2360b57cec5SDimitry Andric 2370b57cec5SDimitry Andric int64_t RISCVMCExpr::evaluateAsInt64(int64_t Value) const { 2380b57cec5SDimitry Andric switch (Kind) { 2390b57cec5SDimitry Andric default: 2400b57cec5SDimitry Andric llvm_unreachable("Invalid kind"); 2410b57cec5SDimitry Andric case VK_RISCV_LO: 2420b57cec5SDimitry Andric return SignExtend64<12>(Value); 2430b57cec5SDimitry Andric case VK_RISCV_HI: 2440b57cec5SDimitry Andric // Add 1 if bit 11 is 1, to compensate for low 12 bits being negative. 2450b57cec5SDimitry Andric return ((Value + 0x800) >> 12) & 0xfffff; 2460b57cec5SDimitry Andric } 2470b57cec5SDimitry Andric } 248