X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FPowerPC%2FMCTargetDesc%2FPPCMCExpr.cpp;h=7204befe15ee49188c4c69fa093c621b61991a0e;hb=3af13568fbd7dc26d9274a19838c52c6875248bc;hp=10d068dc49e61e760cec7d86f66794f6af52a22b;hpb=42e8630239989fd40820975c361554546c1ccc2d;p=oota-llvm.git diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp index 10d068dc49e..7204befe15e 100644 --- a/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp +++ b/lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.cpp @@ -7,10 +7,12 @@ // //===----------------------------------------------------------------------===// +#include "PPCFixupKinds.h" #include "PPCMCExpr.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCObjectStreamer.h" using namespace llvm; @@ -50,41 +52,57 @@ void PPCMCExpr::PrintImpl(raw_ostream &OS) const { } } +bool +PPCMCExpr::EvaluateAsConstant(int64_t &Res) const { + MCValue Value; + + if (!getSubExpr()->EvaluateAsRelocatable(Value, nullptr, nullptr)) + return false; + + if (!Value.isAbsolute()) + return false; + + Res = EvaluateAsInt64(Value.getConstant()); + return true; +} + +int64_t +PPCMCExpr::EvaluateAsInt64(int64_t Value) const { + switch (Kind) { + case VK_PPC_LO: + return Value & 0xffff; + case VK_PPC_HI: + return (Value >> 16) & 0xffff; + case VK_PPC_HA: + return ((Value + 0x8000) >> 16) & 0xffff; + case VK_PPC_HIGHER: + return (Value >> 32) & 0xffff; + case VK_PPC_HIGHERA: + return ((Value + 0x8000) >> 32) & 0xffff; + case VK_PPC_HIGHEST: + return (Value >> 48) & 0xffff; + case VK_PPC_HIGHESTA: + return ((Value + 0x8000) >> 48) & 0xffff; + case VK_PPC_None: + break; + } + llvm_unreachable("Invalid kind!"); +} + bool PPCMCExpr::EvaluateAsRelocatableImpl(MCValue &Res, - const MCAsmLayout *Layout) const { + const MCAsmLayout *Layout, + const MCFixup *Fixup) const { MCValue Value; - if (!getSubExpr()->EvaluateAsRelocatable(Value, Layout)) + if (!getSubExpr()->EvaluateAsRelocatable(Value, Layout, Fixup)) return false; if (Value.isAbsolute()) { - int64_t Result = Value.getConstant(); - switch (Kind) { - default: - llvm_unreachable("Invalid kind!"); - case VK_PPC_LO: - Result = Result & 0xffff; - break; - case VK_PPC_HI: - Result = (Result >> 16) & 0xffff; - break; - case VK_PPC_HA: - Result = ((Result + 0x8000) >> 16) & 0xffff; - break; - case VK_PPC_HIGHER: - Result = (Result >> 32) & 0xffff; - break; - case VK_PPC_HIGHERA: - Result = ((Result + 0x8000) >> 32) & 0xffff; - break; - case VK_PPC_HIGHEST: - Result = (Result >> 48) & 0xffff; - break; - case VK_PPC_HIGHESTA: - Result = ((Result + 0x8000) >> 48) & 0xffff; - break; - } + int64_t Result = EvaluateAsInt64(Value.getConstant()); + if ((Fixup == nullptr || (unsigned)Fixup->getKind() != PPC::fixup_ppc_half16) && + (Result >= 0x8000)) + return false; Res = MCValue::get(Result); } else { if (!Layout) @@ -127,33 +145,6 @@ PPCMCExpr::EvaluateAsRelocatableImpl(MCValue &Res, return true; } -// FIXME: This basically copies MCObjectStreamer::AddValueSymbols. Perhaps -// that method should be made public? -static void AddValueSymbols_(const MCExpr *Value, MCAssembler *Asm) { - switch (Value->getKind()) { - case MCExpr::Target: - llvm_unreachable("Can't handle nested target expr!"); - - case MCExpr::Constant: - break; - - case MCExpr::Binary: { - const MCBinaryExpr *BE = cast(Value); - AddValueSymbols_(BE->getLHS(), Asm); - AddValueSymbols_(BE->getRHS(), Asm); - break; - } - - case MCExpr::SymbolRef: - Asm->getOrCreateSymbolData(cast(Value)->getSymbol()); - break; - - case MCExpr::Unary: - AddValueSymbols_(cast(Value)->getSubExpr(), Asm); - break; - } -} - -void PPCMCExpr::AddValueSymbols(MCAssembler *Asm) const { - AddValueSymbols_(getSubExpr(), Asm); +void PPCMCExpr::visitUsedExpr(MCStreamer &Streamer) const { + Streamer.visitUsedExpr(*getSubExpr()); }