1263320SdimPull in r200961 from upstream llvm trunk (by Venkatraman Govindaraju): 2263320Sdim 3263320Sdim [Sparc] Emit correct relocations for PIC code when integrated assembler is used. 4263320Sdim 5263320SdimIntroduced here: http://svn.freebsd.org/changeset/base/262261 6263320Sdim 7263320SdimIndex: test/CodeGen/SPARC/obj-relocs.ll 8263320Sdim=================================================================== 9263320Sdim--- test/CodeGen/SPARC/obj-relocs.ll 10263320Sdim+++ test/CodeGen/SPARC/obj-relocs.ll 11263320Sdim@@ -0,0 +1,33 @@ 12263320Sdim+; RUN: llc < %s -march=sparcv9 -filetype=obj --relocation-model=static | llvm-readobj -r | FileCheck %s --check-prefix=CHECK-ABS 13263320Sdim+; RUN: llc < %s -march=sparcv9 -filetype=obj --relocation-model=pic | llvm-readobj -r | FileCheck %s --check-prefix=CHECK-PIC 14263320Sdim+ 15263320Sdim+;CHECK-ABS: Relocations [ 16263320Sdim+;CHECK-ABS: 0x{{[0-9,A-F]+}} R_SPARC_H44 AGlobalVar 0x0 17263320Sdim+;CHECK-ABS: 0x{{[0-9,A-F]+}} R_SPARC_M44 AGlobalVar 0x0 18263320Sdim+;CHECK-ABS: 0x{{[0-9,A-F]+}} R_SPARC_L44 AGlobalVar 0x0 19263320Sdim+;CHECK-ABS: 0x{{[0-9,A-F]+}} R_SPARC_WDISP30 bar 0x0 20263320Sdim+;CHECK-ABS:] 21263320Sdim+ 22263320Sdim+; CHECK-PIC: Relocations [ 23263320Sdim+; CHECK-PIC: 0x{{[0-9,A-F]+}} R_SPARC_PC22 _GLOBAL_OFFSET_TABLE_ 0x4 24263320Sdim+; CHECK-PIC: 0x{{[0-9,A-F]+}} R_SPARC_PC10 _GLOBAL_OFFSET_TABLE_ 0x8 25263320Sdim+; CHECK-PIC: 0x{{[0-9,A-F]+}} R_SPARC_GOT22 AGlobalVar 0x0 26263320Sdim+; CHECK-PIC: 0x{{[0-9,A-F]+}} R_SPARC_GOT10 AGlobalVar 0x0 27263320Sdim+; CHECK-PIC: 0x{{[0-9,A-F]+}} R_SPARC_WPLT30 bar 0x0 28263320Sdim+; CHECK-PIC: ] 29263320Sdim+ 30263320Sdim+ 31263320Sdim+@AGlobalVar = global i64 0, align 8 32263320Sdim+ 33263320Sdim+; CHECK-ASM: sethi %h44(AGlobalVar), [[R:%[goli][0-7]]] 34263320Sdim+; CHECK-ASM: add [[R]], %m44(AGlobalVar), [[R]] 35263320Sdim+define i64 @foo(i64 %a) { 36263320Sdim+entry: 37263320Sdim+ %0 = load i64* @AGlobalVar, align 4 38263320Sdim+ %1 = add i64 %a, %0 39263320Sdim+ %2 = call i64 @bar(i64 %1) 40263320Sdim+ ret i64 %2 41263320Sdim+} 42263320Sdim+ 43263320Sdim+ 44263320Sdim+declare i64 @bar(i64) 45263320SdimIndex: lib/Target/Sparc/SparcISelLowering.cpp 46263320Sdim=================================================================== 47263320Sdim--- lib/Target/Sparc/SparcISelLowering.cpp 48263320Sdim+++ lib/Target/Sparc/SparcISelLowering.cpp 49263320Sdim@@ -895,10 +895,12 @@ SparcTargetLowering::LowerCall_32(TargetLowering:: 50263320Sdim // If the callee is a GlobalAddress node (quite common, every direct call is) 51263320Sdim // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. 52263320Sdim // Likewise ExternalSymbol -> TargetExternalSymbol. 53263320Sdim+ unsigned TF = ((getTargetMachine().getRelocationModel() == Reloc::PIC_) 54263320Sdim+ ? SparcMCExpr::VK_Sparc_WPLT30 : 0); 55263320Sdim if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) 56263320Sdim- Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i32); 57263320Sdim+ Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i32, 0, TF); 58263320Sdim else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) 59263320Sdim- Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i32); 60263320Sdim+ Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i32, TF); 61263320Sdim 62263320Sdim // Returns a chain & a flag for retval copy to use 63263320Sdim SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 64263320Sdim@@ -1209,10 +1211,13 @@ SparcTargetLowering::LowerCall_64(TargetLowering:: 65263320Sdim // Likewise ExternalSymbol -> TargetExternalSymbol. 66263320Sdim SDValue Callee = CLI.Callee; 67263320Sdim bool hasReturnsTwice = hasReturnsTwiceAttr(DAG, Callee, CLI.CS); 68263320Sdim+ unsigned TF = ((getTargetMachine().getRelocationModel() == Reloc::PIC_) 69263320Sdim+ ? SparcMCExpr::VK_Sparc_WPLT30 : 0); 70263320Sdim if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) 71263320Sdim- Callee = DAG.getTargetGlobalAddress(G->getGlobal(), DL, getPointerTy()); 72263320Sdim+ Callee = DAG.getTargetGlobalAddress(G->getGlobal(), DL, getPointerTy(), 0, 73263320Sdim+ TF); 74263320Sdim else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) 75263320Sdim- Callee = DAG.getTargetExternalSymbol(E->getSymbol(), getPointerTy()); 76263320Sdim+ Callee = DAG.getTargetExternalSymbol(E->getSymbol(), getPointerTy(), TF); 77263320Sdim 78263320Sdim // Build the operands for the call instruction itself. 79263320Sdim SmallVector<SDValue, 8> Ops; 80263320Sdim@@ -1796,8 +1801,8 @@ SDValue SparcTargetLowering::makeAddress(SDValue O 81263320Sdim // Handle PIC mode first. 82263320Sdim if (getTargetMachine().getRelocationModel() == Reloc::PIC_) { 83263320Sdim // This is the pic32 code model, the GOT is known to be smaller than 4GB. 84263320Sdim- SDValue HiLo = makeHiLoPair(Op, SparcMCExpr::VK_Sparc_HI, 85263320Sdim- SparcMCExpr::VK_Sparc_LO, DAG); 86263320Sdim+ SDValue HiLo = makeHiLoPair(Op, SparcMCExpr::VK_Sparc_GOT22, 87263320Sdim+ SparcMCExpr::VK_Sparc_GOT10, DAG); 88263320Sdim SDValue GlobalBase = DAG.getNode(SPISD::GLOBAL_BASE_REG, DL, VT); 89263320Sdim SDValue AbsAddr = DAG.getNode(ISD::ADD, DL, VT, GlobalBase, HiLo); 90263320Sdim // GLOBAL_BASE_REG codegen'ed with call. Inform MFI that this 91263320SdimIndex: lib/Target/Sparc/SparcAsmPrinter.cpp 92263320Sdim=================================================================== 93263320Sdim--- lib/Target/Sparc/SparcAsmPrinter.cpp 94263320Sdim+++ lib/Target/Sparc/SparcAsmPrinter.cpp 95263320Sdim@@ -232,12 +232,12 @@ void SparcAsmPrinter::LowerGETPCXAndEmitMCInsts(co 96263320Sdim MCOperand Callee = createPCXCallOP(EndLabel, OutContext); 97263320Sdim EmitCall(OutStreamer, Callee); 98263320Sdim OutStreamer.EmitLabel(SethiLabel); 99263320Sdim- MCOperand hiImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_HI, 100263320Sdim+ MCOperand hiImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_PC22, 101263320Sdim GOTLabel, StartLabel, SethiLabel, 102263320Sdim OutContext); 103263320Sdim EmitSETHI(OutStreamer, hiImm, MCRegOP); 104263320Sdim OutStreamer.EmitLabel(EndLabel); 105263320Sdim- MCOperand loImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_LO, 106263320Sdim+ MCOperand loImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_PC10, 107263320Sdim GOTLabel, StartLabel, EndLabel, 108263320Sdim OutContext); 109263320Sdim EmitOR(OutStreamer, MCRegOP, loImm, MCRegOP); 110263320SdimIndex: lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp 111263320Sdim=================================================================== 112263320Sdim--- lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp 113263320Sdim+++ lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp 114263320Sdim@@ -26,6 +26,7 @@ static unsigned adjustFixupValue(unsigned Kind, ui 115263320Sdim case FK_Data_4: 116263320Sdim case FK_Data_8: 117263320Sdim return Value; 118263320Sdim+ case Sparc::fixup_sparc_wplt30: 119263320Sdim case Sparc::fixup_sparc_call30: 120263320Sdim return (Value >> 2) & 0x3fffffff; 121263320Sdim case Sparc::fixup_sparc_br22: 122263320Sdim@@ -32,8 +33,12 @@ static unsigned adjustFixupValue(unsigned Kind, ui 123263320Sdim return (Value >> 2) & 0x3fffff; 124263320Sdim case Sparc::fixup_sparc_br19: 125263320Sdim return (Value >> 2) & 0x7ffff; 126263320Sdim+ case Sparc::fixup_sparc_pc22: 127263320Sdim+ case Sparc::fixup_sparc_got22: 128263320Sdim case Sparc::fixup_sparc_hi22: 129263320Sdim return (Value >> 10) & 0x3fffff; 130263320Sdim+ case Sparc::fixup_sparc_pc10: 131263320Sdim+ case Sparc::fixup_sparc_got10: 132263320Sdim case Sparc::fixup_sparc_lo10: 133263320Sdim return Value & 0x3ff; 134263320Sdim case Sparc::fixup_sparc_h44: 135263320Sdim@@ -72,6 +77,11 @@ namespace { 136263320Sdim { "fixup_sparc_l44", 20, 12, 0 }, 137263320Sdim { "fixup_sparc_hh", 10, 22, 0 }, 138263320Sdim { "fixup_sparc_hm", 22, 10, 0 }, 139263320Sdim+ { "fixup_sparc_pc22", 10, 22, MCFixupKindInfo::FKF_IsPCRel }, 140263320Sdim+ { "fixup_sparc_pc10", 22, 10, MCFixupKindInfo::FKF_IsPCRel }, 141263320Sdim+ { "fixup_sparc_got22", 10, 22, 0 }, 142263320Sdim+ { "fixup_sparc_got10", 22, 10, 0 }, 143263320Sdim+ { "fixup_sparc_wplt30", 2, 30, MCFixupKindInfo::FKF_IsPCRel } 144263320Sdim }; 145263320Sdim 146263320Sdim if (Kind < FirstTargetFixupKind) 147263320Sdim@@ -82,6 +92,20 @@ namespace { 148263320Sdim return Infos[Kind - FirstTargetFixupKind]; 149263320Sdim } 150263320Sdim 151263320Sdim+ void processFixupValue(const MCAssembler &Asm, 152263320Sdim+ const MCAsmLayout &Layout, 153263320Sdim+ const MCFixup &Fixup, 154263320Sdim+ const MCFragment *DF, 155263320Sdim+ MCValue & Target, 156263320Sdim+ uint64_t &Value, 157263320Sdim+ bool &IsResolved) { 158263320Sdim+ switch ((Sparc::Fixups)Fixup.getKind()) { 159263320Sdim+ default: break; 160263320Sdim+ case Sparc::fixup_sparc_wplt30: IsResolved = false; break; 161263320Sdim+ } 162263320Sdim+ } 163263320Sdim+ 164263320Sdim+ 165263320Sdim bool mayNeedRelaxation(const MCInst &Inst) const { 166263320Sdim // FIXME. 167263320Sdim return false; 168263320SdimIndex: lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h 169263320Sdim=================================================================== 170263320Sdim--- lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h 171263320Sdim+++ lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h 172263320Sdim@@ -48,6 +48,21 @@ namespace llvm { 173263320Sdim /// fixup_sparc_hm - 10-bit fixup corresponding to %hm(foo) 174263320Sdim fixup_sparc_hm, 175263320Sdim 176263320Sdim+ /// fixup_sparc_pc22 - 22-bit fixup corresponding to %pc22(foo) 177263320Sdim+ fixup_sparc_pc22, 178263320Sdim+ 179263320Sdim+ /// fixup_sparc_pc10 - 10-bit fixup corresponding to %pc10(foo) 180263320Sdim+ fixup_sparc_pc10, 181263320Sdim+ 182263320Sdim+ /// fixup_sparc_got22 - 22-bit fixup corresponding to %got22(foo) 183263320Sdim+ fixup_sparc_got22, 184263320Sdim+ 185263320Sdim+ /// fixup_sparc_got10 - 10-bit fixup corresponding to %got10(foo) 186263320Sdim+ fixup_sparc_got10, 187263320Sdim+ 188263320Sdim+ /// fixup_sparc_wplt30 189263320Sdim+ fixup_sparc_wplt30, 190263320Sdim+ 191263320Sdim // Marker 192263320Sdim LastTargetFixupKind, 193263320Sdim NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind 194263320SdimIndex: lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp 195263320Sdim=================================================================== 196263320Sdim--- lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp 197263320Sdim+++ lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp 198263320Sdim@@ -7,8 +7,9 @@ 199263320Sdim // 200263320Sdim //===----------------------------------------------------------------------===// 201263320Sdim 202263320Sdim+#include "MCTargetDesc/SparcFixupKinds.h" 203263320Sdim+#include "MCTargetDesc/SparcMCExpr.h" 204263320Sdim #include "MCTargetDesc/SparcMCTargetDesc.h" 205263320Sdim-#include "MCTargetDesc/SparcFixupKinds.h" 206263320Sdim #include "llvm/ADT/STLExtras.h" 207263320Sdim #include "llvm/MC/MCELFObjectWriter.h" 208263320Sdim #include "llvm/MC/MCExpr.h" 209263320Sdim@@ -31,6 +32,11 @@ namespace { 210263320Sdim bool IsPCRel, bool IsRelocWithSymbol, 211263320Sdim int64_t Addend) const; 212263320Sdim 213263320Sdim+ virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm, 214263320Sdim+ const MCValue &Target, 215263320Sdim+ const MCFragment &F, 216263320Sdim+ const MCFixup &Fixup, 217263320Sdim+ bool IsPCRel) const; 218263320Sdim }; 219263320Sdim } 220263320Sdim 221263320Sdim@@ -40,6 +46,12 @@ unsigned SparcELFObjectWriter::GetRelocType(const 222263320Sdim bool IsPCRel, 223263320Sdim bool IsRelocWithSymbol, 224263320Sdim int64_t Addend) const { 225263320Sdim+ 226263320Sdim+ if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(Fixup.getValue())) { 227263320Sdim+ if (SExpr->getKind() == SparcMCExpr::VK_Sparc_R_DISP32) 228263320Sdim+ return ELF::R_SPARC_DISP32; 229263320Sdim+ } 230263320Sdim+ 231263320Sdim if (IsPCRel) { 232263320Sdim switch((unsigned)Fixup.getKind()) { 233263320Sdim default: 234263320Sdim@@ -51,6 +63,9 @@ unsigned SparcELFObjectWriter::GetRelocType(const 235263320Sdim case Sparc::fixup_sparc_call30: return ELF::R_SPARC_WDISP30; 236263320Sdim case Sparc::fixup_sparc_br22: return ELF::R_SPARC_WDISP22; 237263320Sdim case Sparc::fixup_sparc_br19: return ELF::R_SPARC_WDISP19; 238263320Sdim+ case Sparc::fixup_sparc_pc22: return ELF::R_SPARC_PC22; 239263320Sdim+ case Sparc::fixup_sparc_pc10: return ELF::R_SPARC_PC10; 240263320Sdim+ case Sparc::fixup_sparc_wplt30: return ELF::R_SPARC_WPLT30; 241263320Sdim } 242263320Sdim } 243263320Sdim 244263320Sdim@@ -74,10 +89,30 @@ unsigned SparcELFObjectWriter::GetRelocType(const 245263320Sdim case Sparc::fixup_sparc_l44: return ELF::R_SPARC_L44; 246263320Sdim case Sparc::fixup_sparc_hh: return ELF::R_SPARC_HH22; 247263320Sdim case Sparc::fixup_sparc_hm: return ELF::R_SPARC_HM10; 248263320Sdim+ case Sparc::fixup_sparc_got22: return ELF::R_SPARC_GOT22; 249263320Sdim+ case Sparc::fixup_sparc_got10: return ELF::R_SPARC_GOT10; 250263320Sdim } 251263320Sdim+ 252263320Sdim return ELF::R_SPARC_NONE; 253263320Sdim } 254263320Sdim 255263320Sdim+const MCSymbol *SparcELFObjectWriter::ExplicitRelSym(const MCAssembler &Asm, 256263320Sdim+ const MCValue &Target, 257263320Sdim+ const MCFragment &F, 258263320Sdim+ const MCFixup &Fixup, 259263320Sdim+ bool IsPCRel) const { 260263320Sdim+ 261263320Sdim+ if (!Target.getSymA()) 262263320Sdim+ return NULL; 263263320Sdim+ switch((unsigned)Fixup.getKind()) { 264263320Sdim+ default: break; 265263320Sdim+ case Sparc::fixup_sparc_got22: 266263320Sdim+ case Sparc::fixup_sparc_got10: 267263320Sdim+ return &Target.getSymA()->getSymbol().AliasedSymbol(); 268263320Sdim+ } 269263320Sdim+ return NULL; 270263320Sdim+} 271263320Sdim+ 272263320Sdim MCObjectWriter *llvm::createSparcELFObjectWriter(raw_ostream &OS, 273263320Sdim bool Is64Bit, 274263320Sdim uint8_t OSABI) { 275263320SdimIndex: lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp 276263320Sdim=================================================================== 277263320Sdim--- lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp 278263320Sdim+++ lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp 279263320Sdim@@ -17,6 +17,7 @@ 280263320Sdim #include "llvm/MC/MCContext.h" 281263320Sdim #include "llvm/MC/MCAssembler.h" 282263320Sdim #include "llvm/MC/MCELF.h" 283263320Sdim+#include "llvm/MC/MCSymbol.h" 284263320Sdim #include "llvm/Object/ELF.h" 285263320Sdim 286263320Sdim 287263320Sdim@@ -54,6 +55,13 @@ bool SparcMCExpr::printVariantKind(raw_ostream &OS 288263320Sdim case VK_Sparc_L44: OS << "%l44("; break; 289263320Sdim case VK_Sparc_HH: OS << "%hh("; break; 290263320Sdim case VK_Sparc_HM: OS << "%hm("; break; 291263320Sdim+ // FIXME: use %pc22/%pc10, if system assembler supports them. 292263320Sdim+ case VK_Sparc_PC22: OS << "%hi("; break; 293263320Sdim+ case VK_Sparc_PC10: OS << "%lo("; break; 294263320Sdim+ // FIXME: use %got22/%got10, if system assembler supports them. 295263320Sdim+ case VK_Sparc_GOT22: OS << "%hi("; break; 296263320Sdim+ case VK_Sparc_GOT10: OS << "%lo("; break; 297263320Sdim+ case VK_Sparc_WPLT30: closeParen = false; break; 298263320Sdim case VK_Sparc_R_DISP32: OS << "%r_disp32("; break; 299263320Sdim case VK_Sparc_TLS_GD_HI22: OS << "%tgd_hi22("; break; 300263320Sdim case VK_Sparc_TLS_GD_LO10: OS << "%tgd_lo10("; break; 301263320Sdim@@ -87,6 +95,10 @@ SparcMCExpr::VariantKind SparcMCExpr::parseVariant 302263320Sdim .Case("l44", VK_Sparc_L44) 303263320Sdim .Case("hh", VK_Sparc_HH) 304263320Sdim .Case("hm", VK_Sparc_HM) 305263320Sdim+ .Case("pc22", VK_Sparc_PC22) 306263320Sdim+ .Case("pc10", VK_Sparc_PC10) 307263320Sdim+ .Case("got22", VK_Sparc_GOT22) 308263320Sdim+ .Case("got10", VK_Sparc_GOT10) 309263320Sdim .Case("r_disp32", VK_Sparc_R_DISP32) 310263320Sdim .Case("tgd_hi22", VK_Sparc_TLS_GD_HI22) 311263320Sdim .Case("tgd_lo10", VK_Sparc_TLS_GD_LO10) 312263320Sdim@@ -109,9 +121,26 @@ SparcMCExpr::VariantKind SparcMCExpr::parseVariant 313263320Sdim .Default(VK_Sparc_None); 314263320Sdim } 315263320Sdim 316263320Sdim+Sparc::Fixups SparcMCExpr::getFixupKind(SparcMCExpr::VariantKind Kind) { 317263320Sdim+ switch (Kind) { 318263320Sdim+ default: assert(0 && "Unhandled SparcMCExpr::VariantKind"); 319263320Sdim+ case VK_Sparc_LO: return Sparc::fixup_sparc_lo10; 320263320Sdim+ case VK_Sparc_HI: return Sparc::fixup_sparc_hi22; 321263320Sdim+ case VK_Sparc_H44: return Sparc::fixup_sparc_h44; 322263320Sdim+ case VK_Sparc_M44: return Sparc::fixup_sparc_m44; 323263320Sdim+ case VK_Sparc_L44: return Sparc::fixup_sparc_l44; 324263320Sdim+ case VK_Sparc_HH: return Sparc::fixup_sparc_hh; 325263320Sdim+ case VK_Sparc_HM: return Sparc::fixup_sparc_hm; 326263320Sdim+ case VK_Sparc_PC22: return Sparc::fixup_sparc_pc22; 327263320Sdim+ case VK_Sparc_PC10: return Sparc::fixup_sparc_pc10; 328263320Sdim+ case VK_Sparc_GOT22: return Sparc::fixup_sparc_got22; 329263320Sdim+ case VK_Sparc_GOT10: return Sparc::fixup_sparc_got10; 330263320Sdim+ } 331263320Sdim+} 332263320Sdim+ 333263320Sdim bool 334263320Sdim SparcMCExpr::EvaluateAsRelocatableImpl(MCValue &Res, 335263320Sdim- const MCAsmLayout *Layout) const { 336263320Sdim+ const MCAsmLayout *Layout) const { 337263320Sdim if (!Layout) 338263320Sdim return false; 339263320Sdim return getSubExpr()->EvaluateAsRelocatable(Res, *Layout); 340263320SdimIndex: lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h 341263320Sdim=================================================================== 342263320Sdim--- lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h 343263320Sdim+++ lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h 344263320Sdim@@ -15,6 +15,7 @@ 345263320Sdim #ifndef LLVM_SPARCMCEXPR_H 346263320Sdim #define LLVM_SPARCMCEXPR_H 347263320Sdim 348263320Sdim+#include "SparcFixupKinds.h" 349263320Sdim #include "llvm/MC/MCExpr.h" 350263320Sdim 351263320Sdim namespace llvm { 352263320Sdim@@ -31,6 +32,11 @@ class SparcMCExpr : public MCTargetExpr { 353263320Sdim VK_Sparc_L44, 354263320Sdim VK_Sparc_HH, 355263320Sdim VK_Sparc_HM, 356263320Sdim+ VK_Sparc_PC22, 357263320Sdim+ VK_Sparc_PC10, 358263320Sdim+ VK_Sparc_GOT22, 359263320Sdim+ VK_Sparc_GOT10, 360263320Sdim+ VK_Sparc_WPLT30, 361263320Sdim VK_Sparc_R_DISP32, 362263320Sdim VK_Sparc_TLS_GD_HI22, 363263320Sdim VK_Sparc_TLS_GD_LO10, 364263320Sdim@@ -75,6 +81,9 @@ class SparcMCExpr : public MCTargetExpr { 365263320Sdim /// getSubExpr - Get the child of this expression. 366263320Sdim const MCExpr *getSubExpr() const { return Expr; } 367263320Sdim 368263320Sdim+ /// getFixupKind - Get the fixup kind of this expression. 369263320Sdim+ Sparc::Fixups getFixupKind() const { return getFixupKind(Kind); } 370263320Sdim+ 371263320Sdim /// @} 372263320Sdim void PrintImpl(raw_ostream &OS) const; 373263320Sdim bool EvaluateAsRelocatableImpl(MCValue &Res, 374263320Sdim@@ -94,6 +103,7 @@ class SparcMCExpr : public MCTargetExpr { 375263320Sdim 376263320Sdim static VariantKind parseVariantKind(StringRef name); 377263320Sdim static bool printVariantKind(raw_ostream &OS, VariantKind Kind); 378263320Sdim+ static Sparc::Fixups getFixupKind(VariantKind Kind); 379263320Sdim }; 380263320Sdim 381263320Sdim } // end namespace llvm. 382263320SdimIndex: lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp 383263320Sdim=================================================================== 384263320Sdim--- lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp 385263320Sdim+++ lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp 386263320Sdim@@ -94,37 +94,8 @@ getMachineOpValue(const MCInst &MI, const MCOperan 387263320Sdim assert(MO.isExpr()); 388263320Sdim const MCExpr *Expr = MO.getExpr(); 389263320Sdim if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(Expr)) { 390263320Sdim- switch(SExpr->getKind()) { 391263320Sdim- default: assert(0 && "Unhandled sparc expression!"); break; 392263320Sdim- case SparcMCExpr::VK_Sparc_LO: 393263320Sdim- Fixups.push_back(MCFixup::Create(0, Expr, 394263320Sdim- (MCFixupKind)Sparc::fixup_sparc_lo10)); 395263320Sdim- break; 396263320Sdim- case SparcMCExpr::VK_Sparc_HI: 397263320Sdim- Fixups.push_back(MCFixup::Create(0, Expr, 398263320Sdim- (MCFixupKind)Sparc::fixup_sparc_hi22)); 399263320Sdim- break; 400263320Sdim- case SparcMCExpr::VK_Sparc_H44: 401263320Sdim- Fixups.push_back(MCFixup::Create(0, Expr, 402263320Sdim- (MCFixupKind)Sparc::fixup_sparc_h44)); 403263320Sdim- break; 404263320Sdim- case SparcMCExpr::VK_Sparc_M44: 405263320Sdim- Fixups.push_back(MCFixup::Create(0, Expr, 406263320Sdim- (MCFixupKind)Sparc::fixup_sparc_m44)); 407263320Sdim- break; 408263320Sdim- case SparcMCExpr::VK_Sparc_L44: 409263320Sdim- Fixups.push_back(MCFixup::Create(0, Expr, 410263320Sdim- (MCFixupKind)Sparc::fixup_sparc_l44)); 411263320Sdim- break; 412263320Sdim- case SparcMCExpr::VK_Sparc_HH: 413263320Sdim- Fixups.push_back(MCFixup::Create(0, Expr, 414263320Sdim- (MCFixupKind)Sparc::fixup_sparc_hh)); 415263320Sdim- break; 416263320Sdim- case SparcMCExpr::VK_Sparc_HM: 417263320Sdim- Fixups.push_back(MCFixup::Create(0, Expr, 418263320Sdim- (MCFixupKind)Sparc::fixup_sparc_hm)); 419263320Sdim- break; 420263320Sdim- } 421263320Sdim+ MCFixupKind Kind = (MCFixupKind)SExpr->getFixupKind(); 422263320Sdim+ Fixups.push_back(MCFixup::Create(0, Expr, Kind)); 423263320Sdim return 0; 424263320Sdim } 425263320Sdim 426263320Sdim@@ -143,8 +114,15 @@ getCallTargetOpValue(const MCInst &MI, unsigned Op 427263320Sdim if (MO.isReg() || MO.isImm()) 428263320Sdim return getMachineOpValue(MI, MO, Fixups); 429263320Sdim 430263320Sdim- Fixups.push_back(MCFixup::Create(0, MO.getExpr(), 431263320Sdim- (MCFixupKind)Sparc::fixup_sparc_call30)); 432263320Sdim+ MCFixupKind fixupKind = (MCFixupKind)Sparc::fixup_sparc_call30; 433263320Sdim+ 434263320Sdim+ if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(MO.getExpr())) { 435263320Sdim+ if (SExpr->getKind() == SparcMCExpr::VK_Sparc_WPLT30) 436263320Sdim+ fixupKind = (MCFixupKind)Sparc::fixup_sparc_wplt30; 437263320Sdim+ } 438263320Sdim+ 439263320Sdim+ Fixups.push_back(MCFixup::Create(0, MO.getExpr(), fixupKind)); 440263320Sdim+ 441263320Sdim return 0; 442263320Sdim } 443263320Sdim 444