This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH] sparc: Allow non-fpop2 instructions before floating point branches
- From: Daniel Cederman <cederman at gaisler dot com>
- To: binutils at sourceware dot org
- Cc: jose dot marchesi at oracle dot com
- Date: Tue, 4 Sep 2018 14:42:24 +0200
- Subject: [PATCH] sparc: Allow non-fpop2 instructions before floating point branches
- Authorized-sender: cederman at gaisler dot com
Sparc V8 does not allow fpop2 instructions (floating point comparisons)
immediately before floating point branches. The existing check, however,
does not allow any kind of floating point instruction before the branch.
This patch adds an extra condition to only disallow fpop2 instructions.
gas/ChangeLog:
2018-09-04 Daniel Cederman <cederman@gaisler.com>
* config/tc-sparc.c (md_assemble): Allow non-fpop2 instructions
before floating point branches for Sparc V8 and earlier.
* testsuite/gas/sparc/sparc.exp: Execute the new test.
* testsuite/gas/sparc/v8branch.d: New test.
* testsuite/gas/sparc/v8branch.s: New test.
---
gas/config/tc-sparc.c | 11 ++++++-----
gas/testsuite/gas/sparc/sparc.exp | 1 +
gas/testsuite/gas/sparc/v8branch.d | 18 ++++++++++++++++++
gas/testsuite/gas/sparc/v8branch.s | 11 +++++++++++
4 files changed, 36 insertions(+), 5 deletions(-)
create mode 100644 gas/testsuite/gas/sparc/v8branch.d
create mode 100644 gas/testsuite/gas/sparc/v8branch.s
diff --git a/gas/config/tc-sparc.c b/gas/config/tc-sparc.c
index a0118befda4..b59c92ca4a1 100644
--- a/gas/config/tc-sparc.c
+++ b/gas/config/tc-sparc.c
@@ -1557,20 +1557,21 @@ md_assemble (char *str)
as_warn (_("FP branch in delay slot"));
}
- /* SPARC before v9 requires a nop instruction between a floating
- point instruction and a floating point branch. We insert one
- automatically, with a warning. */
+ /* SPARC before v9 does not allow a floating point compare
+ directly before a floating point branch. Insert a nop
+ instruction if needed, with a warning. */
if (max_architecture < SPARC_OPCODE_ARCH_V9
&& last_insn != NULL
&& (insn->flags & F_FBR) != 0
- && (last_insn->flags & F_FLOAT) != 0)
+ && (last_insn->flags & F_FLOAT) != 0
+ && (last_insn->match & OP3 (0x35)) == OP3 (0x35))
{
struct sparc_it nop_insn;
nop_insn.opcode = NOP_INSN;
nop_insn.reloc = BFD_RELOC_NONE;
output_insn (insn, &nop_insn);
- as_warn (_("FP branch preceded by FP instruction; NOP inserted"));
+ as_warn (_("FP branch preceded by FP compare; NOP inserted"));
}
switch (special_case)
diff --git a/gas/testsuite/gas/sparc/sparc.exp b/gas/testsuite/gas/sparc/sparc.exp
index bb5f7295211..4b54e52da20 100644
--- a/gas/testsuite/gas/sparc/sparc.exp
+++ b/gas/testsuite/gas/sparc/sparc.exp
@@ -66,6 +66,7 @@ if [istarget sparc*-*-*] {
run_dump_test "v8-movwr-imm"
run_dump_test "save-args"
run_dump_test "leon"
+ run_dump_test "v8branch"
set_tests_arch "v9c"
run_dump_test "ldtxa"
diff --git a/gas/testsuite/gas/sparc/v8branch.d b/gas/testsuite/gas/sparc/v8branch.d
new file mode 100644
index 00000000000..1365885a725
--- /dev/null
+++ b/gas/testsuite/gas/sparc/v8branch.d
@@ -0,0 +1,18 @@
+#as: -Av8
+#objdump: -dr -m sparc
+#warning: Warning: FP branch preceded by FP compare; NOP inserted
+#name: v8 branch instructions
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+ <no_fpop2_before_fcmp>:
+ 0: 81 a0 08 20 fadds %f0, %f0, %f0
+ 4: 13 80 00 06 fbe 1c <no_fpop2_before_fcmp\+0x1c>
+ 8: 01 00 00 00 nop
+ c: 81 a8 0a 20 fcmps %f0, %f0
+ 10: 01 00 00 00 nop
+ 14: 13 80 00 02 fbe 1c <no_fpop2_before_fcmp\+0x1c>
+ 18: 01 00 00 00 nop
+ 1c: 01 00 00 00 nop
diff --git a/gas/testsuite/gas/sparc/v8branch.s b/gas/testsuite/gas/sparc/v8branch.s
new file mode 100644
index 00000000000..ba8265db096
--- /dev/null
+++ b/gas/testsuite/gas/sparc/v8branch.s
@@ -0,0 +1,11 @@
+ .text
+ # Check that a nop instruction is inserted to prevent a floating
+ # point compare directly followed by a floating point branch.
+no_fpop2_before_fcmp:
+ fadds %f0, %f0, %f0
+ fbe 1f
+ nop
+ fcmps %f0, %f0
+ fbe 1f
+ nop
+1: nop
--
2.17.1