[mips][mips64r6] Relocation R_MIPS_PC18_S3

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


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@210908 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Zoran Jovanovic 2014-06-13 14:26:47 +00:00
parent 6eaf840a3d
commit 636ae2b660
6 changed files with 38 additions and 6 deletions

View File

@ -111,6 +111,13 @@ static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
if (!isIntN(16, Value) && Ctx)
Ctx->FatalError(Fixup.getLoc(), "out of range PC16 fixup");
break;
case Mips::fixup_MIPS_PC18_S3:
// Forcing a signed division because Value can be negative.
Value = (int64_t)Value / 8;
// We now check if Value can be encoded as a 18-bit signed immediate.
if (!isIntN(18, Value) && Ctx)
Ctx->FatalError(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.
@ -254,6 +261,7 @@ getFixupKindInfo(MCFixupKind Kind) const {
{ "fixup_Mips_GOT_LO16", 0, 16, 0 },
{ "fixup_Mips_CALL_HI16", 0, 16, 0 },
{ "fixup_Mips_CALL_LO16", 0, 16, 0 },
{ "fixup_Mips_PC18_S3", 0, 18, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_MIPS_PC19_S2", 0, 19, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_MIPS_PC21_S2", 0, 21, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_MIPS_PC26_S2", 0, 26, MCFixupKindInfo::FKF_IsPCRel },
@ -316,6 +324,7 @@ getFixupKindInfo(MCFixupKind Kind) const {
{ "fixup_Mips_GOT_LO16", 16, 16, 0 },
{ "fixup_Mips_CALL_HI16", 16, 16, 0 },
{ "fixup_Mips_CALL_LO16", 16, 16, 0 },
{ "fixup_Mips_PC18_S3", 14, 18, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_MIPS_PC19_S2", 13, 19, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_MIPS_PC21_S2", 11, 21, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_MIPS_PC26_S2", 6, 26, MCFixupKindInfo::FKF_IsPCRel },

View File

@ -196,6 +196,9 @@ unsigned MipsELFObjectWriter::GetRelocType(const MCValue &Target,
case Mips::fixup_MIPS_PC19_S2:
Type = ELF::R_MIPS_PC19_S2;
break;
case Mips::fixup_MIPS_PC18_S3:
Type = ELF::R_MIPS_PC18_S3;
break;
case Mips::fixup_MIPS_PC21_S2:
Type = ELF::R_MIPS_PC21_S2;
break;

View File

@ -128,6 +128,9 @@ namespace Mips {
// resulting in - R_MIPS_CALL_LO16
fixup_Mips_CALL_LO16,
// resulting in - R_MIPS_PC18_S3
fixup_MIPS_PC18_S3,
// resulting in - R_MIPS_PC19_S2
fixup_MIPS_PC19_S2,

View File

@ -642,11 +642,21 @@ unsigned
MipsMCCodeEmitter::getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
assert(MI.getOperand(OpNo).isImm());
// The immediate is encoded as 'immediate << 3'.
unsigned Res = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
assert((Res & 7) == 0);
return Res >> 3;
const MCOperand &MO = MI.getOperand(OpNo);
if (MO.isImm()) {
// The immediate is encoded as 'immediate << 3'.
unsigned Res = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
assert((Res & 7) == 0);
return Res >> 3;
}
assert(MO.isExpr() &&
"getSimm18Lsl2Encoding expects only expressions or an immediate");
const MCExpr *Expr = MO.getExpr();
Fixups.push_back(MCFixup::Create(0, Expr,
MCFixupKind(Mips::fixup_MIPS_PC18_S3)));
return 0;
}
#include "MipsGenMCCodeEmitter.inc"

View File

@ -365,6 +365,7 @@ def simm19_lsl2 : Operand<i32> {
def simm18_lsl3 : Operand<i32> {
let EncoderMethod = "getSimm18Lsl3Encoding";
let DecoderMethod = "DecodeSimm18Lsl3";
let ParserMatchClass = MipsJumpTargetAsmOperand;
}
def simm20 : Operand<i32> {

View File

@ -34,6 +34,10 @@
# CHECK-FIXUP: # fixup A - offset: 0,
# CHECK-FIXUP: value: bar@PCREL_LO16,
# CHECK-FIXUP: kind: fixup_MIPS_PCLO16
# CHECK-FIXUP: ldpc $2, bar # encoding: [0xec,0b010110AA,A,A]
# CHECK-FIXUP: # fixup A - offset: 0,
# CHECK-FIXUP: value: bar,
# CHECK-FIXUP: kind: fixup_Mips_PC18_S3
# CHECK-FIXUP: lwpc $2, bar # encoding: [0xec,0b01001AAA,A,A]
# CHECK-FIXUP: # fixup A - offset: 0,
# CHECK-FIXUP: value: bar, kind: fixup_MIPS_PC19_S2
@ -53,8 +57,9 @@
# CHECK-ELF: 0x18 R_MIPS_PC26_S2 bar 0x0
# CHECK-ELF: 0x1C R_MIPS_PCHI16 bar 0x0
# CHECK-ELF: 0x20 R_MIPS_PCLO16 bar 0x0
# CHECK-ELF: 0x24 R_MIPS_PC19_S2 bar 0x0
# CHECK-ELF: 0x24 R_MIPS_PC18_S3 bar 0x0
# CHECK-ELF: 0x28 R_MIPS_PC19_S2 bar 0x0
# CHECK-ELF: 0x2C R_MIPS_PC19_S2 bar 0x0
# CHECK-ELF: ]
addiupc $2,bar
@ -66,5 +71,6 @@
bc bar
aluipc $2, %pcrel_hi(bar)
addiu $2, $2, %pcrel_lo(bar)
ldpc $2,bar
lwpc $2,bar
lwupc $2,bar