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 24using namespace llvm; 25 26#define DEBUG_TYPE "mipsmcexpr" 27 28const MipsMCExpr *MipsMCExpr::create(MipsMCExpr::MipsExprKind Kind, 29 const MCExpr *Expr, MCContext &Ctx) { 30 return new (Ctx) MipsMCExpr(Kind, Expr); 31} 32 33const 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 38void 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 128bool 129MipsMCExpr::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 211void MipsMCExpr::visitUsedExpr(MCStreamer &Streamer) const { 212 Streamer.visitUsedExpr(*getSubExpr()); 213} 214 215static 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 241void 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:
| 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 24using namespace llvm; 25 26#define DEBUG_TYPE "mipsmcexpr" 27 28const MipsMCExpr *MipsMCExpr::create(MipsMCExpr::MipsExprKind Kind, 29 const MCExpr *Expr, MCContext &Ctx) { 30 return new (Ctx) MipsMCExpr(Kind, Expr); 31} 32 33const 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 38void 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 128bool 129MipsMCExpr::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 211void MipsMCExpr::visitUsedExpr(MCStreamer &Streamer) const { 212 Streamer.visitUsedExpr(*getSubExpr()); 213} 214 215static 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 241void 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:
|