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 #include "PPCFixupKinds.h"
11 #include "PPCMCExpr.h"
12 #include "llvm/MC/MCAsmInfo.h"
13 #include "llvm/MC/MCAssembler.h"
14 #include "llvm/MC/MCContext.h"
15 #include "llvm/MC/MCObjectStreamer.h"
19 #define DEBUG_TYPE "ppcmcexpr"
22 PPCMCExpr::Create(VariantKind Kind, const MCExpr *Expr,
23 bool isDarwin, MCContext &Ctx) {
24 return new (Ctx) PPCMCExpr(Kind, Expr, isDarwin);
27 void PPCMCExpr::PrintImpl(raw_ostream &OS) const {
28 if (isDarwinSyntax()) {
30 default: llvm_unreachable("Invalid kind!");
31 case VK_PPC_LO: OS << "lo16"; break;
32 case VK_PPC_HI: OS << "hi16"; break;
33 case VK_PPC_HA: OS << "ha16"; break;
37 getSubExpr()->print(OS);
40 getSubExpr()->print(OS);
43 default: llvm_unreachable("Invalid kind!");
44 case VK_PPC_LO: OS << "@l"; break;
45 case VK_PPC_HI: OS << "@h"; break;
46 case VK_PPC_HA: OS << "@ha"; break;
47 case VK_PPC_HIGHER: OS << "@higher"; break;
48 case VK_PPC_HIGHERA: OS << "@highera"; break;
49 case VK_PPC_HIGHEST: OS << "@highest"; break;
50 case VK_PPC_HIGHESTA: OS << "@highesta"; break;
56 PPCMCExpr::EvaluateAsConstant(int64_t &Res) const {
59 if (!getSubExpr()->EvaluateAsRelocatable(Value, nullptr, nullptr))
62 if (!Value.isAbsolute())
65 Res = EvaluateAsInt64(Value.getConstant());
70 PPCMCExpr::EvaluateAsInt64(int64_t Value) const {
73 return Value & 0xffff;
75 return (Value >> 16) & 0xffff;
77 return ((Value + 0x8000) >> 16) & 0xffff;
79 return (Value >> 32) & 0xffff;
81 return ((Value + 0x8000) >> 32) & 0xffff;
83 return (Value >> 48) & 0xffff;
85 return ((Value + 0x8000) >> 48) & 0xffff;
89 llvm_unreachable("Invalid kind!");
93 PPCMCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
94 const MCAsmLayout *Layout,
95 const MCFixup *Fixup) const {
98 if (!getSubExpr()->EvaluateAsRelocatable(Value, Layout, Fixup))
101 if (Value.isAbsolute()) {
102 int64_t Result = EvaluateAsInt64(Value.getConstant());
103 if ((Fixup == nullptr || (unsigned)Fixup->getKind() != PPC::fixup_ppc_half16) &&
106 Res = MCValue::get(Result);
111 MCContext &Context = Layout->getAssembler().getContext();
112 const MCSymbolRefExpr *Sym = Value.getSymA();
113 MCSymbolRefExpr::VariantKind Modifier = Sym->getKind();
114 if (Modifier != MCSymbolRefExpr::VK_None)
118 llvm_unreachable("Invalid kind!");
120 Modifier = MCSymbolRefExpr::VK_PPC_LO;
123 Modifier = MCSymbolRefExpr::VK_PPC_HI;
126 Modifier = MCSymbolRefExpr::VK_PPC_HA;
129 Modifier = MCSymbolRefExpr::VK_PPC_HIGHERA;
132 Modifier = MCSymbolRefExpr::VK_PPC_HIGHER;
135 Modifier = MCSymbolRefExpr::VK_PPC_HIGHEST;
137 case VK_PPC_HIGHESTA:
138 Modifier = MCSymbolRefExpr::VK_PPC_HIGHESTA;
141 Sym = MCSymbolRefExpr::Create(&Sym->getSymbol(), Modifier, Context);
142 Res = MCValue::get(Sym, Value.getSymB(), Value.getConstant());
148 void PPCMCExpr::visitUsedExpr(MCStreamer &Streamer) const {
149 Streamer.visitUsedExpr(*getSubExpr());