Add testcase for LAA insn.
Patch by Divya Vyas (divyvyas@linux.vnet.ibm.com).
Part of fixing BZ #306035.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13146 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/none/tests/s390x/Makefile.am b/none/tests/s390x/Makefile.am
index 26c155b..9abe649 100644
--- a/none/tests/s390x/Makefile.am
+++ b/none/tests/s390x/Makefile.am
@@ -17,7 +17,7 @@
 	     spechelper-cr  spechelper-clr  \
 	     spechelper-ltr spechelper-or   \
 	     spechelper-icm-1  spechelper-icm-2 spechelper-tmll \
-	     spechelper-tm
+	     spechelper-tm laa
 if BUILD_DFP_TESTS
   INSN_TESTS += dfp-1
 endif
diff --git a/none/tests/s390x/laa.c b/none/tests/s390x/laa.c
new file mode 100644
index 0000000..91a2bb1
--- /dev/null
+++ b/none/tests/s390x/laa.c
@@ -0,0 +1,59 @@
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+void 
+test(int32_t op1_init, int32_t op2_init, int32_t op3_init, int expected_cc)
+{
+   register int32_t op1 asm("8") = op1_init;
+   register int32_t op3 asm("9") = op3_init;
+   
+   int32_t op2 = op2_init;
+   int cc = 1 - expected_cc; 
+
+   printf("before op1 = %#x\n", op1);
+   printf("before op2 = %#x\n", op2);
+   printf("before op3 = %#x\n", op3);
+
+   __asm__ volatile (
+           ".insn rsy,0xEB00000000f8, 8,9,%1\n\t"
+           "ipm     %0\n\t"
+           "srl     %0,28\n\t"
+           : "=d" (cc), "+Q" (op2), "+d"(op1), "+d"(op3)
+           : 
+           : "cc");
+
+   printf("after  op1 = %#x\n", op1);
+   printf("after  op2 = %#x\n", op2);
+   printf("after  op3 = %#x\n", op3);
+   printf("cc = %d\n", cc);
+
+   if (cc != expected_cc) {
+      printf("condition code is incorrect\n");
+   }
+   if (expected_cc == 0 && op2 != 0) {
+      printf("cc = 0, but result != 0\n");
+   } 
+   if (expected_cc == 1 && op2 >= 0) {
+      printf("cc = 1, but result >= 0\n");
+   } 
+   if (expected_cc == 2 && op2 <= 0) {
+      printf("cc = 2, but result <= 0\n");
+   } 
+   /* the test for cc = 3 is left as an exercise for the reader. */
+}
+
+int main ()
+{
+   test(0, 0, 0, 0);
+   test(-1, -1, -1, 1);
+   test(0x10000000, 0x10000000, 0x12345678, 2);
+   test(0x10000000, 0x20000000, 0x12345678, 2);
+
+   test(-1, 3, -3, 0);
+   test(0, -1, -1, 1);
+   test(-1, 0x10000000, 0x12345678, 2);
+   test(0x10000000, 0x7fffffff, 1, 3);
+
+   return 0;
+}
diff --git a/none/tests/s390x/laa.stderr.exp b/none/tests/s390x/laa.stderr.exp
new file mode 100644
index 0000000..139597f
--- /dev/null
+++ b/none/tests/s390x/laa.stderr.exp
@@ -0,0 +1,2 @@
+
+
diff --git a/none/tests/s390x/laa.stdout.exp b/none/tests/s390x/laa.stdout.exp
new file mode 100644
index 0000000..e6e2dee
--- /dev/null
+++ b/none/tests/s390x/laa.stdout.exp
@@ -0,0 +1,56 @@
+before op1 = 0
+before op2 = 0
+before op3 = 0
+after  op1 = 0
+after  op2 = 0
+after  op3 = 0
+cc = 0
+before op1 = 0xffffffff
+before op2 = 0xffffffff
+before op3 = 0xffffffff
+after  op1 = 0xffffffff
+after  op2 = 0xfffffffe
+after  op3 = 0xffffffff
+cc = 1
+before op1 = 0x10000000
+before op2 = 0x10000000
+before op3 = 0x12345678
+after  op1 = 0x10000000
+after  op2 = 0x22345678
+after  op3 = 0x12345678
+cc = 2
+before op1 = 0x10000000
+before op2 = 0x20000000
+before op3 = 0x12345678
+after  op1 = 0x20000000
+after  op2 = 0x32345678
+after  op3 = 0x12345678
+cc = 2
+before op1 = 0xffffffff
+before op2 = 0x3
+before op3 = 0xfffffffd
+after  op1 = 0x3
+after  op2 = 0
+after  op3 = 0xfffffffd
+cc = 0
+before op1 = 0
+before op2 = 0xffffffff
+before op3 = 0xffffffff
+after  op1 = 0xffffffff
+after  op2 = 0xfffffffe
+after  op3 = 0xffffffff
+cc = 1
+before op1 = 0xffffffff
+before op2 = 0x10000000
+before op3 = 0x12345678
+after  op1 = 0x10000000
+after  op2 = 0x22345678
+after  op3 = 0x12345678
+cc = 2
+before op1 = 0x10000000
+before op2 = 0x7fffffff
+before op3 = 0x1
+after  op1 = 0x7fffffff
+after  op2 = 0x80000000
+after  op3 = 0x1
+cc = 3
diff --git a/none/tests/s390x/laa.vgtest b/none/tests/s390x/laa.vgtest
new file mode 100644
index 0000000..7047c56
--- /dev/null
+++ b/none/tests/s390x/laa.vgtest
@@ -0,0 +1 @@
+prog: laa