1 //===-- PPCMCExpr.cpp - PPC specific MC expression classes ----------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #define DEBUG_TYPE "ppcmcexpr"
11 #include "PPCMCExpr.h"
12 #include "llvm/MC/MCAssembler.h"
13 #include "llvm/MC/MCContext.h"
18 PPCMCExpr::Create(VariantKind Kind, const MCExpr *Expr,
20 return new (Ctx) PPCMCExpr(Kind, Expr);
23 void PPCMCExpr::PrintImpl(raw_ostream &OS) const {
25 default: llvm_unreachable("Invalid kind!");
26 case VK_PPC_HA16: OS << "ha16"; break;
27 case VK_PPC_LO16: OS << "lo16"; break;
31 getSubExpr()->print(OS);
36 PPCMCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
37 const MCAsmLayout *Layout) const {
40 if (!getSubExpr()->EvaluateAsRelocatable(Value, *Layout))
43 if (Value.isAbsolute()) {
44 int64_t Result = Value.getConstant();
47 llvm_unreachable("Invalid kind!");
49 Result = ((Result >> 16) + ((Result & 0x8000) ? 1 : 0)) & 0xffff;
52 Result = Result & 0xffff;
55 Res = MCValue::get(Result);
57 MCContext &Context = Layout->getAssembler().getContext();
58 const MCSymbolRefExpr *Sym = Value.getSymA();
59 MCSymbolRefExpr::VariantKind Modifier = Sym->getKind();
60 if (Modifier != MCSymbolRefExpr::VK_None)
64 llvm_unreachable("Invalid kind!");
66 Modifier = MCSymbolRefExpr::VK_PPC_ADDR16_HA;
69 Modifier = MCSymbolRefExpr::VK_PPC_ADDR16_LO;
72 Sym = MCSymbolRefExpr::Create(&Sym->getSymbol(), Modifier, Context);
73 Res = MCValue::get(Sym, Value.getSymB(), Value.getConstant());
79 // FIXME: This basically copies MCObjectStreamer::AddValueSymbols. Perhaps
80 // that method should be made public?
81 static void AddValueSymbols_(const MCExpr *Value, MCAssembler *Asm) {
82 switch (Value->getKind()) {
84 llvm_unreachable("Can't handle nested target expr!");
86 case MCExpr::Constant:
89 case MCExpr::Binary: {
90 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value);
91 AddValueSymbols_(BE->getLHS(), Asm);
92 AddValueSymbols_(BE->getRHS(), Asm);
96 case MCExpr::SymbolRef:
97 Asm->getOrCreateSymbolData(cast<MCSymbolRefExpr>(Value)->getSymbol());
101 AddValueSymbols_(cast<MCUnaryExpr>(Value)->getSubExpr(), Asm);
106 void PPCMCExpr::AddValueSymbols(MCAssembler *Asm) const {
107 AddValueSymbols_(getSubExpr(), Asm);