1 //===-- MipsMCExpr.cpp - Mips 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 "MipsMCExpr.h" 11 #include "llvm/BinaryFormat/ELF.h" 12 #include "llvm/MC/MCAsmInfo.h" 13 #include "llvm/MC/MCAssembler.h" 14 #include "llvm/MC/MCContext.h" 15 #include "llvm/MC/MCStreamer.h" 16 #include "llvm/MC/MCSymbolELF.h" 17 #include "llvm/MC/MCValue.h" 18 #include "llvm/Support/Casting.h" 19 #include "llvm/Support/ErrorHandling.h" 20 #include "llvm/Support/MathExtras.h" 21 #include "llvm/Support/raw_ostream.h" 22 #include <cstdint> 23 24 using namespace llvm; 25 26 #define DEBUG_TYPE "mipsmcexpr" 27 28 const MipsMCExpr *MipsMCExpr::create(MipsMCExpr::MipsExprKind Kind, 29 const MCExpr *Expr, MCContext &Ctx) { 30 return new (Ctx) MipsMCExpr(Kind, Expr); 31 } 32 33 const MipsMCExpr *MipsMCExpr::createGpOff(MipsMCExpr::MipsExprKind Kind, 34 const MCExpr *Expr, MCContext &Ctx) { 35 return create(Kind, create(MEK_NEG, create(MEK_GPREL, Expr, Ctx), Ctx), Ctx); 36 } 37 38 void MipsMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const { 39 int64_t AbsVal; 40 41 switch (Kind) { 42 case MEK_None: 43 case MEK_Special: 44 llvm_unreachable("MEK_None and MEK_Special are invalid"); 45 break; 46 case MEK_CALL_HI16: 47 OS << "%call_hi"; 48 break; 49 case MEK_CALL_LO16: 50 OS << "%call_lo"; 51 break; 52 case MEK_DTPREL_HI: 53 OS << "%dtprel_hi"; 54 break; 55 case MEK_DTPREL_LO: 56 OS << "%dtprel_lo"; 57 break; 58 case MEK_GOT: 59 OS << "%got"; 60 break; 61 case MEK_GOTTPREL: 62 OS << "%gottprel"; 63 break; 64 case MEK_GOT_CALL: 65 OS << "%call16"; 66 break; 67 case MEK_GOT_DISP: 68 OS << "%got_disp"; 69 break; 70 case MEK_GOT_HI16: 71 OS << "%got_hi"; 72 break; 73 case MEK_GOT_LO16: 74 OS << "%got_lo"; 75 break; 76 case MEK_GOT_PAGE: 77 OS << "%got_page"; 78 break; 79 case MEK_GOT_OFST: 80 OS << "%got_ofst"; 81 break; 82 case MEK_GPREL: 83 OS << "%gp_rel"; 84 break; 85 case MEK_HI: 86 OS << "%hi"; 87 break; 88 case MEK_HIGHER: 89 OS << "%higher"; 90 break; 91 case MEK_HIGHEST: 92 OS << "%highest"; 93 break; 94 case MEK_LO: 95 OS << "%lo"; 96 break; 97 case MEK_NEG: 98 OS << "%neg"; 99 break; 100 case MEK_PCREL_HI16: 101 OS << "%pcrel_hi"; 102 break; 103 case MEK_PCREL_LO16: 104 OS << "%pcrel_lo"; 105 break; 106 case MEK_TLSGD: 107 OS << "%tlsgd"; 108 break; 109 case MEK_TLSLDM: 110 OS << "%tlsldm"; 111 break; 112 case MEK_TPREL_HI: 113 OS << "%tprel_hi"; 114 break; 115 case MEK_TPREL_LO: 116 OS << "%tprel_lo"; 117 break; 118 } 119 120 OS << '('; 121 if (Expr->evaluateAsAbsolute(AbsVal)) 122 OS << AbsVal; 123 else 124 Expr->print(OS, MAI, true); 125 OS << ')'; 126 } 127 128 bool 129 MipsMCExpr::evaluateAsRelocatableImpl(MCValue &Res, 130 const MCAsmLayout *Layout, 131 const MCFixup *Fixup) const { 132 // Look for the %hi(%neg(%gp_rel(X))) and %lo(%neg(%gp_rel(X))) special cases. 133 if (isGpOff()) { 134 const MCExpr *SubExpr = 135 cast<MipsMCExpr>(cast<MipsMCExpr>(getSubExpr())->getSubExpr()) 136 ->getSubExpr(); 137 if (!SubExpr->evaluateAsRelocatable(Res, Layout, Fixup)) 138 return false; 139 140 Res = MCValue::get(Res.getSymA(), Res.getSymB(), Res.getConstant(), 141 MEK_Special); 142 return true; 143 } 144 145 if (!getSubExpr()->evaluateAsRelocatable(Res, Layout, Fixup)) 146 return false; 147 148 if (Res.getRefKind() != MCSymbolRefExpr::VK_None) 149 return false; 150 151 // evaluateAsAbsolute() and evaluateAsValue() require that we evaluate the 152 // %hi/%lo/etc. here. Fixup is a null pointer when either of these is the 153 // caller. 154 if (Res.isAbsolute() && Fixup == nullptr) { 155 int64_t AbsVal = Res.getConstant(); 156 switch (Kind) { 157 case MEK_None: 158 case MEK_Special: 159 llvm_unreachable("MEK_None and MEK_Special are invalid"); 160 case MEK_DTPREL_HI: 161 case MEK_DTPREL_LO: 162 case MEK_GOT: 163 case MEK_GOTTPREL: 164 case MEK_GOT_CALL: 165 case MEK_GOT_DISP: 166 case MEK_GOT_HI16: 167 case MEK_GOT_LO16: 168 case MEK_GOT_OFST: 169 case MEK_GOT_PAGE: 170 case MEK_GPREL: 171 case MEK_PCREL_HI16: 172 case MEK_PCREL_LO16: 173 case MEK_TLSGD: 174 case MEK_TLSLDM: 175 case MEK_TPREL_HI: 176 case MEK_TPREL_LO: 177 return false; 178 case MEK_LO: 179 case MEK_CALL_LO16: 180 AbsVal = SignExtend64<16>(AbsVal); 181 break; 182 case MEK_CALL_HI16: 183 case MEK_HI: 184 AbsVal = SignExtend64<16>((AbsVal + 0x8000) >> 16); 185 break; 186 case MEK_HIGHER: 187 AbsVal = SignExtend64<16>((AbsVal + 0x80008000LL) >> 32); 188 break; 189 case MEK_HIGHEST: 190 AbsVal = SignExtend64<16>((AbsVal + 0x800080008000LL) >> 48); 191 break; 192 case MEK_NEG: 193 AbsVal = -AbsVal; 194 break; 195 } 196 Res = MCValue::get(AbsVal); 197 return true; 198 } 199 200 // We want to defer it for relocatable expressions since the constant is 201 // applied to the whole symbol value. 202 // 203 // The value of getKind() that is given to MCValue is only intended to aid 204 // debugging when inspecting MCValue objects. It shouldn't be relied upon 205 // for decision making. 206 Res = MCValue::get(Res.getSymA(), Res.getSymB(), Res.getConstant(), getKind()); 207 208 return true; 209 } 210 211 void MipsMCExpr::visitUsedExpr(MCStreamer &Streamer) const { 212 Streamer.visitUsedExpr(*getSubExpr()); 213 } 214 215 static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) { 216 switch (Expr->getKind()) { 217 case MCExpr::Target: 218 fixELFSymbolsInTLSFixupsImpl(cast<MipsMCExpr>(Expr)->getSubExpr(), Asm); 219 break; 220 case MCExpr::Constant: 221 break; 222 case MCExpr::Binary: { 223 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr); 224 fixELFSymbolsInTLSFixupsImpl(BE->getLHS(), Asm); 225 fixELFSymbolsInTLSFixupsImpl(BE->getRHS(), Asm); 226 break; 227 } 228 case MCExpr::SymbolRef: { 229 // We're known to be under a TLS fixup, so any symbol should be 230 // modified. There should be only one. 231 const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr); 232 cast<MCSymbolELF>(SymRef.getSymbol()).setType(ELF::STT_TLS); 233 break; 234 } 235 case MCExpr::Unary: 236 fixELFSymbolsInTLSFixupsImpl(cast<MCUnaryExpr>(Expr)->getSubExpr(), Asm); 237 break; 238 } 239 } 240 241 void MipsMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const { 242 switch (getKind()) { 243 case MEK_None: 244 case MEK_Special: 245 llvm_unreachable("MEK_None and MEK_Special are invalid"); 246 break; 247 case MEK_CALL_HI16: 248 case MEK_CALL_LO16: 249 case MEK_DTPREL_HI: 250 case MEK_DTPREL_LO: 251 case MEK_GOT: 252 case MEK_GOT_CALL: 253 case MEK_GOT_DISP: 254 case MEK_GOT_HI16: 255 case MEK_GOT_LO16: 256 case MEK_GOT_OFST: 257 case MEK_GOT_PAGE: 258 case MEK_GPREL: 259 case MEK_HI: 260 case MEK_HIGHER: 261 case MEK_HIGHEST: 262 case MEK_LO: 263 case MEK_NEG: 264 case MEK_PCREL_HI16: 265 case MEK_PCREL_LO16: 266 case MEK_TLSLDM: 267 // If we do have nested target-specific expressions, they will be in 268 // a consecutive chain. 269 if (const MipsMCExpr *E = dyn_cast<const MipsMCExpr>(getSubExpr())) 270 E->fixELFSymbolsInTLSFixups(Asm); 271 break; 272 case MEK_GOTTPREL: 273 case MEK_TLSGD: 274 case MEK_TPREL_HI: 275 case MEK_TPREL_LO: 276 fixELFSymbolsInTLSFixupsImpl(getSubExpr(), Asm); 277 break; 278 } 279 } 280 281 bool MipsMCExpr::isGpOff(MipsExprKind &Kind) const { 282 if (getKind() == MEK_HI || getKind() == MEK_LO) { 283 if (const MipsMCExpr *S1 = dyn_cast<const MipsMCExpr>(getSubExpr())) { 284 if (const MipsMCExpr *S2 = dyn_cast<const MipsMCExpr>(S1->getSubExpr())) { 285 if (S1->getKind() == MEK_NEG && S2->getKind() == MEK_GPREL) { 286 Kind = getKind(); 287 return true; 288 } 289 } 290 } 291 } 292 return false; 293 } 294