xref: /openbmc/qemu/tests/tcg/s390x/cvb.c (revision eb14b021)
1*eb14b021SIlya Leoshkevich /*
2*eb14b021SIlya Leoshkevich  * Test the CONVERT TO BINARY instruction.
3*eb14b021SIlya Leoshkevich  *
4*eb14b021SIlya Leoshkevich  * SPDX-License-Identifier: GPL-2.0-or-later
5*eb14b021SIlya Leoshkevich  */
6*eb14b021SIlya Leoshkevich #include <assert.h>
7*eb14b021SIlya Leoshkevich #include <signal.h>
8*eb14b021SIlya Leoshkevich #include <stdint.h>
9*eb14b021SIlya Leoshkevich #include <stdlib.h>
10*eb14b021SIlya Leoshkevich #include <string.h>
11*eb14b021SIlya Leoshkevich 
12*eb14b021SIlya Leoshkevich static int signum;
13*eb14b021SIlya Leoshkevich 
signal_handler(int n)14*eb14b021SIlya Leoshkevich static void signal_handler(int n)
15*eb14b021SIlya Leoshkevich {
16*eb14b021SIlya Leoshkevich     signum = n;
17*eb14b021SIlya Leoshkevich }
18*eb14b021SIlya Leoshkevich 
19*eb14b021SIlya Leoshkevich #define FAIL 0x1234567887654321
20*eb14b021SIlya Leoshkevich #define OK32(x) (0x1234567800000000 | (uint32_t)(x))
21*eb14b021SIlya Leoshkevich 
cvb(uint64_t x)22*eb14b021SIlya Leoshkevich static int64_t cvb(uint64_t x)
23*eb14b021SIlya Leoshkevich {
24*eb14b021SIlya Leoshkevich     int64_t ret = FAIL;
25*eb14b021SIlya Leoshkevich 
26*eb14b021SIlya Leoshkevich     signum = -1;
27*eb14b021SIlya Leoshkevich     asm("cvb %[ret],%[x]" : [ret] "+r" (ret) : [x] "R" (x));
28*eb14b021SIlya Leoshkevich 
29*eb14b021SIlya Leoshkevich     return ret;
30*eb14b021SIlya Leoshkevich }
31*eb14b021SIlya Leoshkevich 
cvby(uint64_t x)32*eb14b021SIlya Leoshkevich static int64_t cvby(uint64_t x)
33*eb14b021SIlya Leoshkevich {
34*eb14b021SIlya Leoshkevich     int64_t ret = FAIL;
35*eb14b021SIlya Leoshkevich 
36*eb14b021SIlya Leoshkevich     signum = -1;
37*eb14b021SIlya Leoshkevich     asm("cvby %[ret],%[x]" : [ret] "+r" (ret) : [x] "T" (x));
38*eb14b021SIlya Leoshkevich 
39*eb14b021SIlya Leoshkevich     return ret;
40*eb14b021SIlya Leoshkevich }
41*eb14b021SIlya Leoshkevich 
cvbg(__uint128_t x)42*eb14b021SIlya Leoshkevich static int64_t cvbg(__uint128_t x)
43*eb14b021SIlya Leoshkevich {
44*eb14b021SIlya Leoshkevich     int64_t ret = FAIL;
45*eb14b021SIlya Leoshkevich 
46*eb14b021SIlya Leoshkevich     signum = -1;
47*eb14b021SIlya Leoshkevich     asm("cvbg %[ret],%[x]" : [ret] "+r" (ret) : [x] "T" (x));
48*eb14b021SIlya Leoshkevich 
49*eb14b021SIlya Leoshkevich     return ret;
50*eb14b021SIlya Leoshkevich }
51*eb14b021SIlya Leoshkevich 
main(void)52*eb14b021SIlya Leoshkevich int main(void)
53*eb14b021SIlya Leoshkevich {
54*eb14b021SIlya Leoshkevich     __uint128_t m = (((__uint128_t)0x9223372036854775) << 16) | 0x8070;
55*eb14b021SIlya Leoshkevich     struct sigaction act;
56*eb14b021SIlya Leoshkevich     int err;
57*eb14b021SIlya Leoshkevich 
58*eb14b021SIlya Leoshkevich     memset(&act, 0, sizeof(act));
59*eb14b021SIlya Leoshkevich     act.sa_handler = signal_handler;
60*eb14b021SIlya Leoshkevich     err = sigaction(SIGFPE, &act, NULL);
61*eb14b021SIlya Leoshkevich     assert(err == 0);
62*eb14b021SIlya Leoshkevich     err = sigaction(SIGILL, &act, NULL);
63*eb14b021SIlya Leoshkevich     assert(err == 0);
64*eb14b021SIlya Leoshkevich 
65*eb14b021SIlya Leoshkevich     assert(cvb(0xc) == OK32(0) && signum == -1);
66*eb14b021SIlya Leoshkevich     assert(cvb(0x1c) == OK32(1) && signum == -1);
67*eb14b021SIlya Leoshkevich     assert(cvb(0x25594c) == OK32(25594) && signum == -1);
68*eb14b021SIlya Leoshkevich     assert(cvb(0x1d) == OK32(-1) && signum == -1);
69*eb14b021SIlya Leoshkevich     assert(cvb(0x2147483647c) == OK32(0x7fffffff) && signum == -1);
70*eb14b021SIlya Leoshkevich     assert(cvb(0x2147483648d) == OK32(-0x80000000) && signum == -1);
71*eb14b021SIlya Leoshkevich     assert(cvb(0x7) == FAIL && signum == SIGILL);
72*eb14b021SIlya Leoshkevich     assert(cvb(0x2147483648c) == OK32(0x80000000) && signum == SIGFPE);
73*eb14b021SIlya Leoshkevich     assert(cvb(0x3000000000c) == OK32(0xb2d05e00) && signum == SIGFPE);
74*eb14b021SIlya Leoshkevich     assert(cvb(0x2147483649d) == OK32(0x7fffffff) && signum == SIGFPE);
75*eb14b021SIlya Leoshkevich     assert(cvb(0x3000000000d) == OK32(0x4d2fa200) && signum == SIGFPE);
76*eb14b021SIlya Leoshkevich 
77*eb14b021SIlya Leoshkevich     assert(cvby(0xc) == OK32(0));
78*eb14b021SIlya Leoshkevich     assert(cvby(0x1c) == OK32(1));
79*eb14b021SIlya Leoshkevich     assert(cvby(0x25594c) == OK32(25594));
80*eb14b021SIlya Leoshkevich     assert(cvby(0x1d) == OK32(-1));
81*eb14b021SIlya Leoshkevich     assert(cvby(0x2147483647c) == OK32(0x7fffffff));
82*eb14b021SIlya Leoshkevich     assert(cvby(0x2147483648d) == OK32(-0x80000000));
83*eb14b021SIlya Leoshkevich     assert(cvby(0x7) == FAIL && signum == SIGILL);
84*eb14b021SIlya Leoshkevich     assert(cvby(0x2147483648c) == OK32(0x80000000) && signum == SIGFPE);
85*eb14b021SIlya Leoshkevich     assert(cvby(0x3000000000c) == OK32(0xb2d05e00) && signum == SIGFPE);
86*eb14b021SIlya Leoshkevich     assert(cvby(0x2147483649d) == OK32(0x7fffffff) && signum == SIGFPE);
87*eb14b021SIlya Leoshkevich     assert(cvby(0x3000000000d) == OK32(0x4d2fa200) && signum == SIGFPE);
88*eb14b021SIlya Leoshkevich 
89*eb14b021SIlya Leoshkevich     assert(cvbg(0xc) == 0);
90*eb14b021SIlya Leoshkevich     assert(cvbg(0x1c) == 1);
91*eb14b021SIlya Leoshkevich     assert(cvbg(0x25594c) == 25594);
92*eb14b021SIlya Leoshkevich     assert(cvbg(0x1d) == -1);
93*eb14b021SIlya Leoshkevich     assert(cvbg(m + 0xc) == 0x7fffffffffffffff);
94*eb14b021SIlya Leoshkevich     assert(cvbg(m + 0x1d) == -0x8000000000000000);
95*eb14b021SIlya Leoshkevich     assert(cvbg(0x7) == FAIL && signum == SIGILL);
96*eb14b021SIlya Leoshkevich     assert(cvbg(m + 0x1c) == FAIL && signum == SIGFPE);
97*eb14b021SIlya Leoshkevich     assert(cvbg(m + 0x2d) == FAIL && signum == SIGFPE);
98*eb14b021SIlya Leoshkevich     assert(cvbg(((__uint128_t)1 << 80) + 0xc) == FAIL && signum == SIGFPE);
99*eb14b021SIlya Leoshkevich     assert(cvbg(((__uint128_t)1 << 80) + 0xd) == FAIL && signum == SIGFPE);
100*eb14b021SIlya Leoshkevich 
101*eb14b021SIlya Leoshkevich     return EXIT_SUCCESS;
102*eb14b021SIlya Leoshkevich }
103