[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.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@200373 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Venkatraman Govindaraju 2014-01-29 04:51:35 +00:00
parent 6a67a3f3ec
commit 771023dbcb
9 changed files with 134 additions and 9 deletions

View File

@ -27,6 +27,7 @@ add_llvm_target(SparcCodeGen
SparcJITInfo.cpp
SparcCodeEmitter.cpp
SparcMCInstLower.cpp
SparcTargetObjectFile.cpp
)
add_subdirectory(TargetInfo)

View File

@ -12,7 +12,9 @@
//===----------------------------------------------------------------------===//
#include "SparcMCAsmInfo.h"
#include "SparcMCExpr.h"
#include "llvm/ADT/Triple.h"
#include "llvm/MC/MCStreamer.h"
using namespace llvm;
@ -42,4 +44,15 @@ SparcELFMCAsmInfo::SparcELFMCAsmInfo(StringRef TT) {
UsesELFSectionDirectiveForBSS = true;
}
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);
}

View File

@ -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

View File

@ -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::parseVariantKind(StringRef name)
.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::parseVariantKind(StringRef name)
bool
SparcMCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
const MCAsmLayout *Layout) const {
if (!Layout)
return false;
return getSubExpr()->EvaluateAsRelocatable(Res, *Layout);
}

View File

@ -31,6 +31,7 @@ public:
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,

View File

@ -17,6 +17,7 @@
#include "SparcMachineFunctionInfo.h"
#include "SparcRegisterInfo.h"
#include "SparcTargetMachine.h"
#include "SparcTargetObjectFile.h"
#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
@ -1363,7 +1364,7 @@ static SPCC::CondCodes FPCondCCodeToFCC(ISD::CondCode CC) {
}
SparcTargetLowering::SparcTargetLowering(TargetMachine &TM)
: TargetLowering(TM, new TargetLoweringObjectFileELF()) {
: TargetLowering(TM, new SparcELFTargetObjectFile()) {
Subtarget = &TM.getSubtarget<SparcSubtarget>();
// Set up the register classes.

View File

@ -0,0 +1,43 @@
//===------- 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"
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<MachineModuleInfoELF>();
MCSymbol *SSym = getSymbolWithGlobalValueBase(*Mang, GV, ".DW.stub");
// 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);
}

View File

@ -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

View File

@ -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