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