Path: blob/main/contrib/llvm-project/llvm/lib/Target/CSKY/MCTargetDesc/CSKYMCExpr.cpp
35294 views
//===-- CSKYMCExpr.cpp - CSKY specific MC expression classes -*- C++ -*----===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "CSKYMCExpr.h"9#include "CSKYFixupKinds.h"10#include "llvm/BinaryFormat/ELF.h"11#include "llvm/MC/MCAssembler.h"12#include "llvm/MC/MCContext.h"13#include "llvm/MC/MCStreamer.h"14#include "llvm/MC/MCSymbolELF.h"15#include "llvm/Support/Casting.h"1617using namespace llvm;1819#define DEBUG_TYPE "csky-mc-expr"2021const CSKYMCExpr *CSKYMCExpr::create(const MCExpr *Expr, VariantKind Kind,22MCContext &Ctx) {23return new (Ctx) CSKYMCExpr(Kind, Expr);24}2526StringRef CSKYMCExpr::getVariantKindName(VariantKind Kind) {27switch (Kind) {28default:29llvm_unreachable("Invalid ELF symbol kind");30case VK_CSKY_None:31case VK_CSKY_ADDR:32return "";33case VK_CSKY_ADDR_HI16:34return "@HI16";35case VK_CSKY_ADDR_LO16:36return "@LO16";37case VK_CSKY_GOT_IMM18_BY4:38case VK_CSKY_GOT:39return "@GOT";40case VK_CSKY_GOTPC:41return "@GOTPC";42case VK_CSKY_GOTOFF:43return "@GOTOFF";44case VK_CSKY_PLT_IMM18_BY4:45case VK_CSKY_PLT:46return "@PLT";47case VK_CSKY_TLSLE:48return "@TPOFF";49case VK_CSKY_TLSIE:50return "@GOTTPOFF";51case VK_CSKY_TLSGD:52return "@TLSGD32";53case VK_CSKY_TLSLDO:54return "@TLSLDO32";55case VK_CSKY_TLSLDM:56return "@TLSLDM32";57}58}5960void CSKYMCExpr::visitUsedExpr(MCStreamer &Streamer) const {61Streamer.visitUsedExpr(*getSubExpr());62}6364void CSKYMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {65Expr->print(OS, MAI);66OS << getVariantKindName(getKind());67}6869static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) {70switch (Expr->getKind()) {71case MCExpr::Target:72llvm_unreachable("Can't handle nested target expression");73break;74case MCExpr::Constant:75break;7677case MCExpr::Binary: {78const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);79fixELFSymbolsInTLSFixupsImpl(BE->getLHS(), Asm);80fixELFSymbolsInTLSFixupsImpl(BE->getRHS(), Asm);81break;82}8384case MCExpr::SymbolRef: {85// We're known to be under a TLS fixup, so any symbol should be86// modified. There should be only one.87const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);88cast<MCSymbolELF>(SymRef.getSymbol()).setType(ELF::STT_TLS);89break;90}9192case MCExpr::Unary:93fixELFSymbolsInTLSFixupsImpl(cast<MCUnaryExpr>(Expr)->getSubExpr(), Asm);94break;95}96}9798void CSKYMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const {99switch (getKind()) {100default:101return;102case VK_CSKY_TLSLE:103case VK_CSKY_TLSIE:104case VK_CSKY_TLSGD:105break;106}107108fixELFSymbolsInTLSFixupsImpl(getSubExpr(), Asm);109}110111bool CSKYMCExpr::evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,112const MCFixup *Fixup) const {113if (!getSubExpr()->evaluateAsRelocatable(Res, Asm, Fixup))114return false;115116// Some custom fixup types are not valid with symbol difference expressions117if (Res.getSymA() && Res.getSymB()) {118switch (getKind()) {119default:120return true;121case VK_CSKY_GOT:122case VK_CSKY_GOT_IMM18_BY4:123case VK_CSKY_GOTPC:124case VK_CSKY_GOTOFF:125case VK_CSKY_PLT:126case VK_CSKY_PLT_IMM18_BY4:127case VK_CSKY_TLSIE:128case VK_CSKY_TLSLE:129case VK_CSKY_TLSGD:130case VK_CSKY_TLSLDO:131case VK_CSKY_TLSLDM:132return false;133}134}135136return true;137}138139140