Skip to content

Commit

Permalink
[Mips] Add support for MCJIT for MIPS32r6
Browse files Browse the repository at this point in the history
Add support for resolving MIPS32r6 relocations in MCJIT.

Patch by Vladimir Radosavljevic.

Differential Revision: http://reviews.llvm.org/D10687

llvm-svn: 241442
  • Loading branch information
petar-jovanovic committed Jul 6, 2015
1 parent d6a62cc commit 0326a06
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 3 deletions.
61 changes: 58 additions & 3 deletions llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
Expand Up @@ -511,11 +511,54 @@ void RuntimeDyldELF::resolveMIPSRelocation(const SectionEntry &Section,
Insn |= Value & 0xffff;
writeBytesUnaligned(Insn, TargetPtr, 4);
break;
case ELF::R_MIPS_PC32:
case ELF::R_MIPS_PC32: {
uint32_t FinalAddress = (Section.LoadAddress + Offset);
writeBytesUnaligned(Value - FinalAddress, (uint8_t *)TargetPtr, 4);
break;
}
case ELF::R_MIPS_PC16: {
uint32_t FinalAddress = (Section.LoadAddress + Offset);
Insn &= 0xffff0000;
Insn |= ((Value - FinalAddress) >> 2) & 0xffff;
writeBytesUnaligned(Insn, TargetPtr, 4);
break;
}
case ELF::R_MIPS_PC19_S2: {
uint32_t FinalAddress = (Section.LoadAddress + Offset);
Insn &= 0xfff80000;
Insn |= ((Value - (FinalAddress & ~0x3)) >> 2) & 0x7ffff;
writeBytesUnaligned(Insn, TargetPtr, 4);
break;
}
case ELF::R_MIPS_PC21_S2: {
uint32_t FinalAddress = (Section.LoadAddress + Offset);
Insn &= 0xffe00000;
Insn |= ((Value - FinalAddress) >> 2) & 0x1fffff;
writeBytesUnaligned(Insn, TargetPtr, 4);
break;
}
case ELF::R_MIPS_PC26_S2: {
uint32_t FinalAddress = (Section.LoadAddress + Offset);
Insn &= 0xfc000000;
Insn |= ((Value - FinalAddress) >> 2) & 0x3ffffff;
writeBytesUnaligned(Insn, TargetPtr, 4);
break;
}
case ELF::R_MIPS_PCHI16: {
uint32_t FinalAddress = (Section.LoadAddress + Offset);
writeBytesUnaligned(Value + Addend - FinalAddress, (uint8_t *)TargetPtr, 4);
Insn &= 0xffff0000;
Insn |= ((Value - FinalAddress + 0x8000) >> 16) & 0xffff;
writeBytesUnaligned(Insn, TargetPtr, 4);
break;
}
case ELF::R_MIPS_PCLO16: {
uint32_t FinalAddress = (Section.LoadAddress + Offset);
Insn &= 0xffff0000;
Insn |= (Value - FinalAddress) & 0xffff;
writeBytesUnaligned(Insn, TargetPtr, 4);
break;
}
}
}

void RuntimeDyldELF::setMipsABI(const ObjectFile &Obj) {
Expand Down Expand Up @@ -1263,12 +1306,24 @@ relocation_iterator RuntimeDyldELF::processRelocationRef(
Section.StubOffset += getMaxStubSize();
}
} else {
if (RelType == ELF::R_MIPS_HI16)
// FIXME: Calculate correct addends for R_MIPS_HI16, R_MIPS_LO16,
// R_MIPS_PCHI16 and R_MIPS_PCLO16 relocations.
if (RelType == ELF::R_MIPS_HI16 || RelType == ELF::R_MIPS_PCHI16)
Value.Addend += (Opcode & 0x0000ffff) << 16;
else if (RelType == ELF::R_MIPS_LO16)
Value.Addend += (Opcode & 0x0000ffff);
else if (RelType == ELF::R_MIPS_32)
Value.Addend += Opcode;
else if (RelType == ELF::R_MIPS_PCLO16)
Value.Addend += SignExtend32<16>((Opcode & 0x0000ffff));
else if (RelType == ELF::R_MIPS_PC16)
Value.Addend += SignExtend32<18>((Opcode & 0x0000ffff) << 2);
else if (RelType == ELF::R_MIPS_PC19_S2)
Value.Addend += SignExtend32<21>((Opcode & 0x0007ffff) << 2);
else if (RelType == ELF::R_MIPS_PC21_S2)
Value.Addend += SignExtend32<23>((Opcode & 0x001fffff) << 2);
else if (RelType == ELF::R_MIPS_PC26_S2)
Value.Addend += SignExtend32<28>((Opcode & 0x03ffffff) << 2);
processSimpleRelocation(SectionID, Offset, RelType, Value);
}
} else if (IsMipsN64ABI) {
Expand Down
49 changes: 49 additions & 0 deletions llvm/test/ExecutionEngine/RuntimeDyld/Mips/ELF_O32R6_relocations.s
@@ -0,0 +1,49 @@
# RUN: llvm-mc -triple=mipsel-unknown-linux -mcpu=mips32r6 -relocation-model=pic -code-model=small -filetype=obj -o %T/test_ELF_O32R6.o %s
# RUN: llc -mtriple=mipsel-unknown-linux -mcpu=mips32r6 -relocation-model=pic -filetype=obj -o %T/test_ELF_ExternalFunction_O32R6.o %S/Inputs/ExternalFunction.ll
# RUN: llvm-rtdyld -triple=mipsel-unknown-linux -mcpu=mips32r6 -verify -map-section test_ELF_O32R6.o,.text=0x1000 -map-section test_ELF_ExternalFunction_O32R6.o,.text=0x10000 -check=%s %/T/test_ELF_O32R6.o %T/test_ELF_ExternalFunction_O32R6.o

# RUN: llvm-mc -triple=mips-unknown-linux -mcpu=mips32r6 -relocation-model=pic -code-model=small -filetype=obj -o %T/test_ELF_O32R6.o %s
# RUN: llc -mtriple=mips-unknown-linux -mcpu=mips32r6 -relocation-model=pic -filetype=obj -o %T/test_ELF_ExternalFunction_O32R6.o %S/Inputs/ExternalFunction.ll
# RUN: llvm-rtdyld -triple=mips-unknown-linux -mcpu=mips32r6 -verify -map-section test_ELF_O32R6.o,.text=0x1000 -map-section test_ELF_ExternalFunction_O32R6.o,.text=0x10000 -check=%s %/T/test_ELF_O32R6.o %T/test_ELF_ExternalFunction_O32R6.o

.text
.abicalls
.nan 2008
.text
.set nomicromips
.set nomips16
.set noreorder
.set nomacro
.set noat

.align 3
.globl bar
.type bar,@function

bar:
# Test R_MIPS_PC19_S2 relocation.
# rtdyld-check: decode_operand(R_MIPS_PC19_S2, 1)[20:0] = (foo - R_MIPS_PC19_S2)[20:0]
R_MIPS_PC19_S2:
lwpc $6,foo

# Test R_MIPS_PC21_S2 relocation.
# rtdyld-check: decode_operand(R_MIPS_PC21_S2, 1)[22:0] = (foo - next_pc(R_MIPS_PC21_S2))[22:0]
R_MIPS_PC21_S2:
bnezc $5,foo

# Test R_MIPS_PC26_S2 relocation.
# rtdyld-check: decode_operand(R_MIPS_PC26_S2, 0)[27:0] = (foo - next_pc(R_MIPS_PC26_S2))[27:0]
R_MIPS_PC26_S2:
balc foo

# Test R_MIPS_PCHI16 relocation.
# rtdyld-check: decode_operand(R_MIPS_PCHI16, 1)[15:0] = (foo - R_MIPS_PCHI16 + 0x8000)[31:16]
R_MIPS_PCHI16:
aluipc $5, %pcrel_hi(foo)

# Test R_MIPS_PCLO16 relocation.
# rtdyld-check: decode_operand(R_MIPS_PCLO16, 2)[15:0] = (foo - R_MIPS_PCLO16)[15:0]
R_MIPS_PCLO16:
addiu $5, $5, %pcrel_lo(foo)

.size bar, .-bar
Expand Up @@ -39,6 +39,11 @@ R_MIPS_26:
j foo
nop

# rtdyld-check: decode_operand(R_MIPS_PC16, 1)[17:0] = (foo - R_MIPS_PC16)[17:0]
R_MIPS_PC16:
bal foo
nop

# rtdyld-check: decode_operand(R_MIPS_HI16, 1)[15:0] = foo[31:16]
R_MIPS_HI16:
lui $1, %hi(foo)
Expand Down

0 comments on commit 0326a06

Please sign in to comment.