1edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand//===-- PPCMCExpr.cpp - PPC specific MC expression classes ----------------===// 2edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand// 3edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand// The LLVM Compiler Infrastructure 4edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand// 5edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand// This file is distributed under the University of Illinois Open Source 6edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand// License. See LICENSE.TXT for details. 7edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand// 8edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand//===----------------------------------------------------------------------===// 9edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand 10edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand#define DEBUG_TYPE "ppcmcexpr" 11edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand#include "PPCMCExpr.h" 12edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand#include "llvm/MC/MCAssembler.h" 13edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand#include "llvm/MC/MCContext.h" 14027e94479c9e69eb3c3c5536fa9990d0b96e9510Ulrich Weigand#include "llvm/MC/MCAsmInfo.h" 15edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand 16edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigandusing namespace llvm; 17edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand 18edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigandconst PPCMCExpr* 19edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich WeigandPPCMCExpr::Create(VariantKind Kind, const MCExpr *Expr, 20a68f58ab2bec6a024afae498e4082ddd8b01f178Ulrich Weigand bool isDarwin, MCContext &Ctx) { 21a68f58ab2bec6a024afae498e4082ddd8b01f178Ulrich Weigand return new (Ctx) PPCMCExpr(Kind, Expr, isDarwin); 22edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand} 23edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand 24edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigandvoid PPCMCExpr::PrintImpl(raw_ostream &OS) const { 25027e94479c9e69eb3c3c5536fa9990d0b96e9510Ulrich Weigand if (isDarwinSyntax()) { 26027e94479c9e69eb3c3c5536fa9990d0b96e9510Ulrich Weigand switch (Kind) { 27027e94479c9e69eb3c3c5536fa9990d0b96e9510Ulrich Weigand default: llvm_unreachable("Invalid kind!"); 2892cfa61c50d01307d658753f8d47f4e8555a6fa9Ulrich Weigand case VK_PPC_LO: OS << "lo16"; break; 29d2849572463da994c685b3bd7a60d5a7566c01e3Ulrich Weigand case VK_PPC_HI: OS << "hi16"; break; 3092cfa61c50d01307d658753f8d47f4e8555a6fa9Ulrich Weigand case VK_PPC_HA: OS << "ha16"; break; 31027e94479c9e69eb3c3c5536fa9990d0b96e9510Ulrich Weigand } 32027e94479c9e69eb3c3c5536fa9990d0b96e9510Ulrich Weigand 33027e94479c9e69eb3c3c5536fa9990d0b96e9510Ulrich Weigand OS << '('; 34027e94479c9e69eb3c3c5536fa9990d0b96e9510Ulrich Weigand getSubExpr()->print(OS); 35027e94479c9e69eb3c3c5536fa9990d0b96e9510Ulrich Weigand OS << ')'; 36027e94479c9e69eb3c3c5536fa9990d0b96e9510Ulrich Weigand } else { 37027e94479c9e69eb3c3c5536fa9990d0b96e9510Ulrich Weigand getSubExpr()->print(OS); 38edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand 39027e94479c9e69eb3c3c5536fa9990d0b96e9510Ulrich Weigand switch (Kind) { 40027e94479c9e69eb3c3c5536fa9990d0b96e9510Ulrich Weigand default: llvm_unreachable("Invalid kind!"); 4192cfa61c50d01307d658753f8d47f4e8555a6fa9Ulrich Weigand case VK_PPC_LO: OS << "@l"; break; 42d2849572463da994c685b3bd7a60d5a7566c01e3Ulrich Weigand case VK_PPC_HI: OS << "@h"; break; 4392cfa61c50d01307d658753f8d47f4e8555a6fa9Ulrich Weigand case VK_PPC_HA: OS << "@ha"; break; 44f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand case VK_PPC_HIGHER: OS << "@higher"; break; 45f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand case VK_PPC_HIGHERA: OS << "@highera"; break; 46f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand case VK_PPC_HIGHEST: OS << "@highest"; break; 47f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand case VK_PPC_HIGHESTA: OS << "@highesta"; break; 48027e94479c9e69eb3c3c5536fa9990d0b96e9510Ulrich Weigand } 49027e94479c9e69eb3c3c5536fa9990d0b96e9510Ulrich Weigand } 50edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand} 51edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand 52edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigandbool 53edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich WeigandPPCMCExpr::EvaluateAsRelocatableImpl(MCValue &Res, 54edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand const MCAsmLayout *Layout) const { 55edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand MCValue Value; 56edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand 57edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand if (!getSubExpr()->EvaluateAsRelocatable(Value, *Layout)) 58edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand return false; 59edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand 60edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand if (Value.isAbsolute()) { 61edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand int64_t Result = Value.getConstant(); 62edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand switch (Kind) { 63edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand default: 64edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand llvm_unreachable("Invalid kind!"); 6592cfa61c50d01307d658753f8d47f4e8555a6fa9Ulrich Weigand case VK_PPC_LO: 66edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand Result = Result & 0xffff; 67edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand break; 68d2849572463da994c685b3bd7a60d5a7566c01e3Ulrich Weigand case VK_PPC_HI: 69d2849572463da994c685b3bd7a60d5a7566c01e3Ulrich Weigand Result = (Result >> 16) & 0xffff; 70d2849572463da994c685b3bd7a60d5a7566c01e3Ulrich Weigand break; 7192cfa61c50d01307d658753f8d47f4e8555a6fa9Ulrich Weigand case VK_PPC_HA: 72f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand Result = ((Result + 0x8000) >> 16) & 0xffff; 73f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand break; 74f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand case VK_PPC_HIGHER: 75f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand Result = (Result >> 32) & 0xffff; 76f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand break; 77f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand case VK_PPC_HIGHERA: 78f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand Result = ((Result + 0x8000) >> 32) & 0xffff; 79f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand break; 80f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand case VK_PPC_HIGHEST: 81f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand Result = (Result >> 48) & 0xffff; 82f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand break; 83f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand case VK_PPC_HIGHESTA: 84f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand Result = ((Result + 0x8000) >> 48) & 0xffff; 8592cfa61c50d01307d658753f8d47f4e8555a6fa9Ulrich Weigand break; 86edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand } 87edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand Res = MCValue::get(Result); 88edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand } else { 89edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand MCContext &Context = Layout->getAssembler().getContext(); 90edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand const MCSymbolRefExpr *Sym = Value.getSymA(); 91edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand MCSymbolRefExpr::VariantKind Modifier = Sym->getKind(); 92edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand if (Modifier != MCSymbolRefExpr::VK_None) 93edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand return false; 94edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand switch (Kind) { 95edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand default: 96edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand llvm_unreachable("Invalid kind!"); 9792cfa61c50d01307d658753f8d47f4e8555a6fa9Ulrich Weigand case VK_PPC_LO: 9892cfa61c50d01307d658753f8d47f4e8555a6fa9Ulrich Weigand Modifier = MCSymbolRefExpr::VK_PPC_LO; 99edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand break; 100d2849572463da994c685b3bd7a60d5a7566c01e3Ulrich Weigand case VK_PPC_HI: 101d2849572463da994c685b3bd7a60d5a7566c01e3Ulrich Weigand Modifier = MCSymbolRefExpr::VK_PPC_HI; 102d2849572463da994c685b3bd7a60d5a7566c01e3Ulrich Weigand break; 10392cfa61c50d01307d658753f8d47f4e8555a6fa9Ulrich Weigand case VK_PPC_HA: 10492cfa61c50d01307d658753f8d47f4e8555a6fa9Ulrich Weigand Modifier = MCSymbolRefExpr::VK_PPC_HA; 105edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand break; 106f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand case VK_PPC_HIGHERA: 107f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand Modifier = MCSymbolRefExpr::VK_PPC_HIGHERA; 108f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand break; 109f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand case VK_PPC_HIGHER: 110f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand Modifier = MCSymbolRefExpr::VK_PPC_HIGHER; 111f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand break; 112f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand case VK_PPC_HIGHEST: 113f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand Modifier = MCSymbolRefExpr::VK_PPC_HIGHEST; 114f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand break; 115f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand case VK_PPC_HIGHESTA: 116f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand Modifier = MCSymbolRefExpr::VK_PPC_HIGHESTA; 117f7c1ee79fe90353fcd3f545f9d45a01a837bbf4bUlrich Weigand break; 118edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand } 119edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand Sym = MCSymbolRefExpr::Create(&Sym->getSymbol(), Modifier, Context); 120edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand Res = MCValue::get(Sym, Value.getSymB(), Value.getConstant()); 121edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand } 122edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand 123edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand return true; 124edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand} 125edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand 126edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand// FIXME: This basically copies MCObjectStreamer::AddValueSymbols. Perhaps 127edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand// that method should be made public? 128edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigandstatic void AddValueSymbols_(const MCExpr *Value, MCAssembler *Asm) { 129edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand switch (Value->getKind()) { 130edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand case MCExpr::Target: 131edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand llvm_unreachable("Can't handle nested target expr!"); 132edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand 133edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand case MCExpr::Constant: 134edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand break; 135edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand 136edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand case MCExpr::Binary: { 137edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value); 138edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand AddValueSymbols_(BE->getLHS(), Asm); 139edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand AddValueSymbols_(BE->getRHS(), Asm); 140edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand break; 141edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand } 142edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand 143edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand case MCExpr::SymbolRef: 144edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand Asm->getOrCreateSymbolData(cast<MCSymbolRefExpr>(Value)->getSymbol()); 145edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand break; 146edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand 147edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand case MCExpr::Unary: 148edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand AddValueSymbols_(cast<MCUnaryExpr>(Value)->getSubExpr(), Asm); 149edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand break; 150edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand } 151edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand} 152edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand 153edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigandvoid PPCMCExpr::AddValueSymbols(MCAssembler *Asm) const { 154edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand AddValueSymbols_(getSubExpr(), Asm); 155edaa58ee66699b99841ee5dfdd485aedbae3bf90Ulrich Weigand} 156