From: Julian Seward Date: Tue, 17 May 2011 16:19:53 +0000 (+0000) Subject: s390x: add test cases for STCK{,E,F} instructions. See #271779. X-Git-Tag: svn/VALGRIND_3_7_0~471 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2184f38863a8a4d5c271c52b299742fe3c45b378;p=thirdparty%2Fvalgrind.git s390x: add test cases for STCK{,E,F} instructions. See #271779. (Christian Borntraeger and Divya Vyas) git-svn-id: svn://svn.valgrind.org/valgrind/trunk@11766 --- diff --git a/none/tests/s390x/Makefile.am b/none/tests/s390x/Makefile.am index 9e97b8632d..a100e88676 100644 --- a/none/tests/s390x/Makefile.am +++ b/none/tests/s390x/Makefile.am @@ -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 index 0000000000..2925d5e658 --- /dev/null +++ b/none/tests/s390x/stck.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include + +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 index 0000000000..139597f9cb --- /dev/null +++ b/none/tests/s390x/stck.stderr.exp @@ -0,0 +1,2 @@ + + diff --git a/none/tests/s390x/stck.stdout.exp b/none/tests/s390x/stck.stdout.exp new file mode 100644 index 0000000000..abd0531dfd --- /dev/null +++ b/none/tests/s390x/stck.stdout.exp @@ -0,0 +1 @@ +OK.....Testcase passed diff --git a/none/tests/s390x/stck.vgtest b/none/tests/s390x/stck.vgtest new file mode 100644 index 0000000000..289dced6e9 --- /dev/null +++ b/none/tests/s390x/stck.vgtest @@ -0,0 +1 @@ +prog:stck diff --git a/none/tests/s390x/stcke.c b/none/tests/s390x/stcke.c new file mode 100644 index 0000000000..8cd8e0d0b9 --- /dev/null +++ b/none/tests/s390x/stcke.c @@ -0,0 +1,56 @@ +#include +#include +#include + +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 index 0000000000..139597f9cb --- /dev/null +++ b/none/tests/s390x/stcke.stderr.exp @@ -0,0 +1,2 @@ + + diff --git a/none/tests/s390x/stcke.stdout.exp b/none/tests/s390x/stcke.stdout.exp new file mode 100644 index 0000000000..abd0531dfd --- /dev/null +++ b/none/tests/s390x/stcke.stdout.exp @@ -0,0 +1 @@ +OK.....Testcase passed diff --git a/none/tests/s390x/stcke.vgtest b/none/tests/s390x/stcke.vgtest new file mode 100644 index 0000000000..9ea1ba852d --- /dev/null +++ b/none/tests/s390x/stcke.vgtest @@ -0,0 +1 @@ +prog:stcke diff --git a/none/tests/s390x/stckf.c b/none/tests/s390x/stckf.c new file mode 100644 index 0000000000..a7cb1068ec --- /dev/null +++ b/none/tests/s390x/stckf.c @@ -0,0 +1,42 @@ +#include +#include +#include +#include + +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 index 0000000000..139597f9cb --- /dev/null +++ b/none/tests/s390x/stckf.stderr.exp @@ -0,0 +1,2 @@ + + diff --git a/none/tests/s390x/stckf.stdout.exp b/none/tests/s390x/stckf.stdout.exp new file mode 100644 index 0000000000..abd0531dfd --- /dev/null +++ b/none/tests/s390x/stckf.stdout.exp @@ -0,0 +1 @@ +OK.....Testcase passed diff --git a/none/tests/s390x/stckf.vgtest b/none/tests/s390x/stckf.vgtest new file mode 100644 index 0000000000..c16fbff198 --- /dev/null +++ b/none/tests/s390x/stckf.vgtest @@ -0,0 +1,2 @@ +prog:stckf +prereq: ../../../tests/s390x_features s390x-stckf diff --git a/tests/Makefile.am b/tests/Makefile.am index fe314897b3..6230ec068f 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -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 index 0000000000..1e9e8e216f --- /dev/null +++ b/tests/s390x_features.c @@ -0,0 +1,93 @@ +#include +#include +#include +#include +#include +#include + +// 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 \n" ); + exit(3); // Usage error. + } + return go(argv[1]); +}