Skip to content

Commit

Permalink
MIPS: fix emitDirectiveCpsetup on N32
Browse files Browse the repository at this point in the history
In the current code, we don't support -mno-shared yet, and
for N32, .cpsetup is expand as the style -f -mno-shared.

It will generate bad code for PIC binaries like:
00000000 <t1>:
   0:   ffbc0008        sd      gp,8(sp)
   4:   3c1c0000        lui     gp,0x0
                        4: R_MIPS_HI16  __gnu_local_gp
   8:   279c0000        addiu   gp,gp,0
                        8: R_MIPS_LO16  __gnu_local_gp

In fact which style of .cpsetup is used should be determined
by -m(no-)shared option instead of -mabi=n32 option.

Fixes: llvm#52785
  • Loading branch information
wzssyqa committed Feb 22, 2024
1 parent 0d12628 commit 0e9ab65
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 15 deletions.
12 changes: 9 additions & 3 deletions llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1255,7 +1255,9 @@ void MipsTargetELFStreamer::emitDirectiveCpsetup(unsigned RegNo,
emitRRI(Mips::SD, GPReg, Mips::SP, RegOrOffset, SMLoc(), &STI);
}

if (getABI().IsN32()) {
#if 0
// We haven't support -mabicalls -mno-shared yet.
if (-mno-shared) {
MCSymbol *GPSym = MCA.getContext().getOrCreateSymbol("__gnu_local_gp");
const MipsMCExpr *HiExpr = MipsMCExpr::create(
MipsMCExpr::MEK_HI, MCSymbolRefExpr::create(GPSym, MCA.getContext()),
Expand All @@ -1273,6 +1275,7 @@ void MipsTargetELFStreamer::emitDirectiveCpsetup(unsigned RegNo,

return;
}
#endif

const MipsMCExpr *HiExpr = MipsMCExpr::createGpOff(
MipsMCExpr::MEK_HI, MCSymbolRefExpr::create(&Sym, MCA.getContext()),
Expand All @@ -1288,8 +1291,11 @@ void MipsTargetELFStreamer::emitDirectiveCpsetup(unsigned RegNo,
emitRRX(Mips::ADDiu, GPReg, GPReg, MCOperand::createExpr(LoExpr), SMLoc(),
&STI);

// daddu $gp, $gp, $funcreg
emitRRR(Mips::DADDu, GPReg, GPReg, RegNo, SMLoc(), &STI);
// (d)addu $gp, $gp, $funcreg
if (getABI().IsN32())
emitRRR(Mips::ADDu, GPReg, GPReg, RegNo, SMLoc(), &STI);
else
emitRRR(Mips::DADDu, GPReg, GPReg, RegNo, SMLoc(), &STI);
}

void MipsTargetELFStreamer::emitDirectiveCpreturn(unsigned SaveLocation,
Expand Down
47 changes: 35 additions & 12 deletions llvm/test/MC/Mips/cpsetup.s
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
# RUN: llvm-mc -triple mips-unknown-linux -target-abi o32 %s | \
# RUN: FileCheck -check-prefixes=ASM,ASM-O32 %s

# FIXME: Now we check .cpsetup expansion for `-mno-shared` case only.
# We also need to implement/check the `-mshared` case.
# RUN: llvm-mc -triple mips64-unknown-linux -target-abi n32 -filetype=obj -o - %s | \
# RUN: llvm-objdump --no-print-imm-hex -d -r -z - | \
# RUN: FileCheck -check-prefixes=ALL,NXX,N32 %s
Expand Down Expand Up @@ -35,11 +33,16 @@ t1:

# NXX-NEXT: sd $gp, 8($sp)
# NXX-NEXT: lui $gp, 0
# N32-NEXT: R_MIPS_HI16 __gnu_local_gp
# N64-NEXT: R_MIPS_GPREL16/R_MIPS_SUB/R_MIPS_HI16 __cerror
# N32-NEXT: R_MIPS_GPREL16 __cerror
# N32-NEXT: R_MIPS_SUB
# N32-NEXT: R_MIPS_HI16
# NXX-NEXT: addiu $gp, $gp, 0
# N32-NEXT: R_MIPS_LO16 __gnu_local_gp
# N64-NEXT: R_MIPS_GPREL16/R_MIPS_SUB/R_MIPS_LO16 __cerror
# N32-NEXT: R_MIPS_GPREL16 __cerror
# N32-NEXT: R_MIPS_SUB
# N32-NEXT: R_MIPS_LO16
# N32-NEXT: addu $gp, $gp, $25
# N64-NEXT: daddu $gp, $gp, $25

# ASM-NEXT: .cpsetup $25, 8, __cerror
Expand All @@ -64,11 +67,16 @@ t2:

# NXX-NEXT: move $2, $gp
# NXX-NEXT: lui $gp, 0
# N32-NEXT: R_MIPS_HI16 __gnu_local_gp
# N64-NEXT: R_MIPS_GPREL16/R_MIPS_SUB/R_MIPS_HI16 __cerror
# N32-NEXT: R_MIPS_GPREL16 __cerror
# N32-NEXT: R_MIPS_SUB
# N32-NEXT: R_MIPS_HI16
# NXX-NEXT: addiu $gp, $gp, 0
# N32-NEXT: R_MIPS_LO16 __gnu_local_gp
# N64-NEXT: R_MIPS_GPREL16/R_MIPS_SUB/R_MIPS_LO16 __cerror
# N32-NEXT: R_MIPS_GPREL16 __cerror
# N32-NEXT: R_MIPS_SUB
# N32-NEXT: R_MIPS_LO16
# N32-NEXT: addu $gp, $gp, $25
# N64-NEXT: daddu $gp, $gp, $25

# ASM-NEXT: .cpsetup $25, $2, __cerror
Expand Down Expand Up @@ -101,11 +109,16 @@ t3:

# NXX-NEXT: move $2, $gp
# NXX-NEXT: lui $gp, 0
# N32-NEXT: {{^ *0+}}38: R_MIPS_HI16 __gnu_local_gp
# N64-NEXT: {{^ *0+}}40: R_MIPS_GPREL16/R_MIPS_SUB/R_MIPS_HI16 .text
# N32-NEXT: {{^ *0+}}40: R_MIPS_GPREL16 .text
# N32-NEXT: R_MIPS_SUB
# N32-NEXT: R_MIPS_HI16
# NXX-NEXT: addiu $gp, $gp, 0
# N32-NEXT: {{^ *0+}}3c: R_MIPS_LO16 __gnu_local_gp
# N64-NEXT: {{^ *0+}}44: R_MIPS_GPREL16/R_MIPS_SUB/R_MIPS_LO16 .text
# N32-NEXT: {{^ *0+}}44: R_MIPS_GPREL16 .text
# N32-NEXT: R_MIPS_SUB
# N32-NEXT: R_MIPS_LO16
# N32-NEXT: addu $gp, $gp, $25
# N64-NEXT: daddu $gp, $gp, $25
# NXX-NEXT: nop
# NXX-NEXT: sub $3, $3, $2
Expand Down Expand Up @@ -158,11 +171,16 @@ t5:

# NXX-NEXT: sd $gp, 8($sp)
# NXX-NEXT: lui $gp, 0
# N32-NEXT: R_MIPS_HI16 __gnu_local_gp
# N64-NEXT: R_MIPS_GPREL16/R_MIPS_SUB/R_MIPS_HI16 __cerror
# N32-NEXT: R_MIPS_GPREL16 __cerror
# N32-NEXT: R_MIPS_SUB
# N32-NEXT: R_MIPS_HI16
# NXX-NEXT: addiu $gp, $gp, 0
# N32-NEXT: R_MIPS_LO16 __gnu_local_gp
# N64-NEXT: R_MIPS_GPREL16/R_MIPS_SUB/R_MIPS_LO16 __cerror
# N32-NEXT: R_MIPS_GPREL16 __cerror
# N32-NEXT: R_MIPS_SUB
# N32-NEXT: R_MIPS_LO16
# N32-NEXT: addu $gp, $gp, $25
# N64-NEXT: daddu $gp, $gp, $25

# ASM-NEXT: .cpsetup $25, 8, __cerror
Expand All @@ -184,11 +202,16 @@ IMM_8 = 8

# NXX-NEXT: sd $gp, 8($sp)
# NXX-NEXT: lui $gp, 0
# N32-NEXT: R_MIPS_HI16 __gnu_local_gp
# N64-NEXT: R_MIPS_GPREL16/R_MIPS_SUB/R_MIPS_HI16 __cerror
# N32-NEXT: R_MIPS_GPREL16 __cerror
# N32-NEXT: R_MIPS_SUB
# N32-NEXT: R_MIPS_HI16
# NXX-NEXT: addiu $gp, $gp, 0
# N32-NEXT: R_MIPS_LO16 __gnu_local_gp
# N64-NEXT: R_MIPS_GPREL16/R_MIPS_SUB/R_MIPS_LO16 __cerror
# N32-NEXT: R_MIPS_GPREL16 __cerror
# N32-NEXT: R_MIPS_SUB
# N32-NEXT: R_MIPS_LO16
# N32-NEXT: addu $gp, $gp, $25
# N64-NEXT: daddu $gp, $gp, $25

# ASM-NEXT: .cpsetup $25, 8, __cerror
Expand Down

0 comments on commit 0e9ab65

Please sign in to comment.