aarch64 sim addv bug fix

Message ID CABXYE2W_Mn=K=4jsYXa14UimQedL-JrJD9-tJTdijrfRfOKyqw@mail.gmail.com
State New, archived
Headers

Commit Message

Jim Wilson Jan. 14, 2017, 7:16 p.m. UTC
  The addv instruction is storing results to general registers instead
of vector registers.  The reserved instruction check is wrong,  It
should be not full in case 2, and unconditionally in case 3.

The testcase fails without the patch, and works with the patch.  The
patch reduces gcc C testsuite failures from 2227 to 2174 (-57).

Jim
  

Comments

Nick Clifton Jan. 16, 2017, 11:10 a.m. UTC | #1
Hi Jim,

> The addv instruction is storing results to general registers instead
> of vector registers.  The reserved instruction check is wrong,  It
> should be not full in case 2, and unconditionally in case 3.
> 
> The testcase fails without the patch, and works with the patch.  The
> patch reduces gcc C testsuite failures from 2227 to 2174 (-57).

Approved - please apply.

Cheers
  Nick
  

Patch

	sim/aarch64/
	* simulator.c (do_vec_ADDV): Call aarch64_set_vec_u64 instead of
	aarch64_set_reg_u64.  In case 2, call HALT_UNALLOC if not full.  In
	case 3, call HALT_UNALLOC unconditionally.

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

diff --git a/sim/aarch64/simulator.c b/sim/aarch64/simulator.c
index 36129e5..6237c09 100644
--- a/sim/aarch64/simulator.c
+++ b/sim/aarch64/simulator.c
@@ -3445,28 +3445,25 @@  do_vec_ADDV (sim_cpu *cpu)
     case 0:
       for (i = 0; i < (full ? 16 : 8); i++)
 	val += aarch64_get_vec_u8 (cpu, vm, i);
-      aarch64_set_reg_u64 (cpu, rd, NO_SP, val);
+      aarch64_set_vec_u64 (cpu, rd, 0, val);
       return;
 
     case 1:
       for (i = 0; i < (full ? 8 : 4); i++)
 	val += aarch64_get_vec_u16 (cpu, vm, i);
-      aarch64_set_reg_u64 (cpu, rd, NO_SP, val);
+      aarch64_set_vec_u64 (cpu, rd, 0, val);
       return;
 
     case 2:
-      for (i = 0; i < (full ? 4 : 2); i++)
+      if (! full)
+	HALT_UNALLOC;
+      for (i = 0; i < 4; i++)
 	val += aarch64_get_vec_u32 (cpu, vm, i);
-      aarch64_set_reg_u64 (cpu, rd, NO_SP, val);
+      aarch64_set_vec_u64 (cpu, rd, 0, val);
       return;
 
     case 3:
-      if (! full)
-	HALT_UNALLOC;
-      val = aarch64_get_vec_u64 (cpu, vm, 0);
-      val += aarch64_get_vec_u64 (cpu, vm, 1);
-      aarch64_set_reg_u64 (cpu, rd, NO_SP, val);
-      return;
+      HALT_UNALLOC;
     }
 }
 
diff --git a/sim/testsuite/sim/aarch64/addv.s b/sim/testsuite/sim/aarch64/addv.s
new file mode 100644
index 0000000..4da8935
--- /dev/null
+++ b/sim/testsuite/sim/aarch64/addv.s
@@ -0,0 +1,50 @@ 
+# mach: aarch64
+
+# Check the add across vector instruction: addv.
+
+.include "testutils.inc"
+
+	.data
+	.align 4
+input:
+	.word 0x04030201
+	.word 0x08070605
+	.word 0x0c0b0a09
+	.word 0x100f0e0d
+
+	start
+	adrp x0, input
+	ldr q0, [x0, #:lo12:input]
+
+	addv b1, v0.8b
+	mov x1, v1.d[0]
+	cmp x1, #36
+	bne .Lfailure
+
+	addv b1, v0.16b
+	mov x1, v1.d[0]
+	cmp x1, #136
+	bne .Lfailure
+
+	addv h1, v0.4h
+	mov x1, v1.d[0]
+	mov x2, #5136
+	cmp x1, x2
+	bne .Lfailure
+
+	addv h1, v0.8h
+	mov x1, v1.d[0]
+	mov x2, #18496
+	cmp x1, x2
+	bne .Lfailure
+
+	addv s1, v0.4s
+	mov x1, v1.d[0]
+	mov x2, 8220
+	movk x2, 0x2824, lsl 16
+	cmp x1, x2
+	bne .Lfailure
+
+	pass
+.Lfailure:
+	fail