[mips] Emit R_MICROMIPS_GPREL16/R_MICROMIPS_SUB/R_MICROMIPS_LO16 / HI16 relocations

Emit R_MICROMIPS_GPREL16/R_MICROMIPS_SUB/R_MICROMIPS_LO16 and
R_MICROMIPS_GPREL16/R_MICROMIPS_SUB/R_MICROMIPS_HI16 chains of
relocations for %lo(%neg(%gp_rel())) and %hi(%neg(%gp_rel()))
expressions in case of microMIPS.

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

llvm-svn: 333409
This commit is contained in:
Simon Atanasyan 2018-05-29 11:33:54 +00:00
parent 98686c6b15
commit a1d69f9e53
5 changed files with 69 additions and 13 deletions

View File

@ -54,6 +54,8 @@ static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
case Mips::fixup_Mips_GOT_DISP:
case Mips::fixup_Mips_GOT_LO16:
case Mips::fixup_Mips_CALL_LO16:
case Mips::fixup_MICROMIPS_GPOFF_HI:
case Mips::fixup_MICROMIPS_GPOFF_LO:
case Mips::fixup_MICROMIPS_LO16:
case Mips::fixup_MICROMIPS_GOT_PAGE:
case Mips::fixup_MICROMIPS_GOT_OFST:
@ -336,7 +338,9 @@ getFixupKindInfo(MCFixupKind Kind) const {
{ "fixup_Mips_DTPREL_LO", 0, 16, 0 },
{ "fixup_Mips_Branch_PCRel", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_Mips_GPOFF_HI", 0, 16, 0 },
{ "fixup_MICROMIPS_GPOFF_HI",0, 16, 0 },
{ "fixup_Mips_GPOFF_LO", 0, 16, 0 },
{ "fixup_MICROMIPS_GPOFF_LO",0, 16, 0 },
{ "fixup_Mips_GOT_PAGE", 0, 16, 0 },
{ "fixup_Mips_GOT_OFST", 0, 16, 0 },
{ "fixup_Mips_GOT_DISP", 0, 16, 0 },
@ -412,7 +416,9 @@ getFixupKindInfo(MCFixupKind Kind) const {
{ "fixup_Mips_DTPREL_LO", 16, 16, 0 },
{ "fixup_Mips_Branch_PCRel",16, 16, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_Mips_GPOFF_HI", 16, 16, 0 },
{ "fixup_MICROMIPS_GPOFF_HI", 16, 16, 0 },
{ "fixup_Mips_GPOFF_LO", 16, 16, 0 },
{ "fixup_MICROMIPS_GPOFF_LO", 16, 16, 0 },
{ "fixup_Mips_GOT_PAGE", 16, 16, 0 },
{ "fixup_Mips_GOT_OFST", 16, 16, 0 },
{ "fixup_Mips_GOT_DISP", 16, 16, 0 },

View File

@ -329,6 +329,13 @@ unsigned MipsELFObjectWriter::getRelocType(MCContext &Ctx,
Type = setRType3((unsigned)ELF::R_MIPS_HI16, Type);
return Type;
}
case Mips::fixup_MICROMIPS_GPOFF_HI: {
unsigned Type = (unsigned)ELF::R_MIPS_NONE;
Type = setRType((unsigned)ELF::R_MICROMIPS_GPREL16, Type);
Type = setRType2((unsigned)ELF::R_MICROMIPS_SUB, Type);
Type = setRType3((unsigned)ELF::R_MICROMIPS_HI16, Type);
return Type;
}
case Mips::fixup_Mips_GPOFF_LO: {
unsigned Type = (unsigned)ELF::R_MIPS_NONE;
Type = setRType((unsigned)ELF::R_MIPS_GPREL16, Type);
@ -336,6 +343,13 @@ unsigned MipsELFObjectWriter::getRelocType(MCContext &Ctx,
Type = setRType3((unsigned)ELF::R_MIPS_LO16, Type);
return Type;
}
case Mips::fixup_MICROMIPS_GPOFF_LO: {
unsigned Type = (unsigned)ELF::R_MIPS_NONE;
Type = setRType((unsigned)ELF::R_MICROMIPS_GPREL16, Type);
Type = setRType2((unsigned)ELF::R_MICROMIPS_SUB, Type);
Type = setRType3((unsigned)ELF::R_MICROMIPS_LO16, Type);
return Type;
}
case Mips::fixup_Mips_HIGHER:
return ELF::R_MIPS_HIGHER;
case Mips::fixup_Mips_HIGHEST:

View File

@ -96,10 +96,14 @@ namespace Mips {
fixup_Mips_Branch_PCRel,
// resulting in - R_MIPS_GPREL16/R_MIPS_SUB/R_MIPS_HI16
// R_MICROMIPS_GPREL16/R_MICROMIPS_SUB/R_MICROMIPS_HI16
fixup_Mips_GPOFF_HI,
fixup_MICROMIPS_GPOFF_HI,
// resulting in - R_MIPS_GPREL16/R_MIPS_SUB/R_MIPS_LO16
// R_MICROMIPS_GPREL16/R_MICROMIPS_SUB/R_MICROMIPS_LO16
fixup_Mips_GPOFF_LO,
fixup_MICROMIPS_GPOFF_LO,
// resulting in - R_MIPS_PAGE
fixup_Mips_GOT_PAGE,

View File

@ -656,12 +656,12 @@ getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups,
break;
case MipsMCExpr::MEK_LO:
// Check for %lo(%neg(%gp_rel(X)))
if (MipsExpr->isGpOff()) {
FixupKind = Mips::fixup_Mips_GPOFF_LO;
break;
}
FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16
: Mips::fixup_Mips_LO16;
if (MipsExpr->isGpOff())
FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GPOFF_LO
: Mips::fixup_Mips_GPOFF_LO;
else
FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16
: Mips::fixup_Mips_LO16;
break;
case MipsMCExpr::MEK_HIGHEST:
FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HIGHEST
@ -673,12 +673,12 @@ getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups,
break;
case MipsMCExpr::MEK_HI:
// Check for %hi(%neg(%gp_rel(X)))
if (MipsExpr->isGpOff()) {
FixupKind = Mips::fixup_Mips_GPOFF_HI;
break;
}
FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16
: Mips::fixup_Mips_HI16;
if (MipsExpr->isGpOff())
FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GPOFF_HI
: Mips::fixup_Mips_GPOFF_HI;
else
FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16
: Mips::fixup_Mips_HI16;
break;
case MipsMCExpr::MEK_PCREL_HI16:
FixupKind = Mips::fixup_MIPS_PCHI16;

View File

@ -23,17 +23,49 @@
// DATA-LABEL: Name: .text
// DATA: SectionData (
// DATA-NEXT: 0000: 24620000 24620000
// DATA-NEXT: 0000: 3C030000 24620000 3C030000 24620000
lui $3, %hi(%neg(%gp_rel(foo))) // RELOC: R_MIPS_GPREL16/R_MIPS_SUB/R_MIPS_HI16 foo
// ENCBE: lui $3, %hi(%neg(%gp_rel(foo))) # encoding: [0x3c,0x03,A,A]
// ENCLE: lui $3, %hi(%neg(%gp_rel(foo))) # encoding: [A,A,0x03,0x3c]
// FIXUP: # fixup A - offset: 0, value: %hi(%neg(%gp_rel(foo))), kind: fixup_Mips_GPOFF_HI
addiu $2, $3, %lo(%neg(%gp_rel(foo))) // RELOC: R_MIPS_GPREL16/R_MIPS_SUB/R_MIPS_LO16 foo
// ENCBE: addiu $2, $3, %lo(%neg(%gp_rel(foo))) # encoding: [0x24,0x62,A,A]
// ENCLE: addiu $2, $3, %lo(%neg(%gp_rel(foo))) # encoding: [A,A,0x62,0x24]
// FIXUP: # fixup A - offset: 0, value: %lo(%neg(%gp_rel(foo))), kind: fixup_Mips_GPOFF_LO
lui $3, %hi(%neg(%gp_rel(bar))) // RELOC: R_MIPS_GPREL16/R_MIPS_SUB/R_MIPS_HI16 .data
// ENCBE: lui $3, %hi(%neg(%gp_rel(bar))) # encoding: [0x3c,0x03,A,A]
// ENCLE: lui $3, %hi(%neg(%gp_rel(bar))) # encoding: [A,A,0x03,0x3c]
// FIXUP: # fixup A - offset: 0, value: %hi(%neg(%gp_rel(bar))), kind: fixup_Mips_GPOFF_HI
addiu $2, $3, %lo(%neg(%gp_rel(bar))) // RELOC: R_MIPS_GPREL16/R_MIPS_SUB/R_MIPS_LO16 .data
// ENCBE: addiu $2, $3, %lo(%neg(%gp_rel(bar))) # encoding: [0x24,0x62,A,A]
// ENCLE: addiu $2, $3, %lo(%neg(%gp_rel(bar))) # encoding: [A,A,0x62,0x24]
// FIXUP: # fixup A - offset: 0, value: %lo(%neg(%gp_rel(bar))), kind: fixup_Mips_GPOFF_LO
// DATA-NEXT: 0010: 41A30000 30430000 41A30000 30430000
.set micromips
lui $3, %hi(%neg(%gp_rel(foo))) // RELOC: R_MICROMIPS_GPREL16/R_MICROMIPS_SUB/R_MICROMIPS_HI16 foo
// ENCBE: lui $3, %hi(%neg(%gp_rel(foo))) # encoding: [0x41,0xa3,A,A]
// ENCLE: lui $3, %hi(%neg(%gp_rel(foo))) # encoding: [0xa3'A',0x41'A',0x00,0x00]
// FIXUP: # fixup A - offset: 0, value: %hi(%neg(%gp_rel(foo))), kind: fixup_MICROMIPS_GPOFF_HI
addiu $2, $3, %lo(%neg(%gp_rel(foo))) // RELOC: R_MICROMIPS_GPREL16/R_MICROMIPS_SUB/R_MICROMIPS_LO16 foo
// ENCBE: addiu $2, $3, %lo(%neg(%gp_rel(foo))) # encoding: [0x30,0x43,A,A]
// ENCLE: addiu $2, $3, %lo(%neg(%gp_rel(foo))) # encoding: [0x43'A',0x30'A',0x00,0x00]
// FIXUP: # fixup A - offset: 0, value: %lo(%neg(%gp_rel(foo))), kind: fixup_MICROMIPS_GPOFF_LO
lui $3, %hi(%neg(%gp_rel(bar))) // RELOC: R_MICROMIPS_GPREL16/R_MICROMIPS_SUB/R_MICROMIPS_HI16 bar
// ENCBE: lui $3, %hi(%neg(%gp_rel(bar))) # encoding: [0x41,0xa3,A,A]
// ENCLE: lui $3, %hi(%neg(%gp_rel(bar))) # encoding: [0xa3'A',0x41'A',0x00,0x00]
// FIXUP: # fixup A - offset: 0, value: %hi(%neg(%gp_rel(bar))), kind: fixup_MICROMIPS_GPOFF_HI
addiu $2, $3, %lo(%neg(%gp_rel(bar))) // RELOC: R_MICROMIPS_GPREL16/R_MICROMIPS_SUB/R_MICROMIPS_LO16 bar
// ENCBE: addiu $2, $3, %lo(%neg(%gp_rel(bar))) # encoding: [0x30,0x43,A,A]
// ENCLE: addiu $2, $3, %lo(%neg(%gp_rel(bar))) # encoding: [0x43'A',0x30'A',0x00,0x00]
// FIXUP: # fixup A - offset: 0, value: %lo(%neg(%gp_rel(bar))), kind: fixup_MICROMIPS_GPOFF_LO
.data
.word 0
bar: