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