xref: /openbmc/qemu/tests/tcg/s390x/clst.c (revision c432198a)
1 #define _GNU_SOURCE
2 #include <stdio.h>
3 #include <stdlib.h>
4 
clst(char sep,const char ** s1,const char ** s2)5 static int clst(char sep, const char **s1, const char **s2)
6 {
7     const char *r1 = *s1;
8     const char *r2 = *s2;
9     int cc;
10 
11     do {
12         register int r0 asm("r0") = sep;
13 
14         asm("clst %[r1],%[r2]\n"
15             "ipm %[cc]\n"
16             "srl %[cc],28"
17             : [r1] "+r" (r1), [r2] "+r" (r2), "+r" (r0), [cc] "=r" (cc)
18             :
19             : "cc");
20         *s1 = r1;
21         *s2 = r2;
22     } while (cc == 3);
23 
24     return cc;
25 }
26 
27 static const struct test {
28     const char *name;
29     char sep;
30     const char *s1;
31     const char *s2;
32     int exp_cc;
33     int exp_off;
34 } tests[] = {
35     {
36         .name = "cc0",
37         .sep = 0,
38         .s1 = "aa",
39         .s2 = "aa",
40         .exp_cc = 0,
41         .exp_off = 0,
42     },
43     {
44         .name = "cc1",
45         .sep = 1,
46         .s1 = "a\x01",
47         .s2 = "aa\x01",
48         .exp_cc = 1,
49         .exp_off = 1,
50     },
51     {
52         .name = "cc2",
53         .sep = 2,
54         .s1 = "abc\x02",
55         .s2 = "abb\x02",
56         .exp_cc = 2,
57         .exp_off = 2,
58     },
59 };
60 
main(void)61 int main(void)
62 {
63     const struct test *t;
64     const char *s1, *s2;
65     size_t i;
66     int cc;
67 
68     for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
69         t = &tests[i];
70         s1 = t->s1;
71         s2 = t->s2;
72         cc = clst(t->sep, &s1, &s2);
73         if (cc != t->exp_cc ||
74                 s1 != t->s1 + t->exp_off ||
75                 s2 != t->s2 + t->exp_off) {
76             fprintf(stderr, "%s\n", t->name);
77             return EXIT_FAILURE;
78         }
79     }
80 
81     return EXIT_SUCCESS;
82 }
83