18eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/* x86 variant of the amd64-solaris/context_sse.c test. */
28eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
38eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include <assert.h>
48eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include <signal.h>
58eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include <stdio.h>
68eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include <stdlib.h>
78eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include <unistd.h>
88eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include <sys/syscall.h>
98eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include <sys/ucontext.h>
108eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
118eb8bab992e3998c33770b0cdb16059a8b918a06sewardjstatic siginfo_t si;
128eb8bab992e3998c33770b0cdb16059a8b918a06sewardjstatic ucontext_t uc;
138eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/* x0 is always zero, but is visible to Valgrind as uninitialised. */
148eb8bab992e3998c33770b0cdb16059a8b918a06sewardjstatic upad128_t x0;
158eb8bab992e3998c33770b0cdb16059a8b918a06sewardjstatic upad128_t d0 = {0};
168eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
178eb8bab992e3998c33770b0cdb16059a8b918a06sewardjstatic void sighandler(int sig, siginfo_t *sip, ucontext_t *ucp)
188eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{
198eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   si = *sip;
208eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   uc = *ucp;
218eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
228eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   ucp->uc_mcontext.fpregs.fp_reg_set.fpchip_state.xmm[0] = d0;
238eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   ucp->uc_mcontext.fpregs.fp_reg_set.fpchip_state.xmm[1] = x0;
248eb8bab992e3998c33770b0cdb16059a8b918a06sewardj}
258eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
268eb8bab992e3998c33770b0cdb16059a8b918a06sewardjint main(void)
278eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{
288eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   struct sigaction sa;
298eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   pid_t pid;
308eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   upad128_t out[8];
318eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   upad128_t y0;
328eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   struct fpchip_state *fs = &uc.uc_mcontext.fpregs.fp_reg_set.fpchip_state;
338eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
348eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   /* Uninitialised, but we know px[0] is 0x0. */
358eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   upad128_t *px = malloc(sizeof(*px));
368eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   x0 = px[0];
378eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
388eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   /* Uninitialised, but we know py[0] is 0x0. */
398eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   upad128_t *py = malloc(sizeof(*py));
408eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   y0 = py[0];
418eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
428eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   sa.sa_handler = sighandler;
438eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   sa.sa_flags = SA_SIGINFO;
448eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   if (sigfillset(&sa.sa_mask)) {
458eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      perror("sigfillset");
468eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      return 1;
478eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   }
488eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   if (sigaction(SIGUSR1, &sa, NULL)) {
498eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      perror("sigaction");
508eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      return 1;
518eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   }
528eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
538eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   pid = getpid();
548eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
558eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   __asm__ __volatile__(
568eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      /* Set values in the SSE registers. */
578eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      "movups %[y0], %%xmm0\n"
588eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      "movups %[d0], %%xmm1\n"
598eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      "movups %[d0], %%xmm2\n"
608eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      "movups %[y0], %%xmm3\n"
618eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      "movups %[y0], %%xmm4\n"
628eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      "movups %[d0], %%xmm5\n"
638eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      "movups %[d0], %%xmm6\n"
648eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      "movups %[y0], %%xmm7\n"
658eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
668eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      /* Prepare syscall parameters. */
678eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      "pushl  %[sig]\n"
688eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      "pushl  %[pid]\n"
698eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      "pushl  $0xdeadbeef\n"
708eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      "movl   %[scall], %%eax\n"
718eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
728eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      /* Trigger the signal handler. */
738eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      "int    $0x91\n"
748eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      "addl   $12, %%esp\n"
758eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      "movups %%xmm0, 0x00 + %[out]\n"
768eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      "movups %%xmm1, 0x10 + %[out]\n"
778eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      "movups %%xmm2, 0x20 + %[out]\n"
788eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      "movups %%xmm3, 0x30 + %[out]\n"
798eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      "movups %%xmm4, 0x40 + %[out]\n"
808eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      "movups %%xmm5, 0x50 + %[out]\n"
818eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      "movups %%xmm6, 0x60 + %[out]\n"
828eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      "movups %%xmm7, 0x70 + %[out]\n"
838eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      : [out] "=m" (out[0])
848eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      : [scall] "i" (SYS_kill), [pid] "a" (pid), [sig] "i" (SIGUSR1),
858eb8bab992e3998c33770b0cdb16059a8b918a06sewardj        [y0] "m" (y0), [d0] "m" (d0)
868eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      : "edx", "cc", "memory");
878eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
888eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   printf("Values in the signal handler:\n");
898eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   printf("  xmm1=%Lf, xmm2=%Lf, xmm5=%Lf, xmm6=%Lf\n",
908eb8bab992e3998c33770b0cdb16059a8b918a06sewardj          fs->xmm[1]._q, fs->xmm[2]._q, fs->xmm[5]._q, fs->xmm[6]._q);
918eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   /* Check that fs->xmm[0], fs->xmm[3], fs->xmm[4] and fs->xmm[7] contain
928eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      uninitialised values (origin is py[0]). */
938eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   if (fs->xmm[0]._q || fs->xmm[3]._q || fs->xmm[4]._q || fs->xmm[7]._q)
948eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      assert(0);
958eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
968eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   printf("Values after the return from the signal handler:\n");
978eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   printf("  xmm0=%Lf, xmm2=%Lf, xmm5=%Lf, xmm6=%Lf\n",
988eb8bab992e3998c33770b0cdb16059a8b918a06sewardj          out[0]._q, out[2]._q, out[5]._q, out[6]._q);
998eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   /* Check that out[1], out[3], out[4] and out[7] contain uninitialised
1008eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      values (origin is px[0]). */
1018eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   if (out[1]._q || out[3]._q || out[4]._q || out[7]._q)
1028eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      assert(0);
1038eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
1048eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   return 0;
1058eb8bab992e3998c33770b0cdb16059a8b918a06sewardj}
1068eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
107