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 "PPCFixupKinds.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_HIGH: OS << "@high"; break; 48 case VK_PPC_HIGHA: OS << "@higha"; break; 49 case VK_PPC_HIGHER: OS << "@higher"; break; 50 case VK_PPC_HIGHERA: OS << "@highera"; break; 51 case VK_PPC_HIGHEST: OS << "@highest"; break; 52 case VK_PPC_HIGHESTA: OS << "@highesta"; break; 53 } 54 } 55 } 56 57 bool 58 PPCMCExpr::evaluateAsConstant(int64_t &Res) const { 59 MCValue Value; 60 61 if (!getSubExpr()->evaluateAsRelocatable(Value, nullptr, nullptr)) 62 return false; 63 64 if (!Value.isAbsolute()) 65 return false; 66 67 Res = evaluateAsInt64(Value.getConstant()); 68 return true; 69 } 70 71 int64_t 72 PPCMCExpr::evaluateAsInt64(int64_t Value) const { 73 switch (Kind) { 74 case VK_PPC_LO: 75 return Value & 0xffff; 76 case VK_PPC_HI: 77 return (Value >> 16) & 0xffff; 78 case VK_PPC_HA: 79 return ((Value + 0x8000) >> 16) & 0xffff; 80 case VK_PPC_HIGH: 81 return (Value >> 16) & 0xffff; 82 case VK_PPC_HIGHA: 83 return ((Value + 0x8000) >> 16) & 0xffff; 84 case VK_PPC_HIGHER: 85 return (Value >> 32) & 0xffff; 86 case VK_PPC_HIGHERA: 87 return ((Value + 0x8000) >> 32) & 0xffff; 88 case VK_PPC_HIGHEST: 89 return (Value >> 48) & 0xffff; 90 case VK_PPC_HIGHESTA: 91 return ((Value + 0x8000) >> 48) & 0xffff; 92 case VK_PPC_None: 93 break; 94 } 95 llvm_unreachable("Invalid kind!"); 96 } 97 98 bool 99 PPCMCExpr::evaluateAsRelocatableImpl(MCValue &Res, 100 const MCAsmLayout *Layout, 101 const MCFixup *Fixup) const { 102 MCValue Value; 103 104 if (!getSubExpr()->evaluateAsRelocatable(Value, Layout, Fixup)) 105 return false; 106 107 if (Value.isAbsolute()) { 108 int64_t Result = evaluateAsInt64(Value.getConstant()); 109 if ((Fixup == nullptr || (unsigned)Fixup->getKind() != PPC::fixup_ppc_half16) && 110 (Result >= 0x8000)) 111 return false; 112 Res = MCValue::get(Result); 113 } else { 114 if (!Layout) 115 return false; 116 117 MCContext &Context = Layout->getAssembler().getContext(); 118 const MCSymbolRefExpr *Sym = Value.getSymA(); 119 MCSymbolRefExpr::VariantKind Modifier = Sym->getKind(); 120 if (Modifier != MCSymbolRefExpr::VK_None) 121 return false; 122 switch (Kind) { 123 default: 124 llvm_unreachable("Invalid kind!"); 125 case VK_PPC_LO: 126 Modifier = MCSymbolRefExpr::VK_PPC_LO; 127 break; 128 case VK_PPC_HI: 129 Modifier = MCSymbolRefExpr::VK_PPC_HI; 130 break; 131 case VK_PPC_HA: 132 Modifier = MCSymbolRefExpr::VK_PPC_HA; 133 break; 134 case VK_PPC_HIGH: 135 Modifier = MCSymbolRefExpr::VK_PPC_HIGH; 136 break; 137 case VK_PPC_HIGHA: 138 Modifier = MCSymbolRefExpr::VK_PPC_HIGHA; 139 break; 140 case VK_PPC_HIGHERA: 141 Modifier = MCSymbolRefExpr::VK_PPC_HIGHERA; 142 break; 143 case VK_PPC_HIGHER: 144 Modifier = MCSymbolRefExpr::VK_PPC_HIGHER; 145 break; 146 case VK_PPC_HIGHEST: 147 Modifier = MCSymbolRefExpr::VK_PPC_HIGHEST; 148 break; 149 case VK_PPC_HIGHESTA: 150 Modifier = MCSymbolRefExpr::VK_PPC_HIGHESTA; 151 break; 152 } 153 Sym = MCSymbolRefExpr::create(&Sym->getSymbol(), Modifier, Context); 154 Res = MCValue::get(Sym, Value.getSymB(), Value.getConstant()); 155 } 156 157 return true; 158 } 159 160 void PPCMCExpr::visitUsedExpr(MCStreamer &Streamer) const { 161 Streamer.visitUsedExpr(*getSubExpr()); 162 } 163