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