Path: blob/main/contrib/llvm-project/llvm/lib/Target/VE/MCTargetDesc/VEMCExpr.cpp
35294 views
//===-- VEMCExpr.cpp - VE specific MC expression classes ------------------===//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//===----------------------------------------------------------------------===//7//8// This file contains the implementation of the assembly expression modifiers9// accepted by the VE architecture (e.g. "%hi", "%lo", ...).10//11//===----------------------------------------------------------------------===//1213#include "VEMCExpr.h"14#include "llvm/BinaryFormat/ELF.h"15#include "llvm/MC/MCAssembler.h"16#include "llvm/MC/MCContext.h"17#include "llvm/MC/MCObjectStreamer.h"18#include "llvm/MC/MCSymbolELF.h"19#include "llvm/MC/MCValue.h"20#include "llvm/Support/Casting.h"2122using namespace llvm;2324#define DEBUG_TYPE "vemcexpr"2526const VEMCExpr *VEMCExpr::create(VariantKind Kind, const MCExpr *Expr,27MCContext &Ctx) {28return new (Ctx) VEMCExpr(Kind, Expr);29}3031void VEMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {3233bool closeParen = printVariantKind(OS, Kind);3435const MCExpr *Expr = getSubExpr();36Expr->print(OS, MAI);3738if (closeParen)39OS << ')';40printVariantKindSuffix(OS, Kind);41}4243bool VEMCExpr::printVariantKind(raw_ostream &OS, VariantKind Kind) {44switch (Kind) {45case VK_VE_None:46case VK_VE_REFLONG:47return false;4849case VK_VE_HI32:50case VK_VE_LO32:51case VK_VE_PC_HI32:52case VK_VE_PC_LO32:53case VK_VE_GOT_HI32:54case VK_VE_GOT_LO32:55case VK_VE_GOTOFF_HI32:56case VK_VE_GOTOFF_LO32:57case VK_VE_PLT_HI32:58case VK_VE_PLT_LO32:59case VK_VE_TLS_GD_HI32:60case VK_VE_TLS_GD_LO32:61case VK_VE_TPOFF_HI32:62case VK_VE_TPOFF_LO32:63// Use suffix for these variant kinds64return false;65}66return true;67}6869void VEMCExpr::printVariantKindSuffix(raw_ostream &OS, VariantKind Kind) {70switch (Kind) {71case VK_VE_None:72case VK_VE_REFLONG:73break;74case VK_VE_HI32:75OS << "@hi";76break;77case VK_VE_LO32:78OS << "@lo";79break;80case VK_VE_PC_HI32:81OS << "@pc_hi";82break;83case VK_VE_PC_LO32:84OS << "@pc_lo";85break;86case VK_VE_GOT_HI32:87OS << "@got_hi";88break;89case VK_VE_GOT_LO32:90OS << "@got_lo";91break;92case VK_VE_GOTOFF_HI32:93OS << "@gotoff_hi";94break;95case VK_VE_GOTOFF_LO32:96OS << "@gotoff_lo";97break;98case VK_VE_PLT_HI32:99OS << "@plt_hi";100break;101case VK_VE_PLT_LO32:102OS << "@plt_lo";103break;104case VK_VE_TLS_GD_HI32:105OS << "@tls_gd_hi";106break;107case VK_VE_TLS_GD_LO32:108OS << "@tls_gd_lo";109break;110case VK_VE_TPOFF_HI32:111OS << "@tpoff_hi";112break;113case VK_VE_TPOFF_LO32:114OS << "@tpoff_lo";115break;116}117}118119VEMCExpr::VariantKind VEMCExpr::parseVariantKind(StringRef name) {120return StringSwitch<VEMCExpr::VariantKind>(name)121.Case("hi", VK_VE_HI32)122.Case("lo", VK_VE_LO32)123.Case("pc_hi", VK_VE_PC_HI32)124.Case("pc_lo", VK_VE_PC_LO32)125.Case("got_hi", VK_VE_GOT_HI32)126.Case("got_lo", VK_VE_GOT_LO32)127.Case("gotoff_hi", VK_VE_GOTOFF_HI32)128.Case("gotoff_lo", VK_VE_GOTOFF_LO32)129.Case("plt_hi", VK_VE_PLT_HI32)130.Case("plt_lo", VK_VE_PLT_LO32)131.Case("tls_gd_hi", VK_VE_TLS_GD_HI32)132.Case("tls_gd_lo", VK_VE_TLS_GD_LO32)133.Case("tpoff_hi", VK_VE_TPOFF_HI32)134.Case("tpoff_lo", VK_VE_TPOFF_LO32)135.Default(VK_VE_None);136}137138VE::Fixups VEMCExpr::getFixupKind(VEMCExpr::VariantKind Kind) {139switch (Kind) {140default:141llvm_unreachable("Unhandled VEMCExpr::VariantKind");142case VK_VE_REFLONG:143return VE::fixup_ve_reflong;144case VK_VE_HI32:145return VE::fixup_ve_hi32;146case VK_VE_LO32:147return VE::fixup_ve_lo32;148case VK_VE_PC_HI32:149return VE::fixup_ve_pc_hi32;150case VK_VE_PC_LO32:151return VE::fixup_ve_pc_lo32;152case VK_VE_GOT_HI32:153return VE::fixup_ve_got_hi32;154case VK_VE_GOT_LO32:155return VE::fixup_ve_got_lo32;156case VK_VE_GOTOFF_HI32:157return VE::fixup_ve_gotoff_hi32;158case VK_VE_GOTOFF_LO32:159return VE::fixup_ve_gotoff_lo32;160case VK_VE_PLT_HI32:161return VE::fixup_ve_plt_hi32;162case VK_VE_PLT_LO32:163return VE::fixup_ve_plt_lo32;164case VK_VE_TLS_GD_HI32:165return VE::fixup_ve_tls_gd_hi32;166case VK_VE_TLS_GD_LO32:167return VE::fixup_ve_tls_gd_lo32;168case VK_VE_TPOFF_HI32:169return VE::fixup_ve_tpoff_hi32;170case VK_VE_TPOFF_LO32:171return VE::fixup_ve_tpoff_lo32;172}173}174175bool VEMCExpr::evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,176const MCFixup *Fixup) const {177if (!getSubExpr()->evaluateAsRelocatable(Res, Asm, Fixup))178return false;179180Res =181MCValue::get(Res.getSymA(), Res.getSymB(), Res.getConstant(), getKind());182183return true;184}185186static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) {187switch (Expr->getKind()) {188case MCExpr::Target:189llvm_unreachable("Can't handle nested target expr!");190break;191192case MCExpr::Constant:193break;194195case MCExpr::Binary: {196const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);197fixELFSymbolsInTLSFixupsImpl(BE->getLHS(), Asm);198fixELFSymbolsInTLSFixupsImpl(BE->getRHS(), Asm);199break;200}201202case MCExpr::SymbolRef: {203// We're known to be under a TLS fixup, so any symbol should be204// modified. There should be only one.205const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);206cast<MCSymbolELF>(SymRef.getSymbol()).setType(ELF::STT_TLS);207break;208}209210case MCExpr::Unary:211fixELFSymbolsInTLSFixupsImpl(cast<MCUnaryExpr>(Expr)->getSubExpr(), Asm);212break;213}214}215216void VEMCExpr::visitUsedExpr(MCStreamer &Streamer) const {217Streamer.visitUsedExpr(*getSubExpr());218}219220void VEMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const {221switch (getKind()) {222default:223return;224case VK_VE_TLS_GD_HI32:225case VK_VE_TLS_GD_LO32:226case VK_VE_TPOFF_HI32:227case VK_VE_TPOFF_LO32:228break;229}230fixELFSymbolsInTLSFixupsImpl(getSubExpr(), Asm);231}232233234