This is the mail archive of the gdb-cvs@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] Fix bugs with float compare and Inf operands.


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

commit 87903eafb083abbf330c22fbf941fcbad700c098
Author: Jim Wilson <jim.wilson@linaro.org>
Date:   Wed Dec 21 12:33:12 2016 -0800

    Fix bugs with float compare and Inf operands.
    
    	sim/aarch64/
    	* simulator.c (set_flags_for_float_compare): Add code to handle Inf.
    	Add comment to document NaN issue.
    	(set_flags_for_double_compare): Likewise.
    
    	sim/testsuite/sim/aarch64/
    	* fcmp.s: New.

Diff:
---
 sim/aarch64/ChangeLog               |   6 ++
 sim/aarch64/simulator.c             |  28 +++++++
 sim/testsuite/sim/aarch64/ChangeLog |   4 +
 sim/testsuite/sim/aarch64/fcmp.s    | 146 ++++++++++++++++++++++++++++++++++++
 4 files changed, 184 insertions(+)

diff --git a/sim/aarch64/ChangeLog b/sim/aarch64/ChangeLog
index 2346a49..b1baf26 100644
--- a/sim/aarch64/ChangeLog
+++ b/sim/aarch64/ChangeLog
@@ -1,3 +1,9 @@
+2016-12-21  Jim Wilson  <jim.wilson@linaro.org>
+
+	* simulator.c (set_flags_for_float_compare): Add code to handle Inf.
+	Add comment to document NaN issue.
+	(set_flags_for_double_compare): Likewise.
+
 2016-12-13  Jim Wilson  <jim.wilson@linaro.org>
 
 	* simulator.c (NEG, POS): Move before set_flags_for_add64.
diff --git a/sim/aarch64/simulator.c b/sim/aarch64/simulator.c
index e6406dc..be3d6c7 100644
--- a/sim/aarch64/simulator.c
+++ b/sim/aarch64/simulator.c
@@ -8468,8 +8468,22 @@ set_flags_for_float_compare (sim_cpu *cpu, float fvalue1, float fvalue2)
 {
   uint32_t flags;
 
+  /* FIXME: Add exception raising.  */
   if (isnan (fvalue1) || isnan (fvalue2))
     flags = C|V;
+  else if (isinf (fvalue1) && isinf (fvalue2))
+    {
+      /* Subtracting two infinities may give a NaN.  We only need to compare
+	 the signs, which we can get from isinf.  */
+      int result = isinf (fvalue1) - isinf (fvalue2);
+
+      if (result == 0)
+	flags = Z|C;
+      else if (result < 0)
+	flags = N;
+      else /* (result > 0).  */
+	flags = C;
+    }
   else
     {
       float result = fvalue1 - fvalue2;
@@ -8540,8 +8554,22 @@ set_flags_for_double_compare (sim_cpu *cpu, double dval1, double dval2)
 {
   uint32_t flags;
 
+  /* FIXME: Add exception raising.  */
   if (isnan (dval1) || isnan (dval2))
     flags = C|V;
+  else if (isinf (dval1) && isinf (dval2))
+    {
+      /* Subtracting two infinities may give a NaN.  We only need to compare
+	 the signs, which we can get from isinf.  */
+      int result = isinf (dval1) - isinf (dval2);
+
+      if (result == 0)
+	flags = Z|C;
+      else if (result < 0)
+	flags = N;
+      else /* (result > 0).  */
+	flags = C;
+    }
   else
     {
       double result = dval1 - dval2;
diff --git a/sim/testsuite/sim/aarch64/ChangeLog b/sim/testsuite/sim/aarch64/ChangeLog
index ff047e3..a130a97 100644
--- a/sim/testsuite/sim/aarch64/ChangeLog
+++ b/sim/testsuite/sim/aarch64/ChangeLog
@@ -1,3 +1,7 @@
+2016-12-21  Jim Wilson  <jim.wilson@linaro.org>
+
+	* fcmp.s: New.
+
 2016-12-13  Jim Wilson  <jim.wilson@linaro.org>
 
 	* testutils.inc (pass): Move .Lpass to start.
diff --git a/sim/testsuite/sim/aarch64/fcmp.s b/sim/testsuite/sim/aarch64/fcmp.s
new file mode 100644
index 0000000..fd826c4
--- /dev/null
+++ b/sim/testsuite/sim/aarch64/fcmp.s
@@ -0,0 +1,146 @@
+# mach: aarch64
+
+# Check the FP compare instructions: fcmps, fcmpzs, fcmpes, fcmpzes, fcmpd,
+# fcmpzd, fcmped, fcmpzed.
+# For 1 operand compares, check 0, 1, -1, +Inf, -Inf.
+# For 2 operand compares, check 1/1, 1/-2, -1/2, +Inf/+Inf, +Inf/-Inf.
+# FIXME: Check for qNaN and sNaN when exception raising support added.
+
+.include "testutils.inc"
+
+	start
+	fmov s0, wzr
+	fcmp s0, #0.0
+	bne .Lfailure
+	fcmpe s0, #0.0
+	bne .Lfailure
+	fmov d0, xzr
+	fcmp d0, #0.0
+	bne .Lfailure
+	fcmpe d0, #0.0
+	bne .Lfailure
+
+	fmov s0, #1.0
+	fcmp s0, #0.0
+	blo .Lfailure
+	fcmpe s0, #0.0
+	blo .Lfailure
+	fmov d0, #1.0
+	fcmp d0, #0.0
+	blo .Lfailure
+	fcmpe d0, #0.0
+	blo .Lfailure
+
+	fmov s0, #-1.0
+	fcmp s0, #0.0
+	bpl .Lfailure
+	fcmpe s0, #0.0
+	bpl .Lfailure
+	fmov d0, #-1.0
+	fcmp d0, #0.0
+	bpl .Lfailure
+	fcmpe d0, #0.0
+	bpl .Lfailure
+
+	fmov s0, #1.0
+	fmov s1, wzr
+	fdiv s0, s0, s1
+	fcmp s0, #0.0
+	blo .Lfailure
+	fcmpe s0, #0.0
+	blo .Lfailure
+	fmov d0, #1.0
+	fmov d1, xzr
+	fdiv d0, d0, d1
+	fcmp d0, #0.0
+	blo .Lfailure
+	fcmpe d0, #0.0
+	blo .Lfailure
+
+	fmov s0, #-1.0
+	fmov s1, wzr
+	fdiv s0, s0, s1
+	fcmp s0, #0.0
+	bpl .Lfailure
+	fcmpe s0, #0.0
+	bpl .Lfailure
+	fmov d0, #-1.0
+	fmov d1, xzr
+	fdiv d0, d0, d1
+	fcmp d0, #0.0
+	bpl .Lfailure
+	fcmpe d0, #0.0
+	bpl .Lfailure
+
+	fmov s0, #1.0
+	fmov s1, #1.0
+	fcmp s0, s1
+	bne .Lfailure
+	fcmpe s0, s1
+	bne .Lfailure
+	fmov d0, #1.0
+	fmov d1, #1.0
+	fcmp d0, d1
+	bne .Lfailure
+	fcmpe d0, d1
+	bne .Lfailure
+
+	fmov s0, #1.0
+	fmov s1, #-2.0
+	fcmp s0, s1
+	blo .Lfailure
+	fcmpe s0, s1
+	blo .Lfailure
+	fmov d0, #1.0
+	fmov d1, #-2.0
+	fcmp d0, d1
+	blo .Lfailure
+	fcmpe d0, d1
+	blo .Lfailure
+
+	fmov s0, #-1.0
+	fmov s1, #2.0
+	fcmp s0, s1
+	bpl .Lfailure
+	fcmpe s0, s1
+	bpl .Lfailure
+	fmov d0, #-1.0
+	fmov d1, #2.0
+	fcmp d0, d1
+	bpl .Lfailure
+	fcmpe d0, d1
+	bpl .Lfailure
+
+	fmov s0, #1.0
+	fmov s1, wzr
+	fdiv s0, s0, s1
+	fcmp s0, s0
+	bne .Lfailure
+	fcmpe s0, s0
+	bne .Lfailure
+	fmov s1, #-1.0
+	fmov s2, wzr
+	fdiv s1, s1, s2
+	fcmp s0, s1
+	blo .Lfailure
+	fcmpe s0, s1
+	blo .Lfailure
+
+	fmov d0, #1.0
+	fmov d1, xzr
+	fdiv d0, d0, d1
+	fcmp d0, d0
+	bne .Lfailure
+	fcmpe d0, d0
+	bne .Lfailure
+	fmov d1, #-1.0
+	fmov d2, xzr
+	fdiv d1, d1, d2
+	fcmp d0, d1
+	blo .Lfailure
+	fcmpe d0, d1
+	blo .Lfailure
+
+	pass
+.Lfailure:
+	fail


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]