1 //===-- SparcMCExpr.cpp - Sparc 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 // This file contains the implementation of the assembly expression modifiers 11 // accepted by the Sparc architecture (e.g. "%hi", "%lo", ...). 12 // 13 //===----------------------------------------------------------------------===// 14 15 #define DEBUG_TYPE "sparcmcexpr" 16 #include "SparcMCExpr.h" 17 #include "llvm/MC/MCAssembler.h" 18 #include "llvm/MC/MCContext.h" 19 #include "llvm/MC/MCELF.h" 20 #include "llvm/Object/ELF.h" 21 22 23 using namespace llvm; 24 25 const SparcMCExpr* 26 SparcMCExpr::Create(VariantKind Kind, const MCExpr *Expr, 27 MCContext &Ctx) { 28 return new (Ctx) SparcMCExpr(Kind, Expr); 29 } 30 31 32 void SparcMCExpr::PrintImpl(raw_ostream &OS) const 33 { 34 bool closeParen = true; 35 switch (Kind) { 36 case VK_Sparc_None: closeParen = false; break; 37 case VK_Sparc_LO: OS << "%lo("; break; 38 case VK_Sparc_HI: OS << "%hi("; break; 39 case VK_Sparc_H44: OS << "%h44("; break; 40 case VK_Sparc_M44: OS << "%m44("; break; 41 case VK_Sparc_L44: OS << "%l44("; break; 42 case VK_Sparc_HH: OS << "%hh("; break; 43 case VK_Sparc_HM: OS << "%hm("; break; 44 case VK_Sparc_R_DISP32: OS << "%r_disp32("; break; 45 case VK_Sparc_TLS_GD_HI22: OS << "%tgd_hi22("; break; 46 case VK_Sparc_TLS_GD_LO10: OS << "%tgd_lo10("; break; 47 case VK_Sparc_TLS_GD_ADD: OS << "%tgd_add("; break; 48 case VK_Sparc_TLS_GD_CALL: OS << "%tgd_call("; break; 49 case VK_Sparc_TLS_LDM_HI22: OS << "%tldm_hi22("; break; 50 case VK_Sparc_TLS_LDM_LO10: OS << "%tldm_lo10("; break; 51 case VK_Sparc_TLS_LDM_ADD: OS << "%tldm_add("; break; 52 case VK_Sparc_TLS_LDM_CALL: OS << "%tldm_call("; break; 53 case VK_Sparc_TLS_LDO_HIX22: OS << "%tldo_hix22("; break; 54 case VK_Sparc_TLS_LDO_LOX10: OS << "%tldo_lox10("; break; 55 case VK_Sparc_TLS_LDO_ADD: OS << "%tldo_add("; break; 56 case VK_Sparc_TLS_IE_HI22: OS << "%tie_hi22("; break; 57 case VK_Sparc_TLS_IE_LO10: OS << "%tie_lo10("; break; 58 case VK_Sparc_TLS_IE_LD: OS << "%tie_ld("; break; 59 case VK_Sparc_TLS_IE_LDX: OS << "%tie_ldx("; break; 60 case VK_Sparc_TLS_IE_ADD: OS << "%tie_add("; break; 61 case VK_Sparc_TLS_LE_HIX22: OS << "%tle_hix22("; break; 62 case VK_Sparc_TLS_LE_LOX10: OS << "%tle_lox10("; break; 63 } 64 65 const MCExpr *Expr = getSubExpr(); 66 Expr->print(OS); 67 if (closeParen) 68 OS << ')'; 69 } 70 71 SparcMCExpr::VariantKind SparcMCExpr::parseVariantKind(StringRef name) 72 { 73 return StringSwitch<SparcMCExpr::VariantKind>(name) 74 .Case("lo", VK_Sparc_LO) 75 .Case("hi", VK_Sparc_HI) 76 .Case("h44", VK_Sparc_H44) 77 .Case("m44", VK_Sparc_M44) 78 .Case("l44", VK_Sparc_L44) 79 .Case("hh", VK_Sparc_HH) 80 .Case("hm", VK_Sparc_HM) 81 .Case("r_disp32", VK_Sparc_R_DISP32) 82 .Case("tgd_hi22", VK_Sparc_TLS_GD_HI22) 83 .Case("tgd_lo10", VK_Sparc_TLS_GD_LO10) 84 .Case("tgd_add", VK_Sparc_TLS_GD_ADD) 85 .Case("tgd_call", VK_Sparc_TLS_GD_CALL) 86 .Case("tldm_hi22", VK_Sparc_TLS_LDM_HI22) 87 .Case("tldm_lo10", VK_Sparc_TLS_LDM_LO10) 88 .Case("tldm_add", VK_Sparc_TLS_LDM_ADD) 89 .Case("tldm_call", VK_Sparc_TLS_LDM_CALL) 90 .Case("tldo_hix22", VK_Sparc_TLS_LDO_HIX22) 91 .Case("tldo_lox10", VK_Sparc_TLS_LDO_LOX10) 92 .Case("tldo_add", VK_Sparc_TLS_LDO_ADD) 93 .Case("tie_hi22", VK_Sparc_TLS_IE_HI22) 94 .Case("tie_lo10", VK_Sparc_TLS_IE_LO10) 95 .Case("tie_ld", VK_Sparc_TLS_IE_LD) 96 .Case("tie_ldx", VK_Sparc_TLS_IE_LDX) 97 .Case("tie_add", VK_Sparc_TLS_IE_ADD) 98 .Case("tle_hix22", VK_Sparc_TLS_LE_HIX22) 99 .Case("tle_lox10", VK_Sparc_TLS_LE_LOX10) 100 .Default(VK_Sparc_None); 101 } 102 103 bool 104 SparcMCExpr::EvaluateAsRelocatableImpl(MCValue &Res, 105 const MCAsmLayout *Layout) const { 106 if (!Layout) 107 return false; 108 return getSubExpr()->EvaluateAsRelocatable(Res, *Layout); 109 } 110 111 static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) { 112 assert(0 && "Implement fixELFSymbolsInTLSFixupsImpl!"); 113 } 114 115 void SparcMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const { 116 switch(getKind()) { 117 default: return; 118 case VK_Sparc_TLS_GD_HI22: 119 case VK_Sparc_TLS_GD_LO10: 120 case VK_Sparc_TLS_GD_ADD: 121 case VK_Sparc_TLS_GD_CALL: 122 case VK_Sparc_TLS_LDM_HI22: 123 case VK_Sparc_TLS_LDM_LO10: 124 case VK_Sparc_TLS_LDM_ADD: 125 case VK_Sparc_TLS_LDM_CALL: 126 case VK_Sparc_TLS_LDO_HIX22: 127 case VK_Sparc_TLS_LDO_LOX10: 128 case VK_Sparc_TLS_LDO_ADD: 129 case VK_Sparc_TLS_IE_HI22: 130 case VK_Sparc_TLS_IE_LO10: 131 case VK_Sparc_TLS_IE_LD: 132 case VK_Sparc_TLS_IE_LDX: 133 case VK_Sparc_TLS_IE_ADD: 134 case VK_Sparc_TLS_LE_HIX22: 135 case VK_Sparc_TLS_LE_LOX10: break; 136 } 137 fixELFSymbolsInTLSFixupsImpl(getSubExpr(), Asm); 138 } 139 140 // FIXME: This basically copies MCObjectStreamer::AddValueSymbols. Perhaps 141 // that method should be made public? 142 // FIXME: really do above: now that at least three other backends are using it. 143 static void AddValueSymbolsImpl(const MCExpr *Value, MCAssembler *Asm) { 144 switch (Value->getKind()) { 145 case MCExpr::Target: 146 llvm_unreachable("Can't handle nested target expr!"); 147 break; 148 149 case MCExpr::Constant: 150 break; 151 152 case MCExpr::Binary: { 153 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value); 154 AddValueSymbolsImpl(BE->getLHS(), Asm); 155 AddValueSymbolsImpl(BE->getRHS(), Asm); 156 break; 157 } 158 159 case MCExpr::SymbolRef: 160 Asm->getOrCreateSymbolData(cast<MCSymbolRefExpr>(Value)->getSymbol()); 161 break; 162 163 case MCExpr::Unary: 164 AddValueSymbolsImpl(cast<MCUnaryExpr>(Value)->getSubExpr(), Asm); 165 break; 166 } 167 } 168 169 void SparcMCExpr::AddValueSymbols(MCAssembler *Asm) const { 170 AddValueSymbolsImpl(getSubExpr(), Asm); 171 } 172