xref: /openbmc/qemu/tests/tcg/s390x/shift.c (revision 5e0214cdeee17de949f2565f4429c15173179ae3)
1*f7cff073SIlya Leoshkevich #include <inttypes.h>
2*f7cff073SIlya Leoshkevich #include <stdint.h>
3*f7cff073SIlya Leoshkevich #include <stdio.h>
4*f7cff073SIlya Leoshkevich 
5*f7cff073SIlya Leoshkevich #define DEFINE_SHIFT_SINGLE_COMMON(_name, _insn_str) \
6*f7cff073SIlya Leoshkevich     static uint64_t _name(uint64_t op1, uint64_t op2, uint64_t *cc) \
7*f7cff073SIlya Leoshkevich     { \
8*f7cff073SIlya Leoshkevich         asm("    sll %[cc],28\n" \
9*f7cff073SIlya Leoshkevich             "    spm %[cc]\n" \
10*f7cff073SIlya Leoshkevich             "    " _insn_str "\n" \
11*f7cff073SIlya Leoshkevich             "    ipm %[cc]\n" \
12*f7cff073SIlya Leoshkevich             "    srl %[cc],28" \
13*f7cff073SIlya Leoshkevich             : [op1] "+&r" (op1), \
14*f7cff073SIlya Leoshkevich               [cc] "+&r" (*cc) \
15*f7cff073SIlya Leoshkevich             : [op2] "r" (op2) \
16*f7cff073SIlya Leoshkevich             : "cc"); \
17*f7cff073SIlya Leoshkevich         return op1; \
18*f7cff073SIlya Leoshkevich     }
19*f7cff073SIlya Leoshkevich #define DEFINE_SHIFT_SINGLE_2(_insn, _offset) \
20*f7cff073SIlya Leoshkevich     DEFINE_SHIFT_SINGLE_COMMON(_insn ## _ ## _offset, \
21*f7cff073SIlya Leoshkevich                                #_insn " %[op1]," #_offset "(%[op2])")
22*f7cff073SIlya Leoshkevich #define DEFINE_SHIFT_SINGLE_3(_insn, _offset) \
23*f7cff073SIlya Leoshkevich     DEFINE_SHIFT_SINGLE_COMMON(_insn ## _ ## _offset, \
24*f7cff073SIlya Leoshkevich                                #_insn " %[op1],%[op1]," #_offset "(%[op2])")
25*f7cff073SIlya Leoshkevich #define DEFINE_SHIFT_DOUBLE(_insn, _offset) \
26*f7cff073SIlya Leoshkevich     static uint64_t _insn ## _ ## _offset(uint64_t op1, uint64_t op2, \
27*f7cff073SIlya Leoshkevich                                           uint64_t *cc) \
28*f7cff073SIlya Leoshkevich     { \
29*f7cff073SIlya Leoshkevich         uint32_t op1h = op1 >> 32; \
30*f7cff073SIlya Leoshkevich         uint32_t op1l = op1 & 0xffffffff; \
31*f7cff073SIlya Leoshkevich         register uint32_t r2 asm("2") = op1h; \
32*f7cff073SIlya Leoshkevich         register uint32_t r3 asm("3") = op1l; \
33*f7cff073SIlya Leoshkevich         \
34*f7cff073SIlya Leoshkevich         asm("    sll %[cc],28\n" \
35*f7cff073SIlya Leoshkevich             "    spm %[cc]\n" \
36*f7cff073SIlya Leoshkevich             "    " #_insn " %[r2]," #_offset "(%[op2])\n" \
37*f7cff073SIlya Leoshkevich             "    ipm %[cc]\n" \
38*f7cff073SIlya Leoshkevich             "    srl %[cc],28" \
39*f7cff073SIlya Leoshkevich             : [r2] "+&r" (r2), \
40*f7cff073SIlya Leoshkevich               [r3] "+&r" (r3), \
41*f7cff073SIlya Leoshkevich               [cc] "+&r" (*cc) \
42*f7cff073SIlya Leoshkevich             : [op2] "r" (op2) \
43*f7cff073SIlya Leoshkevich             : "cc"); \
44*f7cff073SIlya Leoshkevich         op1h = r2; \
45*f7cff073SIlya Leoshkevich         op1l = r3; \
46*f7cff073SIlya Leoshkevich         return (((uint64_t)op1h) << 32) | op1l; \
47*f7cff073SIlya Leoshkevich     }
48*f7cff073SIlya Leoshkevich 
49*f7cff073SIlya Leoshkevich DEFINE_SHIFT_SINGLE_3(rll, 0x4cf3b);
50*f7cff073SIlya Leoshkevich DEFINE_SHIFT_SINGLE_3(rllg, 0x697c9);
51*f7cff073SIlya Leoshkevich DEFINE_SHIFT_SINGLE_2(sla, 0x4b0);
52*f7cff073SIlya Leoshkevich DEFINE_SHIFT_SINGLE_2(sla, 0xd54);
53*f7cff073SIlya Leoshkevich DEFINE_SHIFT_SINGLE_3(slak, 0x2832c);
54*f7cff073SIlya Leoshkevich DEFINE_SHIFT_SINGLE_3(slag, 0x66cc4);
55*f7cff073SIlya Leoshkevich DEFINE_SHIFT_SINGLE_3(slag, 0xd54);
56*f7cff073SIlya Leoshkevich DEFINE_SHIFT_SINGLE_2(sll, 0xd04);
57*f7cff073SIlya Leoshkevich DEFINE_SHIFT_SINGLE_3(sllk, 0x2699f);
58*f7cff073SIlya Leoshkevich DEFINE_SHIFT_SINGLE_3(sllg, 0x59df9);
59*f7cff073SIlya Leoshkevich DEFINE_SHIFT_SINGLE_2(sra, 0x67e);
60*f7cff073SIlya Leoshkevich DEFINE_SHIFT_SINGLE_3(srak, 0x60943);
61*f7cff073SIlya Leoshkevich DEFINE_SHIFT_SINGLE_3(srag, 0x6b048);
62*f7cff073SIlya Leoshkevich DEFINE_SHIFT_SINGLE_2(srl, 0x035);
63*f7cff073SIlya Leoshkevich DEFINE_SHIFT_SINGLE_3(srlk, 0x43dfc);
64*f7cff073SIlya Leoshkevich DEFINE_SHIFT_SINGLE_3(srlg, 0x27227);
65*f7cff073SIlya Leoshkevich DEFINE_SHIFT_DOUBLE(slda, 0x38b);
66*f7cff073SIlya Leoshkevich DEFINE_SHIFT_DOUBLE(sldl, 0x031);
67*f7cff073SIlya Leoshkevich DEFINE_SHIFT_DOUBLE(srda, 0x36f);
68*f7cff073SIlya Leoshkevich DEFINE_SHIFT_DOUBLE(srdl, 0x99a);
69*f7cff073SIlya Leoshkevich 
70*f7cff073SIlya Leoshkevich struct shift_test {
71*f7cff073SIlya Leoshkevich     const char *name;
72*f7cff073SIlya Leoshkevich     uint64_t (*insn)(uint64_t, uint64_t, uint64_t *);
73*f7cff073SIlya Leoshkevich     uint64_t op1;
74*f7cff073SIlya Leoshkevich     uint64_t op2;
75*f7cff073SIlya Leoshkevich     uint64_t exp_result;
76*f7cff073SIlya Leoshkevich     uint64_t exp_cc;
77*f7cff073SIlya Leoshkevich };
78*f7cff073SIlya Leoshkevich 
79*f7cff073SIlya Leoshkevich static const struct shift_test tests[] = {
80*f7cff073SIlya Leoshkevich     {
81*f7cff073SIlya Leoshkevich         .name = "rll",
82*f7cff073SIlya Leoshkevich         .insn = rll_0x4cf3b,
83*f7cff073SIlya Leoshkevich         .op1 = 0xecbd589a45c248f5ull,
84*f7cff073SIlya Leoshkevich         .op2 = 0x62e5508ccb4c99fdull,
85*f7cff073SIlya Leoshkevich         .exp_result = 0xecbd589af545c248ull,
86*f7cff073SIlya Leoshkevich         .exp_cc = 0,
87*f7cff073SIlya Leoshkevich     },
88*f7cff073SIlya Leoshkevich     {
89*f7cff073SIlya Leoshkevich         .name = "rllg",
90*f7cff073SIlya Leoshkevich         .insn = rllg_0x697c9,
91*f7cff073SIlya Leoshkevich         .op1 = 0xaa2d54c1b729f7f4ull,
92*f7cff073SIlya Leoshkevich         .op2 = 0x5ffcf7465f5cd71full,
93*f7cff073SIlya Leoshkevich         .exp_result = 0x29f7f4aa2d54c1b7ull,
94*f7cff073SIlya Leoshkevich         .exp_cc = 0,
95*f7cff073SIlya Leoshkevich     },
96*f7cff073SIlya Leoshkevich     {
97*f7cff073SIlya Leoshkevich         .name = "sla-1",
98*f7cff073SIlya Leoshkevich         .insn = sla_0x4b0,
99*f7cff073SIlya Leoshkevich         .op1 = 0x8bf21fb67cca0e96ull,
100*f7cff073SIlya Leoshkevich         .op2 = 0x3ddf2f53347d3030ull,
101*f7cff073SIlya Leoshkevich         .exp_result = 0x8bf21fb600000000ull,
102*f7cff073SIlya Leoshkevich         .exp_cc = 3,
103*f7cff073SIlya Leoshkevich     },
104*f7cff073SIlya Leoshkevich     {
105*f7cff073SIlya Leoshkevich         .name = "sla-2",
106*f7cff073SIlya Leoshkevich         .insn = sla_0xd54,
107*f7cff073SIlya Leoshkevich         .op1 = 0xe4faaed5def0e926ull,
108*f7cff073SIlya Leoshkevich         .op2 = 0x18d586fab239cbeeull,
109*f7cff073SIlya Leoshkevich         .exp_result = 0xe4faaed5fbc3a498ull,
110*f7cff073SIlya Leoshkevich         .exp_cc = 3,
111*f7cff073SIlya Leoshkevich     },
112*f7cff073SIlya Leoshkevich     {
113*f7cff073SIlya Leoshkevich         .name = "slak",
114*f7cff073SIlya Leoshkevich         .insn = slak_0x2832c,
115*f7cff073SIlya Leoshkevich         .op1 = 0x7300bf78707f09f9ull,
116*f7cff073SIlya Leoshkevich         .op2 = 0x4d193b85bb5cb39bull,
117*f7cff073SIlya Leoshkevich         .exp_result = 0x7300bf783f84fc80ull,
118*f7cff073SIlya Leoshkevich         .exp_cc = 3,
119*f7cff073SIlya Leoshkevich     },
120*f7cff073SIlya Leoshkevich     {
121*f7cff073SIlya Leoshkevich         .name = "slag-1",
122*f7cff073SIlya Leoshkevich         .insn = slag_0x66cc4,
123*f7cff073SIlya Leoshkevich         .op1 = 0xe805966de1a77762ull,
124*f7cff073SIlya Leoshkevich         .op2 = 0x0e92953f6aa91c6bull,
125*f7cff073SIlya Leoshkevich         .exp_result = 0xbbb1000000000000ull,
126*f7cff073SIlya Leoshkevich         .exp_cc = 3,
127*f7cff073SIlya Leoshkevich     },
128*f7cff073SIlya Leoshkevich     {
129*f7cff073SIlya Leoshkevich         .name = "slag-2",
130*f7cff073SIlya Leoshkevich         .insn = slag_0xd54,
131*f7cff073SIlya Leoshkevich         .op1 = 0xdef0e92600000000ull,
132*f7cff073SIlya Leoshkevich         .op2 = 0x18d586fab239cbeeull,
133*f7cff073SIlya Leoshkevich         .exp_result = 0xfbc3a49800000000ull,
134*f7cff073SIlya Leoshkevich         .exp_cc = 3,
135*f7cff073SIlya Leoshkevich     },
136*f7cff073SIlya Leoshkevich     {
137*f7cff073SIlya Leoshkevich         .name = "sll",
138*f7cff073SIlya Leoshkevich         .insn = sll_0xd04,
139*f7cff073SIlya Leoshkevich         .op1 = 0xb90281a3105939dfull,
140*f7cff073SIlya Leoshkevich         .op2 = 0xb5e4df7e082e4c5eull,
141*f7cff073SIlya Leoshkevich         .exp_result = 0xb90281a300000000ull,
142*f7cff073SIlya Leoshkevich         .exp_cc = 0,
143*f7cff073SIlya Leoshkevich     },
144*f7cff073SIlya Leoshkevich     {
145*f7cff073SIlya Leoshkevich         .name = "sllk",
146*f7cff073SIlya Leoshkevich         .insn = sllk_0x2699f,
147*f7cff073SIlya Leoshkevich         .op1 = 0x777c6cf116f99557ull,
148*f7cff073SIlya Leoshkevich         .op2 = 0xe0556cf112e5a458ull,
149*f7cff073SIlya Leoshkevich         .exp_result = 0x777c6cf100000000ull,
150*f7cff073SIlya Leoshkevich         .exp_cc = 0,
151*f7cff073SIlya Leoshkevich     },
152*f7cff073SIlya Leoshkevich     {
153*f7cff073SIlya Leoshkevich         .name = "sllg",
154*f7cff073SIlya Leoshkevich         .insn = sllg_0x59df9,
155*f7cff073SIlya Leoshkevich         .op1 = 0xcdf86cbfbc0f3557ull,
156*f7cff073SIlya Leoshkevich         .op2 = 0x325a45acf99c6d3dull,
157*f7cff073SIlya Leoshkevich         .exp_result = 0x55c0000000000000ull,
158*f7cff073SIlya Leoshkevich         .exp_cc = 0,
159*f7cff073SIlya Leoshkevich     },
160*f7cff073SIlya Leoshkevich     {
161*f7cff073SIlya Leoshkevich         .name = "sra",
162*f7cff073SIlya Leoshkevich         .insn = sra_0x67e,
163*f7cff073SIlya Leoshkevich         .op1 = 0xb878f048d5354183ull,
164*f7cff073SIlya Leoshkevich         .op2 = 0x9e27d13195931f79ull,
165*f7cff073SIlya Leoshkevich         .exp_result = 0xb878f048ffffffffull,
166*f7cff073SIlya Leoshkevich         .exp_cc = 1,
167*f7cff073SIlya Leoshkevich     },
168*f7cff073SIlya Leoshkevich     {
169*f7cff073SIlya Leoshkevich         .name = "srak",
170*f7cff073SIlya Leoshkevich         .insn = srak_0x60943,
171*f7cff073SIlya Leoshkevich         .op1 = 0xb6ceb5a429cedb35ull,
172*f7cff073SIlya Leoshkevich         .op2 = 0x352354900ae34d7aull,
173*f7cff073SIlya Leoshkevich         .exp_result = 0xb6ceb5a400000000ull,
174*f7cff073SIlya Leoshkevich         .exp_cc = 0,
175*f7cff073SIlya Leoshkevich     },
176*f7cff073SIlya Leoshkevich     {
177*f7cff073SIlya Leoshkevich         .name = "srag",
178*f7cff073SIlya Leoshkevich         .insn = srag_0x6b048,
179*f7cff073SIlya Leoshkevich         .op1 = 0xd54dd4468676c63bull,
180*f7cff073SIlya Leoshkevich         .op2 = 0x84d026db7b4dca28ull,
181*f7cff073SIlya Leoshkevich         .exp_result = 0xffffffffffffd54dull,
182*f7cff073SIlya Leoshkevich         .exp_cc = 1,
183*f7cff073SIlya Leoshkevich     },
184*f7cff073SIlya Leoshkevich     {
185*f7cff073SIlya Leoshkevich         .name = "srl",
186*f7cff073SIlya Leoshkevich         .insn = srl_0x035,
187*f7cff073SIlya Leoshkevich         .op1 = 0x09be503ef826815full,
188*f7cff073SIlya Leoshkevich         .op2 = 0xbba8d1a0e542d5c1ull,
189*f7cff073SIlya Leoshkevich         .exp_result = 0x9be503e00000000ull,
190*f7cff073SIlya Leoshkevich         .exp_cc = 0,
191*f7cff073SIlya Leoshkevich     },
192*f7cff073SIlya Leoshkevich     {
193*f7cff073SIlya Leoshkevich         .name = "srlk",
194*f7cff073SIlya Leoshkevich         .insn = srlk_0x43dfc,
195*f7cff073SIlya Leoshkevich         .op1 = 0x540d6c8de71aee2aull,
196*f7cff073SIlya Leoshkevich         .op2 = 0x0000000000000000ull,
197*f7cff073SIlya Leoshkevich         .exp_result = 0x540d6c8d00000000ull,
198*f7cff073SIlya Leoshkevich         .exp_cc = 0,
199*f7cff073SIlya Leoshkevich     },
200*f7cff073SIlya Leoshkevich     {
201*f7cff073SIlya Leoshkevich         .name = "srlg",
202*f7cff073SIlya Leoshkevich         .insn = srlg_0x27227,
203*f7cff073SIlya Leoshkevich         .op1 = 0x26f7123c1c447a34ull,
204*f7cff073SIlya Leoshkevich         .op2 = 0x0000000000000000ull,
205*f7cff073SIlya Leoshkevich         .exp_result = 0x00000000004dee24ull,
206*f7cff073SIlya Leoshkevich         .exp_cc = 0,
207*f7cff073SIlya Leoshkevich     },
208*f7cff073SIlya Leoshkevich     {
209*f7cff073SIlya Leoshkevich         .name = "slda",
210*f7cff073SIlya Leoshkevich         .insn = slda_0x38b,
211*f7cff073SIlya Leoshkevich         .op1 = 0x7988f722dd5bbe7cull,
212*f7cff073SIlya Leoshkevich         .op2 = 0x9aed3f95b4d78cc2ull,
213*f7cff073SIlya Leoshkevich         .exp_result = 0x1ee45bab77cf8000ull,
214*f7cff073SIlya Leoshkevich         .exp_cc = 3,
215*f7cff073SIlya Leoshkevich     },
216*f7cff073SIlya Leoshkevich     {
217*f7cff073SIlya Leoshkevich         .name = "sldl",
218*f7cff073SIlya Leoshkevich         .insn = sldl_0x031,
219*f7cff073SIlya Leoshkevich         .op1 = 0xaae2918dce2b049aull,
220*f7cff073SIlya Leoshkevich         .op2 = 0x0000000000000000ull,
221*f7cff073SIlya Leoshkevich         .exp_result = 0x0934000000000000ull,
222*f7cff073SIlya Leoshkevich         .exp_cc = 0,
223*f7cff073SIlya Leoshkevich     },
224*f7cff073SIlya Leoshkevich     {
225*f7cff073SIlya Leoshkevich         .name = "srda",
226*f7cff073SIlya Leoshkevich         .insn = srda_0x36f,
227*f7cff073SIlya Leoshkevich         .op1 = 0x0cd4ed9228a50978ull,
228*f7cff073SIlya Leoshkevich         .op2 = 0x72b046f0848b8cc9ull,
229*f7cff073SIlya Leoshkevich         .exp_result = 0x000000000000000cull,
230*f7cff073SIlya Leoshkevich         .exp_cc = 2,
231*f7cff073SIlya Leoshkevich     },
232*f7cff073SIlya Leoshkevich     {
233*f7cff073SIlya Leoshkevich         .name = "srdl",
234*f7cff073SIlya Leoshkevich         .insn = srdl_0x99a,
235*f7cff073SIlya Leoshkevich         .op1 = 0x1018611c41689a1dull,
236*f7cff073SIlya Leoshkevich         .op2 = 0x2907e150c50ba319ull,
237*f7cff073SIlya Leoshkevich         .exp_result = 0x0000000000000203ull,
238*f7cff073SIlya Leoshkevich         .exp_cc = 0,
239*f7cff073SIlya Leoshkevich     },
240*f7cff073SIlya Leoshkevich };
241*f7cff073SIlya Leoshkevich 
main(void)242*f7cff073SIlya Leoshkevich int main(void)
243*f7cff073SIlya Leoshkevich {
244*f7cff073SIlya Leoshkevich     int ret = 0;
245*f7cff073SIlya Leoshkevich     size_t i;
246*f7cff073SIlya Leoshkevich 
247*f7cff073SIlya Leoshkevich     for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
248*f7cff073SIlya Leoshkevich         uint64_t result;
249*f7cff073SIlya Leoshkevich         uint64_t cc = 0;
250*f7cff073SIlya Leoshkevich 
251*f7cff073SIlya Leoshkevich         result = tests[i].insn(tests[i].op1, tests[i].op2, &cc);
252*f7cff073SIlya Leoshkevich         if (result != tests[i].exp_result) {
253*f7cff073SIlya Leoshkevich             fprintf(stderr,
254*f7cff073SIlya Leoshkevich                     "bad %s result:\n"
255*f7cff073SIlya Leoshkevich                     "actual   = 0x%" PRIx64 "\n"
256*f7cff073SIlya Leoshkevich                     "expected = 0x%" PRIx64 "\n",
257*f7cff073SIlya Leoshkevich                     tests[i].name, result, tests[i].exp_result);
258*f7cff073SIlya Leoshkevich             ret = 1;
259*f7cff073SIlya Leoshkevich         }
260*f7cff073SIlya Leoshkevich         if (cc != tests[i].exp_cc) {
261*f7cff073SIlya Leoshkevich             fprintf(stderr,
262*f7cff073SIlya Leoshkevich                     "bad %s cc:\n"
263*f7cff073SIlya Leoshkevich                     "actual   = %" PRIu64 "\n"
264*f7cff073SIlya Leoshkevich                     "expected = %" PRIu64 "\n",
265*f7cff073SIlya Leoshkevich                     tests[i].name, cc, tests[i].exp_cc);
266*f7cff073SIlya Leoshkevich             ret = 1;
267*f7cff073SIlya Leoshkevich         }
268*f7cff073SIlya Leoshkevich     }
269*f7cff073SIlya Leoshkevich     return ret;
270*f7cff073SIlya Leoshkevich }
271