MIPS: Add `-mfix-r5900' option for the R5900 short loop erratum
authorFredrik Noring <noring@nocrew.org>
Tue, 27 Nov 2018 16:01:10 +0000 (16:01 +0000)
committerMaciej W. Rozycki <macro@gcc.gnu.org>
Tue, 27 Nov 2018 16:01:10 +0000 (16:01 +0000)
The short loop bug under certain conditions causes loops to
execute only once or twice, due to a hardware bug in the R5900 chip.

`-march=r5900' already enables the R5900 short loop workaround.
However, the R5900 ISA and most other MIPS ISAs are mutually
exclusive since R5900-specific instructions are generated as well.

The `-mfix-r5900' option can be used in combination with e.g.
`-mips2' or `-mips3' to generate generic MIPS binaries that also
work with the R5900 target.  The workaround is implemented by GAS
rather than by GCC.

The following small `shortloop.c' file has been used as a test
with GCC 8.2.0:

void shortloop(void)
{
    __asm__ __volatile__ (
" li $3, 300\n"
"loop:\n"
" addi $3, -1\n"
" addi $4, -1\n"
" bne $3, $0, loop\n"
" li $4, 3\n"
::);
}

The following six combinations have been tested:

% mipsr5900el-unknown-linux-gnu-gcc -O1 -c shortloop.c
% mipsr5900el-unknown-linux-gnu-gcc -O1 -c shortloop.c -mfix-r5900
% mipsr5900el-unknown-linux-gnu-gcc -O1 -c shortloop.c -mno-fix-r5900

% mipsr4000el-unknown-linux-gnu-gcc -O1 -c shortloop.c
% mipsr4000el-unknown-linux-gnu-gcc -O1 -c shortloop.c -mfix-r5900
% mipsr4000el-unknown-linux-gnu-gcc -O1 -c shortloop.c -mno-fix-r5900

The R5900 short loop erratum is corrected in exactly three cases:

1. for the target `mipsr5900el' by default;

2. for the target `mipsr5900el' with `-mfix-r5900';

3. for any other MIPS target (e.g. `mipsr4000el') with `-mfix-r5900'.

In all other cases the correction is not made.

2018-11-27  Fredrik Noring  <noring@nocrew.org>

gcc/
* config/mips/mips.c (mips_reorg_process_insns)
(mips_option_override): Handle `-mfix-r5900'.
* config/mips/mips.h (ASM_SPEC): Add `mfix-r5900' and
`mno-fix-r5900'.
* config/mips/mips.opt (mfix-r5900): New option.
* doc/invoke.texi: Document the `r5900' processor name, and
`-mfix-r5900' and `-mno-fix-r5900' options.

From-SVN: r266519

gcc/ChangeLog
gcc/config/mips/mips.c
gcc/config/mips/mips.h
gcc/config/mips/mips.opt
gcc/doc/invoke.texi

index aea7767bde68b01b18527e72f48f269637843a44..766fd4b6dd191a4aca64f3ccf99abf10f1eb2801 100644 (file)
@@ -1,3 +1,13 @@
+2018-11-27  Fredrik Noring  <noring@nocrew.org>
+
+       * config/mips/mips.c (mips_reorg_process_insns)
+       (mips_option_override): Handle `-mfix-r5900'.
+       * config/mips/mips.h (ASM_SPEC): Add `mfix-r5900' and
+       `mno-fix-r5900'.
+       * config/mips/mips.opt (mfix-r5900): New option.
+       * doc/invoke.texi: Document the `r5900' processor name, and
+       `-mfix-r5900' and `-mno-fix-r5900' options.
+
 2018-11-27  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/88188
index 09b2ae7219907154c5289a1611eda7cccf7a7bee..55b44078518c80da8a5d7e0bf2630b32a8a595a3 100644 (file)
@@ -18908,13 +18908,13 @@ mips_reorg_process_insns (void)
   if (crtl->profile)
     cfun->machine->all_noreorder_p = false;
 
-  /* Code compiled with -mfix-vr4120, -mfix-rm7000 or -mfix-24k can't be
-     all noreorder because we rely on the assembler to work around some
-     errata.  The R5900 too has several bugs.  */
+  /* Code compiled with -mfix-vr4120, -mfix-r5900, -mfix-rm7000 or
+     -mfix-24k can't be all noreorder because we rely on the assembler
+     to work around some errata.  The R5900 target has several bugs.  */
   if (TARGET_FIX_VR4120
       || TARGET_FIX_RM7000
       || TARGET_FIX_24K
-      || TARGET_MIPS5900)
+      || TARGET_FIX_R5900)
     cfun->machine->all_noreorder_p = false;
 
   /* The same is true for -mfix-vr4130 if we might generate MFLO or
@@ -20289,6 +20289,12 @@ mips_option_override (void)
       && strcmp (mips_arch_info->name, "r4400") == 0)
     target_flags |= MASK_FIX_R4400;
 
+  /* Default to working around R5900 errata only if the processor
+     was selected explicitly.  */
+  if ((target_flags_explicit & MASK_FIX_R5900) == 0
+      && strcmp (mips_arch_info->name, "r5900") == 0)
+    target_flags |= MASK_FIX_R5900;
+
   /* Default to working around R10000 errata only if the processor
      was selected explicitly.  */
   if ((target_flags_explicit & MASK_FIX_R10000) == 0
index 11ca364d752293b1b45443b6cd6712620c4e4183..d2205f08972e576e717b1390a903a13fd76dc9f5 100644 (file)
@@ -1411,6 +1411,7 @@ struct mips_cpu_info {
 %{mloongson-ext2} %{mno-loongson-ext2} \
 %{msmartmips} %{mno-smartmips} \
 %{mmt} %{mno-mt} \
+%{mfix-r5900} %{mno-fix-r5900} \
 %{mfix-rm7000} %{mno-fix-rm7000} \
 %{mfix-vr4120} %{mfix-vr4130} \
 %{mfix-24k} \
index 16c33d12e2208a252bab04fe885bd4ccd229d587..7533210043505d7665088e45e202b17970a68825 100644 (file)
@@ -165,6 +165,10 @@ mfix-r4400
 Target Report Mask(FIX_R4400)
 Work around certain R4400 errata.
 
+mfix-r5900
+Target Report Mask(FIX_R5900)
+Work around the R5900 short loop erratum.
+
 mfix-rm7000
 Target Report Var(TARGET_FIX_RM7000)
 Work around certain RM7000 errata.
index 93938ab486bdfa3eb5eec8fa501138937f3410d4..682da942553561da8108552070436102bf4210b9 100644 (file)
@@ -948,6 +948,7 @@ Objective-C and Objective-C++ Dialects}.
 -mmad  -mno-mad  -mimadd  -mno-imadd  -mfused-madd  -mno-fused-madd  -nocpp @gol
 -mfix-24k  -mno-fix-24k @gol
 -mfix-r4000  -mno-fix-r4000  -mfix-r4400  -mno-fix-r4400 @gol
+-mfix-r5900  -mno-fix-r5900 @gol
 -mfix-r10000  -mno-fix-r10000  -mfix-rm7000  -mno-fix-rm7000 @gol
 -mfix-vr4120  -mno-fix-vr4120 @gol
 -mfix-vr4130  -mno-fix-vr4130  -mfix-sb1  -mno-fix-sb1 @gol
@@ -21290,7 +21291,8 @@ The processor names are:
 @samp{orion},
 @samp{p5600}, @samp{p6600},
 @samp{r2000}, @samp{r3000}, @samp{r3900}, @samp{r4000}, @samp{r4400},
-@samp{r4600}, @samp{r4650}, @samp{r4700}, @samp{r6000}, @samp{r8000},
+@samp{r4600}, @samp{r4650}, @samp{r4700}, @samp{r5900},
+@samp{r6000}, @samp{r8000},
 @samp{rm7000}, @samp{rm9000},
 @samp{r10000}, @samp{r12000}, @samp{r14000}, @samp{r16000},
 @samp{sb1},
@@ -22082,6 +22084,16 @@ branch-likely instructions.  @option{-mfix-r10000} is the default when
 @option{-march=r10000} is used; @option{-mno-fix-r10000} is the default
 otherwise.
 
+@item -mfix-r5900
+@itemx -mno-fix-r5900
+@opindex mfix-r5900
+Do not attempt to schedule the preceding instruction into the delay slot
+of a branch instruction placed at the end of a short loop of six
+instructions or fewer and always schedule a @code{nop} instruction there
+instead.  The short loop bug under certain conditions causes loops to
+execute only once or twice, due to a hardware bug in the R5900 chip.  The
+workaround is implemented by the assembler rather than by GCC@.
+
 @item -mfix-rm7000
 @itemx -mno-fix-rm7000
 @opindex mfix-rm7000