PPCMCExpr.cpp revision dce4a407a24b04eebc6a376f8e62b41aaa7b071f
1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//===-- PPCMCExpr.cpp - PPC specific MC expression classes ----------------===// 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// The LLVM Compiler Infrastructure 4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// This file is distributed under the University of Illinois Open Source 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// License. See LICENSE.TXT for details. 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown//===----------------------------------------------------------------------===// 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 10436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "PPCMCExpr.h" 11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "llvm/MC/MCAsmInfo.h" 12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "llvm/MC/MCAssembler.h" 13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "llvm/MC/MCContext.h" 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownusing namespace llvm; 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define DEBUG_TYPE "ppcmcexpr" 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownconst PPCMCExpr* 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPPCMCExpr::Create(VariantKind Kind, const MCExpr *Expr, 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bool isDarwin, MCContext &Ctx) { 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return new (Ctx) PPCMCExpr(Kind, Expr, isDarwin); 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid PPCMCExpr::PrintImpl(raw_ostream &OS) const { 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isDarwinSyntax()) { 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (Kind) { 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: llvm_unreachable("Invalid kind!"); 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VK_PPC_LO: OS << "lo16"; break; 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VK_PPC_HI: OS << "hi16"; break; 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VK_PPC_HA: OS << "ha16"; break; 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown OS << '('; 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown getSubExpr()->print(OS); 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown OS << ')'; 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown getSubExpr()->print(OS); 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (Kind) { 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: llvm_unreachable("Invalid kind!"); 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VK_PPC_LO: OS << "@l"; break; 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VK_PPC_HI: OS << "@h"; break; 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VK_PPC_HA: OS << "@ha"; break; 45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VK_PPC_HIGHER: OS << "@higher"; break; 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VK_PPC_HIGHERA: OS << "@highera"; break; 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VK_PPC_HIGHEST: OS << "@highest"; break; 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VK_PPC_HIGHESTA: OS << "@highesta"; break; 49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownbool 54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownPPCMCExpr::EvaluateAsRelocatableImpl(MCValue &Res, 55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const MCAsmLayout *Layout) const { 56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MCValue Value; 57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!getSubExpr()->EvaluateAsRelocatable(Value, Layout)) 59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return false; 60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (Value.isAbsolute()) { 62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int64_t Result = Value.getConstant(); 63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (Kind) { 64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown llvm_unreachable("Invalid kind!"); 66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VK_PPC_LO: 67436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Result = Result & 0xffff; 68436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VK_PPC_HI: 70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Result = (Result >> 16) & 0xffff; 71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VK_PPC_HA: 73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Result = ((Result + 0x8000) >> 16) & 0xffff; 74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VK_PPC_HIGHER: 76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Result = (Result >> 32) & 0xffff; 77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VK_PPC_HIGHERA: 79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Result = ((Result + 0x8000) >> 32) & 0xffff; 80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VK_PPC_HIGHEST: 82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Result = (Result >> 48) & 0xffff; 83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VK_PPC_HIGHESTA: 85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Result = ((Result + 0x8000) >> 48) & 0xffff; 86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Res = MCValue::get(Result); 89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!Layout) 91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return false; 92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MCContext &Context = Layout->getAssembler().getContext(); 94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const MCSymbolRefExpr *Sym = Value.getSymA(); 95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MCSymbolRefExpr::VariantKind Modifier = Sym->getKind(); 96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (Modifier != MCSymbolRefExpr::VK_None) 97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return false; 98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (Kind) { 99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown llvm_unreachable("Invalid kind!"); 101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VK_PPC_LO: 102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Modifier = MCSymbolRefExpr::VK_PPC_LO; 103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VK_PPC_HI: 105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Modifier = MCSymbolRefExpr::VK_PPC_HI; 106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VK_PPC_HA: 108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Modifier = MCSymbolRefExpr::VK_PPC_HA; 109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VK_PPC_HIGHERA: 111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Modifier = MCSymbolRefExpr::VK_PPC_HIGHERA; 112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VK_PPC_HIGHER: 114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Modifier = MCSymbolRefExpr::VK_PPC_HIGHER; 115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VK_PPC_HIGHEST: 117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Modifier = MCSymbolRefExpr::VK_PPC_HIGHEST; 118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case VK_PPC_HIGHESTA: 120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Modifier = MCSymbolRefExpr::VK_PPC_HIGHESTA; 121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Sym = MCSymbolRefExpr::Create(&Sym->getSymbol(), Modifier, Context); 124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Res = MCValue::get(Sym, Value.getSymB(), Value.getConstant()); 125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return true; 128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// FIXME: This basically copies MCObjectStreamer::AddValueSymbols. Perhaps 131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// that method should be made public? 132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void AddValueSymbols_(const MCExpr *Value, MCAssembler *Asm) { 133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (Value->getKind()) { 134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case MCExpr::Target: 135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown llvm_unreachable("Can't handle nested target expr!"); 136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case MCExpr::Constant: 138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case MCExpr::Binary: { 141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value); 142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AddValueSymbols_(BE->getLHS(), Asm); 143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AddValueSymbols_(BE->getRHS(), Asm); 144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case MCExpr::SymbolRef: 148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Asm->getOrCreateSymbolData(cast<MCSymbolRefExpr>(Value)->getSymbol()); 149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case MCExpr::Unary: 152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AddValueSymbols_(cast<MCUnaryExpr>(Value)->getSubExpr(), Asm); 153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid PPCMCExpr::AddValueSymbols(MCAssembler *Asm) const { 158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AddValueSymbols_(getSubExpr(), Asm); 159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown