diff options
author | Jack Carter <jcarter@mips.com> | 2012-08-22 00:49:30 +0000 |
---|---|---|
committer | Jack Carter <jcarter@mips.com> | 2012-08-22 00:49:30 +0000 |
commit | 101771ba4d9c2421f836069fcedf9ddc8a0c9dc7 (patch) | |
tree | 1f743fb5f09df0548a3df1224fd0ad863cb4877a | |
parent | cb1f68d7c8bea99530ba55813c2b4ddd14556286 (diff) |
For mips64 switch statements in subroutines could generate
within the codegen EK_GPRel64BlockAddress. This was not
supported for direct object output and resulted in an assertion.
This change adds support for EK_GPRel64BlockAddress for
direct object.
One fallout from this is to turn on rela relocations
for mips64 to match gas.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162334 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/llvm/MC/MCObjectStreamer.h | 1 | ||||
-rw-r--r-- | lib/MC/MCObjectStreamer.cpp | 12 | ||||
-rw-r--r-- | lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp | 2 | ||||
-rw-r--r-- | test/MC/Mips/do_switch.ll | 39 |
4 files changed, 50 insertions, 4 deletions
diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h index a69075ddd0..b59b76c2be 100644 --- a/include/llvm/MC/MCObjectStreamer.h +++ b/include/llvm/MC/MCObjectStreamer.h @@ -80,6 +80,7 @@ public: virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, const MCSymbol *Label); virtual void EmitGPRel32Value(const MCExpr *Value); + virtual void EmitGPRel64Value(const MCExpr *Value); virtual void FinishImpl(); /// @} diff --git a/lib/MC/MCObjectStreamer.cpp b/lib/MC/MCObjectStreamer.cpp index bad7cfe38a..21756cd149 100644 --- a/lib/MC/MCObjectStreamer.cpp +++ b/lib/MC/MCObjectStreamer.cpp @@ -258,12 +258,18 @@ bool MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset, void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) { MCDataFragment *DF = getOrCreateDataFragment(); - DF->addFixup(MCFixup::Create(DF->getContents().size(), - Value, - FK_GPRel_4)); + DF->addFixup(MCFixup::Create(DF->getContents().size(), Value, FK_GPRel_4)); DF->getContents().resize(DF->getContents().size() + 4, 0); } +// Associate GPRel32 fixup with data and resize data area +void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) { + MCDataFragment *DF = getOrCreateDataFragment(); + + DF->addFixup(MCFixup::Create(DF->getContents().size(), Value, FK_GPRel_4)); + DF->getContents().resize(DF->getContents().size() + 8, 0); +} + void MCObjectStreamer::FinishImpl() { // Dump out the dwarf file & directory tables and line tables. const MCSymbol *LineSectionSymbol = NULL; diff --git a/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp b/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp index b8489cac55..5d240fe847 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp @@ -56,7 +56,7 @@ namespace { MipsELFObjectWriter::MipsELFObjectWriter(bool _is64Bit, uint8_t OSABI, bool _isN64, bool IsLittleEndian) : MCELFObjectTargetWriter(_is64Bit, OSABI, ELF::EM_MIPS, - /*HasRelocationAddend*/ false, + /*HasRelocationAddend*/ (_isN64) ? true : false, /*IsN64*/ _isN64) {} MipsELFObjectWriter::~MipsELFObjectWriter() {} diff --git a/test/MC/Mips/do_switch.ll b/test/MC/Mips/do_switch.ll new file mode 100644 index 0000000000..7eda1b41d1 --- /dev/null +++ b/test/MC/Mips/do_switch.ll @@ -0,0 +1,39 @@ +; This test case will cause an internal EK_GPRel64BlockAddress to be +; produced. This was not handled for direct object and an assertion +; to occur. This is a variation on test case test/CodeGen/Mips/do_switch.ll + +; RUN: llc < %s -filetype=obj -march=mips -relocation-model=static + +; RUN: llc < %s -filetype=obj -march=mips -relocation-model=pic + +; RUN: llc < %s -filetype=obj -march=mips64 -relocation-model=pic -mcpu=mips64 -mattr=n64 + +define i32 @main() nounwind readnone { +entry: + %x = alloca i32, align 4 ; <i32*> [#uses=2] + store volatile i32 2, i32* %x, align 4 + %0 = load volatile i32* %x, align 4 ; <i32> [#uses=1] + + switch i32 %0, label %bb4 [ + i32 0, label %bb5 + i32 1, label %bb1 + i32 2, label %bb2 + i32 3, label %bb3 + ] + +bb1: ; preds = %entry + ret i32 2 + +bb2: ; preds = %entry + ret i32 0 + +bb3: ; preds = %entry + ret i32 3 + +bb4: ; preds = %entry + ret i32 4 + +bb5: ; preds = %entry + ret i32 1 +} + |