diff options
author | Fredrik Noring <noring@nocrew.org> | 2018-10-19 09:47:55 +0100 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2018-10-19 09:47:55 +0100 |
commit | 33d64ca5db656f1f377de18f94403d8b3b91e3a1 (patch) | |
tree | 898e440de0a4f6763f3a17b8c9cc0391b43304cc /gas/config/tc-mips.c | |
parent | 08acaf5caf47225ff94dc5e64ce8edce6664615a (diff) | |
download | gdb-33d64ca5db656f1f377de18f94403d8b3b91e3a1.zip gdb-33d64ca5db656f1f377de18f94403d8b3b91e3a1.tar.gz gdb-33d64ca5db656f1f377de18f94403d8b3b91e3a1.tar.bz2 |
This set of changes clarifies the conditions for the R5900 short loop fix and extends its test with the border cases of six and seven instructions.
* testsuite/gas/mips/r5900.s: Extend the R5900 short loop fix
test with border cases.
* testsuite/gas/mips/r5900.d: Add extra expected disassembly.
* config/tc-mips.c (can_swap_branch_p): Clarify the R5900 short
loop hardware bug conditions. Correct note on the R5900
instruction count short loop fix.
Diffstat (limited to 'gas/config/tc-mips.c')
-rw-r--r-- | gas/config/tc-mips.c | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index c9fc6c6..918525b 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) @@ -7002,8 +7014,8 @@ can_swap_branch_p (struct mips_cl_insn *ip, expressionS *address_expr, || (ip->insn_opcode & 0xffff0000) == 0x04110000)) /* bgezal $0 */ { int distance; - /* Check if loop is shorter than 6 instructions including - branch and delay slot. */ + /* Check if loop is shorter than or equal to 6 instructions + including branch and delay slot. */ distance = frag_now_fix () - S_GET_VALUE (address_expr->X_add_symbol); if (distance <= 20) { |