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 #include "llvm/MC/MCObjectStreamer.h" 15 16 using namespace llvm; 17 18 #define DEBUG_TYPE "ppcmcexpr" 19 20 const PPCMCExpr* 21 PPCMCExpr::Create(VariantKind Kind, const MCExpr *Expr, 22 bool isDarwin, MCContext &Ctx) { 23 return new (Ctx) PPCMCExpr(Kind, Expr, isDarwin); 24 } 25 26 void PPCMCExpr::PrintImpl(raw_ostream &OS) const { 27 if (isDarwinSyntax()) { 28 switch (Kind) { 29 default: llvm_unreachable("Invalid kind!"); 30 case VK_PPC_LO: OS << "lo16"; break; 31 case VK_PPC_HI: OS << "hi16"; break; 32 case VK_PPC_HA: OS << "ha16"; break; 33 } 34 35 OS << '('; 36 getSubExpr()->print(OS); 37 OS << ')'; 38 } else { 39 getSubExpr()->print(OS); 40 41 switch (Kind) { 42 default: llvm_unreachable("Invalid kind!"); 43 case VK_PPC_LO: OS << "@l"; break; 44 case VK_PPC_HI: OS << "@h"; break; 45 case VK_PPC_HA: OS << "@ha"; break; 46 case VK_PPC_HIGHER: OS << "@higher"; break; 47 case VK_PPC_HIGHERA: OS << "@highera"; break; 48 case VK_PPC_HIGHEST: OS << "@highest"; break; 49 case VK_PPC_HIGHESTA: OS << "@highesta"; break; 50 } 51 } 52 } 53 54 bool 55 PPCMCExpr::EvaluateAsRelocatableImpl(MCValue &Res, 56 const MCAsmLayout *Layout, 57 const MCFixup *Fixup) const { 58 MCValue Value; 59 60 if (!getSubExpr()->EvaluateAsRelocatable(Value, Layout, Fixup)) 61 return false; 62 63 if (Value.isAbsolute()) { 64 int64_t Result = Value.getConstant(); 65 switch (Kind) { 66 default: 67 llvm_unreachable("Invalid kind!"); 68 case VK_PPC_LO: 69 Result = Result & 0xffff; 70 break; 71 case VK_PPC_HI: 72 Result = (Result >> 16) & 0xffff; 73 break; 74 case VK_PPC_HA: 75 Result = ((Result + 0x8000) >> 16) & 0xffff; 76 break; 77 case VK_PPC_HIGHER: 78 Result = (Result >> 32) & 0xffff; 79 break; 80 case VK_PPC_HIGHERA: 81 Result = ((Result + 0x8000) >> 32) & 0xffff; 82 break; 83 case VK_PPC_HIGHEST: 84 Result = (Result >> 48) & 0xffff; 85 break; 86 case VK_PPC_HIGHESTA: 87 Result = ((Result + 0x8000) >> 48) & 0xffff; 88 break; 89 } 90 Res = MCValue::get(Result); 91 } else { 92 if (!Layout) 93 return false; 94 95 MCContext &Context = Layout->getAssembler().getContext(); 96 const MCSymbolRefExpr *Sym = Value.getSymA(); 97 MCSymbolRefExpr::VariantKind Modifier = Sym->getKind(); 98 if (Modifier != MCSymbolRefExpr::VK_None) 99 return false; 100 switch (Kind) { 101 default: 102 llvm_unreachable("Invalid kind!"); 103 case VK_PPC_LO: 104 Modifier = MCSymbolRefExpr::VK_PPC_LO; 105 break; 106 case VK_PPC_HI: 107 Modifier = MCSymbolRefExpr::VK_PPC_HI; 108 break; 109 case VK_PPC_HA: 110 Modifier = MCSymbolRefExpr::VK_PPC_HA; 111 break; 112 case VK_PPC_HIGHERA: 113 Modifier = MCSymbolRefExpr::VK_PPC_HIGHERA; 114 break; 115 case VK_PPC_HIGHER: 116 Modifier = MCSymbolRefExpr::VK_PPC_HIGHER; 117 break; 118 case VK_PPC_HIGHEST: 119 Modifier = MCSymbolRefExpr::VK_PPC_HIGHEST; 120 break; 121 case VK_PPC_HIGHESTA: 122 Modifier = MCSymbolRefExpr::VK_PPC_HIGHESTA; 123 break; 124 } 125 Sym = MCSymbolRefExpr::Create(&Sym->getSymbol(), Modifier, Context); 126 Res = MCValue::get(Sym, Value.getSymB(), Value.getConstant()); 127 } 128 129 return true; 130 } 131 132 void PPCMCExpr::visitUsedExpr(MCStreamer &Streamer) const { 133 Streamer.visitUsedExpr(*getSubExpr()); 134 } 135