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