Pull in r200373 from upstream llvm trunk (by Venkatraman Govindaraju): [Sparc] Use %r_disp32 for pc_rel entries in gcc_except_table and eh_frame. Otherwise, assembler (gas) fails to assemble them with error message "operation combines symbols in different segments". This is because MC computes pc_rel entries with subtract expression between labels from different sections. Introduced here: http://svnweb.freebsd.org/changeset/base/262261 Index: lib/Target/Sparc/SparcTargetObjectFile.h =================================================================== --- lib/Target/Sparc/SparcTargetObjectFile.h +++ lib/Target/Sparc/SparcTargetObjectFile.h @@ -0,0 +1,34 @@ +//===-- SparcTargetObjectFile.h - Sparc Object Info -------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TARGET_SPARC_TARGETOBJECTFILE_H +#define LLVM_TARGET_SPARC_TARGETOBJECTFILE_H + +#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" + +namespace llvm { + +class MCContext; +class TargetMachine; + +class SparcELFTargetObjectFile : public TargetLoweringObjectFileELF { +public: + SparcELFTargetObjectFile() : + TargetLoweringObjectFileELF() + {} + + const MCExpr * + getTTypeGlobalReference(const GlobalValue *GV, Mangler *Mang, + MachineModuleInfo *MMI, unsigned Encoding, + MCStreamer &Streamer) const; +}; + +} // end namespace llvm + +#endif Index: lib/Target/Sparc/SparcISelLowering.cpp =================================================================== --- lib/Target/Sparc/SparcISelLowering.cpp +++ lib/Target/Sparc/SparcISelLowering.cpp @@ -16,6 +16,7 @@ #include "SparcMachineFunctionInfo.h" #include "SparcRegisterInfo.h" #include "SparcTargetMachine.h" +#include "SparcTargetObjectFile.h" #include "MCTargetDesc/SparcBaseInfo.h" #include "llvm/CodeGen/CallingConvLower.h" #include "llvm/CodeGen/MachineFrameInfo.h" @@ -1361,7 +1362,7 @@ static SPCC::CondCodes FPCondCCodeToFCC(ISD::CondC } SparcTargetLowering::SparcTargetLowering(TargetMachine &TM) - : TargetLowering(TM, new TargetLoweringObjectFileELF()) { + : TargetLowering(TM, new SparcELFTargetObjectFile()) { Subtarget = &TM.getSubtarget(); // Set up the register classes. Index: lib/Target/Sparc/SparcTargetObjectFile.cpp =================================================================== --- lib/Target/Sparc/SparcTargetObjectFile.cpp +++ lib/Target/Sparc/SparcTargetObjectFile.cpp @@ -0,0 +1,48 @@ +//===------- SparcTargetObjectFile.cpp - Sparc Object Info Impl -----------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "SparcTargetObjectFile.h" +#include "MCTargetDesc/SparcMCExpr.h" +#include "llvm/CodeGen/MachineModuleInfoImpls.h" +#include "llvm/Support/Dwarf.h" +#include "llvm/Target/Mangler.h" + +using namespace llvm; + + +const MCExpr *SparcELFTargetObjectFile:: +getTTypeGlobalReference(const GlobalValue *GV, Mangler *Mang, + MachineModuleInfo *MMI, unsigned Encoding, + MCStreamer &Streamer) const { + + if (Encoding & dwarf::DW_EH_PE_pcrel) { + MachineModuleInfoELF &ELFMMI = MMI->getObjFileInfo(); + + //MCSymbol *SSym = getSymbolWithGlobalValueBase(*Mang, GV, ".DW.stub"); + SmallString<60> NameStr; + Mang->getNameWithPrefix(NameStr, GV, true); + NameStr.append(".DW.stub"); + MCSymbol *SSym = getContext().GetOrCreateSymbol(NameStr.str()); + + // Add information about the stub reference to ELFMMI so that the stub + // gets emitted by the asmprinter. + MachineModuleInfoImpl::StubValueTy &StubSym = ELFMMI.getGVStubEntry(SSym); + if (StubSym.getPointer() == 0) { + MCSymbol *Sym = getSymbol(*Mang, GV); + StubSym = MachineModuleInfoImpl::StubValueTy(Sym, !GV->hasLocalLinkage()); + } + + MCContext &Ctx = getContext(); + return SparcMCExpr::Create(SparcMCExpr::VK_Sparc_R_DISP32, + MCSymbolRefExpr::Create(SSym, Ctx), Ctx); + } + + return TargetLoweringObjectFileELF:: + getTTypeGlobalReference(GV, Mang, MMI, Encoding, Streamer); +} Index: lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.cpp =================================================================== --- lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.cpp +++ lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.cpp @@ -12,7 +12,9 @@ //===----------------------------------------------------------------------===// #include "SparcMCAsmInfo.h" +#include "SparcMCExpr.h" #include "llvm/ADT/Triple.h" +#include "llvm/MC/MCStreamer.h" using namespace llvm; @@ -44,4 +46,15 @@ SparcELFMCAsmInfo::SparcELFMCAsmInfo(StringRef TT) PrivateGlobalPrefix = ".L"; } +const MCExpr* +SparcELFMCAsmInfo::getExprForPersonalitySymbol(const MCSymbol *Sym, + unsigned Encoding, + MCStreamer &Streamer) const { + if (Encoding & dwarf::DW_EH_PE_pcrel) { + MCContext &Ctx = Streamer.getContext(); + return SparcMCExpr::Create(SparcMCExpr::VK_Sparc_R_DISP32, + MCSymbolRefExpr::Create(Sym, Ctx), Ctx); + } + return MCAsmInfo::getExprForPersonalitySymbol(Sym, Encoding, Streamer); +} Index: lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp =================================================================== --- lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp +++ lib/Target/Sparc/MCTargetDesc/SparcMCExpr.cpp @@ -41,6 +41,7 @@ void SparcMCExpr::PrintImpl(raw_ostream &OS) const case VK_Sparc_L44: OS << "%l44("; break; case VK_Sparc_HH: OS << "%hh("; break; case VK_Sparc_HM: OS << "%hm("; break; + case VK_Sparc_R_DISP32: OS << "%r_disp32("; break; case VK_Sparc_TLS_GD_HI22: OS << "%tgd_hi22("; break; case VK_Sparc_TLS_GD_LO10: OS << "%tgd_lo10("; break; case VK_Sparc_TLS_GD_ADD: OS << "%tgd_add("; break; @@ -77,6 +78,7 @@ SparcMCExpr::VariantKind SparcMCExpr::parseVariant .Case("l44", VK_Sparc_L44) .Case("hh", VK_Sparc_HH) .Case("hm", VK_Sparc_HM) + .Case("r_disp32", VK_Sparc_R_DISP32) .Case("tgd_hi22", VK_Sparc_TLS_GD_HI22) .Case("tgd_lo10", VK_Sparc_TLS_GD_LO10) .Case("tgd_add", VK_Sparc_TLS_GD_ADD) @@ -101,6 +103,8 @@ SparcMCExpr::VariantKind SparcMCExpr::parseVariant bool SparcMCExpr::EvaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout) const { + if (!Layout) + return false; return getSubExpr()->EvaluateAsRelocatable(Res, *Layout); } Index: lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.h =================================================================== --- lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.h +++ lib/Target/Sparc/MCTargetDesc/SparcMCAsmInfo.h @@ -17,13 +17,16 @@ #include "llvm/MC/MCAsmInfoELF.h" namespace llvm { - class StringRef; +class StringRef; - class SparcELFMCAsmInfo : public MCAsmInfoELF { - virtual void anchor(); - public: - explicit SparcELFMCAsmInfo(StringRef TT); - }; +class SparcELFMCAsmInfo : public MCAsmInfoELF { + virtual void anchor(); +public: + explicit SparcELFMCAsmInfo(StringRef TT); + virtual const MCExpr* getExprForPersonalitySymbol(const MCSymbol *Sym, + unsigned Encoding, + MCStreamer &Streamer) const; +}; } // namespace llvm Index: lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h =================================================================== --- lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h +++ lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h @@ -31,6 +31,7 @@ class SparcMCExpr : public MCTargetExpr { VK_Sparc_L44, VK_Sparc_HH, VK_Sparc_HM, + VK_Sparc_R_DISP32, VK_Sparc_TLS_GD_HI22, VK_Sparc_TLS_GD_LO10, VK_Sparc_TLS_GD_ADD, Index: lib/Target/Sparc/CMakeLists.txt =================================================================== --- lib/Target/Sparc/CMakeLists.txt +++ lib/Target/Sparc/CMakeLists.txt @@ -27,6 +27,7 @@ add_llvm_target(SparcCodeGen SparcJITInfo.cpp SparcCodeEmitter.cpp SparcMCInstLower.cpp + SparcTargetObjectFile.cpp ) add_dependencies(LLVMSparcCodeGen SparcCommonTableGen intrinsics_gen) Index: test/CodeGen/SPARC/exception.ll =================================================================== --- test/CodeGen/SPARC/exception.ll +++ test/CodeGen/SPARC/exception.ll @@ -1,7 +1,9 @@ ; RUN: llc < %s -march=sparc -relocation-model=static | FileCheck -check-prefix=V8ABS %s ; RUN: llc < %s -march=sparc -relocation-model=pic | FileCheck -check-prefix=V8PIC %s +; RUN: llc < %s -march=sparc -relocation-model=pic -disable-cfi | FileCheck -check-prefix=V8PIC_NOCFI %s ; RUN: llc < %s -march=sparcv9 -relocation-model=static | FileCheck -check-prefix=V9ABS %s ; RUN: llc < %s -march=sparcv9 -relocation-model=pic | FileCheck -check-prefix=V9PIC %s +; RUN: llc < %s -march=sparcv9 -relocation-model=pic -disable-cfi | FileCheck -check-prefix=V9PIC_NOCFI %s %struct.__fundamental_type_info_pseudo = type { %struct.__type_info_pseudo } @@ -40,11 +42,23 @@ ; V8PIC: .cfi_register 15, 31 ; V8PIC: .section .gcc_except_table ; V8PIC-NOT: .section -; V8PIC: .word .L_ZTIi.DW.stub- +; V8PIC: .word %r_disp32(.L_ZTIi.DW.stub) ; V8PIC: .data ; V8PIC: .L_ZTIi.DW.stub: ; V8PIC-NEXT: .word _ZTIi +; V8PIC_NOCFI-LABEL: main: +; V8PIC_NOCFI: .section .gcc_except_table +; V8PIC_NOCFI-NOT: .section +; V8PIC_NOCFI: .word %r_disp32(.L_ZTIi.DW.stub) +; V8PIC_NOCFI: .data +; V8PIC_NOCFI: .L_ZTIi.DW.stub: +; V8PIC_NOCFI-NEXT: .word _ZTIi +; V8PIC_NOCFI: .section .eh_frame +; V8PIC_NOCFI-NOT: .section +; V8PIC_NOCFI: .word %r_disp32(DW.ref.__gxx_personality_v0) + + ; V9ABS-LABEL: main: ; V9ABS: .cfi_startproc ; V9ABS: .cfi_personality 0, __gxx_personality_v0 @@ -65,11 +79,22 @@ ; V9PIC: .cfi_register 15, 31 ; V9PIC: .section .gcc_except_table ; V9PIC-NOT: .section -; V9PIC: .word .L_ZTIi.DW.stub- +; V9PIC: .word %r_disp32(.L_ZTIi.DW.stub) ; V9PIC: .data ; V9PIC: .L_ZTIi.DW.stub: ; V9PIC-NEXT: .xword _ZTIi +; V9PIC_NOCFI-LABEL: main: +; V9PIC_NOCFI: .section .gcc_except_table +; V9PIC_NOCFI-NOT: .section +; V9PIC_NOCFI: .word %r_disp32(.L_ZTIi.DW.stub) +; V9PIC_NOCFI: .data +; V9PIC_NOCFI: .L_ZTIi.DW.stub: +; V9PIC_NOCFI-NEXT: .xword _ZTIi +; V9PIC_NOCFI: .section .eh_frame +; V9PIC_NOCFI-NOT: .section +; V9PIC_NOCFI: .word %r_disp32(DW.ref.__gxx_personality_v0) + define i32 @main(i32 %argc, i8** nocapture readnone %argv) unnamed_addr #0 { entry: %0 = icmp eq i32 %argc, 2