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
handle_sigill(int sig,siginfo_t * info,void * ucontext)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
vrep(S390Vector * v1,const S390Vector * v3,const uint16_t i2,const uint8_t m4)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
main(int argc,char * argv[])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