Test improvements for FLOGR. Part of #268715.
(Florian Krohm, britzel@acm.org)
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@11662 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/none/tests/s390x/flogr.c b/none/tests/s390x/flogr.c
index 63ed036..f3631e5 100644
--- a/none/tests/s390x/flogr.c
+++ b/none/tests/s390x/flogr.c
@@ -1,15 +1,25 @@
#include <stdio.h>
+/* The FLOGR insn reads from register R2 and writes to register R1 and
+ R1 + 1. So we need to distinguish three cases:
+
+ (1) All three registers R1, R1 + 1, and R2 are distinct
+ (2) R2 == R1
+ (3) R2 == R1 + 1
+
+ These are tested by flogr1, flogr2, and flogr3, respectively. */
/* Call FLOGR on INPUT. The results are returned through the parms. */
+
+/* R2 != R1 && R2 != R1 + 1 */
void
-flogr(unsigned long input, unsigned long *bitpos, unsigned long *modval,
- unsigned int *cc)
+flogr1(unsigned long input, unsigned long *bitpos, unsigned long *modval,
+ unsigned int *cc)
{
unsigned int psw;
register unsigned long value asm("4") = input;
- asm volatile ( "flogr 2, %[val]\n\t"
+ asm volatile ( ".long 0xB9830024\n\t" // "flogr 2, %[val]\n\t"
"ipm %[psw]\n\t"
"stg 2, %[bitpos]\n\t"
"stg 3, %[modval]\n\t"
@@ -25,8 +35,57 @@
#endif
}
+/* R2 == R1 */
void
-runtest(void)
+flogr2(unsigned long input, unsigned long *bitpos, unsigned long *modval,
+ unsigned int *cc)
+{
+ unsigned int psw;
+ register unsigned long value asm("2") = input;
+
+ asm volatile ( ".long 0xB9830022\n\t" // "flogr 2, %[val]\n\t"
+ "ipm %[psw]\n\t"
+ "stg 2, %[bitpos]\n\t"
+ "stg 3, %[modval]\n\t"
+ : [bitpos]"=m"(*bitpos), [modval]"=m"(*modval),
+ [psw]"=d"(psw), [val] "+d"(value)
+ :
+ : "3", "cc");
+
+ *cc = psw >> 28;
+#if 0
+ printf("value = %lx, bitpos = %lu, modval = %lx, cc = %d\n",
+ value, *bitpos, *modval, *cc);
+#endif
+}
+
+/* R2 == R1 + 1 */
+void
+flogr3(unsigned long input, unsigned long *bitpos, unsigned long *modval,
+ unsigned int *cc)
+{
+ unsigned int psw;
+ register unsigned long value asm("3") = input;
+
+ asm volatile ( ".long 0xB9830023\n\t" // "flogr 2, %[val]\n\t"
+ "ipm %[psw]\n\t"
+ "stg 2, %[bitpos]\n\t"
+ "stg 3, %[modval]\n\t"
+ : [bitpos]"=m"(*bitpos), [modval]"=m"(*modval),
+ [psw]"=d"(psw), [val] "+d"(value)
+ :
+ : "2", "cc");
+
+ *cc = psw >> 28;
+#if 0
+ printf("value = %lx, bitpos = %lu, modval = %lx, cc = %d\n",
+ value, *bitpos, *modval, *cc);
+#endif
+}
+
+void
+runtest(void (*func)(unsigned long, unsigned long *, unsigned long *,
+ unsigned int *))
{
unsigned long bitpos, modval, value;
unsigned int cc;
@@ -34,7 +93,7 @@
/* Value 0 is special */
value = 0;
- flogr(value, &bitpos, &modval, &cc);
+ func(value, &bitpos, &modval, &cc);
if (modval != 0) fprintf(stderr, "modval is wrong for %lx\n", value);
if (bitpos != 64) fprintf(stderr, "bitpos is wrong for %lx\n", value);
if (cc != 0) fprintf(stderr, "cc is wrong for %lx\n", value);
@@ -42,7 +101,7 @@
/* Test with exactly 1 bit set */
for (i = 0; i < 64; ++i) {
value = 1ull << i;
- flogr(value, &bitpos, &modval, &cc);
+ func(value, &bitpos, &modval, &cc);
if (modval != 0) fprintf(stderr, "modval is wrong for %lx\n", value);
if (bitpos != 63 - i) fprintf(stderr, "bitpos is wrong for %lx\n", value);
if (cc != 2) fprintf(stderr, "cc is wrong for %lx\n", value);
@@ -52,7 +111,7 @@
for (i = 1; i < 64; ++i) {
value = 1ull << i;
value = value | (value - 1);
- flogr(value, &bitpos, &modval, &cc);
+ func(value, &bitpos, &modval, &cc);
if (modval != (value >> 1)) fprintf(stderr, "modval is wrong for %lx\n", value);
if (bitpos != 63 - i) fprintf(stderr, "bitpos is wrong for %lx\n", value);
if (cc != 2) fprintf(stderr, "cc is wrong for %lx\n", value);
@@ -62,7 +121,9 @@
int main()
{
- runtest();
+ runtest(flogr1);
+ runtest(flogr2);
+ runtest(flogr3);
return 0;
}