Path: blob/main/contrib/llvm-project/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp
35294 views
//===-- PPCMCExpr.cpp - PPC 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//===----------------------------------------------------------------------===//78#include "PPCMCExpr.h"9#include "PPCFixupKinds.h"10#include "llvm/MC/MCAsmInfo.h"11#include "llvm/MC/MCAssembler.h"12#include "llvm/MC/MCContext.h"13#include "llvm/MC/MCObjectStreamer.h"1415using namespace llvm;1617#define DEBUG_TYPE "ppcmcexpr"1819const PPCMCExpr *PPCMCExpr::create(VariantKind Kind, const MCExpr *Expr,20MCContext &Ctx) {21return new (Ctx) PPCMCExpr(Kind, Expr);22}2324void PPCMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {25getSubExpr()->print(OS, MAI);2627switch (Kind) {28default:29llvm_unreachable("Invalid kind!");30case VK_PPC_LO:31OS << "@l";32break;33case VK_PPC_HI:34OS << "@h";35break;36case VK_PPC_HA:37OS << "@ha";38break;39case VK_PPC_HIGH:40OS << "@high";41break;42case VK_PPC_HIGHA:43OS << "@higha";44break;45case VK_PPC_HIGHER:46OS << "@higher";47break;48case VK_PPC_HIGHERA:49OS << "@highera";50break;51case VK_PPC_HIGHEST:52OS << "@highest";53break;54case VK_PPC_HIGHESTA:55OS << "@highesta";56break;57}58}5960bool61PPCMCExpr::evaluateAsConstant(int64_t &Res) const {62MCValue Value;6364if (!getSubExpr()->evaluateAsRelocatable(Value, nullptr, nullptr))65return false;6667if (!Value.isAbsolute())68return false;6970Res = evaluateAsInt64(Value.getConstant());71return true;72}7374int64_t75PPCMCExpr::evaluateAsInt64(int64_t Value) const {76switch (Kind) {77case VK_PPC_LO:78return Value & 0xffff;79case VK_PPC_HI:80return (Value >> 16) & 0xffff;81case VK_PPC_HA:82return ((Value + 0x8000) >> 16) & 0xffff;83case VK_PPC_HIGH:84return (Value >> 16) & 0xffff;85case VK_PPC_HIGHA:86return ((Value + 0x8000) >> 16) & 0xffff;87case VK_PPC_HIGHER:88return (Value >> 32) & 0xffff;89case VK_PPC_HIGHERA:90return ((Value + 0x8000) >> 32) & 0xffff;91case VK_PPC_HIGHEST:92return (Value >> 48) & 0xffff;93case VK_PPC_HIGHESTA:94return ((Value + 0x8000) >> 48) & 0xffff;95case VK_PPC_None:96break;97}98llvm_unreachable("Invalid kind!");99}100101bool PPCMCExpr::evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,102const MCFixup *Fixup) const {103MCValue Value;104105if (!getSubExpr()->evaluateAsRelocatable(Value, Asm, Fixup))106return false;107108if (Value.isAbsolute()) {109int64_t Result = evaluateAsInt64(Value.getConstant());110bool IsHalf16 = Fixup && Fixup->getTargetKind() == PPC::fixup_ppc_half16;111bool IsHalf16DS =112Fixup && Fixup->getTargetKind() == PPC::fixup_ppc_half16ds;113bool IsHalf16DQ =114Fixup && Fixup->getTargetKind() == PPC::fixup_ppc_half16dq;115bool IsHalf = IsHalf16 || IsHalf16DS || IsHalf16DQ;116117if (!IsHalf && Result >= 0x8000)118return false;119if ((IsHalf16DS && (Result & 0x3)) || (IsHalf16DQ && (Result & 0xf)))120return false;121122Res = MCValue::get(Result);123} else {124if (!Asm || !Asm->hasLayout())125return false;126127MCContext &Context = Asm->getContext();128const MCSymbolRefExpr *Sym = Value.getSymA();129MCSymbolRefExpr::VariantKind Modifier = Sym->getKind();130if (Modifier != MCSymbolRefExpr::VK_None)131return false;132switch (Kind) {133default:134llvm_unreachable("Invalid kind!");135case VK_PPC_LO:136Modifier = MCSymbolRefExpr::VK_PPC_LO;137break;138case VK_PPC_HI:139Modifier = MCSymbolRefExpr::VK_PPC_HI;140break;141case VK_PPC_HA:142Modifier = MCSymbolRefExpr::VK_PPC_HA;143break;144case VK_PPC_HIGH:145Modifier = MCSymbolRefExpr::VK_PPC_HIGH;146break;147case VK_PPC_HIGHA:148Modifier = MCSymbolRefExpr::VK_PPC_HIGHA;149break;150case VK_PPC_HIGHERA:151Modifier = MCSymbolRefExpr::VK_PPC_HIGHERA;152break;153case VK_PPC_HIGHER:154Modifier = MCSymbolRefExpr::VK_PPC_HIGHER;155break;156case VK_PPC_HIGHEST:157Modifier = MCSymbolRefExpr::VK_PPC_HIGHEST;158break;159case VK_PPC_HIGHESTA:160Modifier = MCSymbolRefExpr::VK_PPC_HIGHESTA;161break;162}163Sym = MCSymbolRefExpr::create(&Sym->getSymbol(), Modifier, Context);164Res = MCValue::get(Sym, Value.getSymB(), Value.getConstant());165}166167return true;168}169170void PPCMCExpr::visitUsedExpr(MCStreamer &Streamer) const {171Streamer.visitUsedExpr(*getSubExpr());172}173174175