1 /* 2 * Test the VREP instruction. 3 * 4 * SPDX-License-Identifier: GPL-2.0-or-later 5 */ 6 #include <assert.h> 7 #include <signal.h> 8 #include <stdbool.h> 9 #include <stdint.h> 10 #include <stdlib.h> 11 #include <string.h> 12 #include <unistd.h> 13 #include "vx.h" 14 15 static void handle_sigill(int sig, siginfo_t *info, void *ucontext) 16 { 17 mcontext_t *mcontext = &((ucontext_t *)ucontext)->uc_mcontext; 18 char *insn = (char *)info->si_addr; 19 20 if (insn[0] != 0xe7 || insn[5] != 0x4d) { 21 _exit(EXIT_FAILURE); 22 } 23 24 mcontext->gregs[2] = SIGILL; 25 } 26 27 static inline __attribute__((__always_inline__)) unsigned long 28 vrep(S390Vector *v1, const S390Vector *v3, const uint16_t i2, const uint8_t m4) 29 { 30 register unsigned long sig asm("r2") = -1; 31 32 asm("vrep %[v1],%[v3],%[i2],%[m4]\n" 33 : [v1] "=v" (v1->v) 34 , [sig] "+r" (sig) 35 : [v3] "v" (v3->v) 36 , [i2] "i" (i2) 37 , [m4] "i" (m4)); 38 39 return sig; 40 } 41 42 int main(int argc, char *argv[]) 43 { 44 S390Vector v3 = {.d[0] = 1, .d[1] = 2}; 45 struct sigaction act; 46 S390Vector v1; 47 int err; 48 49 memset(&act, 0, sizeof(act)); 50 act.sa_sigaction = handle_sigill; 51 act.sa_flags = SA_SIGINFO; 52 err = sigaction(SIGILL, &act, NULL); 53 assert(err == 0); 54 55 assert(vrep(&v1, &v3, 7, 0) == -1); 56 assert(v1.d[0] == 0x0101010101010101ULL); 57 assert(v1.d[1] == 0x0101010101010101ULL); 58 59 assert(vrep(&v1, &v3, 7, 1) == -1); 60 assert(v1.d[0] == 0x0002000200020002ULL); 61 assert(v1.d[1] == 0x0002000200020002ULL); 62 63 assert(vrep(&v1, &v3, 1, 2) == -1); 64 assert(v1.d[0] == 0x0000000100000001ULL); 65 assert(v1.d[1] == 0x0000000100000001ULL); 66 67 assert(vrep(&v1, &v3, 1, 3) == -1); 68 assert(v1.d[0] == 2); 69 assert(v1.d[1] == 2); 70 71 assert(vrep(&v1, &v3, 0x10, 0) == SIGILL); 72 assert(vrep(&v1, &v3, 0x101, 0) == SIGILL); 73 assert(vrep(&v1, &v3, 0x8, 1) == SIGILL); 74 assert(vrep(&v1, &v3, 0x108, 1) == SIGILL); 75 assert(vrep(&v1, &v3, 0x4, 2) == SIGILL); 76 assert(vrep(&v1, &v3, 0x104, 2) == SIGILL); 77 assert(vrep(&v1, &v3, 0x2, 3) == SIGILL); 78 assert(vrep(&v1, &v3, 0x102, 3) == SIGILL); 79 80 return EXIT_SUCCESS; 81 } 82