]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
s390x: add test cases for STCK{,E,F} instructions. See #271779.
authorJulian Seward <jseward@acm.org>
Tue, 17 May 2011 16:19:53 +0000 (16:19 +0000)
committerJulian Seward <jseward@acm.org>
Tue, 17 May 2011 16:19:53 +0000 (16:19 +0000)
(Christian Borntraeger <borntraeger@de.ibm.com> and Divya Vyas)

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@11766

15 files changed:
none/tests/s390x/Makefile.am
none/tests/s390x/stck.c [new file with mode: 0644]
none/tests/s390x/stck.stderr.exp [new file with mode: 0644]
none/tests/s390x/stck.stdout.exp [new file with mode: 0644]
none/tests/s390x/stck.vgtest [new file with mode: 0644]
none/tests/s390x/stcke.c [new file with mode: 0644]
none/tests/s390x/stcke.stderr.exp [new file with mode: 0644]
none/tests/s390x/stcke.stdout.exp [new file with mode: 0644]
none/tests/s390x/stcke.vgtest [new file with mode: 0644]
none/tests/s390x/stckf.c [new file with mode: 0644]
none/tests/s390x/stckf.stderr.exp [new file with mode: 0644]
none/tests/s390x/stckf.stdout.exp [new file with mode: 0644]
none/tests/s390x/stckf.vgtest [new file with mode: 0644]
tests/Makefile.am
tests/s390x_features.c [new file with mode: 0644]

index 9e97b8632da114fdb5b8381e32d53683876d7ef9..a100e88676e5614baa9df09a979deb2efbc74cbb 100644 (file)
@@ -5,7 +5,7 @@ dist_noinst_SCRIPTS = filter_stderr
 INSN_TESTS = clc clcle cvb cvd icm lpr tcxb lam_stam xc mvst add sub mul \
              and or xor insert div srst fold_And16 flogr sub_EI add_EI \
              and_EI or_EI xor_EI insert_EI mul_GE add_GE condloadstore \
-             op_exception fgx
+             op_exception fgx stck stckf stcke
 
 check_PROGRAMS = $(INSN_TESTS) \
                 ex_sig \
diff --git a/none/tests/s390x/stck.c b/none/tests/s390x/stck.c
new file mode 100644 (file)
index 0000000..2925d5e
--- /dev/null
@@ -0,0 +1,41 @@
+#include<stdio.h>
+#include<time.h>
+#include<stdlib.h>
+#include<unistd.h>
+
+int stck(unsigned long *addr)
+{
+       int cc;
+       asm volatile (  "stck   %0\n"
+                       "ipm    %1\n"
+                       "srl    %1,28\n"
+                     :"=Q" (*addr), "=d"(cc)::"memory", "cc");
+       return cc;
+}
+
+unsigned long clockticks_in_msec(unsigned long b, unsigned long a)
+{
+       return (b - a) / 4096000UL;
+}
+
+int main()
+{
+
+       int cc;
+       unsigned long start, end, diff;
+
+       cc = stck(&start);
+       if (cc)
+               printf("cc != 0!\n");
+       sleep(1);
+       cc = stck(&end);
+       if (cc)
+               printf("cc != 0!\n");
+       diff = clockticks_in_msec(end, start);
+       if (diff >= 1000 && diff < 1500)
+               printf("OK.....Testcase passed\n");
+       else
+               printf("FAILED.....Testcase failed\n");
+       return 0;
+
+}
diff --git a/none/tests/s390x/stck.stderr.exp b/none/tests/s390x/stck.stderr.exp
new file mode 100644 (file)
index 0000000..139597f
--- /dev/null
@@ -0,0 +1,2 @@
+
+
diff --git a/none/tests/s390x/stck.stdout.exp b/none/tests/s390x/stck.stdout.exp
new file mode 100644 (file)
index 0000000..abd0531
--- /dev/null
@@ -0,0 +1 @@
+OK.....Testcase passed
diff --git a/none/tests/s390x/stck.vgtest b/none/tests/s390x/stck.vgtest
new file mode 100644 (file)
index 0000000..289dced
--- /dev/null
@@ -0,0 +1 @@
+prog:stck
diff --git a/none/tests/s390x/stcke.c b/none/tests/s390x/stcke.c
new file mode 100644 (file)
index 0000000..8cd8e0d
--- /dev/null
@@ -0,0 +1,56 @@
+#include <stdio.h>
+#include<stdlib.h>
+#include<unistd.h>
+
+union stcke {
+       unsigned long buffer[2];
+       struct reader {
+               char pad;
+               unsigned long long time;
+               int time2;
+               short program;
+       } __attribute__ ((packed)) reader;
+};
+
+int stcke(unsigned long *addr)
+{
+
+       int cc;
+       asm volatile (  "stcke %0\n"
+                       "ipm %1\n"
+                       "srl %1, 28\n"
+                     :"+Q" (*addr), "=d"(cc)::"cc");
+
+       return cc;
+}
+
+unsigned long clockticks_in_msec(unsigned long b, unsigned long a)
+{
+       return (b -a ) / 4096000UL;
+}
+
+int main()
+{
+       union stcke start, end;
+       int cc;
+
+       cc = stcke(start.buffer);
+       if (cc)
+               printf("cc != 0!\n");
+
+       sleep(1);
+       cc = stcke(end.buffer);
+       if (cc)
+               printf("cc != 0!\n");
+
+       unsigned long c = clockticks_in_msec(end.reader.time,
+                                            start.reader.time);
+
+       if (c >= 1000 && c < 1500)
+               printf("OK.....Testcase passed\n");
+       else
+               printf("FAILED.....Testcase failed\n");
+
+       return 0;
+
+}
diff --git a/none/tests/s390x/stcke.stderr.exp b/none/tests/s390x/stcke.stderr.exp
new file mode 100644 (file)
index 0000000..139597f
--- /dev/null
@@ -0,0 +1,2 @@
+
+
diff --git a/none/tests/s390x/stcke.stdout.exp b/none/tests/s390x/stcke.stdout.exp
new file mode 100644 (file)
index 0000000..abd0531
--- /dev/null
@@ -0,0 +1 @@
+OK.....Testcase passed
diff --git a/none/tests/s390x/stcke.vgtest b/none/tests/s390x/stcke.vgtest
new file mode 100644 (file)
index 0000000..9ea1ba8
--- /dev/null
@@ -0,0 +1 @@
+prog:stcke
diff --git a/none/tests/s390x/stckf.c b/none/tests/s390x/stckf.c
new file mode 100644 (file)
index 0000000..a7cb106
--- /dev/null
@@ -0,0 +1,42 @@
+#include<stdio.h>
+#include<time.h>
+#include<stdlib.h>
+#include<unistd.h>
+
+int stckf(unsigned long *addr)
+{
+       int cc;
+       asm volatile (  ".insn s,0xb27c0000,%0\n"
+                       "ipm    %1\n"
+                       "srl    %1,28\n"
+                     :"=Q" (*addr), "=d"(cc)::"memory", "cc");
+       return cc;
+}
+
+unsigned long clockticks_in_msec(unsigned long b, unsigned long a)
+{
+       return (b - a) / 4096000UL;
+}
+
+int main()
+{
+
+       int cc;
+       unsigned long start, end, diff;
+
+       cc = stckf(&start);
+       if (cc)
+               printf("cc != 0!\n");
+       sleep(1);
+       cc = stckf(&end);
+       if (cc)
+               printf("cc != 0!\n");
+
+       diff = clockticks_in_msec(end, start);
+       if (diff >= 1000 && diff < 1500)
+               printf("OK.....Testcase passed\n");
+       else
+               printf("FAILED.....Testcase failed\n");
+       return 0;
+
+}
diff --git a/none/tests/s390x/stckf.stderr.exp b/none/tests/s390x/stckf.stderr.exp
new file mode 100644 (file)
index 0000000..139597f
--- /dev/null
@@ -0,0 +1,2 @@
+
+
diff --git a/none/tests/s390x/stckf.stdout.exp b/none/tests/s390x/stckf.stdout.exp
new file mode 100644 (file)
index 0000000..abd0531
--- /dev/null
@@ -0,0 +1 @@
+OK.....Testcase passed
diff --git a/none/tests/s390x/stckf.vgtest b/none/tests/s390x/stckf.vgtest
new file mode 100644 (file)
index 0000000..c16fbff
--- /dev/null
@@ -0,0 +1,2 @@
+prog:stckf
+prereq: ../../../tests/s390x_features s390x-stckf
index fe314897b343d82bd805267e5053c38b0235192d..6230ec068fbc5391490eec282af06d6e23306554 100644 (file)
@@ -21,7 +21,8 @@ check_PROGRAMS = \
        arch_test \
        os_test \
        true \
-       x86_amd64_features
+       x86_amd64_features \
+       s390x_features
 
 AM_CFLAGS   += $(AM_FLAG_M3264_PRI)
 AM_CXXFLAGS += $(AM_FLAG_M3264_PRI)
diff --git a/tests/s390x_features.c b/tests/s390x_features.c
new file mode 100644 (file)
index 0000000..1e9e8e2
--- /dev/null
@@ -0,0 +1,93 @@
+#include <setjmp.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+// This file determines s390x features a processor supports.
+//
+// We return:
+// - 0 if the machine matches the asked-for feature.
+// - 1 if the machine does not.
+// - 2 if the asked-for feature isn't recognised (this will be the case for
+//     any feature if run on a non-s390x machine).
+// - 3 if there was a usage error (it also prints an error message).
+
+jmp_buf env;
+
+#if defined(VGA_s390x)
+
+void handle_sigill(int signum)
+{
+   longjmp(env, 1);
+}
+
+unsigned long long stfle(void)
+{
+
+   unsigned long long ret;
+
+   signal(SIGILL, handle_sigill);
+   if (setjmp(env)) {
+      /* stfle not available: assume no facilities */
+      return 0;
+   } else {
+      asm volatile("lghi 0, 0\n"
+                   ".insn s,0xb2b00000,%0\n" /* stfle */
+      : "=Q" (ret)::"0", "cc");
+      return ret;
+   }
+}
+
+static int go(char* cpu)
+{
+   unsigned long long facilities;
+   unsigned long long match;
+
+   facilities = stfle();
+
+   if        (strcmp(cpu, "s390x-zarch") == 0 ) {
+     match = (facilities & (1ULL << 62) && (facilities & (1ULL << 61)));
+   } else if (strcmp(cpu, "s390x-n3") == 0 ) {
+     match = (facilities & (1ULL << 63));
+   } else if (strcmp(cpu, "s390x-stfle") == 0 ) {
+     match = (facilities & (1ULL << 56));
+   } else if (strcmp(cpu, "s390x-ldisp") == 0 ) {
+     match = (facilities & (1ULL << 45) && (facilities & (1ULL << 44)));
+   } else if (strcmp(cpu, "s390x-eimm") == 0 ) {
+     match = (facilities & (1ULL << 42));
+   } else if (strcmp(cpu, "s390x-stckf") == 0 ) {
+     match = (facilities & (1ULL << 38));
+   } else if (strcmp(cpu, "s390x-genins") == 0 ) {
+     match = (facilities & (1ULL << 29));
+   } else if (strcmp(cpu, "s390x-exrl") == 0 ) {
+     match = (facilities & (1ULL << 28));
+   } else {
+     return 2;          // Unrecognised feature.
+   }
+
+   return match == 0;
+}
+
+#else
+
+static int go(char* cpu)
+{
+   return 2;      // Feature not recognised (non-s390x machine!)
+}
+
+#endif
+
+
+//---------------------------------------------------------------------------
+// main
+//---------------------------------------------------------------------------
+int main(int argc, char **argv)
+{
+   if ( argc != 2 ) {
+      fprintf( stderr, "usage: s390x_features <feature>\n" );
+      exit(3);                // Usage error.
+   }
+   return go(argv[1]);
+}