1 #include <assert.h>
2 #include <stdint.h>
3 #include <signal.h>
4 #include <sys/user.h>
5 
6 #define XER_SO   (1 << 31)
7 #define XER_OV   (1 << 30)
8 #define XER_CA   (1 << 29)
9 #define XER_OV32 (1 << 19)
10 #define XER_CA32 (1 << 18)
11 
12 uint64_t saved;
13 
14 void sigtrap_handler(int sig, siginfo_t *si, void *ucontext)
15 {
16     ucontext_t *uc = ucontext;
17     uc->uc_mcontext.regs->nip += 4;
18     saved = uc->uc_mcontext.regs->xer;
19     uc->uc_mcontext.regs->xer |= XER_OV | XER_OV32;
20 }
21 
22 int main(void)
23 {
24     uint64_t initial = XER_CA | XER_CA32, restored;
25     struct sigaction sa = {
26         .sa_sigaction = sigtrap_handler,
27         .sa_flags = SA_SIGINFO
28     };
29 
30     sigaction(SIGTRAP, &sa, NULL);
31 
32     asm("mtspr 1, %1\n\t"
33         "trap\n\t"
34         "mfspr %0, 1\n\t"
35         : "=r" (restored)
36         : "r" (initial));
37 
38     assert(saved == initial);
39     assert(restored == (XER_OV | XER_OV32 | XER_CA | XER_CA32));
40 
41     return 0;
42 }
43