forked from OSchip/llvm-project
[mips][mc] Emit R_{MICRO}MIPS_JALR when expanding jal to jalr
When replacing jal with jalr, also emit '.reloc R_MIPS_JALR' (R_MICROMIPS_JALR for micromips). The linker might then be able to turn jalr into a direct call. Add '-mips-jalr-reloc' to enable/disable this feature (default is true). Differential revision: https://reviews.llvm.org/D55292 llvm-svn: 348760
This commit is contained in:
parent
753efe3584
commit
4433f93afe
|
@ -39,6 +39,7 @@
|
|||
#include "llvm/MC/MCValue.h"
|
||||
#include "llvm/MC/SubtargetFeature.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
|
@ -64,6 +65,11 @@ class MCInstrInfo;
|
|||
|
||||
} // end namespace llvm
|
||||
|
||||
static cl::opt<bool>
|
||||
EmitJalrReloc("mips-jalr-reloc", cl::Hidden,
|
||||
cl::desc("MIPS: Emit R_{MICRO}MIPS_JALR relocation with jalr"),
|
||||
cl::init(true));
|
||||
|
||||
namespace {
|
||||
|
||||
class MipsAssemblerOptions {
|
||||
|
@ -2065,9 +2071,21 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
|
|||
JalrInst.addOperand(MCOperand::createReg(Mips::RA));
|
||||
JalrInst.addOperand(MCOperand::createReg(Mips::T9));
|
||||
|
||||
// FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR.
|
||||
// This relocation is supposed to be an optimization hint for the linker
|
||||
// and is not necessary for correctness.
|
||||
if (EmitJalrReloc) {
|
||||
// As an optimization hint for the linker, before the JALR we add:
|
||||
// .reloc tmplabel, R_{MICRO}MIPS_JALR, symbol
|
||||
// tmplabel:
|
||||
MCSymbol *TmpLabel = getContext().createTempSymbol();
|
||||
const MCExpr *TmpExpr = MCSymbolRefExpr::create(TmpLabel, getContext());
|
||||
const MCExpr *RelocJalrExpr =
|
||||
MCSymbolRefExpr::create(JalSym, MCSymbolRefExpr::VK_None,
|
||||
getContext(), IDLoc);
|
||||
|
||||
TOut.getStreamer().EmitRelocDirective(*TmpExpr,
|
||||
inMicroMipsMode() ? "R_MICROMIPS_JALR" : "R_MIPS_JALR",
|
||||
RelocJalrExpr, IDLoc, *STI);
|
||||
TOut.getStreamer().EmitLabel(TmpLabel);
|
||||
}
|
||||
|
||||
Inst = JalrInst;
|
||||
ExpandedJalSym = true;
|
||||
|
|
|
@ -40,27 +40,38 @@ local_label:
|
|||
# O32: # fixup A - offset: 0, value: %got(local_label), kind: fixup_Mips_GOT
|
||||
# O32: addiu $25, $25, %lo(local_label) # encoding: [0x27,0x39,A,A]
|
||||
# O32: # fixup A - offset: 0, value: %lo(local_label), kind: fixup_Mips_LO16
|
||||
# O32-NEXT: .reloc ($tmp0), R_MIPS_JALR, local_label
|
||||
|
||||
# ELF-O32: 8f 99 00 00 lw $25, 0($gp)
|
||||
# ELF-O32-NEXT: R_MIPS_GOT16 .text
|
||||
# ELF-O32-NEXT: 27 39 00 00 addiu $25, $25, 0
|
||||
# ELF-O32-NEXT: R_MIPS_LO16 .text
|
||||
# ELF-O32-NEXT: 03 20 f8 09 jalr $25
|
||||
# ELF-O32-NEXT: 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 ($tmp0), R_MIPS_JALR, local_label
|
||||
|
||||
# ELF-N32: 8f 99 00 00 lw $25, 0($gp)
|
||||
# ELF-N32-NEXT: R_MIPS_GOT_DISP local_label
|
||||
# ELF-N32-NEXT: 03 20 f8 09 jalr $25
|
||||
# ELF-N32-NEXT: 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
|
||||
|
||||
# ELF-N64: df 99 00 00 ld $25, 0($gp)
|
||||
# ELF-N64-NEXT: R_MIPS_GOT_DISP/R_MIPS_NONE/R_MIPS_NONE 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
|
||||
|
||||
# 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]
|
||||
# O32-MM: # fixup A - offset: 0, value: %lo(local_label), kind: fixup_MICROMIPS_LO16
|
||||
# O32-MM-NEXT: .reloc ($tmp0), R_MICROMIPS_JALR, local_label
|
||||
|
||||
# MIPS: jalr $25 # encoding: [0x03,0x20,0xf8,0x09]
|
||||
# MM: jalr $ra, $25 # encoding: [0x03,0xf9,0x0f,0x3c]
|
||||
|
@ -72,24 +83,34 @@ local_label:
|
|||
# Expanding "jal weak_label":
|
||||
# O32: lw $25, %call16(weak_label)($gp) # encoding: [0x8f,0x99,A,A]
|
||||
# O32: # fixup A - offset: 0, value: %call16(weak_label), kind: fixup_Mips_CALL16
|
||||
# O32-NEXT: .reloc ($tmp1), R_MIPS_JALR, weak_label
|
||||
|
||||
# ELF-O32: 8f 99 00 00 lw $25, 0($gp)
|
||||
# ELF-O32-NEXT: R_MIPS_CALL16 weak_label
|
||||
# ELF-O32-NEXT: 03 20 f8 09 jalr $25
|
||||
# ELF-O32-NEXT: 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 ($tmp1), R_MIPS_JALR, weak_label
|
||||
|
||||
# ELF-N32: 8f 99 00 00 lw $25, 0($gp)
|
||||
# ELF-N32-NEXT: R_MIPS_CALL16 weak_label
|
||||
# ELF-N32-NEXT: 03 20 f8 09 jalr $25
|
||||
# ELF-N32-NEXT: 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
|
||||
|
||||
# ELF-N64: df 99 00 00 ld $25, 0($gp)
|
||||
# ELF-N64-NEXT: R_MIPS_CALL16/R_MIPS_NONE/R_MIPS_NONE weak_label
|
||||
# ELF-N64-NEXT: 03 20 f8 09 jalr $25
|
||||
# ELF-N64-NEXT: R_MIPS_JALR/R_MIPS_NONE/R_MIPS_NONE 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
|
||||
|
||||
# MIPS: jalr $25 # encoding: [0x03,0x20,0xf8,0x09]
|
||||
# MM: jalr $ra, $25 # encoding: [0x03,0xf9,0x0f,0x3c]
|
||||
|
@ -101,24 +122,34 @@ local_label:
|
|||
# Expanding "jal global_label":
|
||||
# O32: lw $25, %call16(global_label)($gp) # encoding: [0x8f,0x99,A,A]
|
||||
# O32: # fixup A - offset: 0, value: %call16(global_label), kind: fixup_Mips_CALL16
|
||||
# O32-NEXT: .reloc ($tmp2), R_MIPS_JALR, global_label
|
||||
|
||||
# ELF-O32: 8f 99 00 00 lw $25, 0($gp)
|
||||
# ELF-O32-NEXT: R_MIPS_CALL16 global_label
|
||||
# ELF-O32-NEXT: 03 20 f8 09 jalr $25
|
||||
# ELF-O32-NEXT: 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 ($tmp2), R_MIPS_JALR, global_label
|
||||
|
||||
# ELF-N32: 8f 99 00 00 lw $25, 0($gp)
|
||||
# ELF-N32-NEXT: R_MIPS_CALL16 global_label
|
||||
# ELF-N32-NEXT: 03 20 f8 09 jalr $25
|
||||
# ELF-N32-NEXT: 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
|
||||
|
||||
# ELF-N64: df 99 00 00 ld $25, 0($gp)
|
||||
# ELF-N64-NEXT: R_MIPS_CALL16/R_MIPS_NONE/R_MIPS_NONE global_label
|
||||
# ELF-N64-NEXT: 03 20 f8 09 jalr $25
|
||||
# ELF-N64-NEXT: R_MIPS_JALR/R_MIPS_NONE/R_MIPS_NONE 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
|
||||
|
||||
# MIPS: jalr $25 # encoding: [0x03,0x20,0xf8,0x09]
|
||||
# MM: jalr $ra, $25 # encoding: [0x03,0xf9,0x0f,0x3c]
|
||||
|
@ -150,6 +181,7 @@ local_label:
|
|||
# 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]
|
||||
# O32-MM-NEXT: # fixup A - offset: 0, value: %lo(.text), kind: fixup_MICROMIPS_LO16
|
||||
# O32-MM-NEXT: .reloc ($tmp3), R_MICROMIPS_JALR, .text
|
||||
|
||||
# MIPS: jalr $25 # encoding: [0x03,0x20,0xf8,0x09]
|
||||
# MM: jalr $ra, $25 # encoding: [0x03,0xf9,0x0f,0x3c]
|
||||
|
@ -160,32 +192,36 @@ local_label:
|
|||
nop
|
||||
|
||||
# Expanding "jal 1f":
|
||||
# O32: lw $25, %got($tmp0)($gp) # encoding: [0x8f,0x99,A,A]
|
||||
# O32: # fixup A - offset: 0, value: %got($tmp0), kind: fixup_Mips_GOT
|
||||
# O32: addiu $25, $25, %lo($tmp0) # encoding: [0x27,0x39,A,A]
|
||||
# O32: # fixup A - offset: 0, value: %lo($tmp0), kind: fixup_Mips_LO16
|
||||
# O32: lw $25, %got($tmp4)($gp) # encoding: [0x8f,0x99,A,A]
|
||||
# O32: # fixup A - offset: 0, value: %got($tmp4), kind: fixup_Mips_GOT
|
||||
# O32: addiu $25, $25, %lo($tmp4) # encoding: [0x27,0x39,A,A]
|
||||
# O32: # fixup A - offset: 0, value: %lo($tmp4), kind: fixup_Mips_LO16
|
||||
# O32-NEXT: .reloc ($tmp5), R_MIPS_JALR, ($tmp4)
|
||||
|
||||
# ELF-O32: 8f 99 00 00 lw $25, 0($gp)
|
||||
# ELF-O32-NEXT: R_MIPS_GOT16 .text
|
||||
# ELF-O32-NEXT: 27 39 00 58 addiu $25, $25, 88
|
||||
# ELF-O32-NEXT: R_MIPS_LO16 .text
|
||||
# ELF-O32-NEXT: 03 20 f8 09 jalr $25
|
||||
# ELF-O32-NEXT: R_MIPS_JALR $tmp0
|
||||
|
||||
# N32: lw $25, %got_disp($tmp0)($gp) # encoding: [0x8f,0x99,A,A]
|
||||
# N32: # fixup A - offset: 0, value: %got_disp($tmp0), kind: fixup_Mips_GOT_DISP
|
||||
# N32: lw $25, %got_disp($tmp4)($gp) # encoding: [0x8f,0x99,A,A]
|
||||
# N32: # fixup A - offset: 0, value: %got_disp($tmp4), kind: fixup_Mips_GOT_DISP
|
||||
|
||||
# ELF-N32: 8f 99 00 00 lw $25, 0($gp)
|
||||
# ELF-N32-NEXT: R_MIPS_GOT_DISP .Ltmp0
|
||||
|
||||
# N64: ld $25, %got_disp(.Ltmp0)($gp) # encoding: [0xdf,0x99,A,A]
|
||||
# N64: # fixup A - offset: 0, value: %got_disp(.Ltmp0), kind: fixup_Mips_GOT_DISP
|
||||
# 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
|
||||
|
||||
# O32-MM: lw $25, %got($tmp0)($gp) # encoding: [0xff,0x3c,A,A]
|
||||
# O32-MM: # fixup A - offset: 0, value: %got($tmp0), kind: fixup_MICROMIPS_GOT16
|
||||
# O32-MM: addiu $25, $25, %lo($tmp0) # encoding: [0x33,0x39,A,A]
|
||||
# O32-MM: # fixup A - offset: 0, value: %lo($tmp0), kind: fixup_MICROMIPS_LO16
|
||||
# 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]
|
||||
# O32-MM: # fixup A - offset: 0, value: %lo($tmp4), kind: fixup_MICROMIPS_LO16
|
||||
# O32-MM-NEXT: .reloc ($tmp5), R_MICROMIPS_JALR, ($tmp4)
|
||||
|
||||
# MIPS: jalr $25 # encoding: [0x03,0x20,0xf8,0x09]
|
||||
# MM: jalr $ra, $25 # encoding: [0x03,0xf9,0x0f,0x3c]
|
||||
|
@ -200,11 +236,14 @@ local_label:
|
|||
# O32-FIXME: # fixup A - offset: 0, value: %got(forward_local), kind: fixup_Mips_GOT
|
||||
# O32-FIXME: addiu $25, $25, %lo(forward_local) # encoding: [0x27,0x39,A,A]
|
||||
# O32-FIXME:: # fixup A - offset: 0, value: %lo(forward_local), kind: fixup_Mips_LO16
|
||||
# O32-FIXME: .reloc ($tmp6), R_MIPS_JALR, forward_local
|
||||
|
||||
# ELF-O32: 8f 99 00 00 lw $25, 0($gp)
|
||||
# ELF-O32-NEXT: R_MIPS_GOT16 .text
|
||||
# ELF-O32-NEXT: 27 39 00 64 addiu $25, $25, 100
|
||||
# ELF-O32-NEXT: R_MIPS_LO16 .text
|
||||
# ELF-O32-NEXT: 03 20 f8 09 jalr $25
|
||||
# ELF-O32-NEXT: R_MIPS_JALR forward_local
|
||||
|
||||
# N32-FIXME: lw $25, %got_disp(forward_local)($gp) # encoding: [0x8f,0x99,A,A]
|
||||
# N32-FIXME: # fixup A - offset: 0, value: %got_disp(forward_local), kind: fixup_Mips_GOT_DISP
|
||||
|
@ -222,6 +261,7 @@ local_label:
|
|||
# O32-MM-FIXME: # fixup A - offset: 0, value: %got(forward_local), kind: fixup_MICROMIPS_GOT16
|
||||
# O32-MM-FIXME: addiu $25, $25, %lo(forward_local) # encoding: [0x33,0x39,A,A]
|
||||
# O32-MM-FIXME: # fixup A - offset: 0, value: %lo(forward_local), kind: fixup_MICROMIPS_LO16
|
||||
# O32-MM-FIXME: .reloc ($tmp6), R_MIPS_JALR, forward_local
|
||||
|
||||
# MIPS: jalr $25 # encoding: [0x03,0x20,0xf8,0x09]
|
||||
# MM: jalr $ra, $25 # encoding: [0x03,0xf9,0x0f,0x3c]
|
||||
|
|
Loading…
Reference in New Issue