Fix `-mrelax-pic-calls' support for microMIPS code where the relocation 
produced is supposed to be R_MICROMIPS_JALR rather than R_MIPS_JALR.  
The lack of short delay support comes from a missed update to this code 
for microMIPS support and can be relieved as JALRS and JRS instructions 
can be relaxed to BALS and B instructions respectively, so do that as 
well.

By doing so complement commit r196828 ("microMIPS gcc support"), 
<https://gcc.gnu.org/ml/gcc-patches/2013-02/msg01103.html>, which is the 
original change that introduced microMIPS support, in particular to 
MIPS_CALL, which is where this code previously resided.

Adjust the test suite accordingly, limiting R_MICROMIPS_JALR cases to 
regular MIPS code only, and adding corresponding R_MICROMIPS_JALR cases 
for microMIPS code.

        gcc/
        * config/mips/mips.c (mips_output_jump): Output R_MICROMIPS_JALR
        rather than R_MIPS_JALR relocation in microMIPS code.  Do not
        cancel short delay slots in PIC call relaxation.

        gcc/testsuite/
        * gcc.target/mips/call-1.c (dg-options): Add `-mno-micromips'.
        (dg-final): Remove microMIPS JALRS mnemonic matching.
        * gcc.target/mips/call-2.c (dg-options): Add `-mno-micromips'.
        (dg-final): Remove microMIPS JALRS mnemonic matching.
        * gcc.target/mips/call-3.c (dg-options): Add `-mno-micromips'.
        (dg-final): Remove microMIPS JALRS mnemonic matching.
        * gcc.target/mips/call-4.c (dg-options): Add `-mno-micromips'.
        * gcc.target/mips/call-5.c (dg-options): Add `-mno-micromips'.
        * gcc.target/mips/call-6.c (dg-options): Add `-mno-micromips'.
        * gcc.target/mips/call-1u.c: New test case.
        * gcc.target/mips/call-2u.c: New test case.
        * gcc.target/mips/call-3u.c: New test case.
        * gcc.target/mips/call-4u.c: New test case.
        * gcc.target/mips/call-5u.c: New test case.
        * gcc.target/mips/call-6u.c: New test case.
---
 NB the use of this feature for microMIPS is limited because short 
encodings of register jump instructions usually do not have their branch 
counterparts and long encodings typically are not used.  However at least 
tail calls can be converted if the jump target is in range, as can calls 
in `-minsn32' code.  Perhaps we could switch to producing `j[al]r[s].32' 
in the `-mrelax-pic-calls' mode like GAS does with the `jal' and `j' 
microMIPS macros in PIC code.

 This change, with commit r235825 reverted (see PR rtl-optimization/78325, 
<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78325>), has passed 
regression testing with the `mips-mti-linux-gnu' target, using the 
big-endian regular MIPS o32 multilib.

 I think verifying with a microMIPS multilib would be worth doing too, 
however it would take a long time, owing to readily available microMIPS 
hardware being limited in terms of performance; and I am not currently set 
up for simulator testing.  It is a fix for an evident code generation bug 
though and by the nature of the change switching the relocation type only 
and permitting short delay slots with PIC call relaxation any reasonably 
possible fallout would only happen with the assembler and/or linker.  So 
while I do intend to push this through microMIPS testing eventually, it 
will likely take a bit yet (with the bit being weeks to months).

 Let me know if the lack of microMIPS results would be a problem for this 
patch's acceptance.  Otherwise, OK to apply?

  Maciej

gcc-umips-jalr.diff
Index: gcc/gcc/config/mips/mips.c
===================================================================
--- gcc.orig/gcc/config/mips/mips.c     2016-11-11 19:55:39.727013997 +0000
+++ gcc/gcc/config/mips/mips.c  2016-11-11 21:02:20.655335552 +0000
@@ -13611,12 +13611,9 @@ mips_output_jump (rtx *operands, int tar
        s += sprintf (s, ".option\tpic0\n\t");
 
       if (reg_p && mips_get_pic_call_symbol (operands, size_opno))
-       {
-         s += sprintf (s, "%%*.reloc\t1f,R_MIPS_JALR,%%%d\n1:\t", size_opno);
-         /* Not sure why this shouldn't permit a short delay but it did not
-            allow it before so we still don't allow it.  */
-         short_delay = "";
-       }
+       s += sprintf (s, "%%*.reloc\t1f,%s,%%%d\n1:\t",
+                     TARGET_MICROMIPS ? "R_MICROMIPS_JALR" : "R_MIPS_JALR",
+                     size_opno);
       else
        s += sprintf (s, "%%*");
 
Index: gcc/gcc/testsuite/gcc.target/mips/call-1.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/mips/call-1.c     2016-11-12 
10:09:33.548220788 +0000
+++ gcc/gcc/testsuite/gcc.target/mips/call-1.c  2016-11-12 10:09:55.004824221 
+0000
@@ -1,8 +1,8 @@
-/* { dg-options "-mrelax-pic-calls -mshared -foptimize-sibling-calls -mabi=32" 
} */
+/* { dg-options "-mno-micromips -mrelax-pic-calls -mshared 
-foptimize-sibling-calls -mabi=32" } */
 /* { dg-skip-if "requires -foptimize-sibling-calls" { *-*-* } { "-O0" } { "" } 
} */
-/* { dg-final { scan-assembler 
"\\.reloc\t1f,R_MIPS_JALR,normal\n1:\tjalrc?s?\t" } } */
-/* { dg-final { scan-assembler 
"\\.reloc\t1f,R_MIPS_JALR,normal2\n1:\tjalrc?s?\t" } } */
-/* { dg-final { scan-assembler 
"\\.reloc\t1f,R_MIPS_JALR,staticfunc\n1:\tjalrc?s?\t" } } */
+/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,normal\n1:\tjalrc?\t" 
} } */
+/* { dg-final { scan-assembler 
"\\.reloc\t1f,R_MIPS_JALR,normal2\n1:\tjalrc?\t" } } */
+/* { dg-final { scan-assembler 
"\\.reloc\t1f,R_MIPS_JALR,staticfunc\n1:\tjalrc?\t" } } */
 /* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,tail\n1:\tjrc?\t" } } 
*/
 /* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,tail2\n1:\tjrc?\t" } 
} */
 /* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,tail3\n1:\tjrc?\t" } 
} */
Index: gcc/gcc/testsuite/gcc.target/mips/call-1u.c
===================================================================
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
+++ gcc/gcc/testsuite/gcc.target/mips/call-1u.c 2016-11-12 10:09:55.019918358 
+0000
@@ -0,0 +1,51 @@
+/* { dg-options "-mmicromips -mrelax-pic-calls -mshared 
-foptimize-sibling-calls -mabi=32" } */
+/* { dg-skip-if "requires -foptimize-sibling-calls" { *-*-* } { "-O0" } { "" } 
} */
+/* { dg-final { scan-assembler 
"\\.reloc\t1f,R_MICROMIPS_JALR,normal\n1:\tjalrs?\t" } } */
+/* { dg-final { scan-assembler 
"\\.reloc\t1f,R_MICROMIPS_JALR,normal2\n1:\tjalrs?\t" } } */
+/* { dg-final { scan-assembler 
"\\.reloc\t1f,R_MICROMIPS_JALR,staticfunc\n1:\tjalrs?\t" } } */
+/* { dg-final { scan-assembler 
"\\.reloc\t1f,R_MICROMIPS_JALR,tail\n1:\tjrc?\t" } } */
+/* { dg-final { scan-assembler 
"\\.reloc\t1f,R_MICROMIPS_JALR,tail2\n1:\tjrc?\t" } } */
+/* { dg-final { scan-assembler 
"\\.reloc\t1f,R_MICROMIPS_JALR,tail3\n1:\tjrc?\t" } } */
+/* { dg-final { scan-assembler 
"\\.reloc\t1f,R_MICROMIPS_JALR,tail4\n1:\tjrc?\t" } } */
+
+__attribute__ ((noinline)) static void staticfunc () { asm (""); }
+int normal ();
+void normal2 ();
+
+int
+NOMIPS16 f (int *p)
+{
+  *p = normal ();
+  normal2 ();
+  staticfunc ();
+  return 1;
+}
+
+int tail ();
+
+int
+NOMIPS16 h ()
+{
+  return tail ();
+}
+
+void tail2 ();
+
+NOMIPS16 void g ()
+{
+  tail2 ();
+}
+
+__attribute__ ((visibility ("hidden"))) void tail3 ();
+
+NOMIPS16 void j ()
+{
+  tail3 ();
+}
+
+__attribute__ ((noinline)) static void tail4 () { asm (""); }
+
+NOMIPS16 void k ()
+{
+  tail4 ();
+}
Index: gcc/gcc/testsuite/gcc.target/mips/call-2.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/mips/call-2.c     2016-11-12 
10:09:33.570398493 +0000
+++ gcc/gcc/testsuite/gcc.target/mips/call-2.c  2016-11-12 10:09:55.031182509 
+0000
@@ -1,6 +1,6 @@
 /* See through some simple data-flow.  */
-/* { dg-options "-mrelax-pic-calls" } */
-/* { dg-final { scan-assembler-times 
"\\.reloc\t1f,R_MIPS_JALR,g\n1:\tjalrc?s?\t" 2 } } */
+/* { dg-options "-mno-micromips -mrelax-pic-calls" } */
+/* { dg-final { scan-assembler-times 
"\\.reloc\t1f,R_MIPS_JALR,g\n1:\tjalrc?\t" 2 } } */
 
 extern void g (void);
 
Index: gcc/gcc/testsuite/gcc.target/mips/call-2u.c
===================================================================
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
+++ gcc/gcc/testsuite/gcc.target/mips/call-2u.c 2016-11-12 10:09:55.053655589 
+0000
@@ -0,0 +1,13 @@
+/* See through some simple data-flow.  */
+/* { dg-options "-mmicromips -mrelax-pic-calls" } */
+/* { dg-final { scan-assembler-times 
"\\.reloc\t1f,R_MICROMIPS_JALR,g\n1:\tjalrs?\t" 2 } } */
+
+extern void g (void);
+
+int
+NOMIPS16 f ()
+{
+  g ();
+  g ();
+  return 1;
+}
Index: gcc/gcc/testsuite/gcc.target/mips/call-3.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/mips/call-3.c     2016-11-12 
10:09:33.586675251 +0000
+++ gcc/gcc/testsuite/gcc.target/mips/call-3.c  2016-11-12 10:09:55.065818862 
+0000
@@ -1,5 +1,5 @@
-/* { dg-options "-mrelax-pic-calls -mno-shared" } */
-/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,g\n1:\tjalrc?s?\t" } 
} */
+/* { dg-options "-mno-micromips -mrelax-pic-calls -mno-shared" } */
+/* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,g\n1:\tjalrc?\t" } } 
*/
 /* { dg-require-visibility "" } */
 
 __attribute__ ((visibility ("hidden"))) void g ();
Index: gcc/gcc/testsuite/gcc.target/mips/call-3u.c
===================================================================
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
+++ gcc/gcc/testsuite/gcc.target/mips/call-3u.c 2016-11-12 10:09:55.086985454 
+0000
@@ -0,0 +1,12 @@
+/* { dg-options "-mmicromips -mrelax-pic-calls -mno-shared" } */
+/* { dg-final { scan-assembler "\\.reloc\t1f,R_MICROMIPS_JALR,g\n1:\tjalrs?\t" 
} } */
+/* { dg-require-visibility "" } */
+
+__attribute__ ((visibility ("hidden"))) void g ();
+
+int
+NOMIPS16 f ()
+{
+  g ();
+  return 1;
+}
Index: gcc/gcc/testsuite/gcc.target/mips/call-4.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/mips/call-4.c     2016-11-12 
10:09:33.609850707 +0000
+++ gcc/gcc/testsuite/gcc.target/mips/call-4.c  2016-11-12 10:09:55.095097004 
+0000
@@ -1,5 +1,5 @@
 /* See through some simple data-flow.  */
-/* { dg-options "-mrelax-pic-calls" } */
+/* { dg-options "-mno-micromips -mrelax-pic-calls" } */
 /* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,g\n1:\tjalrc?\t" } } 
*/
 
 extern void g (void);
Index: gcc/gcc/testsuite/gcc.target/mips/call-4u.c
===================================================================
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
+++ gcc/gcc/testsuite/gcc.target/mips/call-4u.c 2016-11-12 10:09:55.112294350 
+0000
@@ -0,0 +1,12 @@
+/* See through some simple data-flow.  */
+/* { dg-options "-mmicromips -mrelax-pic-calls" } */
+/* { dg-final { scan-assembler "\\.reloc\t1f,R_MICROMIPS_JALR,g\n1:\tjalrs?\t" 
} } */
+
+extern void g (void);
+
+int
+NOMIPS16 f (int i)
+{
+  while (i--)
+    g ();
+}
Index: gcc/gcc/testsuite/gcc.target/mips/call-5.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/mips/call-5.c     2016-11-12 
10:09:33.627014656 +0000
+++ gcc/gcc/testsuite/gcc.target/mips/call-5.c  2016-11-12 10:09:55.122364192 
+0000
@@ -1,6 +1,6 @@
 /* Like call-1.c, but for n32.  We cannot use sibling calls for tail and tail2
    in this case (PR target/57260).  */
-/* { dg-options "-mrelax-pic-calls -mshared -foptimize-sibling-calls 
-mabi=n32" } */
+/* { dg-options "-mno-micromips -mrelax-pic-calls -mshared 
-foptimize-sibling-calls -mabi=n32" } */
 /* { dg-skip-if "requires -foptimize-sibling-calls" { *-*-* } { "-O0" } { "" } 
} */
 /* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,normal\n1:\tjalrc?\t" 
} } */
 /* { dg-final { scan-assembler 
"\\.reloc\t1f,R_MIPS_JALR,normal2\n1:\tjalrc?\t" } } */
Index: gcc/gcc/testsuite/gcc.target/mips/call-5u.c
===================================================================
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
+++ gcc/gcc/testsuite/gcc.target/mips/call-5u.c 2016-11-12 10:09:55.145543603 
+0000
@@ -0,0 +1,53 @@
+/* Like call-1.c, but for n32.  We cannot use sibling calls for tail and tail2
+   in this case (PR target/57260).  */
+/* { dg-options "-mmicromips -mrelax-pic-calls -mshared 
-foptimize-sibling-calls -mabi=n32" } */
+/* { dg-skip-if "requires -foptimize-sibling-calls" { *-*-* } { "-O0" } { "" } 
} */
+/* { dg-final { scan-assembler 
"\\.reloc\t1f,R_MICROMIPS_JALR,normal\n1:\tjalrs?\t" } } */
+/* { dg-final { scan-assembler 
"\\.reloc\t1f,R_MICROMIPS_JALR,normal2\n1:\tjalrs?\t" } } */
+/* { dg-final { scan-assembler 
"\\.reloc\t1f,R_MICROMIPS_JALR,staticfunc\n1:\tjalrs?\t" } } */
+/* { dg-final { scan-assembler 
"\\.reloc\t1f,R_MICROMIPS_JALR,tail\n1:\tjalrs?\t" } } */
+/* { dg-final { scan-assembler 
"\\.reloc\t1f,R_MICROMIPS_JALR,tail2\n1:\tjalrs?\t" } } */
+/* { dg-final { scan-assembler 
"\\.reloc\t1f,R_MICROMIPS_JALR,tail3\n1:\tjrc?\t" } } */
+/* { dg-final { scan-assembler 
"\\.reloc\t1f,R_MICROMIPS_JALR,tail4\n1:\tjrc?\t" } } */
+
+__attribute__ ((noinline)) static void staticfunc () { asm (""); }
+int normal ();
+void normal2 ();
+
+int
+NOMIPS16 f (int *p)
+{
+  *p = normal ();
+  normal2 ();
+  staticfunc ();
+  return 1;
+}
+
+int tail ();
+
+int
+NOMIPS16 h ()
+{
+  return tail ();
+}
+
+void tail2 ();
+
+NOMIPS16 void g ()
+{
+  tail2 ();
+}
+
+__attribute__ ((visibility ("hidden"))) void tail3 ();
+
+NOMIPS16 void j ()
+{
+  tail3 ();
+}
+
+__attribute__ ((noinline)) static void tail4 () { asm (""); }
+
+NOMIPS16 void k ()
+{
+  tail4 ();
+}
Index: gcc/gcc/testsuite/gcc.target/mips/call-6.c
===================================================================
--- gcc.orig/gcc/testsuite/gcc.target/mips/call-6.c     2016-11-12 
10:09:33.658830157 +0000
+++ gcc/gcc/testsuite/gcc.target/mips/call-6.c  2016-11-12 10:09:55.155646930 
+0000
@@ -1,5 +1,5 @@
 /* Like call-5.c, but for n64.  */
-/* { dg-options "-mrelax-pic-calls -mshared -foptimize-sibling-calls -mabi=64" 
} */
+/* { dg-options "-mno-micromips -mrelax-pic-calls -mshared 
-foptimize-sibling-calls -mabi=64" } */
 /* { dg-skip-if "requires -foptimize-sibling-calls" { *-*-* } { "-O0" } { "" } 
} */
 /* { dg-final { scan-assembler "\\.reloc\t1f,R_MIPS_JALR,normal\n1:\tjalrc?\t" 
} } */
 /* { dg-final { scan-assembler 
"\\.reloc\t1f,R_MIPS_JALR,normal2\n1:\tjalrc?\t" } } */
Index: gcc/gcc/testsuite/gcc.target/mips/call-6u.c
===================================================================
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
+++ gcc/gcc/testsuite/gcc.target/mips/call-6u.c 2016-11-12 10:09:55.173844261 
+0000
@@ -0,0 +1,52 @@
+/* Like call-5.c, but for n64.  */
+/* { dg-options "-mmicromips -mrelax-pic-calls -mshared 
-foptimize-sibling-calls -mabi=64" } */
+/* { dg-skip-if "requires -foptimize-sibling-calls" { *-*-* } { "-O0" } { "" } 
} */
+/* { dg-final { scan-assembler 
"\\.reloc\t1f,R_MICROMIPS_JALR,normal\n1:\tjalrs?\t" } } */
+/* { dg-final { scan-assembler 
"\\.reloc\t1f,R_MICROMIPS_JALR,normal2\n1:\tjalrs?\t" } } */
+/* { dg-final { scan-assembler 
"\\.reloc\t1f,R_MICROMIPS_JALR,staticfunc\n1:\tjalrs?\t" } } */
+/* { dg-final { scan-assembler 
"\\.reloc\t1f,R_MICROMIPS_JALR,tail\n1:\tjalrs?\t" } } */
+/* { dg-final { scan-assembler 
"\\.reloc\t1f,R_MICROMIPS_JALR,tail2\n1:\tjalrs?\t" } } */
+/* { dg-final { scan-assembler 
"\\.reloc\t1f,R_MICROMIPS_JALR,tail3\n1:\tjrc?\t" } } */
+/* { dg-final { scan-assembler 
"\\.reloc\t1f,R_MICROMIPS_JALR,tail4\n1:\tjrc?\t" } } */
+
+__attribute__ ((noinline)) static void staticfunc () { asm (""); }
+int normal ();
+void normal2 ();
+
+int
+NOMIPS16 f (int *p)
+{
+  *p = normal ();
+  normal2 ();
+  staticfunc ();
+  return 1;
+}
+
+int tail ();
+
+int
+NOMIPS16 h ()
+{
+  return tail ();
+}
+
+void tail2 ();
+
+NOMIPS16 void g ()
+{
+  tail2 ();
+}
+
+__attribute__ ((visibility ("hidden"))) void tail3 ();
+
+NOMIPS16 void j ()
+{
+  tail3 ();
+}
+
+__attribute__ ((noinline)) static void tail4 () { asm (""); }
+
+NOMIPS16 void k ()
+{
+  tail4 ();
+}

Reply via email to