]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gas, sparc: Allow non-fpop2 instructions before floating point branches
authorDaniel Cederman <cederman@gaisler.com>
Tue, 4 Sep 2018 13:25:52 +0000 (06:25 -0700)
committerjemarch <jemarch@wcoekaer-srv5.us.oracle.com>
Tue, 4 Sep 2018 13:25:52 +0000 (06:25 -0700)
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.

gas/ChangeLog
gas/config/tc-sparc.c
gas/testsuite/gas/sparc/sparc.exp
gas/testsuite/gas/sparc/v8branch.d [new file with mode: 0644]
gas/testsuite/gas/sparc/v8branch.s [new file with mode: 0644]

index 07ab7c74212ed65c976b56531e9febb17d5c56f7..6d556714740987ebdf8d022bae41d616d5d3ab36 100644 (file)
@@ -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
index a0118befda48ac25fe59d168032164cf5e155c87..b59c92ca4a118ac5834464d6b2422da73403870c 100644 (file)
@@ -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)
index bb5f7295211119e897049eda5dd15d4e101383a8..4b54e52da20c9daccbc0fb21240f508c458b3518 100644 (file)
@@ -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 (file)
index 0000000..1365885
--- /dev/null
@@ -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 (file)
index 0000000..ba8265d
--- /dev/null
@@ -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