1263320SdimPull in r200373 from upstream llvm trunk (by Venkatraman Govindaraju):
2263320Sdim
3263320Sdim  [Sparc] Use %r_disp32 for pc_rel entries in gcc_except_table and eh_frame.
4263320Sdim
5263320Sdim  Otherwise, assembler (gas) fails to assemble them with error message "operation
6263320Sdim  combines symbols in different segments". This is because MC computes
7263320Sdim  pc_rel entries with subtract expression between labels from different sections.
8263320Sdim
9269012SemasteIntroduced here: http://svnweb.freebsd.org/changeset/base/262261
10263320Sdim
11263320SdimIndex: lib/Target/Sparc/SparcTargetObjectFile.h
12263320Sdim===================================================================
13263320Sdim--- lib/Target/Sparc/SparcTargetObjectFile.h
14263320Sdim+++ lib/Target/Sparc/SparcTargetObjectFile.h
15263320Sdim@@ -0,0 +1,34 @@
16263320Sdim+//===-- SparcTargetObjectFile.h - Sparc Object Info -------------*- C++ -*-===//
17263320Sdim+//
18263320Sdim+//                     The LLVM Compiler Infrastructure
19263320Sdim+//
20263320Sdim+// This file is distributed under the University of Illinois Open Source
21263320Sdim+// License. See LICENSE.TXT for details.
22263320Sdim+//
23263320Sdim+//===----------------------------------------------------------------------===//
24263320Sdim+
25263320Sdim+#ifndef LLVM_TARGET_SPARC_TARGETOBJECTFILE_H
26263320Sdim+#define LLVM_TARGET_SPARC_TARGETOBJECTFILE_H
27263320Sdim+
28263320Sdim+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
29263320Sdim+
30263320Sdim+namespace llvm {
31263320Sdim+
32263320Sdim+class MCContext;
33263320Sdim+class TargetMachine;
34263320Sdim+
35263320Sdim+class SparcELFTargetObjectFile : public TargetLoweringObjectFileELF {
36263320Sdim+public:
37263320Sdim+  SparcELFTargetObjectFile() :
38263320Sdim+    TargetLoweringObjectFileELF()
39263320Sdim+  {}
40263320Sdim+
41263320Sdim+  const MCExpr *
42263320Sdim+  getTTypeGlobalReference(const GlobalValue *GV, Mangler *Mang,
43263320Sdim+                          MachineModuleInfo *MMI, unsigned Encoding,
44263320Sdim+                          MCStreamer &Streamer) const;
45263320Sdim+};
46263320Sdim+
47263320Sdim+} // end namespace llvm
48263320Sdim+
49263320Sdim+#endif
50263320SdimIndex: lib/Target/Sparc/SparcISelLowering.cpp
51263320Sdim===================================================================
52263320Sdim--- lib/Target/Sparc/SparcISelLowering.cpp
53263320Sdim+++ lib/Target/Sparc/SparcISelLowering.cpp
54263320Sdim@@ -16,6 +16,7 @@
55263320Sdim #include "SparcMachineFunctionInfo.h"
56263320Sdim #include "SparcRegisterInfo.h"
57263320Sdim #include "SparcTargetMachine.h"
58263320Sdim+#include "SparcTargetObjectFile.h"
59263320Sdim #include "MCTargetDesc/SparcBaseInfo.h"
60263320Sdim #include "llvm/CodeGen/CallingConvLower.h"
61263320Sdim #include "llvm/CodeGen/MachineFrameInfo.h"
62263320Sdim@@ -1361,7 +1362,7 @@ static SPCC::CondCodes FPCondCCodeToFCC(ISD::CondC
63263320Sdim }
64263320Sdim 
65263320Sdim SparcTargetLowering::SparcTargetLowering(TargetMachine &TM)
66263320Sdim-  : TargetLowering(TM, new TargetLoweringObjectFileELF()) {
67263320Sdim+  : TargetLowering(TM, new SparcELFTargetObjectFile()) {
68263320Sdim   Subtarget = &TM.getSubtarget<SparcSubtarget>();
69263320Sdim 
70263320Sdim   // Set up the register classes.
71263320SdimIndex: lib/Target/Sparc/SparcTargetObjectFile.cpp
72263320Sdim===================================================================
73263320Sdim--- lib/Target/Sparc/SparcTargetObjectFile.cpp
74263320Sdim+++ lib/Target/Sparc/SparcTargetObjectFile.cpp
75263320Sdim@@ -0,0 +1,48 @@
76263320Sdim+//===------- SparcTargetObjectFile.cpp - Sparc Object Info Impl -----------===//
77263320Sdim+//
78263320Sdim+//                     The LLVM Compiler Infrastructure
79263320Sdim+//
80263320Sdim+// This file is distributed under the University of Illinois Open Source
81263320Sdim+// License. See LICENSE.TXT for details.
82263320Sdim+//
83263320Sdim+//===----------------------------------------------------------------------===//
84263320Sdim+
85263320Sdim+#include "SparcTargetObjectFile.h"
86263320Sdim+#include "MCTargetDesc/SparcMCExpr.h"
87263320Sdim+#include "llvm/CodeGen/MachineModuleInfoImpls.h"
88263320Sdim+#include "llvm/Support/Dwarf.h"
89263320Sdim+#include "llvm/Target/Mangler.h"
90263320Sdim+
91263320Sdim+using namespace llvm;
92263320Sdim+
93263320Sdim+
94263320Sdim+const MCExpr *SparcELFTargetObjectFile::
95263320Sdim+getTTypeGlobalReference(const GlobalValue *GV, Mangler *Mang,
96263320Sdim+                        MachineModuleInfo *MMI, unsigned Encoding,
97263320Sdim+                        MCStreamer &Streamer) const {
98263320Sdim+
99263320Sdim+  if (Encoding & dwarf::DW_EH_PE_pcrel) {
100263320Sdim+    MachineModuleInfoELF &ELFMMI = MMI->getObjFileInfo<MachineModuleInfoELF>();
101263320Sdim+
102263320Sdim+    //MCSymbol *SSym = getSymbolWithGlobalValueBase(*Mang, GV, ".DW.stub");
103263320Sdim+    SmallString<60> NameStr;
104263320Sdim+    Mang->getNameWithPrefix(NameStr, GV, true);
105263320Sdim+    NameStr.append(".DW.stub");
106263320Sdim+    MCSymbol *SSym = getContext().GetOrCreateSymbol(NameStr.str());
107263320Sdim+
108263320Sdim+    // Add information about the stub reference to ELFMMI so that the stub
109263320Sdim+    // gets emitted by the asmprinter.
110263320Sdim+    MachineModuleInfoImpl::StubValueTy &StubSym = ELFMMI.getGVStubEntry(SSym);
111263320Sdim+    if (StubSym.getPointer() == 0) {
112263320Sdim+      MCSymbol *Sym = getSymbol(*Mang, GV);
113263320Sdim+      StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage());
114263320Sdim+    }
115263320Sdim+
116263320Sdim+    MCContext &Ctx = getContext();
117263320Sdim+    return SparcMCExpr::Create(SparcMCExpr::VK_Sparc_R_DISP32,
118263320Sdim+                               MCSymbolRefExpr::Create(SSym, Ctx), Ctx);
119263320Sdim+  }
120263320Sdim+
121263320Sdim+  return TargetLoweringObjectFileELF::
122263320Sdim+    getTTypeGlobalReference(GV, Mang, MMI, Encoding, Streamer);
123263320Sdim+}
124263320SdimIndex: lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.cpp
125263320Sdim===================================================================
126263320Sdim--- lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.cpp
127263320Sdim+++ lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.cpp
128263320Sdim@@ -12,7 +12,9 @@
129263320Sdim //===----------------------------------------------------------------------===//
130263320Sdim 
131263320Sdim #include "SparcMCAsmInfo.h"
132263320Sdim+#include "SparcMCExpr.h"
133263320Sdim #include "llvm/ADT/Triple.h"
134263320Sdim+#include "llvm/MC/MCStreamer.h"
135263320Sdim 
136263320Sdim using namespace llvm;
137263320Sdim 
138263320Sdim@@ -44,4 +46,15 @@ SparcELFMCAsmInfo::SparcELFMCAsmInfo(StringRef TT)
139263320Sdim   PrivateGlobalPrefix = ".L";
140263320Sdim }
141263320Sdim 
142263320Sdim+const MCExpr*
143263320Sdim+SparcELFMCAsmInfo::getExprForPersonalitySymbol(const MCSymbol *Sym,
144263320Sdim+                                               unsigned Encoding,
145263320Sdim+                                               MCStreamer &Streamer) const {
146263320Sdim+  if (Encoding & dwarf::DW_EH_PE_pcrel) {
147263320Sdim+    MCContext &Ctx = Streamer.getContext();
148263320Sdim+    return SparcMCExpr::Create(SparcMCExpr::VK_Sparc_R_DISP32,
149263320Sdim+                               MCSymbolRefExpr::Create(Sym, Ctx), Ctx);
150263320Sdim+  }
151263320Sdim 
152263320Sdim+  return MCAsmInfo::getExprForPersonalitySymbol(Sym, Encoding, Streamer);
153263320Sdim+}
154263320SdimIndex: lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
155263320Sdim===================================================================
156263320Sdim--- lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
157263320Sdim+++ lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp
158263320Sdim@@ -41,6 +41,7 @@ void SparcMCExpr::PrintImpl(raw_ostream &OS) const
159263320Sdim   case VK_Sparc_L44:      OS << "%l44("; break;
160263320Sdim   case VK_Sparc_HH:       OS << "%hh(";  break;
161263320Sdim   case VK_Sparc_HM:       OS << "%hm(";  break;
162263320Sdim+  case VK_Sparc_R_DISP32: OS << "%r_disp32("; break;
163263320Sdim   case VK_Sparc_TLS_GD_HI22:   OS << "%tgd_hi22(";   break;
164263320Sdim   case VK_Sparc_TLS_GD_LO10:   OS << "%tgd_lo10(";   break;
165263320Sdim   case VK_Sparc_TLS_GD_ADD:    OS << "%tgd_add(";    break;
166263320Sdim@@ -77,6 +78,7 @@ SparcMCExpr::VariantKind SparcMCExpr::parseVariant
167263320Sdim     .Case("l44", VK_Sparc_L44)
168263320Sdim     .Case("hh",  VK_Sparc_HH)
169263320Sdim     .Case("hm",  VK_Sparc_HM)
170263320Sdim+    .Case("r_disp32",   VK_Sparc_R_DISP32)
171263320Sdim     .Case("tgd_hi22",   VK_Sparc_TLS_GD_HI22)
172263320Sdim     .Case("tgd_lo10",   VK_Sparc_TLS_GD_LO10)
173263320Sdim     .Case("tgd_add",    VK_Sparc_TLS_GD_ADD)
174263320Sdim@@ -101,6 +103,8 @@ SparcMCExpr::VariantKind SparcMCExpr::parseVariant
175263320Sdim bool
176263320Sdim SparcMCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
177263320Sdim                                          const MCAsmLayout *Layout) const {
178263320Sdim+  if (!Layout)
179263320Sdim+    return false;
180263320Sdim   return getSubExpr()->EvaluateAsRelocatable(Res, *Layout);
181263320Sdim }
182263320Sdim 
183263320SdimIndex: lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.h
184263320Sdim===================================================================
185263320Sdim--- lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.h
186263320Sdim+++ lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.h
187263320Sdim@@ -17,13 +17,16 @@
188263320Sdim #include "llvm/MC/MCAsmInfoELF.h"
189263320Sdim 
190263320Sdim namespace llvm {
191263320Sdim-  class StringRef;
192263320Sdim+class StringRef;
193263320Sdim 
194263320Sdim-  class SparcELFMCAsmInfo : public MCAsmInfoELF {
195263320Sdim-    virtual void anchor();
196263320Sdim-  public:
197263320Sdim-    explicit SparcELFMCAsmInfo(StringRef TT);
198263320Sdim-  };
199263320Sdim+class SparcELFMCAsmInfo : public MCAsmInfoELF {
200263320Sdim+  virtual void anchor();
201263320Sdim+public:
202263320Sdim+  explicit SparcELFMCAsmInfo(StringRef TT);
203263320Sdim+  virtual const MCExpr* getExprForPersonalitySymbol(const MCSymbol *Sym,
204263320Sdim+                                                    unsigned Encoding,
205263320Sdim+                                                    MCStreamer &Streamer) const;
206263320Sdim+};
207263320Sdim 
208263320Sdim } // namespace llvm
209263320Sdim 
210263320SdimIndex: lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
211263320Sdim===================================================================
212263320Sdim--- lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
213263320Sdim+++ lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h
214263320Sdim@@ -31,6 +31,7 @@ class SparcMCExpr : public MCTargetExpr {
215263320Sdim     VK_Sparc_L44,
216263320Sdim     VK_Sparc_HH,
217263320Sdim     VK_Sparc_HM,
218263320Sdim+    VK_Sparc_R_DISP32,
219263320Sdim     VK_Sparc_TLS_GD_HI22,
220263320Sdim     VK_Sparc_TLS_GD_LO10,
221263320Sdim     VK_Sparc_TLS_GD_ADD,
222263320SdimIndex: lib/Target/Sparc/CMakeLists.txt
223263320Sdim===================================================================
224263320Sdim--- lib/Target/Sparc/CMakeLists.txt
225263320Sdim+++ lib/Target/Sparc/CMakeLists.txt
226263320Sdim@@ -27,6 +27,7 @@ add_llvm_target(SparcCodeGen
227263320Sdim   SparcJITInfo.cpp
228263320Sdim   SparcCodeEmitter.cpp
229263320Sdim   SparcMCInstLower.cpp
230263320Sdim+  SparcTargetObjectFile.cpp
231263320Sdim   )
232263320Sdim 
233263320Sdim add_dependencies(LLVMSparcCodeGen SparcCommonTableGen intrinsics_gen)
234263320SdimIndex: test/CodeGen/SPARC/exception.ll
235263320Sdim===================================================================
236263320Sdim--- test/CodeGen/SPARC/exception.ll
237263320Sdim+++ test/CodeGen/SPARC/exception.ll
238263320Sdim@@ -1,7 +1,9 @@
239263320Sdim ; RUN: llc < %s -march=sparc   -relocation-model=static | FileCheck -check-prefix=V8ABS %s
240263320Sdim ; RUN: llc < %s -march=sparc   -relocation-model=pic    | FileCheck -check-prefix=V8PIC %s
241263320Sdim+; RUN: llc < %s -march=sparc   -relocation-model=pic -disable-cfi    | FileCheck -check-prefix=V8PIC_NOCFI %s
242263320Sdim ; RUN: llc < %s -march=sparcv9 -relocation-model=static | FileCheck -check-prefix=V9ABS %s
243263320Sdim ; RUN: llc < %s -march=sparcv9 -relocation-model=pic    | FileCheck -check-prefix=V9PIC %s
244263320Sdim+; RUN: llc < %s -march=sparcv9 -relocation-model=pic -disable-cfi    | FileCheck -check-prefix=V9PIC_NOCFI %s
245263320Sdim 
246263320Sdim 
247263320Sdim %struct.__fundamental_type_info_pseudo = type { %struct.__type_info_pseudo }
248263320Sdim@@ -40,11 +42,23 @@
249263320Sdim ; V8PIC:        .cfi_register 15, 31
250263320Sdim ; V8PIC:        .section .gcc_except_table
251263320Sdim ; V8PIC-NOT:    .section
252263320Sdim-; V8PIC:        .word .L_ZTIi.DW.stub-
253263320Sdim+; V8PIC:        .word %r_disp32(.L_ZTIi.DW.stub)
254263320Sdim ; V8PIC:        .data
255263320Sdim ; V8PIC: .L_ZTIi.DW.stub:
256263320Sdim ; V8PIC-NEXT:   .word _ZTIi
257263320Sdim 
258263320Sdim+; V8PIC_NOCFI-LABEL: main:
259263320Sdim+; V8PIC_NOCFI:        .section .gcc_except_table
260263320Sdim+; V8PIC_NOCFI-NOT:    .section
261263320Sdim+; V8PIC_NOCFI:        .word %r_disp32(.L_ZTIi.DW.stub)
262263320Sdim+; V8PIC_NOCFI:        .data
263263320Sdim+; V8PIC_NOCFI: .L_ZTIi.DW.stub:
264263320Sdim+; V8PIC_NOCFI-NEXT:   .word _ZTIi
265263320Sdim+; V8PIC_NOCFI:        .section .eh_frame
266263320Sdim+; V8PIC_NOCFI-NOT:    .section
267263320Sdim+; V8PIC_NOCFI:        .word %r_disp32(DW.ref.__gxx_personality_v0)
268263320Sdim+
269263320Sdim+
270263320Sdim ; V9ABS-LABEL: main:
271263320Sdim ; V9ABS:        .cfi_startproc
272263320Sdim ; V9ABS:        .cfi_personality 0, __gxx_personality_v0
273263320Sdim@@ -65,11 +79,22 @@
274263320Sdim ; V9PIC:        .cfi_register 15, 31
275263320Sdim ; V9PIC:        .section .gcc_except_table
276263320Sdim ; V9PIC-NOT:    .section
277263320Sdim-; V9PIC:        .word .L_ZTIi.DW.stub-
278263320Sdim+; V9PIC:        .word %r_disp32(.L_ZTIi.DW.stub)
279263320Sdim ; V9PIC:        .data
280263320Sdim ; V9PIC: .L_ZTIi.DW.stub:
281263320Sdim ; V9PIC-NEXT:   .xword _ZTIi
282263320Sdim 
283263320Sdim+; V9PIC_NOCFI-LABEL: main:
284263320Sdim+; V9PIC_NOCFI:        .section .gcc_except_table
285263320Sdim+; V9PIC_NOCFI-NOT:    .section
286263320Sdim+; V9PIC_NOCFI:        .word %r_disp32(.L_ZTIi.DW.stub)
287263320Sdim+; V9PIC_NOCFI:        .data
288263320Sdim+; V9PIC_NOCFI: .L_ZTIi.DW.stub:
289263320Sdim+; V9PIC_NOCFI-NEXT:   .xword _ZTIi
290263320Sdim+; V9PIC_NOCFI:        .section .eh_frame
291263320Sdim+; V9PIC_NOCFI-NOT:    .section
292263320Sdim+; V9PIC_NOCFI:        .word %r_disp32(DW.ref.__gxx_personality_v0)
293263320Sdim+
294263320Sdim define i32 @main(i32 %argc, i8** nocapture readnone %argv) unnamed_addr #0 {
295263320Sdim entry:
296263320Sdim   %0 = icmp eq i32 %argc, 2
297