tests/tcg/s390x: Add cdsg.c
Add a simple test to prevent regressions. Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com> Message-Id: <20230201133257.3223115-1-iii@linux.ibm.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
521d38ec9b
commit
82f6584c9b
@ -27,6 +27,10 @@ TESTS+=noexec
|
||||
TESTS+=div
|
||||
TESTS+=clst
|
||||
TESTS+=long-double
|
||||
TESTS+=cdsg
|
||||
|
||||
cdsg: CFLAGS+=-pthread
|
||||
cdsg: LDFLAGS+=-pthread
|
||||
|
||||
Z13_TESTS=vistr
|
||||
$(Z13_TESTS): CFLAGS+=-march=z13 -O2
|
||||
|
93
tests/tcg/s390x/cdsg.c
Normal file
93
tests/tcg/s390x/cdsg.c
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Test CDSG instruction.
|
||||
*
|
||||
* Increment the first half of aligned_quadword by 1, and the second half by 2
|
||||
* from 2 threads. Verify that the result is consistent.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static volatile bool start;
|
||||
typedef unsigned long aligned_quadword[2] __attribute__((__aligned__(16)));
|
||||
static aligned_quadword val;
|
||||
static const int n_iterations = 1000000;
|
||||
|
||||
static inline int cdsg(unsigned long *orig0, unsigned long *orig1,
|
||||
unsigned long new0, unsigned long new1,
|
||||
aligned_quadword *mem)
|
||||
{
|
||||
register unsigned long r0 asm("r0");
|
||||
register unsigned long r1 asm("r1");
|
||||
register unsigned long r2 asm("r2");
|
||||
register unsigned long r3 asm("r3");
|
||||
int cc;
|
||||
|
||||
r0 = *orig0;
|
||||
r1 = *orig1;
|
||||
r2 = new0;
|
||||
r3 = new1;
|
||||
asm("cdsg %[r0],%[r2],%[db2]\n"
|
||||
"ipm %[cc]"
|
||||
: [r0] "+r" (r0)
|
||||
, [r1] "+r" (r1)
|
||||
, [db2] "+m" (*mem)
|
||||
, [cc] "=r" (cc)
|
||||
: [r2] "r" (r2)
|
||||
, [r3] "r" (r3)
|
||||
: "cc");
|
||||
*orig0 = r0;
|
||||
*orig1 = r1;
|
||||
|
||||
return (cc >> 28) & 3;
|
||||
}
|
||||
|
||||
void *cdsg_loop(void *arg)
|
||||
{
|
||||
unsigned long orig0, orig1, new0, new1;
|
||||
int cc;
|
||||
int i;
|
||||
|
||||
while (!start) {
|
||||
}
|
||||
|
||||
orig0 = val[0];
|
||||
orig1 = val[1];
|
||||
for (i = 0; i < n_iterations;) {
|
||||
new0 = orig0 + 1;
|
||||
new1 = orig1 + 2;
|
||||
|
||||
cc = cdsg(&orig0, &orig1, new0, new1, &val);
|
||||
|
||||
if (cc == 0) {
|
||||
orig0 = new0;
|
||||
orig1 = new1;
|
||||
i++;
|
||||
} else {
|
||||
assert(cc == 1);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
pthread_t thread;
|
||||
int ret;
|
||||
|
||||
ret = pthread_create(&thread, NULL, cdsg_loop, NULL);
|
||||
assert(ret == 0);
|
||||
start = true;
|
||||
cdsg_loop(NULL);
|
||||
ret = pthread_join(thread, NULL);
|
||||
assert(ret == 0);
|
||||
|
||||
assert(val[0] == n_iterations * 2);
|
||||
assert(val[1] == n_iterations * 4);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
Loading…
Reference in New Issue
Block a user