Mips direct object xgot support
authorJack Carter <jcarter@mips.com>
Wed, 21 Nov 2012 23:38:59 +0000 (23:38 +0000)
committerJack Carter <jcarter@mips.com>
Wed, 21 Nov 2012 23:38:59 +0000 (23:38 +0000)
This patch provides support for the MIPS relocations:

    *)  R_MIPS_GOT_HI16
    *)  R_MIPS_GOT_LO16
    *)  R_MIPS_CALL_HI16
    *)  R_MIPS_CALL_LO16

These are used for large GOT instruction sequences.

Contributer: Jack Carter

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@168471 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h
lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
test/MC/Mips/xgot.ll [new file with mode: 0644]

index 9a35bb6bd707fda225b8cb3e112912028292f4f1..c078794899d2ff1adefafbcb74ea598becaa50cc 100644 (file)
@@ -42,6 +42,8 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
   case Mips::fixup_Mips_GOT_PAGE:
   case Mips::fixup_Mips_GOT_OFST:
   case Mips::fixup_Mips_GOT_DISP:
+  case Mips::fixup_Mips_GOT_LO16:
+  case Mips::fixup_Mips_CALL_LO16:
     break;
   case Mips::fixup_Mips_PC16:
     // So far we are only using this type for branches.
@@ -60,6 +62,8 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
     break;
   case Mips::fixup_Mips_HI16:
   case Mips::fixup_Mips_GOT_Local:
+  case Mips::fixup_Mips_GOT_HI16:
+  case Mips::fixup_Mips_CALL_HI16:
     // Get the 2nd 16-bits. Also add 1 if bit 15 is 1.
     Value = ((Value + 0x8000) >> 16) & 0xffff;
     break;
@@ -179,7 +183,11 @@ public:
       { "fixup_Mips_GOT_OFST",     0,     16,   0 },
       { "fixup_Mips_GOT_DISP",     0,     16,   0 },
       { "fixup_Mips_HIGHER",       0,     16,   0 },
-      { "fixup_Mips_HIGHEST",      0,     16,   0 }
+      { "fixup_Mips_HIGHEST",      0,     16,   0 },
+      { "fixup_Mips_GOT_HI16",     0,     16,   0 },
+      { "fixup_Mips_GOT_LO16",     0,     16,   0 },
+      { "fixup_Mips_CALL_HI16",    0,     16,   0 },
+      { "fixup_Mips_CALL_LO16",    0,     16,   0 }
     };
 
     if (Kind < FirstTargetFixupKind)
index 5d240fe847039ac9cc459e52fd4acc0d4dda73b3..f82e203c23caf44439880f8c3a0b4d242aed563a 100644 (file)
@@ -179,6 +179,18 @@ unsigned MipsELFObjectWriter::GetRelocType(const MCValue &Target,
   case Mips::fixup_Mips_HIGHEST:
     Type = ELF::R_MIPS_HIGHEST;
     break;
+  case Mips::fixup_Mips_GOT_HI16:
+    Type = ELF::R_MIPS_GOT_HI16;
+    break;
+  case Mips::fixup_Mips_GOT_LO16:
+    Type = ELF::R_MIPS_GOT_LO16;
+    break;
+  case Mips::fixup_Mips_CALL_HI16:
+    Type = ELF::R_MIPS_CALL_HI16;
+    break;
+  case Mips::fixup_Mips_CALL_LO16:
+    Type = ELF::R_MIPS_CALL_LO16;
+    break;
   }
   return Type;
 }
index 77faec54fb233835a47bf4e4b5217ce60dc37e77..f96390043a3b68771e629452f8c9f22d9df494ec 100644 (file)
@@ -116,6 +116,18 @@ namespace Mips {
     // resulting in - R_MIPS_HIGHEST
     fixup_Mips_HIGHEST,
 
+    // resulting in - R_MIPS_GOT_HI16
+    fixup_Mips_GOT_HI16,
+
+    // resulting in - R_MIPS_GOT_LO16
+    fixup_Mips_GOT_LO16,
+
+    // resulting in - R_MIPS_CALL_HI16
+    fixup_Mips_CALL_HI16,
+
+    // resulting in - R_MIPS_CALL_LO16
+    fixup_Mips_CALL_LO16,
+
     // Marker
     LastTargetFixupKind,
     NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
index 7fbdae02f4119f1c8b550899325961ac85b9efd7..da1e4552c9d0163ed98b132acf191a71be3244cc 100644 (file)
@@ -287,6 +287,18 @@ getMachineOpValue(const MCInst &MI, const MCOperand &MO,
   case MCSymbolRefExpr::VK_Mips_HIGHEST:
     FixupKind = Mips::fixup_Mips_HIGHEST;
     break;
+  case MCSymbolRefExpr::VK_Mips_GOT_HI16:
+    FixupKind = Mips::fixup_Mips_GOT_HI16;
+    break;
+  case MCSymbolRefExpr::VK_Mips_GOT_LO16:
+    FixupKind = Mips::fixup_Mips_GOT_LO16;
+    break;
+  case MCSymbolRefExpr::VK_Mips_CALL_HI16:
+    FixupKind = Mips::fixup_Mips_CALL_HI16;
+    break;
+  case MCSymbolRefExpr::VK_Mips_CALL_LO16:
+    FixupKind = Mips::fixup_Mips_CALL_LO16;
+    break;
   } // switch
 
   Fixups.push_back(MCFixup::Create(0, MO.getExpr(), MCFixupKind(FixupKind)));
diff --git a/test/MC/Mips/xgot.ll b/test/MC/Mips/xgot.ll
new file mode 100644 (file)
index 0000000..bfe9b9a
--- /dev/null
@@ -0,0 +1,42 @@
+; RUN: llc -filetype=obj -mtriple mipsel-unknown-linux -mxgot %s -o - | elf-dump --dump-section-data  | FileCheck %s
+
+@.str = private unnamed_addr constant [16 x i8] c"ext_1=%d, i=%d\0A\00", align 1
+@ext_1 = external global i32
+
+define void @fill() nounwind {
+entry:
+
+; Check that the appropriate relocations were created. 
+; For the xgot case we want to see R_MIPS_[GOT|CALL]_[HI|LO]16.
+
+; R_MIPS_HI16
+; CHECK:     ('r_type', 0x05)
+
+; R_MIPS_LO16
+; CHECK:     ('r_type', 0x06)
+
+; R_MIPS_GOT_HI16
+; CHECK:     ('r_type', 0x16)
+
+; R_MIPS_GOT_LO16
+; CHECK:     ('r_type', 0x17)
+
+; R_MIPS_GOT
+; CHECK:     ('r_type', 0x09)
+
+; R_MIPS_LO16
+; CHECK:     ('r_type', 0x06)
+
+; R_MIPS_CALL_HI16
+; CHECK:     ('r_type', 0x1e)
+
+; R_MIPS_CALL_LO16
+; CHECK:     ('r_type', 0x1f)
+
+  %0 = load i32* @ext_1, align 4
+  %call = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([16 x i8]* @.str, i32 0, i32 0), i32 %0) nounwind
+  ret void
+}
+
+declare i32 @printf(i8* nocapture, ...) nounwind
+