Skip to content

Commit

Permalink
[mips64] Emit correct addend for some PC-relative relocations
Browse files Browse the repository at this point in the history
So far, LLVM has not emitted correct addend for N64 and N32 ABI. This patch
fixes that. It also removes fixup from MCJIT for R_MIPS_PC16 relocation.

Patch by Vladimir Radosavljevic.

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


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240404 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
petar-jovanovic committed Jun 23, 2015
1 parent 14e438d commit 7c5bf4d
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 79 deletions.
2 changes: 1 addition & 1 deletion lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,7 @@ RuntimeDyldELF::evaluateMIPS64Relocation(const SectionEntry &Section,
}
case ELF::R_MIPS_PC16: {
uint64_t FinalAddress = (Section.LoadAddress + Offset);
return ((Value + Addend - FinalAddress - 4) >> 2) & 0xffff;
return ((Value + Addend - FinalAddress) >> 2) & 0xffff;
}
case ELF::R_MIPS_PC32: {
uint64_t FinalAddress = (Section.LoadAddress + Offset);
Expand Down
6 changes: 0 additions & 6 deletions lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,6 @@ static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
case Mips::fixup_MIPS_PCLO16:
break;
case Mips::fixup_Mips_PC16:
// So far we are only using this type for branches.
// For branches we start 1 instruction after the branch
// so the displacement will be one instruction size less.
Value -= 4;
// The displacement is then divided by 4 to give us an 18 bit
// address range. Forcing a signed division because Value can be negative.
Value = (int64_t)Value / 4;
Expand Down Expand Up @@ -135,15 +131,13 @@ static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
Ctx->reportFatalError(Fixup.getLoc(), "out of range PC18 fixup");
break;
case Mips::fixup_MIPS_PC21_S2:
Value -= 4;
// Forcing a signed division because Value can be negative.
Value = (int64_t) Value / 4;
// We now check if Value can be encoded as a 21-bit signed immediate.
if (!isIntN(21, Value) && Ctx)
Ctx->reportFatalError(Fixup.getLoc(), "out of range PC21 fixup");
break;
case Mips::fixup_MIPS_PC26_S2:
Value -= 4;
// Forcing a signed division because Value can be negative.
Value = (int64_t) Value / 4;
// We now check if Value can be encoded as a 26-bit signed immediate.
Expand Down
15 changes: 9 additions & 6 deletions lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,9 @@ getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
assert(MO.isExpr() &&
"getBranchTargetOpValue expects only expressions or immediates");

const MCExpr *Expr = MO.getExpr();
Fixups.push_back(MCFixup::create(0, Expr,
const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
Fixups.push_back(MCFixup::create(0, FixupExpression,
MCFixupKind(Mips::fixup_Mips_PC16)));
return 0;
}
Expand Down Expand Up @@ -315,8 +316,9 @@ getBranchTarget21OpValue(const MCInst &MI, unsigned OpNo,
assert(MO.isExpr() &&
"getBranchTarget21OpValue expects only expressions or immediates");

const MCExpr *Expr = MO.getExpr();
Fixups.push_back(MCFixup::create(0, Expr,
const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
Fixups.push_back(MCFixup::create(0, FixupExpression,
MCFixupKind(Mips::fixup_MIPS_PC21_S2)));
return 0;
}
Expand All @@ -337,8 +339,9 @@ getBranchTarget26OpValue(const MCInst &MI, unsigned OpNo,
assert(MO.isExpr() &&
"getBranchTarget26OpValue expects only expressions or immediates");

const MCExpr *Expr = MO.getExpr();
Fixups.push_back(MCFixup::create(0, Expr,
const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
Fixups.push_back(MCFixup::create(0, FixupExpression,
MCFixupKind(Mips::fixup_MIPS_PC26_S2)));
return 0;
}
Expand Down
74 changes: 37 additions & 37 deletions test/MC/Mips/branch-pseudos.s
Original file line number Diff line number Diff line change
Expand Up @@ -7,183 +7,183 @@ local_label:
blt $7, $8, local_label
# CHECK: slt $1, $7, $8 # encoding: [0x00,0xe8,0x08,0x2a]
# CHECK: bnez $1, local_label # encoding: [0x14,0x20,A,A]
# CHECK: # fixup A - offset: 0, value: local_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: local_label-4, kind: fixup_Mips_PC16
# CHECK: nop
blt $7, $8, global_label
# CHECK: slt $1, $7, $8 # encoding: [0x00,0xe8,0x08,0x2a]
# CHECK: bnez $1, global_label # encoding: [0x14,0x20,A,A]
# CHECK: # fixup A - offset: 0, value: global_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: global_label-4, kind: fixup_Mips_PC16
# CHECK: nop
blt $7, $0, local_label
# CHECK: bltz $7, local_label # encoding: [0x04,0xe0,A,A]
# CHECK: # fixup A - offset: 0, value: local_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: local_label-4, kind: fixup_Mips_PC16
# CHECK: nop
blt $0, $8, local_label
# CHECK: bgtz $8, local_label # encoding: [0x1d,0x00,A,A]
# CHECK: # fixup A - offset: 0, value: local_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: local_label-4, kind: fixup_Mips_PC16
# CHECK: nop
blt $0, $0, local_label
# CHECK: bltz $zero, local_label # encoding: [0x04,0x00,A,A]
# CHECK: # fixup A - offset: 0, value: local_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: local_label-4, kind: fixup_Mips_PC16
# CHECK: nop

bltu $7, $8, local_label
# CHECK: sltu $1, $7, $8 # encoding: [0x00,0xe8,0x08,0x2b]
# CHECK: bnez $1, local_label # encoding: [0x14,0x20,A,A]
# CHECK: # fixup A - offset: 0, value: local_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: local_label-4, kind: fixup_Mips_PC16
# CHECK: nop
bltu $7, $8, global_label
# CHECK: sltu $1, $7, $8 # encoding: [0x00,0xe8,0x08,0x2b]
# CHECK: bnez $1, global_label # encoding: [0x14,0x20,A,A]
# CHECK: # fixup A - offset: 0, value: global_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: global_label-4, kind: fixup_Mips_PC16
# CHECK: nop
bltu $7, $0, local_label
# CHECK: nop
bltu $0, $8, local_label
# CHECK: bnez $8, local_label # encoding: [0x15,0x00,A,A]
# CHECK: # fixup A - offset: 0, value: local_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: local_label-4, kind: fixup_Mips_PC16
# CHECK: nop
bltu $0, $0, local_label
# CHECK: nop

ble $7, $8, local_label
# CHECK: slt $1, $8, $7 # encoding: [0x01,0x07,0x08,0x2a]
# CHECK: beqz $1, local_label # encoding: [0x10,0x20,A,A]
# CHECK: # fixup A - offset: 0, value: local_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: local_label-4, kind: fixup_Mips_PC16
# CHECK: nop
ble $7, $8, global_label
# CHECK: slt $1, $8, $7 # encoding: [0x01,0x07,0x08,0x2a]
# CHECK: beqz $1, global_label # encoding: [0x10,0x20,A,A]
# CHECK: # fixup A - offset: 0, value: global_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: global_label-4, kind: fixup_Mips_PC16
# CHECK: nop
ble $7, $0, local_label
# CHECK: blez $7, local_label # encoding: [0x18,0xe0,A,A]
# CHECK: # fixup A - offset: 0, value: local_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: local_label-4, kind: fixup_Mips_PC16
# CHECK: nop
ble $0, $8, local_label
# CHECK: bgez $8, local_label # encoding: [0x05,0x01,A,A]
# CHECK: # fixup A - offset: 0, value: local_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: local_label-4, kind: fixup_Mips_PC16
# CHECK: nop
ble $0, $0, local_label
# WARNING: :[[@LINE-1]]:3: warning: branch is always taken
# CHECK: blez $zero, local_label # encoding: [0x18,0x00,A,A]
# CHECK: # fixup A - offset: 0, value: local_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: local_label-4, kind: fixup_Mips_PC16
# CHECK: nop

bleu $7, $8, local_label
# CHECK: sltu $1, $8, $7 # encoding: [0x01,0x07,0x08,0x2b]
# CHECK: beqz $1, local_label # encoding: [0x10,0x20,A,A]
# CHECK: # fixup A - offset: 0, value: local_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: local_label-4, kind: fixup_Mips_PC16
# CHECK: nop
bleu $7, $8, global_label
# CHECK: sltu $1, $8, $7 # encoding: [0x01,0x07,0x08,0x2b]
# CHECK: beqz $1, global_label # encoding: [0x10,0x20,A,A]
# CHECK: # fixup A - offset: 0, value: global_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: global_label-4, kind: fixup_Mips_PC16
# CHECK: nop
bleu $7, $0, local_label
# CHECK: beqz $7, local_label # encoding: [0x10,0xe0,A,A]
# CHECK: # fixup A - offset: 0, value: local_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: local_label-4, kind: fixup_Mips_PC16
# CHECK: nop
bleu $0, $8, local_label
# WARNING: :[[@LINE-1]]:3: warning: branch is always taken
# CHECK: b local_label # encoding: [0x10,0x00,A,A]
# CHECK: # fixup A - offset: 0, value: local_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: local_label-4, kind: fixup_Mips_PC16
# CHECK: nop
bleu $0, $0, local_label
# WARNING: :[[@LINE-1]]:3: warning: branch is always taken
# CHECK: b local_label # encoding: [0x10,0x00,A,A]
# CHECK: # fixup A - offset: 0, value: local_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: local_label-4, kind: fixup_Mips_PC16
# CHECK: nop

bge $7, $8, local_label
# CHECK: slt $1, $7, $8 # encoding: [0x00,0xe8,0x08,0x2a]
# CHECK: beqz $1, local_label # encoding: [0x10,0x20,A,A]
# CHECK: # fixup A - offset: 0, value: local_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: local_label-4, kind: fixup_Mips_PC16
# CHECK: nop
bge $7, $8, global_label
# CHECK: slt $1, $7, $8 # encoding: [0x00,0xe8,0x08,0x2a]
# CHECK: beqz $1, global_label # encoding: [0x10,0x20,A,A]
# CHECK: # fixup A - offset: 0, value: global_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: global_label-4, kind: fixup_Mips_PC16
# CHECK: nop
bge $7, $0, local_label
# CHECK: bgez $7, local_label # encoding: [0x04,0xe1,A,A]
# CHECK: # fixup A - offset: 0, value: local_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: local_label-4, kind: fixup_Mips_PC16
# CHECK: nop
bge $0, $8, local_label
# CHECK: blez $8, local_label # encoding: [0x19,0x00,A,A]
# CHECK: # fixup A - offset: 0, value: local_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: local_label-4, kind: fixup_Mips_PC16
# CHECK: nop
bge $0, $0, local_label
# WARNING: :[[@LINE-1]]:3: warning: branch is always taken
# CHECK: bgez $zero, local_label # encoding: [0x04,0x01,A,A]
# CHECK: # fixup A - offset: 0, value: local_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: local_label-4, kind: fixup_Mips_PC16
# CHECK: nop

bgeu $7, $8, local_label
# CHECK: sltu $1, $7, $8 # encoding: [0x00,0xe8,0x08,0x2b]
# CHECK: beqz $1, local_label # encoding: [0x10,0x20,A,A]
# CHECK: # fixup A - offset: 0, value: local_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: local_label-4, kind: fixup_Mips_PC16
# CHECK: nop
bgeu $7, $8, global_label
# CHECK: sltu $1, $7, $8 # encoding: [0x00,0xe8,0x08,0x2b]
# CHECK: beqz $1, global_label # encoding: [0x10,0x20,A,A]
# CHECK: # fixup A - offset: 0, value: global_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: global_label-4, kind: fixup_Mips_PC16
# CHECK: nop
bgeu $7, $0, local_label
# WARNING: :[[@LINE-1]]:3: warning: branch is always taken
# CHECK: b local_label # encoding: [0x10,0x00,A,A]
# CHECK: # fixup A - offset: 0, value: local_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: local_label-4, kind: fixup_Mips_PC16
# CHECK: nop
bgeu $0, $8, local_label
# CHECK: beqz $8, local_label # encoding: [0x11,0x00,A,A]
# CHECK: # fixup A - offset: 0, value: local_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: local_label-4, kind: fixup_Mips_PC16
# CHECK: nop
bgeu $0, $0, local_label
# WARNING: :[[@LINE-1]]:3: warning: branch is always taken
# CHECK: b local_label # encoding: [0x10,0x00,A,A]
# CHECK: # fixup A - offset: 0, value: local_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: local_label-4, kind: fixup_Mips_PC16
# CHECK: nop

bgt $7, $8, local_label
# CHECK: slt $1, $8, $7 # encoding: [0x01,0x07,0x08,0x2a]
# CHECK: bnez $1, local_label # encoding: [0x14,0x20,A,A]
# CHECK: # fixup A - offset: 0, value: local_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: local_label-4, kind: fixup_Mips_PC16
# CHECK: nop
bgt $7, $8, global_label
# CHECK: slt $1, $8, $7 # encoding: [0x01,0x07,0x08,0x2a]
# CHECK: bnez $1, global_label # encoding: [0x14,0x20,A,A]
# CHECK: # fixup A - offset: 0, value: global_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: global_label-4, kind: fixup_Mips_PC16
# CHECK: nop
bgt $7, $0, local_label
# CHECK: bgtz $7, local_label # encoding: [0x1c,0xe0,A,A]
# CHECK: # fixup A - offset: 0, value: local_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: local_label-4, kind: fixup_Mips_PC16
# CHECK: nop
bgt $0, $8, local_label
# CHECK: bltz $8, local_label # encoding: [0x05,0x00,A,A]
# CHECK: # fixup A - offset: 0, value: local_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: local_label-4, kind: fixup_Mips_PC16
# CHECK: nop
bgt $0, $0, local_label
# CHECK: bgtz $zero, local_label # encoding: [0x1c,0x00,A,A]
# CHECK: # fixup A - offset: 0, value: local_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: local_label-4, kind: fixup_Mips_PC16
# CHECK: nop

bgtu $7, $8, local_label
# CHECK: sltu $1, $8, $7 # encoding: [0x01,0x07,0x08,0x2b]
# CHECK: bnez $1, local_label # encoding: [0x14,0x20,A,A]
# CHECK: # fixup A - offset: 0, value: local_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: local_label-4, kind: fixup_Mips_PC16
# CHECK: nop
bgtu $7, $8, global_label
# CHECK: sltu $1, $8, $7 # encoding: [0x01,0x07,0x08,0x2b]
# CHECK: bnez $1, global_label # encoding: [0x14,0x20,A,A]
# CHECK: # fixup A - offset: 0, value: global_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: global_label-4, kind: fixup_Mips_PC16
# CHECK: nop
bgtu $7, $0, local_label
# CHECK: bnez $7, local_label # encoding: [0x14,0xe0,A,A]
# CHECK: # fixup A - offset: 0, value: local_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: local_label-4, kind: fixup_Mips_PC16
# CHECK: nop
bgtu $0, $8, local_label
# CHECK: nop
bgtu $0, $0, local_label
# CHECK: bnez $zero, local_label # encoding: [0x14,0x00,A,A]
# CHECK: # fixup A - offset: 0, value: local_label, kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: local_label-4, kind: fixup_Mips_PC16
# CHECK: nop
2 changes: 1 addition & 1 deletion test/MC/Mips/mips-fpu-instructions.s
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@
# FP move instructions
#------------------------------------------------------------------------------
# CHECK: bc1f $BB_1 # encoding: [A,A,0x00,0x45]
# CHECK: # fixup A - offset: 0, value: ($BB_1), kind: fixup_Mips_PC16
# CHECK: # fixup A - offset: 0, value: ($BB_1)-4, kind: fixup_Mips_PC16

# CHECK: cfc1 $6, $0 # encoding: [0x00,0x00,0x46,0x44]
# CHECK: ctc1 $10, $31 # encoding: [0x00,0xf8,0xca,0x44]
Expand Down
12 changes: 6 additions & 6 deletions test/MC/Mips/mips32r6/relocations.s
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,22 @@
# CHECK-FIXUP: value: bar, kind: fixup_MIPS_PC19_S2
# CHECK-FIXUP: beqc $5, $6, bar # encoding: [0x20,0xa6,A,A]
# CHECK-FIXUP: # fixup A - offset: 0,
# CHECK-FIXUP: value: bar, kind: fixup_Mips_PC16
# CHECK-FIXUP: value: bar-4, kind: fixup_Mips_PC16
# CHECK-FIXUP: bnec $5, $6, bar # encoding: [0x60,0xa6,A,A]
# CHECK-FIXUP: # fixup A - offset: 0,
# CHECK-FIXUP: value: bar, kind: fixup_Mips_PC16
# CHECK-FIXUP: value: bar-4, kind: fixup_Mips_PC16
# CHECK-FIXUP: beqzc $9, bar # encoding: [0xd9,0b001AAAAA,A,A]
# CHECK-FIXUP: # fixup A - offset: 0,
# CHECK-FIXUP: value: bar, kind: fixup_MIPS_PC21_S2
# CHECK-FIXUP: value: bar-4, kind: fixup_MIPS_PC21_S2
# CHECK-FIXUP: bnezc $9, bar # encoding: [0xf9,0b001AAAAA,A,A]
# CHECK-FIXUP: # fixup A - offset: 0,
# CHECK-FIXUP: value: bar, kind: fixup_MIPS_PC21_S2
# CHECK-FIXUP: value: bar-4, kind: fixup_MIPS_PC21_S2
# CHECK-FIXUP: balc bar # encoding: [0b111010AA,A,A,A]
# CHECK-FIXUP: # fixup A - offset: 0,
# CHECK-FIXUP: value: bar, kind: fixup_MIPS_PC26_S2
# CHECK-FIXUP: value: bar-4, kind: fixup_MIPS_PC26_S2
# CHECK-FIXUP: bc bar # encoding: [0b110010AA,A,A,A]
# CHECK-FIXUP: # fixup A - offset: 0,
# CHECK-FIXUP: value: bar, kind: fixup_MIPS_PC26_S2
# CHECK-FIXUP: value: bar-4, kind: fixup_MIPS_PC26_S2
# CHECK-FIXUP: aluipc $2, %pcrel_hi(bar) # encoding: [0xec,0x5f,A,A]
# CHECK-FIXUP: # fixup A - offset: 0,
# CHECK-FIXUP: value: bar@PCREL_HI16,
Expand Down
Loading

0 comments on commit 7c5bf4d

Please sign in to comment.