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