This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH 2/3] MIPS/GAS: Clarify the R5900 short loop hardware bug conditions
- From: Fredrik Noring <noring at nocrew dot org>
- To: "Maciej W. Rozycki" <macro at linux-mips dot org>, Chenghua Xu <paul dot hua dot gm at gmail dot com>, binutils at sourceware dot org
- Cc: Jürgen Urban <JuergenUrban at gmx dot de>
- Date: Thu, 11 Oct 2018 18:26:03 +0200
- Subject: [PATCH 2/3] MIPS/GAS: Clarify the R5900 short loop hardware bug conditions
- References: <cover.1539274600.git.noring@nocrew.org>
This note was originally stated in gcc-2.95.2/gcc/config/mips/mips.c
in the Sony Linux kit for the PlayStation 2. It collects, clarifies
and details the bug conditions that are tested for in the code below.
---
gas/config/tc-mips.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index c9fc6c6ec1..cab1c4c6c8 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -6982,9 +6982,21 @@ can_swap_branch_p (struct mips_cl_insn *ip, expressionS *address_expr,
&& insn_length (history) != 4)
return FALSE;
- /* On R5900 short loops need to be fixed by inserting a nop in
- the branch delay slots.
- A short loop can be terminated too early. */
+ /* On the R5900 short loops need to be fixed by inserting a NOP in the
+ branch delay slot.
+
+ The short loop bug under certain conditions causes loops to execute
+ only once or twice. We must ensure that the assembler never
+ generates loops that satisfy all of the following conditions:
+
+ - a loop consists of less than or equal to six instructions
+ (including the branch delay slot);
+ - a loop contains only one conditional branch instruction at the end
+ of the loop;
+ - a loop does not contain any other branch or jump instructions;
+ - 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
/* Check if instruction has a parameter, ignore "j $31". */
&& (address_expr != NULL)
--
2.16.4