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