]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
s390x: Improve none/tests/s390x/cvb.c
authorFlorian Krohm <flo2030@eich-krohm.de>
Sat, 7 Jun 2025 11:48:01 +0000 (11:48 +0000)
committerFlorian Krohm <flo2030@eich-krohm.de>
Sat, 7 Jun 2025 11:48:01 +0000 (11:48 +0000)
The result of a CVB insn resides in an 8-byte register of which the
most significant 4 bytes ought to unchanged by the insn. We want to
check that. So we need to use a variable of type 'long'.
Rewrite the code a bit.

none/tests/s390x/cvb.c
none/tests/s390x/cvb.stdout.exp

index ce5f9e405c5f78c4e303cb0ff333c1424643b10d..3f928a6b210c63b24a52b79edaa61bfdbce19225 100644 (file)
+#include <assert.h>
 #include <stdio.h>
 
-static unsigned long test[] ={
-       0x000000000000000a,
-       0x000000000000001a,
-       0x000000000000012a,
-       0x000000000000123a,
-       0x000000000001234a,
-       0x000000000012345a,
-       0x000000000123456a,
-       0x000000001234567a,
-       0x000000012345678a,
-       0x000000123456789a,
-       0x000001234567890a,
-       0x000000000000000b,
-       0x000000000000001b,
-       0x000000000000012b,
-       0x000000000000123b,
-       0x000000000001234b,
-       0x000000000012345b,
-       0x000000000123456b,
-       0x000000001234567b,
-       0x000000012345678b,
-       0x000000123456789b,
-       0x000001234567890b,
-       0x000000000000000c,
-       0x000000000000001c,
-       0x000000000000012c,
-       0x000000000000123c,
-       0x000000000001234c,
-       0x000000000012345c,
-       0x000000000123456c,
-       0x000000001234567c,
-       0x000000012345678c,
-       0x000000123456789c,
-       0x000001234567890c,
-       0x000000000000000d,
-       0x000000000000001d,
-       0x000000000000012d,
-       0x000000000000123d,
-       0x000000000001234d,
-       0x000000000012345d,
-       0x000000000123456d,
-       0x000000001234567d,
-       0x000000012345678d,
-       0x000000123456789d,
-       0x000001234567890d,
-       0x000000000000000e,
-       0x000000000000001e,
-       0x000000000000012e,
-       0x000000000000123e,
-       0x000000000001234e,
-       0x000000000012345e,
-       0x000000000123456e,
-       0x000000001234567e,
-       0x000000012345678e,
-       0x000000123456789e,
-       0x000001234567890e,
-       0x000000000000000f,
-       0x000000000000001f,
-       0x000000000000012f,
-       0x000000000000123f,
-       0x000000000001234f,
-       0x000000000012345f,
-       0x000000000123456f,
-       0x000000001234567f,
-       0x000000012345678f,
-       0x000000123456789f,
-       0x000001234567890f,
-        /* min and max */
-       0x000002147483647c,
-       0x000002147483648d,
-
-/* fixs390: we also need to check if invalid values cause a fixed-point-devide exception.
-   Not yet implemented. */
-/*     0x000002147483648c,
-       0x000002147483649d,
-       0x00000000000000fa, */
-
+/* Valid values (excluding sign code) */
+static const unsigned long valid[] = {
+   0x0000000000000000,
+   0x0000000000000010,
+   0x0000000000000120,
+   0x0000000000001230,
+   0x0000000000012340,
+   0x0000000000123450,
+   0x0000000001234560,
+   0x0000000012345670,
+   0x0000000123456780,
+   0x0000001234567890,
+   0x0000012345678900,
 };
 
+/* Boundary values (excluding sign code) */
+static const unsigned long max = 0x0000021474836470;
+static const unsigned long min = 0x0000021474836480;
+
+/* Valid sign codes */
+static const unsigned sign_code_pos[] = { 0xa, 0xc, 0xe, 0xf };
+static const unsigned sign_code_neg[] = { 0xb, 0xd };
+
+#define NUM_EL(x)   (sizeof(x) / sizeof(*(x)))
 
-static signed int dec_to_hex(unsigned long *addr)
+/* The value pointed to by ADDR is valid including sign code. */
+static signed int
+dec_to_hex(unsigned long *addr)
 {
-        register signed int res asm("2") = 0;
-        register unsigned long *_addr asm("4") = addr;
+   long res;
+   int res1, res2;
 
-        asm volatile(
-        "       cvb %0,0(0,%1)"
-                : "=d" (res) : "d" (_addr) : "memory");
-        return res & 0xffffffff;
-}
+   res = 0;
+   asm volatile("cvb %0,0(0,%1)"
+                : "+d" (res) : "a" (addr) : "memory");
+
+   // bits [0:31] ought to be unchanged
+   // Catch bits that are set but shouldn't be
+   assert((res >> 32) == 0);
+   res1 = (int)res;
 
+   res = -1;
+   asm volatile("cvb %0,0(0,%1)"
+                : "+d" (res) : "a" (addr) : "memory");
 
+   // bits [0:31] ought to be unchanged
+   // Catch bits that are cleared but shouldn't be
+   assert((res >> 32) == -1);
+   res2 = (int)(res & 0xffffffff);
 
+   // Successful conversion
+   assert(res1 == res2);
 
-int main()
+   return res1;
+}
+
+int main(void)
 {
-       int i;
+   for (int sign_code = 0xa; sign_code <= 0xf; ++sign_code) {
+      printf("Testing in-range values with sign code 0x%x\n", sign_code);
+      for (int i = 0; i < NUM_EL(valid); ++i) {
+         unsigned long value = valid[i] | sign_code;
+         printf("0x%016lx  -->  %d\n", value, dec_to_hex(&value));
+      }
+   }
+   printf("\n");
+
+   printf("Testing max. value 0x%lx\n", max >> 4);
+   for (int i = 0; i < NUM_EL(sign_code_pos); ++i) {
+      unsigned sign_code = sign_code_pos[i];
+      unsigned long value = max | sign_code;
+      printf("0x%016lx  -->  %d\n", value, dec_to_hex(&value));
+   }
+   printf("\n");
+
+   printf("Testing min. value 0x%lx\n", min >> 4);
+   for (int i = 0; i < NUM_EL(sign_code_neg); ++i) {
+      unsigned sign_code = sign_code_neg[i];
+      unsigned long value = min | sign_code;
+      printf("0x%016lx  -->  %d\n", value, dec_to_hex(&value));
+   }
+
+   /* fixs390: check behaviour for invalid values, out-of-range values and values with invalid sign code */
 
-       for (i = 0; i < sizeof(test) / sizeof(test[0]); i++)
-       printf("%d\n", dec_to_hex(&test[i]));
-       return 0;
+   return 0;
 }
index 35d6a600fea6e3a9339b6eb141a209b1273159f7..268ea354d24f36707e619655fe14f43bf758de29 100644 (file)
@@ -1,68 +1,82 @@
-0
-1
-12
-123
-1234
-12345
-123456
-1234567
-12345678
-123456789
-1234567890
-0
--1
--12
--123
--1234
--12345
--123456
--1234567
--12345678
--123456789
--1234567890
-0
-1
-12
-123
-1234
-12345
-123456
-1234567
-12345678
-123456789
-1234567890
-0
--1
--12
--123
--1234
--12345
--123456
--1234567
--12345678
--123456789
--1234567890
-0
-1
-12
-123
-1234
-12345
-123456
-1234567
-12345678
-123456789
-1234567890
-0
-1
-12
-123
-1234
-12345
-123456
-1234567
-12345678
-123456789
-1234567890
-2147483647
--2147483648
+Testing in-range values with sign code 0xa
+0x000000000000000a  -->  0
+0x000000000000001a  -->  1
+0x000000000000012a  -->  12
+0x000000000000123a  -->  123
+0x000000000001234a  -->  1234
+0x000000000012345a  -->  12345
+0x000000000123456a  -->  123456
+0x000000001234567a  -->  1234567
+0x000000012345678a  -->  12345678
+0x000000123456789a  -->  123456789
+0x000001234567890a  -->  1234567890
+Testing in-range values with sign code 0xb
+0x000000000000000b  -->  0
+0x000000000000001b  -->  -1
+0x000000000000012b  -->  -12
+0x000000000000123b  -->  -123
+0x000000000001234b  -->  -1234
+0x000000000012345b  -->  -12345
+0x000000000123456b  -->  -123456
+0x000000001234567b  -->  -1234567
+0x000000012345678b  -->  -12345678
+0x000000123456789b  -->  -123456789
+0x000001234567890b  -->  -1234567890
+Testing in-range values with sign code 0xc
+0x000000000000000c  -->  0
+0x000000000000001c  -->  1
+0x000000000000012c  -->  12
+0x000000000000123c  -->  123
+0x000000000001234c  -->  1234
+0x000000000012345c  -->  12345
+0x000000000123456c  -->  123456
+0x000000001234567c  -->  1234567
+0x000000012345678c  -->  12345678
+0x000000123456789c  -->  123456789
+0x000001234567890c  -->  1234567890
+Testing in-range values with sign code 0xd
+0x000000000000000d  -->  0
+0x000000000000001d  -->  -1
+0x000000000000012d  -->  -12
+0x000000000000123d  -->  -123
+0x000000000001234d  -->  -1234
+0x000000000012345d  -->  -12345
+0x000000000123456d  -->  -123456
+0x000000001234567d  -->  -1234567
+0x000000012345678d  -->  -12345678
+0x000000123456789d  -->  -123456789
+0x000001234567890d  -->  -1234567890
+Testing in-range values with sign code 0xe
+0x000000000000000e  -->  0
+0x000000000000001e  -->  1
+0x000000000000012e  -->  12
+0x000000000000123e  -->  123
+0x000000000001234e  -->  1234
+0x000000000012345e  -->  12345
+0x000000000123456e  -->  123456
+0x000000001234567e  -->  1234567
+0x000000012345678e  -->  12345678
+0x000000123456789e  -->  123456789
+0x000001234567890e  -->  1234567890
+Testing in-range values with sign code 0xf
+0x000000000000000f  -->  0
+0x000000000000001f  -->  1
+0x000000000000012f  -->  12
+0x000000000000123f  -->  123
+0x000000000001234f  -->  1234
+0x000000000012345f  -->  12345
+0x000000000123456f  -->  123456
+0x000000001234567f  -->  1234567
+0x000000012345678f  -->  12345678
+0x000000123456789f  -->  123456789
+0x000001234567890f  -->  1234567890
+
+Testing max. value 0x2147483647
+0x000002147483647a  -->  2147483647
+0x000002147483647c  -->  2147483647
+0x000002147483647e  -->  2147483647
+0x000002147483647f  -->  2147483647
+
+Testing min. value 0x2147483648
+0x000002147483648b  -->  -2147483648
+0x000002147483648d  -->  -2147483648