[binutils-gdb] gas, sparc: Allow non-fpop2 instructions before floating point branches

Jose E.Marchesi jemarch@sourceware.org
Tue Sep 4 13:40:00 GMT 2018


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=618a8fdba6fc86a6ed88df257bf5f44d85e9071b

commit 618a8fdba6fc86a6ed88df257bf5f44d85e9071b
Author: Daniel Cederman <cederman@gaisler.com>
Date:   Tue Sep 4 06:25:52 2018 -0700

    gas, sparc: Allow non-fpop2 instructions before floating point branches
    
    Sparc V8 does not allow fpop2 instructions (floating point
    comparisons) immediately before floating point branches.  From the
    SPARC Architecture Manual Version 8, section B.22 "Branch on
    Floating-point Condition Codes Instructions":
    
    "If the instruction executed immediately before an FBfcc is an FPop2
    instruction, the result of the FBfcc is undefined.  Therefore, at
    least one non FPop2 instruction should be executed between the FPop2
    instruction and the FBfcc instruction."
    
    The existing check in GAS, 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.

Diff:
---
 gas/ChangeLog                      |  8 ++++++++
 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 +++++++++++
 5 files changed, 44 insertions(+), 5 deletions(-)

diff --git a/gas/ChangeLog b/gas/ChangeLog
index 07ab7c7..6d55671 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,11 @@
+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.
+
 2018-09-03  Nick Clifton  <nickc@redhat.com>
 
 	PR gas/23570
diff --git a/gas/config/tc-sparc.c b/gas/config/tc-sparc.c
index a0118be..b59c92c 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 bb5f729..4b54e52 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 0000000..1365885
--- /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 0000000..ba8265d
--- /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



More information about the Binutils-cvs mailing list