Merge tag 'qemu-macppc-20230206' of https://github.com/mcayland/qemu into staging
[qemu.git] / tests / tcg / s390x / cdsg.c
blob800618ff4b4db06149bbe0a30db27c15e5209136
1 /*
2 * Test CDSG instruction.
4 * Increment the first half of aligned_quadword by 1, and the second half by 2
5 * from 2 threads. Verify that the result is consistent.
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 */
9 #include <assert.h>
10 #include <pthread.h>
11 #include <stdbool.h>
12 #include <stdlib.h>
14 static volatile bool start;
15 typedef unsigned long aligned_quadword[2] __attribute__((__aligned__(16)));
16 static aligned_quadword val;
17 static const int n_iterations = 1000000;
19 static inline int cdsg(unsigned long *orig0, unsigned long *orig1,
20 unsigned long new0, unsigned long new1,
21 aligned_quadword *mem)
23 register unsigned long r0 asm("r0");
24 register unsigned long r1 asm("r1");
25 register unsigned long r2 asm("r2");
26 register unsigned long r3 asm("r3");
27 int cc;
29 r0 = *orig0;
30 r1 = *orig1;
31 r2 = new0;
32 r3 = new1;
33 asm("cdsg %[r0],%[r2],%[db2]\n"
34 "ipm %[cc]"
35 : [r0] "+r" (r0)
36 , [r1] "+r" (r1)
37 , [db2] "+m" (*mem)
38 , [cc] "=r" (cc)
39 : [r2] "r" (r2)
40 , [r3] "r" (r3)
41 : "cc");
42 *orig0 = r0;
43 *orig1 = r1;
45 return (cc >> 28) & 3;
48 void *cdsg_loop(void *arg)
50 unsigned long orig0, orig1, new0, new1;
51 int cc;
52 int i;
54 while (!start) {
57 orig0 = val[0];
58 orig1 = val[1];
59 for (i = 0; i < n_iterations;) {
60 new0 = orig0 + 1;
61 new1 = orig1 + 2;
63 cc = cdsg(&orig0, &orig1, new0, new1, &val);
65 if (cc == 0) {
66 orig0 = new0;
67 orig1 = new1;
68 i++;
69 } else {
70 assert(cc == 1);
74 return NULL;
77 int main(void)
79 pthread_t thread;
80 int ret;
82 ret = pthread_create(&thread, NULL, cdsg_loop, NULL);
83 assert(ret == 0);
84 start = true;
85 cdsg_loop(NULL);
86 ret = pthread_join(thread, NULL);
87 assert(ret == 0);
89 assert(val[0] == n_iterations * 2);
90 assert(val[1] == n_iterations * 4);
92 return EXIT_SUCCESS;