Fredrik Noring
2018-10-26 17:25:14 UTC
`-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.
---
gas/config/tc-mips.c | 18 +++++++++++++++++-
gas/doc/as.texi | 6 ++++++
gas/doc/c-mips.texi | 5 +++++
gas/po/sv.po | 2 ++
gas/testsuite/gas/mips/mips.exp | 1 +
gas/testsuite/gas/mips/r5900-fix.d | 14 ++++++++++++++
gas/testsuite/gas/mips/r5900-fix.s | 19 +++++++++++++++++++
7 files changed, 64 insertions(+), 1 deletion(-)
create mode 100644 gas/testsuite/gas/mips/r5900-fix.d
create mode 100644 gas/testsuite/gas/mips/r5900-fix.s
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index 918525b4e9..358c59f837 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -939,6 +939,9 @@ static int mips_fix_rm7000;
/* ...likewise -mfix-cn63xxp1 */
static bfd_boolean mips_fix_cn63xxp1;
+/* ...likewise -mfix-r5900 */
+static bfd_boolean mips_fix_r5900;
+
/* We don't relax branches by default, since this causes us to expand
`la .l2 - .l1' if there's a branch between .l1 and .l2, because we
fail to compute the offset before expanding the macro to the most
@@ -1488,6 +1491,8 @@ enum options
OPTION_NO_FIX_VR4130,
OPTION_FIX_CN63XXP1,
OPTION_NO_FIX_CN63XXP1,
+ OPTION_FIX_R5900,
+ OPTION_NO_FIX_R5900,
OPTION_TRAP,
OPTION_BREAK,
OPTION_EB,
@@ -1636,6 +1641,8 @@ struct option md_longopts[] =
{"mno-fix-rm7000", no_argument, NULL, OPTION_NO_FIX_RM7000},
{"mfix-cn63xxp1", no_argument, NULL, OPTION_FIX_CN63XXP1},
{"mno-fix-cn63xxp1", no_argument, NULL, OPTION_NO_FIX_CN63XXP1},
+ {"mfix-r5900", no_argument, NULL, OPTION_FIX_R5900},
+ {"mno-fix-r5900", no_argument, NULL, OPTION_NO_FIX_R5900},
/* Miscellaneous options. */
{"trap", no_argument, NULL, OPTION_TRAP},
@@ -6997,7 +7004,7 @@ can_swap_branch_p (struct mips_cl_insn *ip, expressionS *address_expr,
- a branch delay slot of the loop is not NOP (EE 2.9 or later).
We need to do this because of a hardware bug in the R5900 chip. */
- if (mips_opts.arch == CPU_R5900
+ if ((mips_opts.arch == CPU_R5900 || mips_fix_r5900)
/* Check if instruction has a parameter, ignore "j $31". */
&& (address_expr != NULL)
/* Parameter must be 16 bit. */
@@ -14763,6 +14770,14 @@ md_parse_option (int c, const char *arg)
mips_fix_cn63xxp1 = FALSE;
break;
+ case OPTION_FIX_R5900:
+ mips_fix_r5900 = TRUE;
+ break;
+
+ case OPTION_NO_FIX_R5900:
+ mips_fix_r5900 = FALSE;
+ break;
+
case OPTION_RELAX_BRANCH:
mips_relax_branch = 1;
break;
@@ -20125,6 +20140,7 @@ MIPS options:\n\
-mfix-vr4130 work around VR4130 mflo/mfhi errata\n\
-mfix-24k insert a nop after ERET and DERET instructions\n\
-mfix-cn63xxp1 work around CN63XXP1 PREF errata\n\
+-mfix-r5900 work around R5900 short loop errata\n\
-mgp32 use 32-bit GPRs, regardless of the chosen ISA\n\
-mfp32 use 32-bit FPRs, regardless of the chosen ISA\n\
-msym32 assume all symbols have 32-bit values\n\
diff --git a/gas/doc/as.texi b/gas/doc/as.texi
index acecd35225..1270e6efa1 100644
--- a/gas/doc/as.texi
+++ b/gas/doc/as.texi
@@ -453,6 +453,7 @@ gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}.
[@b{-mfix-rm7000}] [@b{-mno-fix-rm7000}]
[@b{-mfix-vr4120}] [@b{-mno-fix-vr4120}]
[@b{-mfix-vr4130}] [@b{-mno-fix-vr4130}]
+ [@b{-mfix-r5900}] [@b{-mno-fix-r5900}]
[@b{-mdebug}] [@b{-no-mdebug}]
[@b{-mpdr}] [@b{-mno-pdr}]
@end ifset
@@ -1444,6 +1445,11 @@ of an mfhi or mflo instruction occurs in the following two instructions.
Cause nops to be inserted if a dmult or dmultu instruction is
followed by a load instruction.
+@item -mfix-r5900
+@itemx -mno-fix-r5900
+Insert a NOP in the branch delay slot for short loops with six
+instructions or less.
+
@item -mdebug
@itemx -no-mdebug
Cause stabs-style debugging output to go into an ECOFF-style .mdebug
diff --git a/gas/doc/c-mips.texi b/gas/doc/c-mips.texi
index 7751ce01d6..3ee407924c 100644
--- a/gas/doc/c-mips.texi
+++ b/gas/doc/c-mips.texi
@@ -327,6 +327,11 @@ Insert nops to work around the 24K @samp{eret}/@samp{deret} errata.
Replace @code{pref} hints 0 - 4 and 6 - 24 with hint 28 to work around
certain CN63XXP1 errata.
+@item -mfix-r5900
+@itemx -mno-fix-r5900
+Insert a @samp{nop} in the branch delay slot for short loops with six
+instructions or less.
+
@item -m4010
@itemx -no-m4010
Generate code for the LSI R4010 chip. This tells the assembler to
diff --git a/gas/po/sv.po b/gas/po/sv.po
index 575bf0621d..cee660b315 100644
--- a/gas/po/sv.po
+++ b/gas/po/sv.po
@@ -12546,6 +12546,7 @@ msgid ""
"-mfix-vr4130\t\twork around VR4130 mflo/mfhi errata\n"
"-mfix-24k\t\tinsert a nop after ERET and DERET instructions\n"
"-mfix-cn63xxp1\t\twork around CN63XXP1 PREF errata\n"
+"-mfix-r5900\t\twork around R5900 short loop errata\n"
"-mgp32\t\t\tuse 32-bit GPRs, regardless of the chosen ISA\n"
"-mfp32\t\t\tuse 32-bit FPRs, regardless of the chosen ISA\n"
"-msym32\t\t\tassume all symbols have 32-bit values\n"
@@ -12560,6 +12561,7 @@ msgstr ""
"-mfix-vr4130\t\tlösning för VR4130 mflo/mfhi-errata\n"
"-mfix-24k\t\tinfoga en nop efter ERET- och DERET-instruktioner\n"
"-mfix-cn63xxp1\t\tlösning för CN63XXP1 PREF-errata\n"
+"-mfix-r5900\t\tlösning för R5900 kort loop-errata\n"
"-mgp32\t\t\tanvänd 32-bitars GPRs, oberoende av vald ISA\n"
"-mfp32\t\t\tanvänd 32-bitars FPRs, oberoende av vald ISA\n"
"-msym32\t\t\tantag att alla symbole har 32-bitars värden\n"
diff --git a/gas/testsuite/gas/mips/mips.exp b/gas/testsuite/gas/mips/mips.exp
index 0da442c1d5..6e788c0484 100644
--- a/gas/testsuite/gas/mips/mips.exp
+++ b/gas/testsuite/gas/mips/mips.exp
@@ -1560,6 +1560,7 @@ if { [istarget mips*-*-vxworks*] } {
run_dump_test_arches "break-error" [mips_arch_list_all]
run_dump_test "r5900"
+ run_dump_test "r5900-fix"
run_dump_test "r5900-full"
run_list_test "r5900-nollsc" "-mabi=o64 -march=r5900"
run_dump_test "r5900-vu0"
diff --git a/gas/testsuite/gas/mips/r5900-fix.d b/gas/testsuite/gas/mips/r5900-fix.d
new file mode 100644
index 0000000000..593a699805
--- /dev/null
+++ b/gas/testsuite/gas/mips/r5900-fix.d
@@ -0,0 +1,14 @@
+#objdump: -dr --prefix-addresses --show-raw-insn -M gpr-names=numeric -mmips:5900
+#name: MIPS R5900 workaround
+#as: -mips3 -mfix-r5900
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 2403012c li \$3,300
+[0-9a-f]+ <[^>]*> 2063ffff addi \$3,\$3,-1
+[0-9a-f]+ <[^>]*> 2084ffff addi \$4,\$4,-1
+[0-9a-f]+ <[^>]*> 1460fffd bnez \$3,[0-9a-f]+ <short_loop_mfix_r5900>
+[0-9a-f]+ <[^>]*> 00000000 nop
+[0-9a-f]+ <[^>]*> 24040003 li \$4,3
+ \.\.\.
diff --git a/gas/testsuite/gas/mips/r5900-fix.s b/gas/testsuite/gas/mips/r5900-fix.s
new file mode 100644
index 0000000000..167eb2c69f
--- /dev/null
+++ b/gas/testsuite/gas/mips/r5900-fix.s
@@ -0,0 +1,19 @@
+ .text
+
+test_mfix_r5900:
+ .ent test_mfix_r5900
+ .set push
+ .set reorder
+ # Test the short loop fix with 3 loop instructions.
+ li $3, 300
+short_loop_mfix_r5900:
+ addi $3, -1
+ addi $4, -1
+ # A NOP will be inserted in the branch delay slot.
+ bne $3, $0, short_loop_mfix_r5900
+
+ li $4, 3
+ .set pop
+
+ .space 8
+ .end test_mfix_r5900
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.
---
gas/config/tc-mips.c | 18 +++++++++++++++++-
gas/doc/as.texi | 6 ++++++
gas/doc/c-mips.texi | 5 +++++
gas/po/sv.po | 2 ++
gas/testsuite/gas/mips/mips.exp | 1 +
gas/testsuite/gas/mips/r5900-fix.d | 14 ++++++++++++++
gas/testsuite/gas/mips/r5900-fix.s | 19 +++++++++++++++++++
7 files changed, 64 insertions(+), 1 deletion(-)
create mode 100644 gas/testsuite/gas/mips/r5900-fix.d
create mode 100644 gas/testsuite/gas/mips/r5900-fix.s
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index 918525b4e9..358c59f837 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -939,6 +939,9 @@ static int mips_fix_rm7000;
/* ...likewise -mfix-cn63xxp1 */
static bfd_boolean mips_fix_cn63xxp1;
+/* ...likewise -mfix-r5900 */
+static bfd_boolean mips_fix_r5900;
+
/* We don't relax branches by default, since this causes us to expand
`la .l2 - .l1' if there's a branch between .l1 and .l2, because we
fail to compute the offset before expanding the macro to the most
@@ -1488,6 +1491,8 @@ enum options
OPTION_NO_FIX_VR4130,
OPTION_FIX_CN63XXP1,
OPTION_NO_FIX_CN63XXP1,
+ OPTION_FIX_R5900,
+ OPTION_NO_FIX_R5900,
OPTION_TRAP,
OPTION_BREAK,
OPTION_EB,
@@ -1636,6 +1641,8 @@ struct option md_longopts[] =
{"mno-fix-rm7000", no_argument, NULL, OPTION_NO_FIX_RM7000},
{"mfix-cn63xxp1", no_argument, NULL, OPTION_FIX_CN63XXP1},
{"mno-fix-cn63xxp1", no_argument, NULL, OPTION_NO_FIX_CN63XXP1},
+ {"mfix-r5900", no_argument, NULL, OPTION_FIX_R5900},
+ {"mno-fix-r5900", no_argument, NULL, OPTION_NO_FIX_R5900},
/* Miscellaneous options. */
{"trap", no_argument, NULL, OPTION_TRAP},
@@ -6997,7 +7004,7 @@ can_swap_branch_p (struct mips_cl_insn *ip, expressionS *address_expr,
- a branch delay slot of the loop is not NOP (EE 2.9 or later).
We need to do this because of a hardware bug in the R5900 chip. */
- if (mips_opts.arch == CPU_R5900
+ if ((mips_opts.arch == CPU_R5900 || mips_fix_r5900)
/* Check if instruction has a parameter, ignore "j $31". */
&& (address_expr != NULL)
/* Parameter must be 16 bit. */
@@ -14763,6 +14770,14 @@ md_parse_option (int c, const char *arg)
mips_fix_cn63xxp1 = FALSE;
break;
+ case OPTION_FIX_R5900:
+ mips_fix_r5900 = TRUE;
+ break;
+
+ case OPTION_NO_FIX_R5900:
+ mips_fix_r5900 = FALSE;
+ break;
+
case OPTION_RELAX_BRANCH:
mips_relax_branch = 1;
break;
@@ -20125,6 +20140,7 @@ MIPS options:\n\
-mfix-vr4130 work around VR4130 mflo/mfhi errata\n\
-mfix-24k insert a nop after ERET and DERET instructions\n\
-mfix-cn63xxp1 work around CN63XXP1 PREF errata\n\
+-mfix-r5900 work around R5900 short loop errata\n\
-mgp32 use 32-bit GPRs, regardless of the chosen ISA\n\
-mfp32 use 32-bit FPRs, regardless of the chosen ISA\n\
-msym32 assume all symbols have 32-bit values\n\
diff --git a/gas/doc/as.texi b/gas/doc/as.texi
index acecd35225..1270e6efa1 100644
--- a/gas/doc/as.texi
+++ b/gas/doc/as.texi
@@ -453,6 +453,7 @@ gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}.
[@b{-mfix-rm7000}] [@b{-mno-fix-rm7000}]
[@b{-mfix-vr4120}] [@b{-mno-fix-vr4120}]
[@b{-mfix-vr4130}] [@b{-mno-fix-vr4130}]
+ [@b{-mfix-r5900}] [@b{-mno-fix-r5900}]
[@b{-mdebug}] [@b{-no-mdebug}]
[@b{-mpdr}] [@b{-mno-pdr}]
@end ifset
@@ -1444,6 +1445,11 @@ of an mfhi or mflo instruction occurs in the following two instructions.
Cause nops to be inserted if a dmult or dmultu instruction is
followed by a load instruction.
+@item -mfix-r5900
+@itemx -mno-fix-r5900
+Insert a NOP in the branch delay slot for short loops with six
+instructions or less.
+
@item -mdebug
@itemx -no-mdebug
Cause stabs-style debugging output to go into an ECOFF-style .mdebug
diff --git a/gas/doc/c-mips.texi b/gas/doc/c-mips.texi
index 7751ce01d6..3ee407924c 100644
--- a/gas/doc/c-mips.texi
+++ b/gas/doc/c-mips.texi
@@ -327,6 +327,11 @@ Insert nops to work around the 24K @samp{eret}/@samp{deret} errata.
Replace @code{pref} hints 0 - 4 and 6 - 24 with hint 28 to work around
certain CN63XXP1 errata.
+@item -mfix-r5900
+@itemx -mno-fix-r5900
+Insert a @samp{nop} in the branch delay slot for short loops with six
+instructions or less.
+
@item -m4010
@itemx -no-m4010
Generate code for the LSI R4010 chip. This tells the assembler to
diff --git a/gas/po/sv.po b/gas/po/sv.po
index 575bf0621d..cee660b315 100644
--- a/gas/po/sv.po
+++ b/gas/po/sv.po
@@ -12546,6 +12546,7 @@ msgid ""
"-mfix-vr4130\t\twork around VR4130 mflo/mfhi errata\n"
"-mfix-24k\t\tinsert a nop after ERET and DERET instructions\n"
"-mfix-cn63xxp1\t\twork around CN63XXP1 PREF errata\n"
+"-mfix-r5900\t\twork around R5900 short loop errata\n"
"-mgp32\t\t\tuse 32-bit GPRs, regardless of the chosen ISA\n"
"-mfp32\t\t\tuse 32-bit FPRs, regardless of the chosen ISA\n"
"-msym32\t\t\tassume all symbols have 32-bit values\n"
@@ -12560,6 +12561,7 @@ msgstr ""
"-mfix-vr4130\t\tlösning för VR4130 mflo/mfhi-errata\n"
"-mfix-24k\t\tinfoga en nop efter ERET- och DERET-instruktioner\n"
"-mfix-cn63xxp1\t\tlösning för CN63XXP1 PREF-errata\n"
+"-mfix-r5900\t\tlösning för R5900 kort loop-errata\n"
"-mgp32\t\t\tanvänd 32-bitars GPRs, oberoende av vald ISA\n"
"-mfp32\t\t\tanvänd 32-bitars FPRs, oberoende av vald ISA\n"
"-msym32\t\t\tantag att alla symbole har 32-bitars värden\n"
diff --git a/gas/testsuite/gas/mips/mips.exp b/gas/testsuite/gas/mips/mips.exp
index 0da442c1d5..6e788c0484 100644
--- a/gas/testsuite/gas/mips/mips.exp
+++ b/gas/testsuite/gas/mips/mips.exp
@@ -1560,6 +1560,7 @@ if { [istarget mips*-*-vxworks*] } {
run_dump_test_arches "break-error" [mips_arch_list_all]
run_dump_test "r5900"
+ run_dump_test "r5900-fix"
run_dump_test "r5900-full"
run_list_test "r5900-nollsc" "-mabi=o64 -march=r5900"
run_dump_test "r5900-vu0"
diff --git a/gas/testsuite/gas/mips/r5900-fix.d b/gas/testsuite/gas/mips/r5900-fix.d
new file mode 100644
index 0000000000..593a699805
--- /dev/null
+++ b/gas/testsuite/gas/mips/r5900-fix.d
@@ -0,0 +1,14 @@
+#objdump: -dr --prefix-addresses --show-raw-insn -M gpr-names=numeric -mmips:5900
+#name: MIPS R5900 workaround
+#as: -mips3 -mfix-r5900
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+[0-9a-f]+ <[^>]*> 2403012c li \$3,300
+[0-9a-f]+ <[^>]*> 2063ffff addi \$3,\$3,-1
+[0-9a-f]+ <[^>]*> 2084ffff addi \$4,\$4,-1
+[0-9a-f]+ <[^>]*> 1460fffd bnez \$3,[0-9a-f]+ <short_loop_mfix_r5900>
+[0-9a-f]+ <[^>]*> 00000000 nop
+[0-9a-f]+ <[^>]*> 24040003 li \$4,3
+ \.\.\.
diff --git a/gas/testsuite/gas/mips/r5900-fix.s b/gas/testsuite/gas/mips/r5900-fix.s
new file mode 100644
index 0000000000..167eb2c69f
--- /dev/null
+++ b/gas/testsuite/gas/mips/r5900-fix.s
@@ -0,0 +1,19 @@
+ .text
+
+test_mfix_r5900:
+ .ent test_mfix_r5900
+ .set push
+ .set reorder
+ # Test the short loop fix with 3 loop instructions.
+ li $3, 300
+short_loop_mfix_r5900:
+ addi $3, -1
+ addi $4, -1
+ # A NOP will be inserted in the branch delay slot.
+ bne $3, $0, short_loop_mfix_r5900
+
+ li $4, 3
+ .set pop
+
+ .space 8
+ .end test_mfix_r5900
--
2.18.1
2.18.1