[llvm] r348760 - [mips][mc] Emit R_{MICRO}MIPS_JALR when expanding jal to jalr

Vladimir Stefanovic via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 10 07:07:36 PST 2018


Author: vstefanovic
Date: Mon Dec 10 07:07:36 2018
New Revision: 348760

URL: http://llvm.org/viewvc/llvm-project?rev=348760&view=rev
Log:
[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

Modified:
    llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
    llvm/trunk/test/MC/Mips/expansion-jal-sym-pic.s

Modified: llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp?rev=348760&r1=348759&r2=348760&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp Mon Dec 10 07:07:36 2018
@@ -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(M
     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;

Modified: llvm/trunk/test/MC/Mips/expansion-jal-sym-pic.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/expansion-jal-sym-pic.s?rev=348760&r1=348759&r2=348760&view=diff
==============================================================================
--- llvm/trunk/test/MC/Mips/expansion-jal-sym-pic.s (original)
+++ llvm/trunk/test/MC/Mips/expansion-jal-sym-pic.s Mon Dec 10 07:07:36 2018
@@ -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]




More information about the llvm-commits mailing list