Index: llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp =================================================================== --- llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp +++ llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp @@ -54,6 +54,8 @@ 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 @@ { "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 @@ { "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 }, Index: llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp =================================================================== --- llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp +++ llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp @@ -329,6 +329,13 @@ 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 @@ 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: Index: llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h =================================================================== --- llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h +++ llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h @@ -96,10 +96,14 @@ 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, Index: llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp =================================================================== --- llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -656,12 +656,12 @@ 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 @@ 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; Index: llvm/trunk/test/MC/Mips/relocation-n64.s =================================================================== --- llvm/trunk/test/MC/Mips/relocation-n64.s +++ llvm/trunk/test/MC/Mips/relocation-n64.s @@ -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: