Index: lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp +++ lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp @@ -476,10 +476,12 @@ bool MipsELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym, unsigned Type) const { - // This must be a compound relocation from the N64 ABI. - // FIXME: Return false iff all sub-relocations return false. + // If it's a compound relocation for N64 then we need the relocation if any + // sub-relocation needs it. if (!isUInt<8>(Type)) - return true; + return needsRelocateWithSymbol(Sym, Type & 0xff) || + needsRelocateWithSymbol(Sym, (Type >> 8) & 0xff) || + needsRelocateWithSymbol(Sym, (Type >> 16) & 0xff); switch (Type) { default: @@ -519,6 +521,7 @@ case ELF::R_MIPS_GPREL16: case ELF::R_MIPS_GPREL32: case ELF::R_MIPS_PC16: + case ELF::R_MIPS_SUB: return false; // FIXME: Many of these relocations should probably return false but this @@ -533,7 +536,6 @@ case ELF::R_MIPS_GOT_OFST: case ELF::R_MIPS_GOT_HI16: case ELF::R_MIPS_GOT_LO16: - case ELF::R_MIPS_SUB: case ELF::R_MIPS_INSERT_A: case ELF::R_MIPS_INSERT_B: case ELF::R_MIPS_DELETE: @@ -621,7 +623,6 @@ case ELF::R_MIPS16_TLS_TPREL_LO16: llvm_unreachable("Unsupported MIPS16 relocation"); return true; - } } Index: test/MC/Mips/cpsetup.s =================================================================== --- test/MC/Mips/cpsetup.s +++ test/MC/Mips/cpsetup.s @@ -6,14 +6,14 @@ # RUN: FileCheck -check-prefix=ALL -check-prefix=ASM %s # RUN: llvm-mc -triple mips64-unknown-unknown -target-abi n32 -filetype=obj -o - %s | \ -# RUN: llvm-objdump -d -r -t -arch=mips64 - | \ +# RUN: llvm-objdump -d -r -arch=mips64 - | \ # RUN: FileCheck -check-prefix=ALL -check-prefix=NXX -check-prefix=N32 %s # RUN: llvm-mc -triple mips64-unknown-unknown -target-abi n32 %s | \ # RUN: FileCheck -check-prefix=ALL -check-prefix=ASM %s # RUN: llvm-mc -triple mips64-unknown-unknown %s -filetype=obj -o - | \ -# RUN: llvm-objdump -d -r -t -arch=mips64 - | \ +# RUN: llvm-objdump -d -r -arch=mips64 - | \ # RUN: FileCheck -check-prefix=ALL -check-prefix=NXX -check-prefix=N64 %s # RUN: llvm-mc -triple mips64-unknown-unknown %s | \ @@ -105,12 +105,11 @@ # N32 doesn't allow 3 operations to be specified in the same relocation # record like N64 does. -# NXX: $tmp0: # NXX-NEXT: move $2, $gp # NXX-NEXT: lui $gp, 0 -# NXX-NEXT: R_MIPS_GPREL16/R_MIPS_SUB/R_MIPS_HI16 $tmp0 +# NXX-NEXT: {{^ *0+}}40: R_MIPS_GPREL16/R_MIPS_SUB/R_MIPS_HI16 .text # NXX-NEXT: addiu $gp, $gp, 0 -# NXX-NEXT: R_MIPS_GPREL16/R_MIPS_SUB/R_MIPS_LO16 $tmp0 +# NXX-NEXT: {{^ *0+}}44: R_MIPS_GPREL16/R_MIPS_SUB/R_MIPS_LO16 .text # N32-NEXT: addu $gp, $gp, $25 # N64-NEXT: daddu $gp, $gp, $25 # NXX-NEXT: nop @@ -174,8 +173,3 @@ # ALL-NEXT: nop -# NXX-LABEL: SYMBOL TABLE: - -# For .cpsetup with local labels, we need to check if $tmp0 is in the symbol -# table: -# NXX: .text 00000000 $tmp0 Index: test/MC/Mips/relocation-n64.s =================================================================== --- /dev/null +++ test/MC/Mips/relocation-n64.s @@ -0,0 +1,41 @@ +// RUN: llvm-mc -triple mips64-unknown-linux < %s -show-encoding \ +// RUN: | FileCheck -check-prefix=ENCBE -check-prefix=FIXUP %s +// RUN: llvm-mc -triple mips64el-unknown-linux < %s -show-encoding \ +// RUN: | FileCheck -check-prefix=ENCLE -check-prefix=FIXUP %s +// RUN: llvm-mc -filetype=obj -triple mips64el-unknown-linux < %s \ +// RUN: | llvm-readobj -r | FileCheck -check-prefix=RELOC %s +// RUN: llvm-mc -filetype=obj -triple mips64-unknown-linux < %s \ +// RUN: | llvm-readobj -sections -section-data \ +// RUN: | FileCheck -check-prefix=DATA %s + +// Test that we produce the correct relocation. +// FIXME: move more relocation only tests here. + +// Check prefixes: +// RELOC - Check the relocation in the object. +// FIXUP - Check the fixup on the instruction. +// ENCBE - Check the big-endian encoding on the instruction. +// ENCLE - Check the little-endian encoding on the instruction. +// ????? - Placeholder. Relocation is defined but the way of generating it is +// unknown. +// FIXME - Placeholder. Generation method is known but doesn't work. + +// DATA-LABEL: Name: .text +// DATA: SectionData ( + +// DATA-NEXT: 0000: 24620000 24620000 + 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 + + 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 + .word 0 +bar: + .word 1 +// DATA-LABEL: Section {