aarch64 sim FP to unsigned integer conversion fix

Message ID CABXYE2W4SHYN5kS_9DLbTV6D6ancjTgnAGgS6vxKjavtNW4mmw@mail.gmail.com
State New
Headers show

Commit Message

Jim Wilson Dec. 23, 2016, 10:04 p.m.
FP to unsigned integer conversions are being truncated to the signed
INT_MAX and LONG_MAX when they should be truncated to UINT_MAX and
ULONG_MAX.  This requires adding a bunch of new variables, as this
truncation happens inside a macro that uses token pasting to create
variable names.

The testcase fails without the patch and works with the patch.  GCC C
testsuite failures drop from 2568 to 2538 with the patch.

Jim

Comments

Nick Clifton Jan. 3, 2017, 2:36 p.m. | #1
Hi Jim,

> FP to unsigned integer conversions are being truncated to the signed

> INT_MAX and LONG_MAX when they should be truncated to UINT_MAX and

> ULONG_MAX.  This requires adding a bunch of new variables, as this

> truncation happens inside a macro that uses token pasting to create

> variable names.

> 

> The testcase fails without the patch and works with the patch.  GCC C

> testsuite failures drop from 2568 to 2538 with the patch.


Approved - please apply.

Cheers
  Nick

Patch

	sim/aarch64/
	* simulator.c (UINT_MIN, ULONG_MIN, FLOAT_UINT_MAX, FLOAT_UINT_MIN,
	DOUBLE_UINT_MAX, DOUBLE_UINT_MIN, FLOAT_ULONG_MAX, FLOAT_ULONG_MIN,
	DOUBLE_ULONG_MAX, DOUBLE_ULONG_MIN): New.
	(do_fcvtzu): Use ULONG instead of LONG, and UINT instead of INT in
	raise_exception calls.

	sim/testsuite/sim/aarch64/
	* fcvtz.s: New.

(diff --git a/sim/aarch64/simulator.c b/sim/aarch64/simulator.c
index be3d6c7..705ba41 100644
--- a/sim/aarch64/simulator.c
+++ b/sim/aarch64/simulator.c
@@ -8117,6 +8117,17 @@  static const float  FLOAT_LONG_MIN  = (float)  LONG_MIN;
 static const double DOUBLE_LONG_MAX = (double) LONG_MAX;
 static const double DOUBLE_LONG_MIN = (double) LONG_MIN;
 
+#define UINT_MIN 0
+#define ULONG_MIN 0
+static const float  FLOAT_UINT_MAX   = (float)  UINT_MAX;
+static const float  FLOAT_UINT_MIN   = (float)  UINT_MIN;
+static const double DOUBLE_UINT_MAX  = (double) UINT_MAX;
+static const double DOUBLE_UINT_MIN  = (double) UINT_MIN;
+static const float  FLOAT_ULONG_MAX  = (float)  ULONG_MAX;
+static const float  FLOAT_ULONG_MIN  = (float)  ULONG_MIN;
+static const double DOUBLE_ULONG_MAX = (double) ULONG_MAX;
+static const double DOUBLE_ULONG_MIN = (double) ULONG_MIN;
+
 /* Check for FP exception conditions:
      NaN raises IO
      Infinity raises IO
@@ -8262,7 +8273,7 @@  do_fcvtzu (sim_cpu *cpu)
 
 	  /* Do not raise an exception if we have reached ULONG_MAX.  */
 	  if (value != (1UL << 63))
-	    RAISE_EXCEPTIONS (d, value, DOUBLE, LONG);
+	    RAISE_EXCEPTIONS (d, value, DOUBLE, ULONG);
 
 	  aarch64_set_reg_u64 (cpu, rd, NO_SP, value);
 	}
@@ -8273,7 +8284,7 @@  do_fcvtzu (sim_cpu *cpu)
 
 	  /* Do not raise an exception if we have reached ULONG_MAX.  */
 	  if (value != (1UL << 63))
-	    RAISE_EXCEPTIONS (f, value, FLOAT, LONG);
+	    RAISE_EXCEPTIONS (f, value, FLOAT, ULONG);
 
 	  aarch64_set_reg_u64 (cpu, rd, NO_SP, value);
 	}
@@ -8290,7 +8301,7 @@  do_fcvtzu (sim_cpu *cpu)
 	  value = (uint32_t) d;
 	  /* Do not raise an exception if we have reached UINT_MAX.  */
 	  if (value != (1UL << 31))
-	    RAISE_EXCEPTIONS (d, value, DOUBLE, INT);
+	    RAISE_EXCEPTIONS (d, value, DOUBLE, UINT);
 	}
       else
 	{
@@ -8299,7 +8310,7 @@  do_fcvtzu (sim_cpu *cpu)
 	  value = (uint32_t) f;
 	  /* Do not raise an exception if we have reached UINT_MAX.  */
 	  if (value != (1UL << 31))
-	    RAISE_EXCEPTIONS (f, value, FLOAT, INT);
+	    RAISE_EXCEPTIONS (f, value, FLOAT, UINT);
 	}
 
       aarch64_set_reg_u64 (cpu, rd, NO_SP, value);
diff --git a/sim/testsuite/sim/aarch64/fcvtz.s b/sim/testsuite/sim/aarch64/fcvtz.s
new file mode 100644
index 0000000..9bb6f9b
--- /dev/null
+++ b/sim/testsuite/sim/aarch64/fcvtz.s
@@ -0,0 +1,202 @@ 
+# mach: aarch64
+
+# Check the FP convert to int round toward zero instructions: fcvtszs32,
+# fcvtszs, fcvtszd32, fcvtszd, fcvtzu.
+# For 32-bit signed convert, test values -1.5, INT_MAX, and INT_MIN.
+# For 64-bit signed convert, test values -1.5, LONG_MAX, and LONG_MIN.
+# For 32-bit unsigned convert, test values 1.5, INT_MAX, and UINT_MAX.
+# For 64-bit unsigned convert, test values 1.5, LONG_MAX, and ULONG_MAX.
+
+	.data
+fm1p5:
+	.word	3217031168
+fimax:
+	.word	1325400064
+fimin:
+	.word	3472883712
+flmax:
+	.word	1593835520
+flmin:
+	.word	3741319168
+f1p5:
+	.word	1069547520
+fuimax:
+	.word	1333788672
+fulmax:
+	.word	1602224128
+
+dm1p5:
+	.word	0
+	.word	-1074266112
+dimax:
+	.word	4290772992
+	.word	1105199103
+dimin:
+	.word	0
+	.word	-1042284544
+dlmax:
+	.word	0
+	.word	1138753536
+dlmin:
+	.word	0
+	.word	-1008730112
+d1p5:
+	.word	0
+	.word	1073217536
+duimax:
+	.word	4292870144
+	.word	1106247679
+dulmax:
+	.word	0
+	.word	1139802112
+
+.include "testutils.inc"
+
+	start
+	adrp x0, fm1p5
+	ldr s0, [x0, #:lo12:fm1p5]
+	fcvtzs w1, s0
+	cmp w1, #-1
+	bne .Lfailure
+	adrp x0, fimax
+	ldr s0, [x0, #:lo12:fimax]
+	fcvtzs w1, s0
+	mov w2, #0x7fffffff
+	cmp w1, w2
+	bne .Lfailure
+	adrp x0, fimin
+	ldr s0, [x0, #:lo12:fimin]
+	fcvtzs w1, s0
+	mov w2, #0x80000000
+	cmp w1, w2
+	bne .Lfailure
+
+	adrp x0, fm1p5
+	ldr s0, [x0, #:lo12:fm1p5]
+	fcvtzs x1, s0
+	cmp x1, #-1
+	bne .Lfailure
+	adrp x0, flmax
+	ldr s0, [x0, #:lo12:flmax]
+	fcvtzs x1, s0
+	mov x2, #0x7fffffffffffffff
+	cmp x1, x2
+	bne .Lfailure
+	adrp x0, flmin
+	ldr s0, [x0, #:lo12:flmin]
+	fcvtzs x1, s0
+	mov x2, #0x8000000000000000
+	cmp x1, x2
+	bne .Lfailure
+
+	adrp x0, dm1p5
+	ldr d0, [x0, #:lo12:dm1p5]
+	fcvtzs w1, d0
+	cmp w1, #-1
+	bne .Lfailure
+	adrp x0, dimax
+	ldr d0, [x0, #:lo12:dimax]
+	fcvtzs w1, d0
+	mov w2, #0x7fffffff
+	cmp w1, w2
+	bne .Lfailure
+	adrp x0, dimin
+	ldr d0, [x0, #:lo12:dimin]
+	fcvtzs w1, d0
+	mov w2, #0x80000000
+	cmp w1, w2
+	bne .Lfailure
+
+	adrp x0, dm1p5
+	ldr d0, [x0, #:lo12:dm1p5]
+	fcvtzs x1, d0
+	cmp x1, #-1
+	bne .Lfailure
+	adrp x0, dlmax
+	ldr d0, [x0, #:lo12:dlmax]
+	fcvtzs x1, d0
+	mov x2, #0x7fffffffffffffff
+	cmp x1, x2
+	bne .Lfailure
+	adrp x0, dlmin
+	ldr d0, [x0, #:lo12:dlmin]
+	fcvtzs x1, d0
+	mov x2, #0x8000000000000000
+	cmp x1, x2
+	bne .Lfailure
+
+	adrp x0, f1p5
+	ldr s0, [x0, #:lo12:f1p5]
+	fcvtzu w1, s0
+	cmp w1, #1
+	bne .Lfailure
+	adrp x0, fimax
+	ldr s0, [x0, #:lo12:fimax]
+	fcvtzu w1, s0
+	mov w2, #0x80000000
+	cmp w1, w2
+	bne .Lfailure
+	adrp x0, fuimax
+	ldr s0, [x0, #:lo12:fuimax]
+	fcvtzu w1, s0
+	mov w2, #0xffffffff
+	cmp w1, w2
+	bne .Lfailure
+
+	adrp x0, f1p5
+	ldr s0, [x0, #:lo12:f1p5]
+	fcvtzu x1, s0
+	cmp x1, #1
+	bne .Lfailure
+	adrp x0, flmax
+	ldr s0, [x0, #:lo12:flmax]
+	fcvtzu x1, s0
+	mov x2, #0x8000000000000000
+	cmp x1, x2
+	bne .Lfailure
+	adrp x0, fulmax
+	ldr s0, [x0, #:lo12:fulmax]
+	fcvtzu x1, s0
+	mov x2, #0xffffffffffffffff
+	cmp x1, x2
+	bne .Lfailure
+
+	adrp x0, d1p5
+	ldr d0, [x0, #:lo12:d1p5]
+	fcvtzu w1, d0
+	cmp w1, #1
+	bne .Lfailure
+	adrp x0, dimax
+	ldr d0, [x0, #:lo12:dimax]
+	fcvtzu w1, d0
+	mov w2, #0x7fffffff
+	cmp w1, w2
+	bne .Lfailure
+	adrp x0, duimax
+	ldr d0, [x0, #:lo12:duimax]
+	fcvtzu w1, d0
+	mov w2, #0xffffffff
+	cmp w1, w2
+	bne .Lfailure
+
+	adrp x0, d1p5
+	ldr d0, [x0, #:lo12:d1p5]
+	fcvtzu x1, d0
+	cmp x1, #1
+	bne .Lfailure
+	adrp x0, dlmax
+	ldr d0, [x0, #:lo12:dlmax]
+	fcvtzu x1, d0
+	mov x2, #0x8000000000000000
+	cmp x1, x2
+	bne .Lfailure
+	adrp x0, dulmax
+	ldr d0, [x0, #:lo12:dulmax]
+	fcvtzu x1, d0
+	mov x2, #0xffffffffffffffff
+	cmp x1, x2
+	bne .Lfailure
+
+	pass
+.Lfailure:
+	fail