For mips64 switch statements in subroutines could generate
authorJack Carter <jcarter@mips.com>
Wed, 22 Aug 2012 00:49:30 +0000 (00:49 +0000)
committerJack Carter <jcarter@mips.com>
Wed, 22 Aug 2012 00:49:30 +0000 (00:49 +0000)
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

include/llvm/MC/MCObjectStreamer.h
lib/MC/MCObjectStreamer.cpp
lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
test/MC/Mips/do_switch.ll [new file with mode: 0644]

index a69075ddd002562e9236a1750ca06d820d9496da..b59b76c2be817dca592ce23cfd9908151e652d74 100644 (file)
@@ -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();
 
   /// @}
index bad7cfe38a17c2bdc17d5878e5a944b057b8e50d..21756cd149b878ba10c449a15f844faf6269448f 100644 (file)
@@ -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;
index b8489cac551a63c9fda05ca839db0b185e0fd75e..5d240fe847039ac9cc459e52fd4acc0d4dda73b3 100644 (file)
@@ -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 (file)
index 0000000..7eda1b4
--- /dev/null
@@ -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
+}
+