]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/patches/patch-r262261-llvm-r200961-sparc.diff
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / llvm / patches / patch-r262261-llvm-r200961-sparc.diff
1 Pull in r200961 from upstream llvm trunk (by Venkatraman Govindaraju):
2
3   [Sparc] Emit correct relocations for PIC code when integrated assembler is used.
4
5 Introduced here: http://svnweb.freebsd.org/changeset/base/262261
6
7 Index: test/CodeGen/SPARC/obj-relocs.ll
8 ===================================================================
9 --- test/CodeGen/SPARC/obj-relocs.ll
10 +++ test/CodeGen/SPARC/obj-relocs.ll
11 @@ -0,0 +1,33 @@
12 +; RUN: llc < %s -march=sparcv9 -filetype=obj --relocation-model=static | llvm-readobj -r | FileCheck %s --check-prefix=CHECK-ABS
13 +; RUN: llc < %s -march=sparcv9 -filetype=obj --relocation-model=pic    | llvm-readobj -r | FileCheck %s --check-prefix=CHECK-PIC
14 +
15 +;CHECK-ABS: Relocations [
16 +;CHECK-ABS:    0x{{[0-9,A-F]+}} R_SPARC_H44 AGlobalVar 0x0
17 +;CHECK-ABS:    0x{{[0-9,A-F]+}} R_SPARC_M44 AGlobalVar 0x0
18 +;CHECK-ABS:    0x{{[0-9,A-F]+}} R_SPARC_L44 AGlobalVar 0x0
19 +;CHECK-ABS:    0x{{[0-9,A-F]+}} R_SPARC_WDISP30 bar 0x0
20 +;CHECK-ABS:]
21 +
22 +; CHECK-PIC: Relocations [
23 +; CHECK-PIC:    0x{{[0-9,A-F]+}} R_SPARC_PC22 _GLOBAL_OFFSET_TABLE_ 0x4
24 +; CHECK-PIC:    0x{{[0-9,A-F]+}} R_SPARC_PC10 _GLOBAL_OFFSET_TABLE_ 0x8
25 +; CHECK-PIC:    0x{{[0-9,A-F]+}} R_SPARC_GOT22 AGlobalVar 0x0
26 +; CHECK-PIC:    0x{{[0-9,A-F]+}} R_SPARC_GOT10 AGlobalVar 0x0
27 +; CHECK-PIC:    0x{{[0-9,A-F]+}} R_SPARC_WPLT30 bar 0x0
28 +; CHECK-PIC: ]
29 +
30 +
31 +@AGlobalVar = global i64 0, align 8
32 +
33 +; CHECK-ASM: sethi %h44(AGlobalVar), [[R:%[goli][0-7]]]
34 +; CHECK-ASM: add   [[R]], %m44(AGlobalVar), [[R]]
35 +define i64 @foo(i64 %a) {
36 +entry:
37 +  %0 = load i64* @AGlobalVar, align 4
38 +  %1 = add i64 %a, %0
39 +  %2 = call i64 @bar(i64 %1)
40 +  ret i64 %2
41 +}
42 +
43 +
44 +declare i64 @bar(i64)
45 Index: lib/Target/Sparc/SparcISelLowering.cpp
46 ===================================================================
47 --- lib/Target/Sparc/SparcISelLowering.cpp
48 +++ lib/Target/Sparc/SparcISelLowering.cpp
49 @@ -895,10 +895,12 @@ SparcTargetLowering::LowerCall_32(TargetLowering::
50    // If the callee is a GlobalAddress node (quite common, every direct call is)
51    // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
52    // Likewise ExternalSymbol -> TargetExternalSymbol.
53 +  unsigned TF = ((getTargetMachine().getRelocationModel() == Reloc::PIC_)
54 +                 ? SparcMCExpr::VK_Sparc_WPLT30 : 0);
55    if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
56 -    Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i32);
57 +    Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i32, 0, TF);
58    else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee))
59 -    Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i32);
60 +    Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i32, TF);
61  
62    // Returns a chain & a flag for retval copy to use
63    SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
64 @@ -1209,10 +1211,13 @@ SparcTargetLowering::LowerCall_64(TargetLowering::
65    // Likewise ExternalSymbol -> TargetExternalSymbol.
66    SDValue Callee = CLI.Callee;
67    bool hasReturnsTwice = hasReturnsTwiceAttr(DAG, Callee, CLI.CS);
68 +  unsigned TF = ((getTargetMachine().getRelocationModel() == Reloc::PIC_)
69 +                 ? SparcMCExpr::VK_Sparc_WPLT30 : 0);
70    if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
71 -    Callee = DAG.getTargetGlobalAddress(G->getGlobal(), DL, getPointerTy());
72 +    Callee = DAG.getTargetGlobalAddress(G->getGlobal(), DL, getPointerTy(), 0,
73 +                                        TF);
74    else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee))
75 -    Callee = DAG.getTargetExternalSymbol(E->getSymbol(), getPointerTy());
76 +    Callee = DAG.getTargetExternalSymbol(E->getSymbol(), getPointerTy(), TF);
77  
78    // Build the operands for the call instruction itself.
79    SmallVector<SDValue, 8> Ops;
80 @@ -1796,8 +1801,8 @@ SDValue SparcTargetLowering::makeAddress(SDValue O
81    // Handle PIC mode first.
82    if (getTargetMachine().getRelocationModel() == Reloc::PIC_) {
83      // This is the pic32 code model, the GOT is known to be smaller than 4GB.
84 -    SDValue HiLo = makeHiLoPair(Op, SparcMCExpr::VK_Sparc_HI,
85 -                                SparcMCExpr::VK_Sparc_LO, DAG);
86 +    SDValue HiLo = makeHiLoPair(Op, SparcMCExpr::VK_Sparc_GOT22,
87 +                                SparcMCExpr::VK_Sparc_GOT10, DAG);
88      SDValue GlobalBase = DAG.getNode(SPISD::GLOBAL_BASE_REG, DL, VT);
89      SDValue AbsAddr = DAG.getNode(ISD::ADD, DL, VT, GlobalBase, HiLo);
90      // GLOBAL_BASE_REG codegen'ed with call. Inform MFI that this
91 Index: lib/Target/Sparc/SparcAsmPrinter.cpp
92 ===================================================================
93 --- lib/Target/Sparc/SparcAsmPrinter.cpp
94 +++ lib/Target/Sparc/SparcAsmPrinter.cpp
95 @@ -232,12 +232,12 @@ void SparcAsmPrinter::LowerGETPCXAndEmitMCInsts(co
96    MCOperand Callee =  createPCXCallOP(EndLabel, OutContext);
97    EmitCall(OutStreamer, Callee);
98    OutStreamer.EmitLabel(SethiLabel);
99 -  MCOperand hiImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_HI,
100 +  MCOperand hiImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_PC22,
101                                         GOTLabel, StartLabel, SethiLabel,
102                                         OutContext);
103    EmitSETHI(OutStreamer, hiImm, MCRegOP);
104    OutStreamer.EmitLabel(EndLabel);
105 -  MCOperand loImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_LO,
106 +  MCOperand loImm = createPCXRelExprOp(SparcMCExpr::VK_Sparc_PC10,
107                                         GOTLabel, StartLabel, EndLabel,
108                                         OutContext);
109    EmitOR(OutStreamer, MCRegOP, loImm, MCRegOP);
110 Index: lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
111 ===================================================================
112 --- lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
113 +++ lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp
114 @@ -26,6 +26,7 @@ static unsigned adjustFixupValue(unsigned Kind, ui
115    case FK_Data_4:
116    case FK_Data_8:
117      return Value;
118 +  case Sparc::fixup_sparc_wplt30:
119    case Sparc::fixup_sparc_call30:
120      return (Value >> 2) & 0x3fffffff;
121    case Sparc::fixup_sparc_br22:
122 @@ -32,8 +33,12 @@ static unsigned adjustFixupValue(unsigned Kind, ui
123      return (Value >> 2) & 0x3fffff;
124    case Sparc::fixup_sparc_br19:
125      return (Value >> 2) & 0x7ffff;
126 +  case Sparc::fixup_sparc_pc22:
127 +  case Sparc::fixup_sparc_got22:
128    case Sparc::fixup_sparc_hi22:
129      return (Value >> 10) & 0x3fffff;
130 +  case Sparc::fixup_sparc_pc10:
131 +  case Sparc::fixup_sparc_got10:
132    case Sparc::fixup_sparc_lo10:
133      return Value & 0x3ff;
134    case Sparc::fixup_sparc_h44:
135 @@ -72,6 +77,11 @@ namespace {
136          { "fixup_sparc_l44",       20,     12,  0 },
137          { "fixup_sparc_hh",        10,     22,  0 },
138          { "fixup_sparc_hm",        22,     10,  0 },
139 +        { "fixup_sparc_pc22",      10,     22,  MCFixupKindInfo::FKF_IsPCRel },
140 +        { "fixup_sparc_pc10",      22,     10,  MCFixupKindInfo::FKF_IsPCRel },
141 +        { "fixup_sparc_got22",     10,     22,  0 },
142 +        { "fixup_sparc_got10",     22,     10,  0 },
143 +        { "fixup_sparc_wplt30",     2,     30,  MCFixupKindInfo::FKF_IsPCRel }
144        };
145  
146        if (Kind < FirstTargetFixupKind)
147 @@ -82,6 +92,20 @@ namespace {
148        return Infos[Kind - FirstTargetFixupKind];
149      }
150  
151 +    void processFixupValue(const MCAssembler &Asm,
152 +                           const MCAsmLayout &Layout,
153 +                           const MCFixup &Fixup,
154 +                           const MCFragment *DF,
155 +                           MCValue &  Target,
156 +                           uint64_t &Value,
157 +                           bool &IsResolved) {
158 +      switch ((Sparc::Fixups)Fixup.getKind()) {
159 +      default: break;
160 +      case Sparc::fixup_sparc_wplt30: IsResolved = false; break;
161 +      }
162 +    }
163 +
164 +
165      bool mayNeedRelaxation(const MCInst &Inst) const {
166        // FIXME.
167        return false;
168 Index: lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
169 ===================================================================
170 --- lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
171 +++ lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h
172 @@ -48,6 +48,21 @@ namespace llvm {
173        /// fixup_sparc_hm  -  10-bit fixup corresponding to %hm(foo)
174        fixup_sparc_hm,
175  
176 +      /// fixup_sparc_pc22 - 22-bit fixup corresponding to %pc22(foo)
177 +      fixup_sparc_pc22,
178 +
179 +      /// fixup_sparc_pc10 - 10-bit fixup corresponding to %pc10(foo)
180 +      fixup_sparc_pc10,
181 +
182 +      /// fixup_sparc_got22 - 22-bit fixup corresponding to %got22(foo)
183 +      fixup_sparc_got22,
184 +
185 +      /// fixup_sparc_got10 - 10-bit fixup corresponding to %got10(foo)
186 +      fixup_sparc_got10,
187 +
188 +      /// fixup_sparc_wplt30
189 +      fixup_sparc_wplt30,
190 +
191        // Marker
192        LastTargetFixupKind,
193        NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
194 Index: lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
195 ===================================================================
196 --- lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
197 +++ lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp
198 @@ -7,8 +7,9 @@
199  //
200  //===----------------------------------------------------------------------===//
201  
202 +#include "MCTargetDesc/SparcFixupKinds.h"
203 +#include "MCTargetDesc/SparcMCExpr.h"
204  #include "MCTargetDesc/SparcMCTargetDesc.h"
205 -#include "MCTargetDesc/SparcFixupKinds.h"
206  #include "llvm/ADT/STLExtras.h"
207  #include "llvm/MC/MCELFObjectWriter.h"
208  #include "llvm/MC/MCExpr.h"
209 @@ -31,6 +32,11 @@ namespace {
210                                    bool IsPCRel, bool IsRelocWithSymbol,
211                                    int64_t Addend) const;
212  
213 +    virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm,
214 +                                           const MCValue &Target,
215 +                                           const MCFragment &F,
216 +                                           const MCFixup &Fixup,
217 +                                           bool IsPCRel) const;
218    };
219  }
220  
221 @@ -40,6 +46,12 @@ unsigned SparcELFObjectWriter::GetRelocType(const
222                                              bool IsPCRel,
223                                              bool IsRelocWithSymbol,
224                                              int64_t Addend) const {
225 +
226 +  if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(Fixup.getValue())) {
227 +    if (SExpr->getKind() == SparcMCExpr::VK_Sparc_R_DISP32)
228 +      return ELF::R_SPARC_DISP32;
229 +  }
230 +
231    if (IsPCRel) {
232      switch((unsigned)Fixup.getKind()) {
233      default:
234 @@ -51,6 +63,9 @@ unsigned SparcELFObjectWriter::GetRelocType(const
235      case Sparc::fixup_sparc_call30:  return ELF::R_SPARC_WDISP30;
236      case Sparc::fixup_sparc_br22:    return ELF::R_SPARC_WDISP22;
237      case Sparc::fixup_sparc_br19:    return ELF::R_SPARC_WDISP19;
238 +    case Sparc::fixup_sparc_pc22:    return ELF::R_SPARC_PC22;
239 +    case Sparc::fixup_sparc_pc10:    return ELF::R_SPARC_PC10;
240 +    case Sparc::fixup_sparc_wplt30:  return ELF::R_SPARC_WPLT30;
241      }
242    }
243  
244 @@ -74,10 +89,30 @@ unsigned SparcELFObjectWriter::GetRelocType(const
245    case Sparc::fixup_sparc_l44:   return ELF::R_SPARC_L44;
246    case Sparc::fixup_sparc_hh:    return ELF::R_SPARC_HH22;
247    case Sparc::fixup_sparc_hm:    return ELF::R_SPARC_HM10;
248 +  case Sparc::fixup_sparc_got22: return ELF::R_SPARC_GOT22;
249 +  case Sparc::fixup_sparc_got10: return ELF::R_SPARC_GOT10;
250    }
251 +
252    return ELF::R_SPARC_NONE;
253  }
254  
255 +const MCSymbol *SparcELFObjectWriter::ExplicitRelSym(const MCAssembler &Asm,
256 +                                                     const MCValue &Target,
257 +                                                     const MCFragment &F,
258 +                                                     const MCFixup &Fixup,
259 +                                                     bool IsPCRel) const {
260 +
261 +  if (!Target.getSymA())
262 +    return NULL;
263 +  switch((unsigned)Fixup.getKind()) {
264 +  default: break;
265 +  case Sparc::fixup_sparc_got22:
266 +  case Sparc::fixup_sparc_got10:
267 +    return &Target.getSymA()->getSymbol().AliasedSymbol();
268 +  }
269 +  return NULL;
270 +}
271 +
272  MCObjectWriter *llvm::createSparcELFObjectWriter(raw_ostream &OS,
273                                                   bool Is64Bit,
274                                                   uint8_t OSABI) {
275 Index: lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
276 ===================================================================
277 --- lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
278 +++ lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
279 @@ -17,6 +17,7 @@
280  #include "llvm/MC/MCContext.h"
281  #include "llvm/MC/MCAssembler.h"
282  #include "llvm/MC/MCELF.h"
283 +#include "llvm/MC/MCSymbol.h"
284  #include "llvm/Object/ELF.h"
285  
286  
287 @@ -54,6 +55,13 @@ bool SparcMCExpr::printVariantKind(raw_ostream &OS
288    case VK_Sparc_L44:      OS << "%l44("; break;
289    case VK_Sparc_HH:       OS << "%hh(";  break;
290    case VK_Sparc_HM:       OS << "%hm(";  break;
291 +    // FIXME: use %pc22/%pc10, if system assembler supports them.
292 +  case VK_Sparc_PC22:     OS << "%hi("; break;
293 +  case VK_Sparc_PC10:     OS << "%lo("; break;
294 +    // FIXME: use %got22/%got10, if system assembler supports them.
295 +  case VK_Sparc_GOT22:    OS << "%hi("; break;
296 +  case VK_Sparc_GOT10:    OS << "%lo("; break;
297 +  case VK_Sparc_WPLT30:   closeParen = false; break;
298    case VK_Sparc_R_DISP32: OS << "%r_disp32("; break;
299    case VK_Sparc_TLS_GD_HI22:   OS << "%tgd_hi22(";   break;
300    case VK_Sparc_TLS_GD_LO10:   OS << "%tgd_lo10(";   break;
301 @@ -87,6 +95,10 @@ SparcMCExpr::VariantKind SparcMCExpr::parseVariant
302      .Case("l44", VK_Sparc_L44)
303      .Case("hh",  VK_Sparc_HH)
304      .Case("hm",  VK_Sparc_HM)
305 +    .Case("pc22",  VK_Sparc_PC22)
306 +    .Case("pc10",  VK_Sparc_PC10)
307 +    .Case("got22", VK_Sparc_GOT22)
308 +    .Case("got10", VK_Sparc_GOT10)
309      .Case("r_disp32",   VK_Sparc_R_DISP32)
310      .Case("tgd_hi22",   VK_Sparc_TLS_GD_HI22)
311      .Case("tgd_lo10",   VK_Sparc_TLS_GD_LO10)
312 @@ -109,9 +121,26 @@ SparcMCExpr::VariantKind SparcMCExpr::parseVariant
313      .Default(VK_Sparc_None);
314  }
315  
316 +Sparc::Fixups SparcMCExpr::getFixupKind(SparcMCExpr::VariantKind Kind) {
317 +  switch (Kind) {
318 +  default:           assert(0 && "Unhandled SparcMCExpr::VariantKind");
319 +  case VK_Sparc_LO:       return Sparc::fixup_sparc_lo10;
320 +  case VK_Sparc_HI:       return Sparc::fixup_sparc_hi22;
321 +  case VK_Sparc_H44:      return Sparc::fixup_sparc_h44;
322 +  case VK_Sparc_M44:      return Sparc::fixup_sparc_m44;
323 +  case VK_Sparc_L44:      return Sparc::fixup_sparc_l44;
324 +  case VK_Sparc_HH:       return Sparc::fixup_sparc_hh;
325 +  case VK_Sparc_HM:       return Sparc::fixup_sparc_hm;
326 +  case VK_Sparc_PC22:     return Sparc::fixup_sparc_pc22;
327 +  case VK_Sparc_PC10:     return Sparc::fixup_sparc_pc10;
328 +  case VK_Sparc_GOT22:    return Sparc::fixup_sparc_got22;
329 +  case VK_Sparc_GOT10:    return Sparc::fixup_sparc_got10;
330 +  }
331 +}
332 +
333  bool
334  SparcMCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
335 -                                         const MCAsmLayout *Layout) const {
336 +                                       const MCAsmLayout *Layout) const {
337    if (!Layout)
338      return false;
339    return getSubExpr()->EvaluateAsRelocatable(Res, *Layout);
340 Index: lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
341 ===================================================================
342 --- lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
343 +++ lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
344 @@ -15,6 +15,7 @@
345  #ifndef LLVM_SPARCMCEXPR_H
346  #define LLVM_SPARCMCEXPR_H
347  
348 +#include "SparcFixupKinds.h"
349  #include "llvm/MC/MCExpr.h"
350  
351  namespace llvm {
352 @@ -31,6 +32,11 @@ class SparcMCExpr : public MCTargetExpr {
353      VK_Sparc_L44,
354      VK_Sparc_HH,
355      VK_Sparc_HM,
356 +    VK_Sparc_PC22,
357 +    VK_Sparc_PC10,
358 +    VK_Sparc_GOT22,
359 +    VK_Sparc_GOT10,
360 +    VK_Sparc_WPLT30,
361      VK_Sparc_R_DISP32,
362      VK_Sparc_TLS_GD_HI22,
363      VK_Sparc_TLS_GD_LO10,
364 @@ -75,6 +81,9 @@ class SparcMCExpr : public MCTargetExpr {
365    /// getSubExpr - Get the child of this expression.
366    const MCExpr *getSubExpr() const { return Expr; }
367  
368 +  /// getFixupKind - Get the fixup kind of this expression.
369 +  Sparc::Fixups getFixupKind() const { return getFixupKind(Kind); }
370 +
371    /// @}
372    void PrintImpl(raw_ostream &OS) const;
373    bool EvaluateAsRelocatableImpl(MCValue &Res,
374 @@ -94,6 +103,7 @@ class SparcMCExpr : public MCTargetExpr {
375  
376    static VariantKind parseVariantKind(StringRef name);
377    static bool printVariantKind(raw_ostream &OS, VariantKind Kind);
378 +  static Sparc::Fixups getFixupKind(VariantKind Kind);
379  };
380  
381  } // end namespace llvm.
382 Index: lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
383 ===================================================================
384 --- lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
385 +++ lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp
386 @@ -94,37 +94,8 @@ getMachineOpValue(const MCInst &MI, const MCOperan
387    assert(MO.isExpr());
388    const MCExpr *Expr = MO.getExpr();
389    if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(Expr)) {
390 -    switch(SExpr->getKind()) {
391 -    default: assert(0 && "Unhandled sparc expression!"); break;
392 -    case SparcMCExpr::VK_Sparc_LO:
393 -      Fixups.push_back(MCFixup::Create(0, Expr,
394 -                                       (MCFixupKind)Sparc::fixup_sparc_lo10));
395 -      break;
396 -    case SparcMCExpr::VK_Sparc_HI:
397 -      Fixups.push_back(MCFixup::Create(0, Expr,
398 -                                       (MCFixupKind)Sparc::fixup_sparc_hi22));
399 -      break;
400 -    case SparcMCExpr::VK_Sparc_H44:
401 -      Fixups.push_back(MCFixup::Create(0, Expr,
402 -                                       (MCFixupKind)Sparc::fixup_sparc_h44));
403 -      break;
404 -    case SparcMCExpr::VK_Sparc_M44:
405 -      Fixups.push_back(MCFixup::Create(0, Expr,
406 -                                       (MCFixupKind)Sparc::fixup_sparc_m44));
407 -      break;
408 -    case SparcMCExpr::VK_Sparc_L44:
409 -      Fixups.push_back(MCFixup::Create(0, Expr,
410 -                                       (MCFixupKind)Sparc::fixup_sparc_l44));
411 -      break;
412 -    case SparcMCExpr::VK_Sparc_HH:
413 -      Fixups.push_back(MCFixup::Create(0, Expr,
414 -                                       (MCFixupKind)Sparc::fixup_sparc_hh));
415 -      break;
416 -    case SparcMCExpr::VK_Sparc_HM:
417 -      Fixups.push_back(MCFixup::Create(0, Expr,
418 -                                       (MCFixupKind)Sparc::fixup_sparc_hm));
419 -      break;
420 -    }
421 +    MCFixupKind Kind = (MCFixupKind)SExpr->getFixupKind();
422 +    Fixups.push_back(MCFixup::Create(0, Expr, Kind));
423      return 0;
424    }
425  
426 @@ -143,8 +114,15 @@ getCallTargetOpValue(const MCInst &MI, unsigned Op
427    if (MO.isReg() || MO.isImm())
428      return getMachineOpValue(MI, MO, Fixups);
429  
430 -  Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
431 -                                   (MCFixupKind)Sparc::fixup_sparc_call30));
432 +  MCFixupKind fixupKind = (MCFixupKind)Sparc::fixup_sparc_call30;
433 +
434 +  if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(MO.getExpr())) {
435 +    if (SExpr->getKind() == SparcMCExpr::VK_Sparc_WPLT30)
436 +      fixupKind = (MCFixupKind)Sparc::fixup_sparc_wplt30;
437 +  }
438 +
439 +  Fixups.push_back(MCFixup::Create(0, MO.getExpr(), fixupKind));
440 +
441    return 0;
442  }
443