1 /*
2 * Test the CLC instruction.
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 #include <assert.h>
7 #include <signal.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <unistd.h>
11
handle_sigsegv(int sig,siginfo_t * info,void * ucontext)12 static void handle_sigsegv(int sig, siginfo_t *info, void *ucontext)
13 {
14 mcontext_t *mcontext = &((ucontext_t *)ucontext)->uc_mcontext;
15 if (mcontext->gregs[0] != 600) {
16 write(STDERR_FILENO, "bad r0\n", 7);
17 _exit(EXIT_FAILURE);
18 }
19 if (((mcontext->psw.mask >> 44) & 3) != 1) {
20 write(STDERR_FILENO, "bad cc\n", 7);
21 _exit(EXIT_FAILURE);
22 }
23 _exit(EXIT_SUCCESS);
24 }
25
main(void)26 int main(void)
27 {
28 register unsigned long r0 asm("r0");
29 unsigned long mem = 42, rhs = 500;
30 struct sigaction act;
31 int err;
32
33 memset(&act, 0, sizeof(act));
34 act.sa_sigaction = handle_sigsegv;
35 act.sa_flags = SA_SIGINFO;
36 err = sigaction(SIGSEGV, &act, NULL);
37 assert(err == 0);
38
39 r0 = 100;
40 asm("algr %[r0],%[rhs]\n"
41 "clc 0(8,%[mem]),0(0)\n" /* The 2nd operand will cause a SEGV. */
42 : [r0] "+r" (r0)
43 : [mem] "r" (&mem)
44 , [rhs] "r" (rhs)
45 : "cc", "memory");
46
47 return EXIT_FAILURE;
48 }
49