summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp56
-rw-r--r--llvm/test/MC/Mips/expansion-jal-sym-pic.s93
2 files changed, 102 insertions, 47 deletions
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index c75ee034caf..b906ca03c00 100644
--- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -2033,56 +2033,15 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
// FIXME: Add support for label+offset operands (currently causes an error).
// FIXME: Add support for forward-declared local symbols.
- // FIXME: Add expansion for when the LargeGOT option is enabled.
- if (JalSym->isInSection() || JalSym->isTemporary() ||
- (JalSym->isELF() &&
- cast<MCSymbolELF>(JalSym)->getBinding() == ELF::STB_LOCAL)) {
- if (isABI_O32()) {
- // If it's a local symbol and the O32 ABI is being used, we expand to:
- // lw $25, 0($gp)
- // R_(MICRO)MIPS_GOT16 label
- // addiu $25, $25, 0
- // R_(MICRO)MIPS_LO16 label
- // jalr $25
- const MCExpr *Got16RelocExpr =
- MipsMCExpr::create(MipsMCExpr::MEK_GOT, JalExpr, getContext());
- const MCExpr *Lo16RelocExpr =
- MipsMCExpr::create(MipsMCExpr::MEK_LO, JalExpr, getContext());
-
- TOut.emitRRX(Mips::LW, Mips::T9, GPReg,
- MCOperand::createExpr(Got16RelocExpr), IDLoc, STI);
- TOut.emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
- MCOperand::createExpr(Lo16RelocExpr), IDLoc, STI);
- } else if (isABI_N32() || isABI_N64()) {
- // If it's a local symbol and the N32/N64 ABIs are being used,
- // we expand to:
- // lw/ld $25, 0($gp)
- // R_(MICRO)MIPS_GOT_DISP label
- // jalr $25
- const MCExpr *GotDispRelocExpr =
- MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, JalExpr, getContext());
-
- TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9,
- GPReg, MCOperand::createExpr(GotDispRelocExpr), IDLoc,
- STI);
- }
- } else {
- // If it's an external/weak symbol, we expand to:
- // lw/ld $25, 0($gp)
- // R_(MICRO)MIPS_CALL16 label
- // jalr $25
- const MCExpr *Call16RelocExpr =
- MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, JalExpr, getContext());
-
- TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, GPReg,
- MCOperand::createExpr(Call16RelocExpr), IDLoc, STI);
- }
+ if (expandLoadAddress(Mips::T9, Mips::NoRegister, Inst.getOperand(0),
+ !isGP64bit(), IDLoc, Out, STI))
+ return true;
MCInst JalrInst;
- if (IsCpRestoreSet && inMicroMipsMode())
- JalrInst.setOpcode(Mips::JALRS_MM);
+ if (inMicroMipsMode())
+ JalrInst.setOpcode(IsCpRestoreSet ? Mips::JALRS_MM : Mips::JALR_MM);
else
- JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
+ JalrInst.setOpcode(Mips::JALR);
JalrInst.addOperand(MCOperand::createReg(Mips::RA));
JalrInst.addOperand(MCOperand::createReg(Mips::T9));
@@ -2933,6 +2892,9 @@ bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
TmpReg = ATReg;
}
+ // FIXME: In case of N32 / N64 ABI and emabled XGOT, local addresses
+ // loaded using R_MIPS_GOT_PAGE / R_MIPS_GOT_OFST pair of relocations.
+ // FIXME: Implement XGOT for microMIPS.
if (UseXGOT) {
// Loading address from XGOT
// External GOT: lui $tmp, %got_hi(symbol)($gp)
diff --git a/llvm/test/MC/Mips/expansion-jal-sym-pic.s b/llvm/test/MC/Mips/expansion-jal-sym-pic.s
index e20562a88a5..bc904420103 100644
--- a/llvm/test/MC/Mips/expansion-jal-sym-pic.s
+++ b/llvm/test/MC/Mips/expansion-jal-sym-pic.s
@@ -1,12 +1,21 @@
# RUN: llvm-mc %s -triple mips-unknown-linux-gnu -show-encoding |\
# RUN: FileCheck %s -check-prefixes=ALL,MIPS,O32
+# RUN: llvm-mc %s -triple mips-unknown-linux-gnu -mattr=+xgot -show-encoding |\
+# RUN: FileCheck %s -check-prefixes=ALL,MIPS,XO32
+
# RUN: llvm-mc %s -triple mips64-unknown-linux-gnuabin32 -show-encoding |\
# RUN: FileCheck %s -check-prefixes=ALL,MIPS,N32
+# RUN: llvm-mc %s -triple mips64-unknown-linux-gnuabin32 -mattr=+xgot -show-encoding |\
+# RUN: FileCheck %s -check-prefixes=ALL,MIPS,XN32
+
# RUN: llvm-mc %s -triple mips64-unknown-linux-gnu -show-encoding |\
# RUN: FileCheck %s -check-prefixes=ALL,MIPS,N64
+# RUN: llvm-mc %s -triple mips64-unknown-linux-gnu -mattr=+xgot -show-encoding |\
+# RUN: FileCheck %s -check-prefixes=ALL,MIPS,XN64
+
# RUN: llvm-mc %s -triple mips-unknown-linux-gnu -mattr=micromips -show-encoding |\
# RUN: FileCheck %s -check-prefixes=ALL,MM,O32-MM
@@ -49,6 +58,12 @@ local_label:
# ELF-O32-NEXT: 03 20 f8 09 jalr $25
# ELF-O32-NEXT: R_MIPS_JALR local_label
+# XO32: lw $25, %got(local_label)($gp) # encoding: [0x8f,0x99,A,A]
+# XO32-NEXT: # fixup A - offset: 0, value: %got(local_label), kind: fixup_Mips_GOT
+# XO32-NEXT: addiu $25, $25, %lo(local_label) # encoding: [0x27,0x39,A,A]
+# XO32-NEXT: # fixup A - offset: 0, value: %lo(local_label), kind: fixup_Mips_LO16
+# XO32-NEXT: .reloc ($tmp0), R_MIPS_JALR, local_label
+
# N32: lw $25, %got_disp(local_label)($gp) # encoding: [0x8f,0x99,A,A]
# N32: # fixup A - offset: 0, value: %got_disp(local_label), kind: fixup_Mips_GOT_DISP
# N32-NEXT: .reloc .Ltmp0, R_MIPS_JALR, local_label
@@ -58,6 +73,10 @@ local_label:
# ELF-N32-NEXT: 03 20 f8 09 jalr $25
# ELF-N32-NEXT: R_MIPS_JALR local_label
+# XN32: lw $25, %got_disp(local_label)($gp) # encoding: [0x8f,0x99,A,A]
+# XN32-NEXT: # fixup A - offset: 0, value: %got_disp(local_label), kind: fixup_Mips_GOT_DISP
+# XN32-NEXT: .reloc .Ltmp0, R_MIPS_JALR, local_label
+
# N64: ld $25, %got_disp(local_label)($gp) # encoding: [0xdf,0x99,A,A]
# N64: # fixup A - offset: 0, value: %got_disp(local_label), kind: fixup_Mips_GOT_DISP
# N64-NEXT: .reloc .Ltmp0, R_MIPS_JALR, local_label
@@ -67,6 +86,10 @@ local_label:
# ELF-N64-NEXT: 03 20 f8 09 jalr $25
# ELF-N64-NEXT: R_MIPS_JALR/R_MIPS_NONE/R_MIPS_NONE local_label
+# XN64: ld $25, %got_disp(local_label)($gp) # encoding: [0xdf,0x99,A,A]
+# XN64-NEXT: # fixup A - offset: 0, value: %got_disp(local_label), kind: fixup_Mips_GOT_DISP
+# XN64-NEXT: .reloc .Ltmp0, R_MIPS_JALR, local_label
+
# O32-MM: lw $25, %got(local_label)($gp) # encoding: [0xff,0x3c,A,A]
# O32-MM: # fixup A - offset: 0, value: %got(local_label), kind: fixup_MICROMIPS_GOT16
# O32-MM: addiu $25, $25, %lo(local_label) # encoding: [0x33,0x39,A,A]
@@ -90,6 +113,13 @@ local_label:
# ELF-O32-NEXT: 03 20 f8 09 jalr $25
# ELF-O32-NEXT: R_MIPS_JALR weak_label
+# XO32: lui $25, %call_hi(weak_label) # encoding: [0x3c,0x19,A,A]
+# XO32-NEXT: # fixup A - offset: 0, value: %call_hi(weak_label), kind: fixup_Mips_CALL_HI16
+# XO32-NEXT: addu $25, $25, $gp # encoding: [0x03,0x3c,0xc8,0x21]
+# XO32-NEXT: lw $25, %call_lo(weak_label)($25) # encoding: [0x8f,0x39,A,A]
+# XO32-NEXT: # fixup A - offset: 0, value: %call_lo(weak_label), kind: fixup_Mips_CALL_LO16
+# XO32-NEXT: .reloc ($tmp1), R_MIPS_JALR, weak_label
+
# N32: lw $25, %call16(weak_label)($gp) # encoding: [0x8f,0x99,A,A]
# N32: # fixup A - offset: 0, value: %call16(weak_label), kind: fixup_Mips_CALL16
# N32-NEXT: .reloc .Ltmp1, R_MIPS_JALR, weak_label
@@ -99,6 +129,13 @@ local_label:
# ELF-N32-NEXT: 03 20 f8 09 jalr $25
# ELF-N32-NEXT: R_MIPS_JALR weak_label
+# XN32: lui $25, %call_hi(weak_label) # encoding: [0x3c,0x19,A,A]
+# XN32-NEXT: # fixup A - offset: 0, value: %call_hi(weak_label), kind: fixup_Mips_CALL_HI16
+# XN32-NEXT: addu $25, $25, $gp # encoding: [0x03,0x3c,0xc8,0x21]
+# XN32-NEXT: lw $25, %call_lo(weak_label)($25) # encoding: [0x8f,0x39,A,A]
+# XN32-NEXT: # fixup A - offset: 0, value: %call_lo(weak_label), kind: fixup_Mips_CALL_LO16
+# XN32-NEXT: .reloc .Ltmp1, R_MIPS_JALR, weak_label
+
# N64: ld $25, %call16(weak_label)($gp) # encoding: [0xdf,0x99,A,A]
# N64: # fixup A - offset: 0, value: %call16(weak_label), kind: fixup_Mips_CALL16
# N64-NEXT: .reloc .Ltmp1, R_MIPS_JALR, weak_label
@@ -108,6 +145,13 @@ local_label:
# ELF-N64-NEXT: 03 20 f8 09 jalr $25
# ELF-N64-NEXT: R_MIPS_JALR/R_MIPS_NONE/R_MIPS_NONE weak_label
+# XN64: lui $25, %call_hi(weak_label) # encoding: [0x3c,0x19,A,A]
+# XN64-NEXT: # fixup A - offset: 0, value: %call_hi(weak_label), kind: fixup_Mips_CALL_HI16
+# XN64-NEXT: daddu $25, $25, $gp # encoding: [0x03,0x3c,0xc8,0x2d]
+# XN64-NEXT: ld $25, %call_lo(weak_label)($25) # encoding: [0xdf,0x39,A,A]
+# XN64-NEXT: # fixup A - offset: 0, value: %call_lo(weak_label), kind: fixup_Mips_CALL_LO16
+# XN64-NEXT: .reloc .Ltmp1, R_MIPS_JALR, weak_label
+
# O32-MM: lw $25, %call16(weak_label)($gp) # encoding: [0xff,0x3c,A,A]
# O32-MM: # fixup A - offset: 0, value: %call16(weak_label), kind: fixup_MICROMIPS_CALL16
# O32-MM-NEXT: .reloc ($tmp1), R_MICROMIPS_JALR, weak_label
@@ -129,6 +173,13 @@ local_label:
# ELF-O32-NEXT: 03 20 f8 09 jalr $25
# ELF-O32-NEXT: R_MIPS_JALR global_label
+# XO32: lui $25, %call_hi(global_label) # encoding: [0x3c,0x19,A,A]
+# XO32-NEXT: # fixup A - offset: 0, value: %call_hi(global_label), kind: fixup_Mips_CALL_HI16
+# XO32-NEXT: addu $25, $25, $gp # encoding: [0x03,0x3c,0xc8,0x21]
+# XO32-NEXT: lw $25, %call_lo(global_label)($25) # encoding: [0x8f,0x39,A,A]
+# XO32-NEXT: # fixup A - offset: 0, value: %call_lo(global_label), kind: fixup_Mips_CALL_LO16
+# XO32-NEXT: .reloc ($tmp2), R_MIPS_JALR, global_label
+
# N32: lw $25, %call16(global_label)($gp) # encoding: [0x8f,0x99,A,A]
# N32: # fixup A - offset: 0, value: %call16(global_label), kind: fixup_Mips_CALL16
# N32-NEXT: .reloc .Ltmp2, R_MIPS_JALR, global_label
@@ -138,6 +189,13 @@ local_label:
# ELF-N32-NEXT: 03 20 f8 09 jalr $25
# ELF-N32-NEXT: R_MIPS_JALR global_label
+# XN32: lui $25, %call_hi(global_label) # encoding: [0x3c,0x19,A,A]
+# XN32-NEXT: # fixup A - offset: 0, value: %call_hi(global_label), kind: fixup_Mips_CALL_HI16
+# XN32-NEXT: addu $25, $25, $gp # encoding: [0x03,0x3c,0xc8,0x21]
+# XN32-NEXT: lw $25, %call_lo(global_label)($25) # encoding: [0x8f,0x39,A,A]
+# XN32-NEXT: # fixup A - offset: 0, value: %call_lo(global_label), kind: fixup_Mips_CALL_LO16
+# XN32-NEXT: .reloc .Ltmp2, R_MIPS_JALR, global_label
+
# N64: ld $25, %call16(global_label)($gp) # encoding: [0xdf,0x99,A,A]
# N64: # fixup A - offset: 0, value: %call16(global_label), kind: fixup_Mips_CALL16
# N64-NEXT: .reloc .Ltmp2, R_MIPS_JALR, global_label
@@ -147,6 +205,13 @@ local_label:
# ELF-N64-NEXT: 03 20 f8 09 jalr $25
# ELF-N64-NEXT: R_MIPS_JALR/R_MIPS_NONE/R_MIPS_NONE global_label
+# XN64: lui $25, %call_hi(global_label) # encoding: [0x3c,0x19,A,A]
+# XN64-NEXT: # fixup A - offset: 0, value: %call_hi(global_label), kind: fixup_Mips_CALL_HI16
+# XN64-NEXT: daddu $25, $25, $gp # encoding: [0x03,0x3c,0xc8,0x2d]
+# XN64-NEXT: ld $25, %call_lo(global_label)($25) # encoding: [0xdf,0x39,A,A]
+# XN64-NEXT: # fixup A - offset: 0, value: %call_lo(global_label), kind: fixup_Mips_CALL_LO16
+# XN64-NEXT: .reloc .Ltmp2, R_MIPS_JALR, global_label
+
# O32-MM: lw $25, %call16(global_label)($gp) # encoding: [0xff,0x3c,A,A]
# O32-MM: # fixup A - offset: 0, value: %call16(global_label), kind: fixup_MICROMIPS_CALL16
# O32-MM-NEXT: .reloc ($tmp2), R_MICROMIPS_JALR, global_label
@@ -165,18 +230,32 @@ local_label:
# ELF-O32: 8f 99 00 00 lw $25, 0($gp)
# ELF-O32-NEXT: R_MIPS_GOT16 .text
+# XO32: lw $25, %got(.text)($gp) # encoding: [0x8f,0x99,A,A]
+# XO32-NEXT: # fixup A - offset: 0, value: %got(.text), kind: fixup_Mips_GOT
+# XO32-NEXT: addiu $25, $25, %lo(.text) # encoding: [0x27,0x39,A,A]
+# XO32-NEXT: # fixup A - offset: 0, value: %lo(.text), kind: fixup_Mips_LO16
+# XO32-NEXT: .reloc ($tmp3), R_MIPS_JALR, .text
+
# N32: lw $25, %got_disp(.text)($gp) # encoding: [0x8f,0x99,A,A]
# N32-NEXT: # fixup A - offset: 0, value: %got_disp(.text), kind: fixup_Mips_GOT_DISP
# ELF-N32: 8f 99 00 00 lw $25, 0($gp)
# ELF-N32-NEXT: R_MIPS_GOT_DISP .text
+# XN32: lw $25, %got_disp(.text)($gp) # encoding: [0x8f,0x99,A,A]
+# XN32-NEXT: # fixup A - offset: 0, value: %got_disp(.text), kind: fixup_Mips_GOT_DISP
+# XN32-NEXT: .reloc .Ltmp3, R_MIPS_JALR, .text
+
# N64: ld $25, %got_disp(.text)($gp) # encoding: [0xdf,0x99,A,A]
# N64-NEXT: # fixup A - offset: 0, value: %got_disp(.text), kind: fixup_Mips_GOT_DISP
# ELF-N64: df 99 00 00 ld $25, 0($gp)
# ELF-N64-NEXT: R_MIPS_GOT_DISP/R_MIPS_NONE/R_MIPS_NONE .text
+# XN64: ld $25, %got_disp(.text)($gp) # encoding: [0xdf,0x99,A,A]
+# XN64-NEXT: # fixup A - offset: 0, value: %got_disp(.text), kind: fixup_Mips_GOT_DISP
+# XN64-NEXT: .reloc .Ltmp3, R_MIPS_JALR, .text
+
# O32-MM: lw $25, %got(.text)($gp) # encoding: [0xff,0x3c,A,A]
# O32-MM-NEXT: # fixup A - offset: 0, value: %got(.text), kind: fixup_MICROMIPS_GOT16
# O32-MM-NEXT: addiu $25, $25, %lo(.text) # encoding: [0x33,0x39,A,A]
@@ -205,18 +284,32 @@ local_label:
# ELF-O32-NEXT: 03 20 f8 09 jalr $25
# ELF-O32-NEXT: R_MIPS_JALR $tmp0
+# XO32: lw $25, %got($tmp4)($gp) # encoding: [0x8f,0x99,A,A]
+# XO32-NEXT: # fixup A - offset: 0, value: %got($tmp4), kind: fixup_Mips_GOT
+# XO32-NEXT: addiu $25, $25, %lo($tmp4) # encoding: [0x27,0x39,A,A]
+# XO32-NEXT: # fixup A - offset: 0, value: %lo($tmp4), kind: fixup_Mips_LO16
+# XO32-NEXT: .reloc ($tmp5), R_MIPS_JALR, ($tmp4)
+
# N32: lw $25, %got_disp(.Ltmp4)($gp) # encoding: [0x8f,0x99,A,A]
# N32: # fixup A - offset: 0, value: %got_disp(.Ltmp4), kind: fixup_Mips_GOT_DISP
# ELF-N32: 8f 99 00 00 lw $25, 0($gp)
# ELF-N32-NEXT: R_MIPS_GOT_DISP .Ltmp0
+# XN32: lw $25, %got_disp(.Ltmp4)($gp) # encoding: [0x8f,0x99,A,A]
+# XN32-NEXT: # fixup A - offset: 0, value: %got_disp(.Ltmp4), kind: fixup_Mips_GOT_DISP
+# XN32-NEXT: .reloc .Ltmp5, R_MIPS_JALR, .Ltmp4
+
# N64: ld $25, %got_disp(.Ltmp4)($gp) # encoding: [0xdf,0x99,A,A]
# N64: # fixup A - offset: 0, value: %got_disp(.Ltmp4), kind: fixup_Mips_GOT_DISP
# ELF-N64: df 99 00 00 ld $25, 0($gp)
# ELF-N64-NEXT: R_MIPS_GOT_DISP/R_MIPS_NONE/R_MIPS_NONE .Ltmp0
+# XN64: ld $25, %got_disp(.Ltmp4)($gp) # encoding: [0xdf,0x99,A,A]
+# XN64-NEXT: # fixup A - offset: 0, value: %got_disp(.Ltmp4), kind: fixup_Mips_GOT_DISP
+# XN64-NEXT: .reloc .Ltmp5, R_MIPS_JALR, .Ltmp4
+
# O32-MM: lw $25, %got($tmp4)($gp) # encoding: [0xff,0x3c,A,A]
# O32-MM: # fixup A - offset: 0, value: %got($tmp4), kind: fixup_MICROMIPS_GOT16
# O32-MM: addiu $25, $25, %lo($tmp4) # encoding: [0x33,0x39,A,A]
OpenPOWER on IntegriCloud