diff options
author | Jack Carter <jcarter@mips.com> | 2012-11-21 23:38:59 +0000 |
---|---|---|
committer | Jack Carter <jcarter@mips.com> | 2012-11-21 23:38:59 +0000 |
commit | 198ad916d736047f8a439f19dee25cee917df8a9 (patch) | |
tree | 7a5851d2e159af0669630c415b536fd92b3010e1 | |
parent | 17ced4521f67255271df17e8d6e3e61de426371c (diff) | |
download | external_llvm-198ad916d736047f8a439f19dee25cee917df8a9.zip external_llvm-198ad916d736047f8a439f19dee25cee917df8a9.tar.gz external_llvm-198ad916d736047f8a439f19dee25cee917df8a9.tar.bz2 |
Mips direct object xgot support
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
-rw-r--r-- | lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp | 10 | ||||
-rw-r--r-- | lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp | 12 | ||||
-rw-r--r-- | lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h | 12 | ||||
-rw-r--r-- | lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 12 | ||||
-rw-r--r-- | test/MC/Mips/xgot.ll | 42 |
5 files changed, 87 insertions, 1 deletions
diff --git a/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp b/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp index 9a35bb6..c078794 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp @@ -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) diff --git a/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp b/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp index 5d240fe..f82e203 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp @@ -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; } diff --git a/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h b/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h index 77faec5..f963900 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h +++ b/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h @@ -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 diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index 7fbdae0..da1e455 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -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 index 0000000..bfe9b9a --- /dev/null +++ b/test/MC/Mips/xgot.ll @@ -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 + |