Home | History | Annotate | Download | only in amd64-solaris
      1 /* Test if SSE valus are correctly propagated into and out of a signal handler
      2    and also check that the same applies for uninitialised values and their
      3    origins. */
      4 
      5 #include <assert.h>
      6 #include <signal.h>
      7 #include <stdio.h>
      8 #include <stdlib.h>
      9 #include <unistd.h>
     10 #include <sys/syscall.h>
     11 #include <sys/ucontext.h>
     12 
     13 static siginfo_t si;
     14 static ucontext_t uc;
     15 /* x0 is always zero, but is visible to Valgrind as uninitialised. */
     16 static upad128_t x0;
     17 static upad128_t d0 = {0};
     18 
     19 static void sighandler(int sig, siginfo_t *sip, ucontext_t *ucp)
     20 {
     21    si = *sip;
     22    uc = *ucp;
     23 
     24    ucp->uc_mcontext.fpregs.fp_reg_set.fpchip_state.xmm[0] = d0;
     25    ucp->uc_mcontext.fpregs.fp_reg_set.fpchip_state.xmm[1] = x0;
     26 }
     27 
     28 int main(void)
     29 {
     30    struct sigaction sa;
     31    pid_t pid;
     32    upad128_t out[8];
     33    upad128_t y0;
     34    struct fpchip_state *fs = &uc.uc_mcontext.fpregs.fp_reg_set.fpchip_state;
     35 
     36    /* Uninitialised, but we know px[0] is 0x0. */
     37    upad128_t *px = malloc(sizeof(*px));
     38    x0 = px[0];
     39 
     40    /* Uninitialised, but we know py[0] is 0x0. */
     41    upad128_t *py = malloc(sizeof(*py));
     42    y0 = py[0];
     43 
     44    sa.sa_handler = sighandler;
     45    sa.sa_flags = SA_SIGINFO;
     46    if (sigfillset(&sa.sa_mask)) {
     47       perror("sigfillset");
     48       return 1;
     49    }
     50    if (sigaction(SIGUSR1, &sa, NULL)) {
     51       perror("sigaction");
     52       return 1;
     53    }
     54 
     55    pid = getpid();
     56 
     57    __asm__ __volatile__(
     58       /* Set values in the SSE registers. */
     59       "movups %[y0], %%xmm0\n"
     60       "movups %[d0], %%xmm1\n"
     61       "movups %[d0], %%xmm2\n"
     62       "movups %[y0], %%xmm3\n"
     63       "movups %[y0], %%xmm4\n"
     64       "movups %[d0], %%xmm5\n"
     65       "movups %[d0], %%xmm6\n"
     66       "movups %[y0], %%xmm7\n"
     67 
     68       /* Trigger the signal handler. */
     69       "syscall\n"
     70       "movups %%xmm0, 0x00 + %[out]\n"
     71       "movups %%xmm1, 0x10 + %[out]\n"
     72       "movups %%xmm2, 0x20 + %[out]\n"
     73       "movups %%xmm3, 0x30 + %[out]\n"
     74       "movups %%xmm4, 0x40 + %[out]\n"
     75       "movups %%xmm5, 0x50 + %[out]\n"
     76       "movups %%xmm6, 0x60 + %[out]\n"
     77       "movups %%xmm7, 0x70 + %[out]\n"
     78       : [out] "=m" (out[0])
     79       : "a" (SYS_kill), "D" (pid), "S" (SIGUSR1), [y0] "m" (y0), [d0] "m" (d0)
     80       : "rdx", "cc", "memory");
     81 
     82    printf("Values in the signal handler:\n");
     83    printf("  xmm1=%Lf, xmm2=%Lf, xmm5=%Lf, xmm6=%Lf\n",
     84           fs->xmm[1]._q, fs->xmm[2]._q, fs->xmm[5]._q, fs->xmm[6]._q);
     85    /* Check that fs->xmm[0], fs->xmm[3], fs->xmm[4] and fs->xmm[7] contain
     86       uninitialised values (origin is py[0]). */
     87    if (fs->xmm[0]._q || fs->xmm[3]._q || fs->xmm[4]._q || fs->xmm[7]._q)
     88       assert(0);
     89 
     90    printf("Values after the return from the signal handler:\n");
     91    printf("  xmm0=%Lf, xmm2=%Lf, xmm5=%Lf, xmm6=%Lf\n",
     92           out[0]._q, out[2]._q, out[5]._q, out[6]._q);
     93    /* Check that out[1], out[3], out[4] and out[7] contain uninitialised
     94       values (origin is px[0]). */
     95    if (out[1]._q || out[3]._q || out[4]._q || out[7]._q)
     96       assert(0);
     97 
     98    return 0;
     99 }
    100 
    101