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.
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.
---
Thanks a lot for your review, Maciej!
Changes in v2:
- ChangeLog entry corrections
- Rebase to origin/trunk
---
gcc/config/mips/mips.c | 14 ++
gcc/config/mips/mips.h | 1 +
gcc/config/mips/mips.opt | 4
gcc/doc/invoke.texi | 14 +-
4 files changed, 28 insertions(+), 5 deletions(-)
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index d78e2056ec2..04de85a3ba2 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -18906,13 +18906,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
@@ -20287,6 +20287,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 R1 errata only if the processor
was selected explicitly. */
if ((target_flags_explicit & MASK_FIX_R1) == 0
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index 11ca364d752..d2205f08972 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -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} \
diff --git a/gcc/config/mips/mips.opt b/gcc/config/mips/mips.opt
index 16c33d12e22..75332100435 100644
--- a/gcc/config/mips/mips.opt
+++ b/gcc/config/mips/mips.opt
@@ -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.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index e071f125efe..44ecc241fd7 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -945,6 +945,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 -m