sewardj | 8eb8bab | 2015-07-21 14:44:28 +0000 | [diff] [blame] | 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 | |
Elliott Hughes | a0664b9 | 2017-04-18 17:46:52 -0700 | [diff] [blame^] | 11 | #include "config.h" |
| 12 | |
sewardj | 8eb8bab | 2015-07-21 14:44:28 +0000 | [diff] [blame] | 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 | |
Elliott Hughes | a0664b9 | 2017-04-18 17:46:52 -0700 | [diff] [blame^] | 19 | static void sighandler(int sig, siginfo_t *sip, void *arg) |
sewardj | 8eb8bab | 2015-07-21 14:44:28 +0000 | [diff] [blame] | 20 | { |
Elliott Hughes | a0664b9 | 2017-04-18 17:46:52 -0700 | [diff] [blame^] | 21 | ucontext_t *ucp = (ucontext_t *) arg; |
| 22 | |
sewardj | 8eb8bab | 2015-07-21 14:44:28 +0000 | [diff] [blame] | 23 | si = *sip; |
| 24 | uc = *ucp; |
| 25 | |
| 26 | ucp->uc_mcontext.fpregs.fp_reg_set.fpchip_state.xmm[0] = d0; |
| 27 | ucp->uc_mcontext.fpregs.fp_reg_set.fpchip_state.xmm[1] = x0; |
| 28 | } |
| 29 | |
| 30 | int main(void) |
| 31 | { |
| 32 | struct sigaction sa; |
| 33 | pid_t pid; |
| 34 | upad128_t out[8]; |
| 35 | upad128_t y0; |
Elliott Hughes | a0664b9 | 2017-04-18 17:46:52 -0700 | [diff] [blame^] | 36 | |
| 37 | #if defined(SOLARIS_FPCHIP_STATE_TAKES_UNDERSCORE) |
| 38 | struct _fpchip_state *fs; |
| 39 | #else |
| 40 | struct fpchip_state *fs; |
| 41 | #endif |
| 42 | fs = &uc.uc_mcontext.fpregs.fp_reg_set.fpchip_state; |
sewardj | 8eb8bab | 2015-07-21 14:44:28 +0000 | [diff] [blame] | 43 | |
| 44 | /* Uninitialised, but we know px[0] is 0x0. */ |
| 45 | upad128_t *px = malloc(sizeof(*px)); |
| 46 | x0 = px[0]; |
| 47 | |
| 48 | /* Uninitialised, but we know py[0] is 0x0. */ |
| 49 | upad128_t *py = malloc(sizeof(*py)); |
| 50 | y0 = py[0]; |
| 51 | |
Elliott Hughes | a0664b9 | 2017-04-18 17:46:52 -0700 | [diff] [blame^] | 52 | sa.sa_sigaction = sighandler; |
sewardj | 8eb8bab | 2015-07-21 14:44:28 +0000 | [diff] [blame] | 53 | sa.sa_flags = SA_SIGINFO; |
| 54 | if (sigfillset(&sa.sa_mask)) { |
| 55 | perror("sigfillset"); |
| 56 | return 1; |
| 57 | } |
| 58 | if (sigaction(SIGUSR1, &sa, NULL)) { |
| 59 | perror("sigaction"); |
| 60 | return 1; |
| 61 | } |
| 62 | |
| 63 | pid = getpid(); |
| 64 | |
| 65 | __asm__ __volatile__( |
| 66 | /* Set values in the SSE registers. */ |
| 67 | "movups %[y0], %%xmm0\n" |
| 68 | "movups %[d0], %%xmm1\n" |
| 69 | "movups %[d0], %%xmm2\n" |
| 70 | "movups %[y0], %%xmm3\n" |
| 71 | "movups %[y0], %%xmm4\n" |
| 72 | "movups %[d0], %%xmm5\n" |
| 73 | "movups %[d0], %%xmm6\n" |
| 74 | "movups %[y0], %%xmm7\n" |
| 75 | |
| 76 | /* Prepare syscall parameters. */ |
| 77 | "pushl %[sig]\n" |
| 78 | "pushl %[pid]\n" |
| 79 | "pushl $0xdeadbeef\n" |
| 80 | "movl %[scall], %%eax\n" |
| 81 | |
| 82 | /* Trigger the signal handler. */ |
| 83 | "int $0x91\n" |
| 84 | "addl $12, %%esp\n" |
| 85 | "movups %%xmm0, 0x00 + %[out]\n" |
| 86 | "movups %%xmm1, 0x10 + %[out]\n" |
| 87 | "movups %%xmm2, 0x20 + %[out]\n" |
| 88 | "movups %%xmm3, 0x30 + %[out]\n" |
| 89 | "movups %%xmm4, 0x40 + %[out]\n" |
| 90 | "movups %%xmm5, 0x50 + %[out]\n" |
| 91 | "movups %%xmm6, 0x60 + %[out]\n" |
| 92 | "movups %%xmm7, 0x70 + %[out]\n" |
| 93 | : [out] "=m" (out[0]) |
| 94 | : [scall] "i" (SYS_kill), [pid] "a" (pid), [sig] "i" (SIGUSR1), |
| 95 | [y0] "m" (y0), [d0] "m" (d0) |
| 96 | : "edx", "cc", "memory"); |
| 97 | |
| 98 | printf("Values in the signal handler:\n"); |
| 99 | printf(" xmm1=%Lf, xmm2=%Lf, xmm5=%Lf, xmm6=%Lf\n", |
| 100 | fs->xmm[1]._q, fs->xmm[2]._q, fs->xmm[5]._q, fs->xmm[6]._q); |
| 101 | /* Check that fs->xmm[0], fs->xmm[3], fs->xmm[4] and fs->xmm[7] contain |
| 102 | uninitialised values (origin is py[0]). */ |
| 103 | if (fs->xmm[0]._q || fs->xmm[3]._q || fs->xmm[4]._q || fs->xmm[7]._q) |
| 104 | assert(0); |
| 105 | |
| 106 | printf("Values after the return from the signal handler:\n"); |
| 107 | printf(" xmm0=%Lf, xmm2=%Lf, xmm5=%Lf, xmm6=%Lf\n", |
| 108 | out[0]._q, out[2]._q, out[5]._q, out[6]._q); |
| 109 | /* Check that out[1], out[3], out[4] and out[7] contain uninitialised |
| 110 | values (origin is px[0]). */ |
| 111 | if (out[1]._q || out[3]._q || out[4]._q || out[7]._q) |
| 112 | assert(0); |
| 113 | |
| 114 | return 0; |
| 115 | } |
| 116 | |