xref: /openbmc/qemu/tests/tcg/s390x/vrep.c (revision 024d7caf)
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 
handle_sigill(int sig,siginfo_t * info,void * ucontext)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
vrep(S390Vector * v1,const S390Vector * v3,const uint16_t i2,const uint8_t m4)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 
main(int argc,char * argv[])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