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