1 
2 /* HOW TO COMPILE:
3 
4  * 32bit build:
5    gcc -Winline -Wall -g -O -mregnames -maltivec -m32
6  * 64bit build:
7    gcc -Winline -Wall -g -O -mregnames -maltivec -m64
8 
9 
10  * test_isa_2_07_part1.c:
11  * PPC tests for the ISA 2.07.  This file is based on the
12  * jm-insns.c file for the new instructions in the ISA 2.07.  The
13  * test structure has been kept the same as the original file to
14  * the extent possible.
15  *
16  * Copyright (C) 2013 IBM
17  *
18  *   Authors: Carl Love <carll@us.ibm.com>
19  *            Maynard Johnson <maynardj@us.ibm.com>
20  *
21  *   This program is free software; you can redistribute it and/or
22  *   modify it under the terms of the GNU General Public License as
23  *   published by the Free Software Foundation; either version 2 of the
24  *   License, or (at your option) any later version.
25  *
26  *   This program is distributed in the hope that it will be useful,
27  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
28  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29  *   GNU General Public License for more details.
30  *
31  *   You should have received a copy of the GNU General Public License
32  *   along with this program; if not, write to the Free Software
33  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
34  *
35  */
36 
37 /*
38  * Operation details
39  * -----------------
40  *
41  * The 'loops' (e.g. int_loops) do the actual work:
42  *  - loops over as many arguments as the insn needs (regs | imms)
43  *     - sets up the environment (reset cr,xer, assign src regs...)
44  *     - maybe modifies the asm instn to test different imm args
45  *     - calls the test function
46  *     - retrieves relevant register data (rD,cr,xer,...)
47  *     - prints argument and result data.
48  *
49  * More specifically...
50  *
51  * all_tests[i] holds insn tests
52  *  - of which each holds: {instn_test_arr[], description, flags}
53  *
54  * flags hold 3 instn classifiers: {family, type, arg_type}
55  *
56  * // The main test loop:
57  * do_tests( user_ctl_flags ) {
58  *    foreach(curr_test = all_test[i]) {
59  *
60  *       // flags are used to control what tests are run:
61  *       if (curr_test->flags && !user_ctl_flags)
62  *          continue;
63  *
64  *       // a 'loop_family_arr' is chosen based on the 'family' flag...
65  *       switch(curr_test->flags->family) {
66  *       case x: loop_family_arr = int_loops;
67  *      ...
68  *       }
69  *
70  *       // ...and the actual test_loop to run is found by indexing into
71  *       // the loop_family_arr with the 'arg_type' flag:
72  *       test_loop = loop_family[curr_test->flags->arg_type]
73  *
74  *       // finally, loop over all instn tests for this test:
75  *       foreach (instn_test = curr_test->instn_test_arr[i]) {
76  *
77  *          // and call the test_loop with the current instn_test function,name
78  *          test_loop( instn_test->func, instn_test->name )
79  *       }
80  *    }
81  * }
82  *
83  */
84 
85 
86 /**********************************************************************/
87 
88 /* Uncomment to enable output of CR flags for float tests */
89 //#define TEST_FLOAT_FLAGS
90 
91 /* Uncomment to enable debug output */
92 //#define DEBUG_ARGS_BUILD
93 //#define DEBUG_FILTER
94 
95 /**********************************************************************/
96 #include <stdio.h>
97 
98 #ifdef HAS_ISA_2_07
99 
100 #include "config.h"
101 #include <altivec.h>
102 #include <stdint.h>
103 
104 #include <assert.h>
105 #include <ctype.h>     // isspace
106 #include <stdlib.h>
107 #include <string.h>
108 #include <unistd.h>    // getopt
109 
110 #if !defined (__TEST_PPC_H__)
111 #define __TEST_PPC_H__
112 
113 #include "tests/sys_mman.h"
114 #include "tests/malloc.h"       // memalign16
115 
116 #define STATIC_ASSERT(e) sizeof(struct { int:-!(e); })
117 
118 /* Something of the same size as void*, so can be safely be coerced
119  * to/from a pointer type. Also same size as the host's gp registers.
120  * According to the AltiVec section of the GCC manual, the syntax does
121  * not allow the use of a typedef name as a type specifier in conjunction
122  * with the vector keyword, so typedefs uint[32|64]_t are #undef'ed here
123  * and redefined using #define.
124  */
125 #undef uint32_t
126 #undef uint64_t
127 #define uint32_t unsigned int
128 #define uint64_t unsigned long long int
129 
130 #ifndef __powerpc64__
131 typedef uint32_t  HWord_t;
132 #define ZERO 0
133 #else
134 typedef uint64_t  HWord_t;
135 #define ZERO 0ULL
136 #endif /* __powerpc64__ */
137 
138 #ifdef VGP_ppc64le_linux
139 #define isLE 1
140 #else
141 #define isLE 0
142 #endif
143 
144 typedef uint64_t Word_t;
145 
146 enum {
147     compile_time_test1 = STATIC_ASSERT(sizeof(uint32_t) == 4),
148     compile_time_test2 = STATIC_ASSERT(sizeof(uint64_t) == 8),
149 };
150 
151 #define ALLCR "cr0","cr1","cr2","cr3","cr4","cr5","cr6","cr7"
152 
153 #define SET_CR(_arg) \
154       __asm__ __volatile__ ("mtcr  %0" : : "b"(_arg) : ALLCR );
155 
156 #define SET_XER(_arg) \
157       __asm__ __volatile__ ("mtxer %0" : : "b"(_arg) : "xer" );
158 
159 #define GET_CR(_lval) \
160       __asm__ __volatile__ ("mfcr %0"  : "=b"(_lval) )
161 
162 #define GET_XER(_lval) \
163       __asm__ __volatile__ ("mfxer %0" : "=b"(_lval) )
164 
165 #define GET_CR_XER(_lval_cr,_lval_xer) \
166    do { GET_CR(_lval_cr); GET_XER(_lval_xer); } while (0)
167 
168 #define SET_CR_ZERO \
169       SET_CR(0)
170 
171 #define SET_XER_ZERO \
172       SET_XER(0)
173 
174 #define SET_CR_XER_ZERO \
175    do { SET_CR_ZERO; SET_XER_ZERO; } while (0)
176 
177 #define SET_FPSCR_ZERO \
178    do { double _d = 0.0; \
179         __asm__ __volatile__ ("mtfsf 0xFF, %0" : : "f"(_d) ); \
180    } while (0)
181 
182 #define DEFAULT_VSCR 0x0
183 
184 static vector unsigned long long vec_out, vec_inA, vec_inB, vec_inC;
185 static vector unsigned int vec_inA_wd, vec_inB_wd;
186 
187 /* XXXX these must all be callee-save regs! */
188 register double f14 __asm__ ("fr14");
189 register double f15 __asm__ ("fr15");
190 register double f16 __asm__ ("fr16");
191 register double f17 __asm__ ("fr17");
192 register HWord_t r14 __asm__ ("r14");
193 register HWord_t r15 __asm__ ("r15");
194 register HWord_t r16 __asm__ ("r16");
195 register HWord_t r17 __asm__ ("r17");
196 
197 typedef void (*test_func_t) (void);
198 typedef struct _test test_t;
199 typedef struct _test_table test_table_t;
200 struct _test {
201     test_func_t func;
202     const char *name;
203 };
204 
205 struct _test_table {
206     test_t *tests;
207     const char *name;
208     uint32_t flags;
209 };
210 
211 typedef void (*test_loop_t) (const char *name, test_func_t func,
212                              uint32_t flags);
213 
214 enum test_flags {
215     /* Nb arguments */
216     PPC_ONE_ARG    = 0x00000001,
217     PPC_TWO_ARGS   = 0x00000002,
218     PPC_THREE_ARGS = 0x00000003,
219     PPC_CMP_ARGS   = 0x00000004,  // family: compare
220     PPC_CMPI_ARGS  = 0x00000005,  // family: compare
221     PPC_TWO_I16    = 0x00000006,  // family: arith/logical
222     PPC_SPECIAL    = 0x00000007,  // family: logical
223     PPC_LD_ARGS    = 0x00000008,  // family: ldst
224     PPC_LDX_ARGS   = 0x00000009,  // family: ldst
225     PPC_ST_ARGS    = 0x0000000A,  // family: ldst
226     PPC_STX_ARGS   = 0x0000000B,  // family: ldst
227     PPC_STQ_ARGS   = 0x0000000C,  // family: ldst, two args, imm
228     PPC_LDQ_ARGS   = 0x0000000D,  // family: ldst, two args, imm
229     PPC_STQX_ARGS  = 0x0000000E,  // family: ldst, three args
230     PPC_LDQX_ARGS  = 0x0000000F,  // family: ldst, three_args
231     PPC_NB_ARGS    = 0x0000000F,
232     /* Type */
233     PPC_ARITH      = 0x00000100,
234     PPC_LOGICAL    = 0x00000200,
235     PPC_COMPARE    = 0x00000300,
236     PPC_CROP       = 0x00000400,
237     PPC_LDST       = 0x00000500,
238     PPC_POPCNT     = 0x00000600,
239     PPC_ARITH_DRES = 0x00000700,
240     PPC_DOUBLE_IN_IRES = 0x00000800,
241     PPC_MOV        = 0x00000A00,
242     PPC_SHA_OR_BCD = 0x00000B00,
243     PPC_TYPE       = 0x00000F00,
244     /* Family */
245     PPC_INTEGER    = 0x00010000,
246     PPC_FLOAT      = 0x00020000,
247     PPC_405        = 0x00030000,  // Leave so we keep numbering consistent
248     PPC_ALTIVEC    = 0x00040000,
249     PPC_FALTIVEC   = 0x00050000,
250     PPC_ALTIVECD   = 0x00060000,    /* double word Altivec tests */
251     PPC_ALTIVECQ   = 0x00070000,
252     PPC_FAMILY     = 0x000F0000,
253     /* Flags: these may be combined, so use separate bitfields. */
254     PPC_CR         = 0x01000000,
255     PPC_XER_CA     = 0x02000000,
256 };
257 
258 #endif /* !defined (__TEST_PPC_H__) */
259 
260 /* -------------- END #include "test-ppc.h" -------------- */
261 
262 
263 #if defined (DEBUG_ARGS_BUILD)
264 #define AB_DPRINTF(fmt, args...) do { fprintf(stderr, fmt , ##args); } while (0)
265 #else
266 #define AB_DPRINTF(fmt, args...) do { } while (0)
267 #endif
268 
269 
270 #if defined (DEBUG_FILTER)
271 #define FDPRINTF(fmt, args...) do { fprintf(stderr, fmt , ##args); } while (0)
272 #else
273 #define FDPRINTF(fmt, args...) do { } while (0)
274 #endif
275 
276 #define unused __attribute__ (( unused ))
277 
278 typedef struct special {
279    const char *name;
280    void (*test_cb)(const char* name, test_func_t func,
281                    unused uint32_t test_flags);
282 } special_t;
283 
test_stq(void)284 static void test_stq(void)
285 {
286   __asm__ __volatile__ ("stq  %0, 0(%1)" : :"r" (r14), "r" (r16));
287 }
288 
289 static test_t tests_istq_ops_two_i16[] = {
290     { &test_stq             , "stq", },
291     { NULL,                   NULL,           },
292 };
293 
test_lq(void)294 static void test_lq(void)
295 {
296   __asm__ __volatile__ ("lq  %0, 0(%1)" : :"r" (r14), "r" (r16));
297 }
298 
299 static test_t tests_ildq_ops_two_i16[] = {
300     { &test_lq              , "lq", },
301     { NULL,                   NULL,          },
302 };
303 
304 #ifdef HAS_ISA_2_07
305 Word_t * mem_resv;
test_stbcx(void)306 static void test_stbcx(void)
307 {
308   /* Have to do the lbarx to the memory address to create the reservation
309    * or the store will not occur.
310    */
311   __asm__ __volatile__ ("lbarx  %0, %1, %2" : :"r" (r14), "r" (r16),"r" (r17));
312   r14 = (HWord_t) 0xABEFCD0145236789ULL;
313   r15 = (HWord_t) 0x1155337744226688ULL;
314   __asm__ __volatile__ ("stbcx. %0, %1, %2" : :"r" (r14), "r" (r16),"r" (r17));
315 }
316 
test_sthcx(void)317 static void test_sthcx(void)
318 {
319   /* Have to do the lharx to the memory address to create the reservation
320    * or the store will not occur.
321    */
322   __asm__ __volatile__ ("lharx  %0, %1, %2" : :"r" (r14), "r" (r16),"r" (r17));
323   r14 = (HWord_t) 0xABEFCD0145236789ULL;
324   r15 = (HWord_t) 0x1155337744226688ULL;
325   __asm__ __volatile__ ("sthcx. %0, %1, %2" : :"r" (r14), "r" (r16),"r" (r17));
326 }
327 #endif
328 
test_stqcx(void)329 static void test_stqcx(void)
330 {
331   /* Have to do the lqarx to the memory address to create the reservation
332    * or the store will not occur.
333    */
334   __asm__ __volatile__ ("lqarx  %0, %1, %2" : :"r" (r14), "r" (r16),"r" (r17));
335   r14 = (HWord_t) 0xABEFCD0145236789ULL;
336   r15 = (HWord_t) 0x1155337744226688ULL;
337   __asm__ __volatile__ ("stqcx. %0, %1, %2" : :"r" (r14), "r" (r16),"r" (r17));
338 }
339 
340 static test_t tests_stq_ops_three[] = {
341 #ifdef HAS_ISA_2_07
342     { &test_stbcx           , "stbcx.", },
343     { &test_sthcx           , "sthcx.", },
344 #endif
345     { &test_stqcx           , "stqcx.", },
346     { NULL,                   NULL,           },
347 };
348 
349 #ifdef HAS_ISA_2_07
test_lbarx(void)350 static void test_lbarx(void)
351 {
352   __asm__ __volatile__ ("lbarx  %0, %1, %2, 0" : :"r" (r14), "r" (r16),"r" (r17));
353 }
test_lharx(void)354 static void test_lharx(void)
355 {
356   __asm__ __volatile__ ("lharx  %0, %1, %2, 0" : :"r" (r14), "r" (r16),"r" (r17));
357 }
358 #endif
test_lqarx(void)359 static void test_lqarx(void)
360 {
361   __asm__ __volatile__ ("lqarx  %0, %1, %2, 0" : :"r" (r14), "r" (r16),"r" (r17));
362 }
363 
364 static test_t tests_ldq_ops_three[] = {
365 #ifdef HAS_ISA_2_07
366     { &test_lbarx           , "lbarx", },
367     { &test_lharx           , "lharx", },
368 #endif
369     { &test_lqarx           , "lqarx", },
370     { NULL,                   NULL,           },
371 };
372 
test_fmrgew(void)373 static void test_fmrgew (void)
374 {
375     __asm__ __volatile__ ("fmrgew        17,14,15");
376 };
377 
test_fmrgow(void)378 static void test_fmrgow (void)
379 {
380     __asm__ __volatile__ ("fmrgow        17,14,15");
381 };
382 
383 
384 
385 // VSX move instructions
test_mfvsrd(void)386 static void test_mfvsrd (void)
387 {
388    __asm__ __volatile__ ("mfvsrd %0,%x1" : "=r" (r14) : "ws" (vec_inA));
389 };
390 
test_mfvsrwz(void)391 static void test_mfvsrwz (void)
392 {
393    __asm__ __volatile__ ("mfvsrwz %0,%x1" : "=r" (r14) : "ws" (vec_inA));
394 };
395 
test_mtvsrd(void)396 static void test_mtvsrd (void)
397 {
398    __asm__ __volatile__ ("mtvsrd %x0,%1" : "=ws" (vec_out) : "r" (r14));
399 };
400 
test_mtvsrwz(void)401 static void test_mtvsrwz (void)
402 {
403    __asm__ __volatile__ ("mtvsrwz %x0,%1" : "=ws" (vec_out) : "r" (r14));
404 };
405 
test_mtvsrwa(void)406 static void test_mtvsrwa (void)
407 {
408    __asm__ __volatile__ ("mtvsrwa %x0,%1" : "=ws" (vec_out) : "r" (r14));
409 };
410 
test_mtfprwa(void)411 static void test_mtfprwa (void)
412 {
413    __asm__ __volatile__ ("mtfprwa %x0,%1" : "=d" (vec_out) : "r" (r14));
414 };
415 
test_mtvrwa(void)416 static void test_mtvrwa (void)
417 {
418    __asm__ __volatile__ ("mtvrwa %0,%1" : "=v" (vec_out) : "r" (r14));
419 };
420 
test_mtvrd(void)421 static void test_mtvrd (void)
422 {
423    __asm__ __volatile__ ("mtvrd %0,%1" : "=v" (vec_out) : "r" (r14));
424 };
425 
test_mtfprd(void)426 static void test_mtfprd (void)
427 {
428    __asm__ __volatile__ ("mtfprd %0,%1" : "=d" (vec_out) : "r" (r14));
429 };
430 
431 static test_t tests_move_ops_spe[] = {
432   { &test_mfvsrd          , "mfvsrd" },
433   { &test_mfvsrwz         , "mfvsrwz" },
434   { &test_mtvsrd          , "mtvsrd" },
435   { &test_mtvsrwz         , "mtvsrwz" },
436   { &test_mtfprwa         , "mtfprwa" },
437   { &test_mtvsrwa         , "mtvsrwa" },
438   { &test_mtfprd          , "mtfprd" },
439   { &test_mtvrwa          , "mtvrwa" },
440   { &test_mtvrd           , "mtvrd" },
441   { NULL,                   NULL }
442 };
443 
444 /* NOTE: Since these are "vector" instructions versus VSX, we must use
445  * vector constraints.
446  *
447  * Vector Double Word tests.
448  */
test_vpkudum(void)449 static void test_vpkudum (void)
450 {
451    __asm__ __volatile__ ("vpkudum %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
452 }
453 
test_vaddudm(void)454 static void test_vaddudm (void)
455 {
456    __asm__ __volatile__ ("vaddudm %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
457 }
458 
test_vsubudm(void)459 static void test_vsubudm (void)
460 {
461    __asm__ __volatile__ ("vsubudm %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
462 }
463 
test_vmaxud(void)464 static void test_vmaxud (void)
465 {
466    __asm__ __volatile__ ("vmaxud %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
467 }
468 
test_vmaxsd(void)469 static void test_vmaxsd (void)
470 {
471    __asm__ __volatile__ ("vmaxsd %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
472 }
473 
test_vminud(void)474 static void test_vminud (void)
475 {
476    __asm__ __volatile__ ("vminud %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
477 }
478 
test_vminsd(void)479 static void test_vminsd (void)
480 {
481    __asm__ __volatile__ ("vminsd %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
482 }
483 
test_vcmpequd(void)484 static void test_vcmpequd (void)
485 {
486    __asm__ __volatile__ ("vcmpequd %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
487 }
488 
test_vcmpgtud(void)489 static void test_vcmpgtud (void)
490 {
491    __asm__ __volatile__ ("vcmpgtud %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
492 }
493 
test_vcmpgtsd(void)494 static void test_vcmpgtsd (void)
495 {
496    __asm__ __volatile__ ("vcmpgtsd %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
497 }
498 
test_vrld(void)499 static void test_vrld (void)
500 {
501    __asm__ __volatile__ ("vrld %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
502 }
503 
test_vsld(void)504 static void test_vsld (void)
505 {
506    __asm__ __volatile__ ("vsld %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
507 }
508 
test_vsrad(void)509 static void test_vsrad (void)
510 {
511    __asm__ __volatile__ ("vsrad %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
512 }
513 
test_vsrd(void)514 static void test_vsrd (void)
515 {
516    __asm__ __volatile__ ("vsrd %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
517 }
518 
519 /* Vector Double Word saturate tests.*/
520 
test_vpkudus(void)521 static void test_vpkudus (void)
522 {
523    __asm__ __volatile__ ("vpkudus %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
524 }
525 
test_vpksdus(void)526 static void test_vpksdus (void)
527 {
528    __asm__ __volatile__ ("vpksdus %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
529 }
530 
test_vpksdss(void)531 static void test_vpksdss (void)
532 {
533    __asm__ __volatile__ ("vpksdss %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
534 }
535 
536 
537 /* Vector unpack two words from one vector arg */
test_vupkhsw(void)538 static void test_vupkhsw (void)
539 {
540     __asm__ __volatile__ ("vupkhsw %0, %1" : "=v" (vec_out): "v" (vec_inB_wd));
541 }
542 
test_vupklsw(void)543 static void test_vupklsw (void)
544 {
545     __asm__ __volatile__ ("vupklsw %0, %1" : "=v" (vec_out): "v" (vec_inB_wd));
546 }
547 
548 
549 /* Vector Integer Word tests.*/
test_vmulouw(void)550 static void test_vmulouw (void)
551 {
552   __asm__ __volatile__ ("vmulouw %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
553 }
554 
test_vmuluwm(void)555 static void test_vmuluwm (void)
556 {
557     __asm__ __volatile__ ("vmuluwm %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
558 }
559 
test_vmulosw(void)560 static void test_vmulosw (void)
561 {
562     __asm__ __volatile__ ("vmulosw %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
563 }
564 
test_vmuleuw(void)565 static void test_vmuleuw (void)
566 {
567     __asm__ __volatile__ ("vmuleuw %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
568 }
569 
test_vmulesw(void)570 static void test_vmulesw (void)
571 {
572     __asm__ __volatile__ ("vmulesw %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
573 }
574 
test_vmrgew(void)575 static void test_vmrgew (void)
576 {
577     __asm__ __volatile__ ("vmrgew %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
578 }
579 
test_vmrgow(void)580 static void test_vmrgow (void)
581 {
582     __asm__ __volatile__ ("vmrgow %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
583 }
584 
test_vpmsumb(void)585 static void test_vpmsumb (void)
586 {
587     __asm__ __volatile__ ("vpmsumb %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
588 }
589 
test_vpmsumh(void)590 static void test_vpmsumh (void)
591 {
592     __asm__ __volatile__ ("vpmsumh %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
593 }
594 
test_vpmsumw(void)595 static void test_vpmsumw (void)
596 {
597     __asm__ __volatile__ ("vpmsumw %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
598 }
599 
test_vpermxor(void)600 static void test_vpermxor (void)
601 {
602   __asm__ __volatile__ ("vpermxor %0, %1, %2, %3" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB),"v" (vec_inC));
603 }
604 
test_vpmsumd(void)605 static void test_vpmsumd (void)
606 {
607     __asm__ __volatile__ ("vpmsumd %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
608 }
609 
test_vnand(void)610 static void test_vnand (void)
611 {
612     __asm__ __volatile__ ("vnand %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
613 }
614 
test_vorc(void)615 static void test_vorc (void)
616 {
617     __asm__ __volatile__ ("vorc %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
618 }
619 
test_veqv(void)620 static void test_veqv (void)
621 {
622     __asm__ __volatile__ ("veqv %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
623 }
624 
test_vcipher(void)625 static void test_vcipher (void)
626 {
627     __asm__ __volatile__ ("vcipher %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
628 }
629 
test_vcipherlast(void)630 static void test_vcipherlast (void)
631 {
632     __asm__ __volatile__ ("vcipherlast %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
633 }
634 
test_vncipher(void)635 static void test_vncipher (void)
636 {
637     __asm__ __volatile__ ("vncipher %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
638 }
639 
test_vncipherlast(void)640 static void test_vncipherlast (void)
641 {
642     __asm__ __volatile__ ("vncipherlast %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
643 }
644 
test_vclzb(void)645 static void test_vclzb (void)
646 {
647     __asm__ __volatile__ ("vclzb %0, %1" : "=v" (vec_out): "v" (vec_inB));
648 }
649 
test_vclzw(void)650 static void test_vclzw (void)
651 {
652     __asm__ __volatile__ ("vclzw %0, %1" : "=v" (vec_out): "v" (vec_inB));
653 }
654 
test_vclzh(void)655 static void test_vclzh (void)
656 {
657     __asm__ __volatile__ ("vclzh %0, %1" : "=v" (vec_out): "v" (vec_inB));
658 }
659 
test_vclzd(void)660 static void test_vclzd (void)
661 {
662     __asm__ __volatile__ ("vclzd %0, %1" : "=v" (vec_out): "v" (vec_inB));
663 }
664 
test_vpopcntb(void)665 static void test_vpopcntb (void)
666 {
667     __asm__ __volatile__ ("vpopcntb %0, %1" : "=v" (vec_out): "v" (vec_inB));
668 }
669 
test_vpopcnth(void)670 static void test_vpopcnth (void)
671 {
672     __asm__ __volatile__ ("vpopcnth %0, %1" : "=v" (vec_out): "v" (vec_inB));
673 }
674 
test_vpopcntw(void)675 static void test_vpopcntw (void)
676 {
677     __asm__ __volatile__ ("vpopcntw %0, %1" : "=v" (vec_out): "v" (vec_inB));
678 }
679 
test_vpopcntd(void)680 static void test_vpopcntd (void)
681 {
682     __asm__ __volatile__ ("vpopcntd %0, %1" : "=v" (vec_out): "v" (vec_inB));
683 }
684 
test_vsbox(void)685 static void test_vsbox (void)
686 {
687     __asm__ __volatile__ ("vsbox %0, %1" : "=v" (vec_out): "v" (vec_inB));
688 }
689 
690 static int st_six;
test_vshasigmad(void)691 static void test_vshasigmad (void)
692 {
693    switch (st_six) {
694    case 0x00:
695       __asm__ __volatile__ ("vshasigmad %0, %1, 0, 0" : "=v" (vec_out): "v" (vec_inA));
696       break;
697    case 0x0f:
698       __asm__ __volatile__ ("vshasigmad %0, %1, 0, 15" : "=v" (vec_out): "v" (vec_inA));
699       break;
700    case 0x10:
701       __asm__ __volatile__ ("vshasigmad %0, %1, 1, 0" : "=v" (vec_out): "v" (vec_inA));
702       break;
703    case 0x1f:
704       __asm__ __volatile__ ("vshasigmad %0, %1, 1, 15" : "=v" (vec_out): "v" (vec_inA));
705       break;
706    }
707 }
708 
test_vshasigmaw(void)709 static void test_vshasigmaw (void)
710 {
711    switch (st_six) {
712    case 0x00:
713       __asm__ __volatile__ ("vshasigmaw %0, %1, 0, 0" : "=v" (vec_out): "v" (vec_inA));
714       break;
715    case 0x0f:
716       __asm__ __volatile__ ("vshasigmaw %0, %1, 0, 15" : "=v" (vec_out): "v" (vec_inA));
717       break;
718    case 0x10:
719       __asm__ __volatile__ ("vshasigmaw %0, %1, 1, 0" : "=v" (vec_out): "v" (vec_inA));
720       break;
721    case 0x1f:
722       __asm__ __volatile__ ("vshasigmaw %0, %1, 1, 15" : "=v" (vec_out): "v" (vec_inA));
723       break;
724    }
725 }
726 
727 static int PS_bit;
test_bcdadd(void)728 static void test_bcdadd (void)
729 {
730    if (PS_bit)
731       __asm__ __volatile__ ("bcdadd. %0, %1, %2, 1" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
732    else
733       __asm__ __volatile__ ("bcdadd. %0, %1, %2, 0" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
734 }
735 
test_bcdsub(void)736 static void test_bcdsub (void)
737 {
738    if (PS_bit)
739       __asm__ __volatile__ ("bcdsub. %0, %1, %2, 1" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
740    else
741       __asm__ __volatile__ ("bcdsub. %0, %1, %2, 0" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
742 }
743 
test_vaddcuq(void)744 static void test_vaddcuq (void)
745 {
746    __asm__ __volatile__ ("vaddcuq %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
747 }
748 
test_vadduqm(void)749 static void test_vadduqm (void)
750 {
751    __asm__ __volatile__ ("vadduqm %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
752 }
753 
test_vaddecuq(void)754 static void test_vaddecuq (void)
755 {
756   __asm__ __volatile__ ("vaddecuq %0, %1, %2, %3" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB),"v" (vec_inC));
757 }
758 
test_vaddeuqm(void)759 static void test_vaddeuqm (void)
760 {
761   __asm__ __volatile__ ("vaddeuqm %0, %1, %2, %3" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB),"v" (vec_inC));
762 }
763 
test_vsubcuq(void)764 static void test_vsubcuq (void)
765 {
766    __asm__ __volatile__ ("vsubcuq %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
767 }
768 
test_vsubuqm(void)769 static void test_vsubuqm (void)
770 {
771    __asm__ __volatile__ ("vsubuqm %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
772 }
773 
test_vsubecuq(void)774 static void test_vsubecuq (void)
775 {
776   __asm__ __volatile__ ("vsubecuq %0, %1, %2, %3" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB),"v" (vec_inC));
777 }
778 
test_vsubeuqm(void)779 static void test_vsubeuqm (void)
780 {
781   __asm__ __volatile__ ("vsubeuqm %0, %1, %2, %3" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB),"v" (vec_inC));
782 }
783 
test_vbpermq(void)784 static void test_vbpermq (void)
785 {
786    __asm__ __volatile__ ("vbpermq %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
787 }
788 
test_vgbbd(void)789 static void test_vgbbd (void)
790 {
791     __asm__ __volatile__ ("vgbbd %0, %1" : "=v" (vec_out): "v" (vec_inB));
792 }
793 
794 
795 static test_t tests_aa_quadword_two_args[] = {
796   { &test_vaddcuq       , "vaddcuq" },
797   { &test_vadduqm       , "vadduqm" },
798   { &test_vsubcuq       , "vsubcuq" },
799   { &test_vsubuqm       , "vsubuqm" },
800   { &test_vbpermq       , "vbpermq" },
801   { NULL                , NULL      },
802 };
803 
804 static test_t tests_aa_quadword_three_args[] = {
805   { &test_vaddecuq      , "vaddecuq" },
806   { &test_vaddeuqm      , "vaddeuqm" },
807   { &test_vsubecuq      , "vsubecuq" },
808   { &test_vsubeuqm      , "vsubeuqm" },
809   { NULL                , NULL      },
810 };
811 
812 static test_t tests_aa_bcd_ops[] = {
813   { &test_bcdadd        , "bcdadd." },
814   { &test_bcdsub        , "bcdsub." },
815   { NULL                , NULL      },
816 };
817 
818 static test_t tests_aa_SHA_ops[] = {
819   { &test_vshasigmad    , "vshasigmad" },
820   { &test_vshasigmaw    , "vshasigmaw" },
821   { NULL                , NULL         },
822 };
823 
824 static test_t tests_aa_ops_three[] = {
825   { &test_vpermxor        , "vpermxor" },
826   { NULL                  , NULL       },
827 };
828 
829 static test_t tests_aa_word_ops_one_arg_dres[] = {
830   { &test_vupkhsw         , "vupkhsw" },
831   { &test_vupklsw         , "vupklsw" },
832   { NULL                  , NULL      }
833 };
834 
835 static test_t tests_aa_word_ops_two_args_dres[] = {
836   { &test_vmulouw         , "vmulouw" },
837   { &test_vmuluwm         , "vmuluwm" },
838   { &test_vmulosw         , "vmulosw" },
839   { &test_vmuleuw         , "vmuleuw" },
840   { &test_vmulesw         , "vmulesw" },
841   { &test_vmrgew          , "vmrgew" },
842   { &test_vmrgow          , "vmrgow" },
843   { &test_vpmsumb         , "vpmsumb" },
844   { &test_vpmsumh         , "vpmsumh" },
845   { &test_vpmsumw         , "vpmsumw" },
846   { NULL                  , NULL      }
847 };
848 
849 static test_t tests_aa_dbl_ops_two_args[] = {
850   { &test_vaddudm         , "vaddudm", },
851   { &test_vsubudm         , "vsubudm", },
852   { &test_vmaxud          , "vmaxud", },
853   { &test_vmaxsd          , "vmaxsd", },
854   { &test_vminud          , "vminud", },
855   { &test_vminsd          , "vminsd", },
856   { &test_vcmpequd        , "vcmpequd", },
857   { &test_vcmpgtud        , "vcmpgtud", },
858   { &test_vcmpgtsd        , "vcmpgtsd", },
859   { &test_vrld            , "vrld", },
860   { &test_vsld            , "vsld", },
861   { &test_vsrad           , "vsrad", },
862   { &test_vsrd            , "vsrd", },
863   { &test_vpkudum         , "vpkudum", },
864   { &test_vpmsumd         , "vpmsumd", },
865   { &test_vnand           , "vnand", },
866   { &test_vorc            , "vorc", },
867   { &test_veqv            , "veqv", },
868   { &test_vcipher         , "vcipher" },
869   { &test_vcipherlast     , "vcipherlast" },
870   { &test_vncipher        , "vncipher" },
871   { &test_vncipherlast    , "vncipherlast" },
872   { NULL                  , NULL,      },
873 };
874 
875 static test_t tests_aa_dbl_ops_one_arg[] = {
876   { &test_vclzb           , "vclzb" },
877   { &test_vclzw           , "vclzw" },
878   { &test_vclzh           , "vclzh" },
879   { &test_vclzd           , "vclzd" },
880   { &test_vpopcntb        , "vpopcntb" },
881   { &test_vpopcnth        , "vpopcnth" },
882   { &test_vpopcntw        , "vpopcntw" },
883   { &test_vpopcntd        , "vpopcntd" },
884   { &test_vsbox           , "vsbox" },
885   { &test_vgbbd           , "vgbbd" },
886   { NULL                  , NULL,      }
887 };
888 
889 static test_t tests_aa_dbl_to_int_two_args[] = {
890   { &test_vpkudus         , "vpkudus", },
891   { &test_vpksdus         , "vpksdus", },
892   { &test_vpksdss         , "vpksdss", },
893   { NULL                  , NULL,      },
894 };
895 
896 static int verbose = 0;
897 static int arg_list_size = 0;
898 static unsigned long long * vdargs = NULL;
899 static unsigned long long * vdargs_x = NULL;
900 #define NB_VDARGS 9
901 #define NB_VDARGS_X 4
902 
build_vdargs_table(void)903 static void build_vdargs_table (void)
904 {
905    // Each VSX register holds two doubleword integer values
906    vdargs = memalign16(NB_VDARGS * sizeof(unsigned long long));
907    vdargs[0] = 0x0102030405060708ULL;
908    vdargs[1] = 0x090A0B0C0E0D0E0FULL;
909    vdargs[2] = 0xF1F2F3F4F5F6F7F8ULL;
910    vdargs[3] = 0xF9FAFBFCFEFDFEFFULL;
911    vdargs[4] = 0x00007FFFFFFFFFFFULL;
912    vdargs[5] = 0xFFFF000000000000ULL;
913    vdargs[6] = 0x0000800000000000ULL;
914    vdargs[7] = 0x0000000000000000ULL;
915    vdargs[8] = 0xFFFFFFFFFFFFFFFFULL;
916 
917    vdargs_x = memalign16(NB_VDARGS_X * sizeof(unsigned long long));
918    vdargs_x[0] = 0x000000007c118a2bULL;
919    vdargs_x[1] = 0x00000000f1112345ULL;
920    vdargs_x[2] = 0x01F2F3F4F5F6F7F8ULL;
921    vdargs_x[3] = 0xF9FAFBFCFEFDFEFFULL;
922 }
923 
924 static unsigned int * vwargs = NULL;
925 #define NB_VWARGS 8
926 
build_vwargs_table(void)927 static void build_vwargs_table (void)
928 {
929    // Each VSX register holds 4 integer word values
930    size_t i = 0;
931    vwargs = memalign(8, 8 * sizeof(int));
932    assert(vwargs);
933    assert(0 == ((8-1) & (unsigned long)vwargs));
934    vwargs[i++] = 0x01020304;
935    vwargs[i++] = 0x05060708;
936    vwargs[i++] = 0x090A0B0C;
937    vwargs[i++] = 0x0E0D0E0F;
938    vwargs[i++] = 0xF1F2F3F4;
939    vwargs[i++] = 0xF5F6F7F8;
940    vwargs[i++] = 0xF9FAFBFC;
941    vwargs[i++] = 0xFEFDFEFF;
942 }
943 
944 static unsigned long long vbcd_args[] __attribute__ ((aligned (16))) = {
945    0x8045090189321003ULL, // Negative BCD value
946    0x001122334556677dULL,
947    0x0000107600000001ULL, // Positive BCD value
948    0x319293945142031aULL,
949    0x0ULL,                // Valid BCD zero
950    0xaULL,
951    0x0ULL,                // Invalid BCD zero (no sign code)
952    0x0ULL
953 };
954 //#define NUM_VBCD_VALS (sizeof vbcd_args/sizeof vbcd_args[0])
955 #define NUM_VBCD_VALS 8
956 
build_vargs_table(void)957 static void build_vargs_table (void)
958 {
959    build_vdargs_table();
960    build_vwargs_table();
961 }
962 
963 static double *fargs = NULL;
964 static int nb_fargs = 0;
965 
register_farg(void * farg,int s,uint16_t _exp,uint64_t mant)966 static inline void register_farg (void *farg,
967                                   int s, uint16_t _exp, uint64_t mant)
968 {
969    uint64_t tmp;
970 
971    tmp = ((uint64_t)s << 63) | ((uint64_t)_exp << 52) | mant;
972    *(uint64_t *)farg = tmp;
973    AB_DPRINTF("%d %03x %013llx => %016llx %0e\n",
974               s, _exp, mant, *(uint64_t *)farg, *(double *)farg);
975 }
976 
build_fargs_table(void)977 static void build_fargs_table (void)
978 {
979    /* Double precision:
980     * Sign goes from zero to one               (1 bit)
981     * Exponent goes from 0 to ((1 << 12) - 1)  (11 bits)
982     * Mantissa goes from 1 to ((1 << 52) - 1)  (52 bits)
983     * + special values:
984     * +0.0      : 0 0x000 0x0000000000000 => 0x0000000000000000
985     * -0.0      : 1 0x000 0x0000000000000 => 0x8000000000000000
986     * +infinity : 0 0x7FF 0x0000000000000 => 0x7FF0000000000000
987     * -infinity : 1 0x7FF 0x0000000000000 => 0xFFF0000000000000
988     * +QNaN     : 0 0x7FF 0x8000000000000 => 0x7FF8000000000000
989     * -QNaN     : 1 0x7FF 0x8000000000000 => 0xFFF8000000000000
990     * +SNaN     : 0 0x7FF 0x7FFFFFFFFFFFF => 0x7FF7FFFFFFFFFFFF
991     * -SNaN     : 1 0x7FF 0x7FFFFFFFFFFFF => 0xFFF7FFFFFFFFFFFF
992     * (8 values)
993 
994     * Ref only:
995     * Single precision
996     * Sign:     1 bit
997     * Exponent: 8 bits
998     * Mantissa: 23 bits
999     * +0.0      : 0 0x00 0x000000 => 0x00000000
1000     * -0.0      : 1 0x00 0x000000 => 0x80000000
1001     * +infinity : 0 0xFF 0x000000 => 0x7F800000
1002     * -infinity : 1 0xFF 0x000000 => 0xFF800000
1003     * +QNaN     : 0 0xFF 0x400000 => 0x7FC00000
1004     * -QNaN     : 1 0xFF 0x400000 => 0xFFC00000
1005     * +SNaN     : 0 0xFF 0x3FFFFF => 0x7FBFFFFF
1006     * -SNaN     : 1 0xFF 0x3FFFFF => 0xFFBFFFFF
1007     */
1008    uint64_t mant;
1009    uint16_t _exp, e0, e1;
1010    int s;
1011    int i=0;
1012 
1013    /* Note: VEX isn't so hot with denormals, so don't bother
1014       testing them: set _exp > 0
1015    */
1016 
1017    if ( arg_list_size == 1 ) {   // Large
1018       fargs = malloc(200 * sizeof(double));
1019       for (s=0; s<2; s++) {
1020          for (e0=0; e0<2; e0++) {
1021             for (e1=0x001; ; e1 = ((e1 + 1) << 2) + 6) {
1022                if (e1 >= 0x400)
1023                   e1 = 0x3fe;
1024                _exp = (e0 << 10) | e1;
1025                for (mant = 0x0000000000001ULL; mant < (1ULL << 52);
1026                     /* Add 'random' bits */
1027                     mant = ((mant + 0x4A6) << 13) + 0x359) {
1028                   register_farg(&fargs[i++], s, _exp, mant);
1029                }
1030                if (e1 == 0x3fe)
1031                   break;
1032             }
1033          }
1034       }
1035    } else {                      // Default
1036       fargs = malloc(16 * sizeof(double));
1037       for (s=0; s<2; s++) {                                // x2
1038             for (e1=0x001; ; e1 = ((e1 + 1) << 13) + 7) {  // x2
1039                if (e1 >= 0x400)
1040                   e1 = 0x3fe;
1041                _exp = e1;
1042                for (mant = 0x0000000000001ULL; mant < (1ULL << 52);
1043                     /* Add 'random' bits */
1044                     mant = ((mant + 0x4A6) << 29) + 0x359) {  // x2
1045                   register_farg(&fargs[i++], s, _exp, mant);
1046                }
1047                if (e1 == 0x3fe)
1048                   break;
1049             }
1050       }
1051    }
1052 
1053    /* Special values */
1054    /* +0.0      : 0 0x000 0x0000000000000 */
1055    s = 0;
1056    _exp = 0x000;
1057    mant = 0x0000000000000ULL;
1058    register_farg(&fargs[i++], s, _exp, mant);
1059    /* -0.0      : 1 0x000 0x0000000000000 */
1060    s = 1;
1061    _exp = 0x000;
1062    mant = 0x0000000000000ULL;
1063    register_farg(&fargs[i++], s, _exp, mant);
1064    /* +infinity : 0 0x7FF 0x0000000000000  */
1065    s = 0;
1066    _exp = 0x7FF;
1067    mant = 0x0000000000000ULL;
1068    register_farg(&fargs[i++], s, _exp, mant);
1069    /* -infinity : 1 0x7FF 0x0000000000000 */
1070    s = 1;
1071    _exp = 0x7FF;
1072    mant = 0x0000000000000ULL;
1073    register_farg(&fargs[i++], s, _exp, mant);
1074    /* +QNaN     : 0 0x7FF 0x7FFFFFFFFFFFF */
1075    s = 0;
1076    _exp = 0x7FF;
1077    mant = 0x7FFFFFFFFFFFFULL;
1078    register_farg(&fargs[i++], s, _exp, mant);
1079    /* -QNaN     : 1 0x7FF 0x7FFFFFFFFFFFF */
1080    s = 1;
1081    _exp = 0x7FF;
1082    mant = 0x7FFFFFFFFFFFFULL;
1083    register_farg(&fargs[i++], s, _exp, mant);
1084    /* +SNaN     : 0 0x7FF 0x8000000000000 */
1085    s = 0;
1086    _exp = 0x7FF;
1087    mant = 0x8000000000000ULL;
1088    register_farg(&fargs[i++], s, _exp, mant);
1089    /* -SNaN     : 1 0x7FF 0x8000000000000 */
1090    s = 1;
1091    _exp = 0x7FF;
1092    mant = 0x8000000000000ULL;
1093    register_farg(&fargs[i++], s, _exp, mant);
1094    AB_DPRINTF("Registered %d fargs values\n", i);
1095 
1096    nb_fargs = i;
1097 }
1098 
1099 
1100 
check_filter(char * filter)1101 static int check_filter (char *filter)
1102 {
1103    char *c;
1104    int ret = 1;
1105 
1106    if (filter != NULL) {
1107       c = strchr(filter, '*');
1108       if (c != NULL) {
1109          *c = '\0';
1110          ret = 0;
1111       }
1112    }
1113    return ret;
1114 }
1115 
check_name(const char * name,const char * filter,int exact)1116 static int check_name (const char* name, const char *filter,
1117                        int exact)
1118 {
1119    int nlen, flen;
1120    int ret = 0;
1121 
1122    if (filter != NULL) {
1123       for (; isspace(*name); name++)
1124          continue;
1125       FDPRINTF("Check '%s' againt '%s' (%s match)\n",
1126                name, filter, exact ? "exact" : "starting");
1127       nlen = strlen(name);
1128       flen = strlen(filter);
1129       if (exact) {
1130          if (nlen == flen && memcmp(name, filter, flen) == 0)
1131             ret = 1;
1132       } else {
1133          if (flen <= nlen && memcmp(name, filter, flen) == 0)
1134             ret = 1;
1135       }
1136    } else {
1137       ret = 1;
1138    }
1139    return ret;
1140 }
1141 
1142 
1143 typedef struct insn_sel_flags_t_struct {
1144    int one_arg, two_args, three_args;
1145    int arith, logical, compare, ldst;
1146    int integer, floats, altivec, faltivec;
1147    int cr;
1148 } insn_sel_flags_t;
1149 
test_float_two_args(const char * name,test_func_t func,unused uint32_t test_flags)1150 static void test_float_two_args (const char* name, test_func_t func,
1151                                  unused uint32_t test_flags)
1152 {
1153    double res;
1154    Word_t u0, u1, ur;
1155    volatile uint32_t flags;
1156    int i, j;
1157 
1158    for (i=0; i<nb_fargs; i+=3) {
1159       for (j=0; j<nb_fargs; j+=5) {
1160          u0 = *(Word_t *)(&fargs[i]);
1161          u1 = *(Word_t *)(&fargs[j]);
1162          f14 = fargs[i];
1163          f15 = fargs[j];
1164 
1165          SET_FPSCR_ZERO;
1166          SET_CR_XER_ZERO;
1167          (*func)();
1168          GET_CR(flags);
1169          res = f17;
1170          ur = *(uint64_t *)(&res);
1171 
1172          printf("%s %016llx, %016llx => %016llx",
1173                 name, u0, u1, ur);
1174 #if defined TEST_FLOAT_FLAGS
1175          printf(" (%08x)", flags);
1176 #endif
1177          printf("\n");
1178       }
1179       if (verbose) printf("\n");
1180    }
1181 }
1182 
1183 
mfvs(const char * name,test_func_t func,unused uint32_t test_flags)1184 static void mfvs(const char* name, test_func_t func,
1185                  unused uint32_t test_flags)
1186 {
1187    /* This test is for move instructions where the input is a scalar register
1188     * and the destination is a vector register.
1189     */
1190    int i;
1191    volatile Word_t result;
1192    result = 0ULL;
1193 
1194    for (i=0; i < NB_VDARGS; i++) {
1195       r14 = ZERO;
1196       if (isLE)
1197          vec_inA = (vector unsigned long long){ 0ULL, vdargs[i] };
1198       else
1199          vec_inA = (vector unsigned long long){ vdargs[i], 0ULL };
1200 
1201       (*func)();
1202       result = r14;
1203       printf("%s: %016llx => %016llx\n", name, vdargs[i], result);
1204    }
1205 }
1206 
mtvs(const char * name,test_func_t func,unused uint32_t test_flags)1207 static void mtvs(const char* name, test_func_t func,
1208                  unused uint32_t test_flags)
1209 {
1210    /* This test is for move instructions where the input is a scalar register
1211     * and the destination is a vector register.
1212     */
1213    unsigned long long *dst;
1214    int i;
1215 
1216    for (i=0; i < NB_VDARGS; i++) {
1217       r14  = vdargs[i];
1218       vec_out = (vector unsigned long long){ 0ULL, 0ULL };
1219 
1220       (*func)();
1221       dst = (unsigned long long *) &vec_out;
1222       if (isLE)
1223          dst++;
1224       printf("%s: %016llx => %016llx\n", name, vdargs[i], *dst);
1225    }
1226 }
1227 
mtvs2s(const char * name,test_func_t func,unused uint32_t test_flags)1228 static void mtvs2s(const char* name, test_func_t func,
1229                  unused uint32_t test_flags)
1230 {
1231    /* This test is the mtvsrwa instruction.
1232     */
1233    unsigned long long *dst;
1234    int i;
1235 
1236    for (i=0; i < NB_VDARGS; i++) {
1237       // Only the lower half of the vdarg doubleword arg will be used as input by mtvsrwa
1238       unsigned int * src = (unsigned int *)&vdargs[i];
1239       if (!isLE)
1240          src++;
1241       r14  = vdargs[i];
1242       vec_out = (vector unsigned long long){ 0ULL, 0ULL };
1243 
1244       (*func)();
1245       // Only doubleword 0 is used in output
1246       dst = (unsigned long long *) &vec_out;
1247       if (isLE)
1248          dst++;
1249       printf("%s: %08x => %016llx\n", name, *src, *dst);
1250    }
1251 }
1252 
test_special(special_t * table,const char * name,test_func_t func,unused uint32_t test_flags)1253 static void test_special (special_t *table,
1254                           const char* name, test_func_t func,
1255                           unused uint32_t test_flags)
1256 {
1257    const char *tmp;
1258    int i;
1259 
1260    for (tmp = name; isspace(*tmp); tmp++)
1261       continue;
1262    for (i=0; table[i].name != NULL; i++) {
1263       if (strcmp(table[i].name, tmp) == 0) {
1264          (*table[i].test_cb)(name, func, test_flags);
1265          return;
1266       }
1267    }
1268    fprintf(stderr, "ERROR: no test found for op '%s'\n", name);
1269 }
1270 
1271 static special_t special_move_ops[] = {
1272    {
1273       "mfvsrd",  /* move from vector to scalar reg doubleword */
1274       &mfvs,
1275    },
1276    {
1277       "mtvsrd",  /* move from scalar to vector reg doubleword */
1278       &mtvs,
1279    },
1280    {
1281       "mtvsrwa", /* mtvsrwa move from scalar to vector reg  */
1282       &mtvs2s,
1283    },
1284    {
1285       "mtfprwa", /* (extended mnemonic for mtvsrwa) move from scalar to vector
1286 		    reg */
1287       &mtvs2s,
1288    },
1289    {
1290       "mfvsrwz", /* move from vector to scalar reg word */
1291       &mfvs,
1292    },
1293    {
1294       "mtvsrwz", /* move from scalar to vector reg word */
1295       &mtvs2s,
1296    },
1297    {
1298       "mtvrwa", /* (extended mnemonic for mtvsrwa) move to vsr word */
1299       &mtvs2s,
1300    },
1301    {
1302       "mtvrd", /* (extended mnemonic for mtvsrd) move to vsr double word */
1303       &mtvs,
1304    },
1305    {
1306       "mtfprd", /* (extended mnemonic for mtvsrd) move to float word */
1307       &mtvs,
1308    }
1309 };
1310 
test_move_special(const char * name,test_func_t func,uint32_t test_flags)1311 static void test_move_special(const char* name, test_func_t func,
1312                                 uint32_t test_flags)
1313 {
1314    test_special(special_move_ops, name, func, test_flags);
1315 }
1316 
1317 /* Vector Double Word tests */
1318 
test_av_dint_two_args(const char * name,test_func_t func,unused uint32_t test_flags)1319 static void test_av_dint_two_args (const char* name, test_func_t func,
1320                                    unused uint32_t test_flags)
1321 {
1322 
1323    unsigned long long * dst;
1324    unsigned int * dst_int;
1325    int i,j;
1326    int family = test_flags & PPC_FAMILY;
1327    int is_vpkudum, is_vpmsumd;
1328    if (strcmp(name, "vpkudum") == 0)
1329       is_vpkudum = 1;
1330    else
1331       is_vpkudum = 0;
1332 
1333    if (strcmp(name, "vpmsumd") == 0)
1334       is_vpmsumd = 1;
1335    else
1336       is_vpmsumd = 0;
1337 
1338    for (i = 0; i < NB_VDARGS - 1; i+=2) {
1339       if (isLE && family == PPC_ALTIVECQ)
1340          vec_inA = (vector unsigned long long){ vdargs[i+1], vdargs[i] };
1341       else
1342          vec_inA = (vector unsigned long long){ vdargs[i], vdargs[i+1] };
1343       for (j = 0; j < NB_VDARGS - 1; j+=2) {
1344          if (isLE && family == PPC_ALTIVECQ)
1345             vec_inB = (vector unsigned long long){ vdargs[j+1], vdargs[j] };
1346          else
1347             vec_inB = (vector unsigned long long){ vdargs[j], vdargs[j+1] };
1348          vec_out = (vector unsigned long long){ 0,0 };
1349 
1350          (*func)();
1351          dst_int = (unsigned int *)&vec_out;
1352          dst  = (unsigned long long*)&vec_out;
1353 
1354          printf("%s: ", name);
1355 
1356          if (is_vpkudum) {
1357             printf("Inputs: %08llx %08llx %08llx %08llx\n", vdargs[i] & 0x00000000ffffffffULL,
1358                    vdargs[i+1] & 0x00000000ffffffffULL, vdargs[j] & 0x00000000ffffffffULL,
1359                    vdargs[j+1] & 0x00000000ffffffffULL);
1360             if (isLE)
1361                printf("         Output: %08x %08x %08x %08x\n", dst_int[2], dst_int[3],
1362                       dst_int[0], dst_int[1]);
1363             else
1364                printf("         Output: %08x %08x %08x %08x\n", dst_int[0], dst_int[1],
1365                       dst_int[2], dst_int[3]);
1366          } else if (is_vpmsumd) {
1367             printf("%016llx @@ %016llx ", vdargs[i], vdargs[j]);
1368             if (isLE)
1369                printf(" ==> %016llx\n", dst[1]);
1370             else
1371                printf(" ==> %016llx\n", dst[0]);
1372             printf("\t%016llx @@ %016llx ", vdargs[i+1], vdargs[j+1]);
1373             if (isLE)
1374                printf(" ==> %016llx\n", dst[0]);
1375             else
1376                printf(" ==> %016llx\n", dst[1]);
1377          } else if (family == PPC_ALTIVECQ) {
1378             if (isLE)
1379                printf("%016llx%016llx @@ %016llx%016llx ==> %016llx%016llx\n",
1380                       vdargs[i], vdargs[i+1], vdargs[j], vdargs[j+1],
1381                       dst[1], dst[0]);
1382             else
1383                printf("%016llx%016llx @@ %016llx%016llx ==> %016llx%016llx\n",
1384                       vdargs[i], vdargs[i+1], vdargs[j], vdargs[j+1],
1385                       dst[0], dst[1]);
1386          } else {
1387             printf("%016llx @@ %016llx ", vdargs[i], vdargs[j]);
1388             printf(" ==> %016llx\n", dst[0]);
1389             printf("\t%016llx @@ %016llx ", vdargs[i+1], vdargs[j+1]);
1390             printf(" ==> %016llx\n", dst[1]);
1391          }
1392       }
1393    }
1394 }
1395 
test_av_dint_one_arg(const char * name,test_func_t func,unused uint32_t test_flags)1396 static void test_av_dint_one_arg (const char* name, test_func_t func,
1397                                   unused uint32_t test_flags)
1398 {
1399 
1400    unsigned long long * dst;
1401    int i;
1402 
1403    for (i = 0; i < NB_VDARGS - 1; i+=2) {
1404       vec_inB = (vector unsigned long long){ vdargs[i], vdargs[i+1] };
1405       vec_out = (vector unsigned long long){ 0,0 };
1406 
1407       (*func)();
1408       dst  = (unsigned long long*)&vec_out;
1409 
1410       printf("%s: ", name);
1411       printf("%016llx @@ %016llx ", vdargs[i], vdargs[i + 1]);
1412       printf(" ==> %016llx%016llx\n", dst[0], dst[1]);
1413    }
1414 }
1415 
test_av_dint_one_arg_SHA(const char * name,test_func_t func,unused uint32_t test_flags)1416 static void test_av_dint_one_arg_SHA (const char* name, test_func_t func,
1417                                       unused uint32_t test_flags)
1418 {
1419    unsigned long long * dst;
1420    int i, st, six;
1421 
1422    for (i = 0; i < NB_VDARGS - 1; i+=2) {
1423       vec_inA = (vector unsigned long long){ vdargs[i], vdargs[i+1] };
1424       vec_out = (vector unsigned long long){ 0,0 };
1425 
1426       for (st = 0; st < 2; st++) {
1427          for (six = 0; six < 16; six+=15) {
1428             st_six = (st << 4) | six;
1429             (*func)();
1430             dst  = (unsigned long long*)&vec_out;
1431 
1432             printf("%s: ", name);
1433             printf("%016llx @@ %016llx ", vdargs[i], vdargs[i + 1]);
1434             printf(" ==> %016llx || %016llx\n", dst[0], dst[1]);
1435          }
1436       }
1437    }
1438 }
1439 
test_av_bcd(const char * name,test_func_t func,unused uint32_t test_flags)1440 static void test_av_bcd (const char* name, test_func_t func,
1441                          unused uint32_t test_flags)
1442 {
1443    unsigned long long * dst;
1444    int i, j;
1445 
1446    for (i = 0; i < NUM_VBCD_VALS - 1; i+=2) {
1447       if (isLE)
1448          vec_inA = (vector unsigned long long){ vbcd_args[i+1], vbcd_args[i]};
1449       else
1450          vec_inA = (vector unsigned long long){ vbcd_args[i], vbcd_args[i+1] };
1451       for (j = 0; j < NUM_VBCD_VALS - 1; j+=2) {
1452          if (isLE)
1453             vec_inB = (vector unsigned long long){ vbcd_args[j+1] , vbcd_args[j] };
1454          else
1455             vec_inB = (vector unsigned long long){ vbcd_args[j], vbcd_args[j+1] };
1456          vec_out = (vector unsigned long long){ 0, 0 };
1457 
1458          for (PS_bit = 0; PS_bit < 2; PS_bit++) {
1459             (*func)();
1460             dst  = (unsigned long long*)&vec_out;
1461             printf("%s: ", name);
1462             printf("%016llx || %016llx @@ %016llx || %016llx",
1463                    vbcd_args[i], vbcd_args[i + 1],
1464                    vbcd_args[j], vbcd_args[j + 1]);
1465             if (isLE)
1466                printf(" ==> %016llx || %016llx\n", dst[1], dst[0]);
1467             else
1468                printf(" ==> %016llx || %016llx\n", dst[0], dst[1]);
1469          }
1470       }
1471    }
1472 }
1473 
1474 /* Vector doubleword-to-int tests, two input args, integer result */
test_av_dint_to_int_two_args(const char * name,test_func_t func,unused uint32_t test_flags)1475 static void test_av_dint_to_int_two_args (const char* name, test_func_t func,
1476                                           unused uint32_t test_flags)
1477 {
1478 
1479    unsigned int * dst_int;
1480    int i,j;
1481    for (i = 0; i < NB_VDARGS_X - 1; i+=2) {
1482       vec_inA = (vector unsigned long long){ vdargs_x[i], vdargs_x[i+1] };
1483       for (j = 0; j < NB_VDARGS_X - 1; j+=2) {
1484          vec_inB = (vector unsigned long long){ vdargs_x[j], vdargs_x[j+1] };
1485          vec_out = (vector unsigned long long){ 0,0 };
1486 
1487          (*func)();
1488          dst_int = (unsigned int *)&vec_out;
1489 
1490          printf("%s: ", name);
1491          printf("%016llx, %016llx @@ %016llx, %016llx ",
1492                 vdargs_x[i], vdargs_x[i+1],
1493                 vdargs_x[j], vdargs_x[j+1]);
1494          if (isLE)
1495             printf(" ==> %08x %08x %08x %08x\n", dst_int[2], dst_int[3],
1496                    dst_int[0], dst_int[1]);
1497          else
1498             printf(" ==> %08x %08x %08x %08x\n", dst_int[0], dst_int[1],
1499                    dst_int[2], dst_int[3]);
1500       }
1501    }
1502 }
1503 
1504 /* Vector Word tests; two integer args, with double word result */
1505 
test_av_wint_two_args_dres(const char * name,test_func_t func,unused uint32_t test_flags)1506 static void test_av_wint_two_args_dres (const char* name, test_func_t func,
1507                                         unused uint32_t test_flags)
1508 {
1509 
1510    unsigned long long * dst;
1511    int i,j;
1512 
1513    for (i = 0; i < NB_VWARGS; i+=4) {
1514       if (isLE)
1515          vec_inA_wd = (vector unsigned int){ vwargs[i+3], vwargs[i+2], vwargs[i+1], vwargs[i] };
1516       else
1517          vec_inA_wd = (vector unsigned int){ vwargs[i], vwargs[i+1], vwargs[i+2], vwargs[i+3] };
1518       for (j = 0; j < NB_VWARGS; j+=4) {
1519          if (isLE)
1520             vec_inB_wd = (vector unsigned int){ vwargs[j+3], vwargs[j+2], vwargs[j+1], vwargs[j] };
1521          else
1522             vec_inB_wd = (vector unsigned int){ vwargs[j], vwargs[j+1], vwargs[j+2], vwargs[j+3] };
1523          vec_out = (vector unsigned long long){ 0, 0 };
1524 
1525          (*func)();
1526          dst  = (unsigned long long *)&vec_out;
1527          printf("%s: ", name);
1528          if (isLE)
1529             printf("%08x %08x %08x %08x ==> %016llx %016llx\n",
1530                    vwargs[i], vwargs[i+1], vwargs[i+2], vwargs[i+3], dst[1], dst[0]);
1531          else
1532             printf("%08x %08x %08x %08x ==> %016llx %016llx\n",
1533                    vwargs[i], vwargs[i+1], vwargs[i+2], vwargs[i+3], dst[0], dst[1]);
1534       }
1535    }
1536 }
1537 
1538 /* Vector Word tests; one input arg, with double word result */
1539 
test_av_wint_one_arg_dres(const char * name,test_func_t func,unused uint32_t test_flags)1540 static void test_av_wint_one_arg_dres (const char* name, test_func_t func,
1541                                        unused uint32_t test_flags)
1542 {
1543    unsigned long long * dst;
1544    int i;
1545    for (i = 0; i < NB_VWARGS; i+=4) {
1546       if (isLE)
1547          vec_inB_wd = (vector unsigned int){ vwargs[i+3], vwargs[i+2], vwargs[i+1], vwargs[i] };
1548       else
1549          vec_inB_wd = (vector unsigned int){ vwargs[i], vwargs[i+1], vwargs[i+2], vwargs[i+3] };
1550       vec_out = (vector unsigned long long){ 0, 0 };
1551 
1552       (*func)();
1553       dst  = (unsigned long long *)&vec_out;
1554       printf("%s: ", name);
1555       if (isLE)
1556          printf("%08x %08x %08x %08x ==> %016llx %016llx\n",
1557                 vwargs[i], vwargs[i+1], vwargs[i+2], vwargs[i+3], dst[1], dst[0]);
1558       else
1559          printf("%08x %08x %08x %08x ==> %016llx %016llx\n",
1560                 vwargs[i], vwargs[i+1], vwargs[i+2], vwargs[i+3], dst[0], dst[1]);
1561    }
1562 }
1563 
1564 
test_int_stq_two_regs_imm16(const char * name,test_func_t func_IN,unused uint32_t test_flags)1565 static void test_int_stq_two_regs_imm16 (const char* name,
1566                                         test_func_t func_IN,
1567                                         unused uint32_t test_flags)
1568 {
1569    /* Store quad word from register pair */
1570    int offs, k;
1571    HWord_t base;
1572    Word_t *iargs_priv;
1573 
1574    // private iargs table to store to, note storing pair of regs
1575    iargs_priv = memalign16(2 * sizeof(Word_t));
1576 
1577    base = (HWord_t)&iargs_priv[0];
1578    for (k = 0; k < 2; k++)  // clear array
1579       iargs_priv[k] = 0;
1580 
1581    offs = 0;
1582 
1583    /* setup source register pair */
1584    r14 = (HWord_t) 0xABCDEF0123456789ULL;
1585    r15 = (HWord_t) 0x1133557722446688ULL;
1586 
1587    r16 = base;                 // store to r16 + offs
1588 
1589    (*func_IN)();
1590 
1591 #ifndef __powerpc64__
1592    printf("%s %08x,%08x, %2d => "
1593 #else
1594    printf("%s %016llx,%016llx, %3d => "
1595 #endif
1596             "%016llx,%016llx)\n",
1597             name, r14, r15, offs, iargs_priv[0], iargs_priv[1]);
1598 
1599    if (verbose) printf("\n");
1600    free(iargs_priv);
1601 }
1602 
1603 
test_int_stq_three_regs(const char * name,test_func_t func_IN,unused uint32_t test_flags)1604 static void test_int_stq_three_regs (const char* name,
1605                                      test_func_t func_IN,
1606                                      unused uint32_t test_flags)
1607 {
1608    /* Store quad word from register pair */
1609    volatile uint32_t flags, xer;
1610    int k;
1611    HWord_t base;
1612 
1613    base = (HWord_t)&mem_resv[0];
1614    for (k = 0; k < 2; k++)  // setup array for lqarx inst
1615       mem_resv[k] = k;
1616 
1617    /* setup source register pair for store */
1618    r14 = ZERO;
1619    r15 = ZERO;
1620    r16 = base;                 // store to r16 + r17
1621    r17 = ZERO;
1622 
1623    /* In order for the store to occur, the lqarx instruction must first
1624     * be used to load from the address thus creating a reservation at the
1625     * memory address.  The lqarx instruction is done in the test_stqcx(),
1626     * then registers 14, r15 are changed to the data to be stored in memory
1627     * by the stqcx instruction.
1628     */
1629    SET_CR_XER_ZERO;
1630    (*func_IN)();
1631    GET_CR_XER(flags,xer);
1632 #ifndef __powerpc64__
1633    printf("%s %08x,%08x, =>  "
1634 #else
1635    printf("%s %016llx,%016llx => "
1636 #endif
1637             "%016llx,%016llx; CR=%08x\n",
1638             name, r14, r15, mem_resv[0], mem_resv[1], flags);
1639 
1640    if (verbose) printf("\n");
1641 }
1642 
test_int_ldq_two_regs_imm16(const char * name,test_func_t func_IN,unused uint32_t test_flags)1643 static void test_int_ldq_two_regs_imm16 (const char* name,
1644                                         test_func_t func_IN,
1645                                         unused uint32_t test_flags)
1646 {
1647    /* load quad word from register pair */
1648    volatile uint32_t flags, xer;
1649    Word_t * mem_priv;
1650    HWord_t base;
1651 
1652    // private iargs table to store to, note storing pair of regs
1653    mem_priv = memalign16(2 * sizeof(Word_t));  // want 128-bits
1654 
1655    base = (HWord_t)&mem_priv[0];
1656 
1657    mem_priv[0] = 0xAACCEE0011335577ULL;
1658    mem_priv[1] = 0xABCDEF0123456789ULL;
1659 
1660    r14 = 0;
1661    r15 = 0;
1662    r16 = base;                 // fetch from r16 + offs
1663    SET_CR_XER_ZERO;
1664    (*func_IN)();
1665    GET_CR_XER(flags,xer);
1666 
1667 #ifndef __powerpc64__
1668    printf("%s (0x%016llx, 0x%016llx) =>  (reg_pair = %08x,%08x)\n",
1669 #else
1670    printf("%s (0x%016llx, 0x%016llx) =>  (reg_pair = 0x%016llx, 0x%016llx)\n",
1671 #endif
1672           name, mem_priv[0], mem_priv[1], r14, r15);
1673 
1674    if (verbose) printf("\n");
1675 
1676    free(mem_priv);
1677 }
1678 
test_int_ldq_three_regs(const char * name,test_func_t func_IN,unused uint32_t test_flags)1679 static void test_int_ldq_three_regs (const char* name,
1680                                      test_func_t func_IN,
1681                                      unused uint32_t test_flags)
1682 {
1683    /* load quad word from register pair */
1684    HWord_t base;
1685 
1686    base = (HWord_t)&mem_resv[0];
1687 
1688    mem_resv[0] = 0xAACCEE0011335577ULL;
1689    mem_resv[1] = 0xABCDEF0123456789ULL;
1690 
1691    r14 = 0;
1692    r15 = 0;
1693    r16 = base;                 // fetch from r16 + r17
1694    r17 = 0;
1695 
1696    (*func_IN)();
1697 
1698 #ifndef __powerpc64__
1699    printf("%s (0x%016llx, 0x%016llx) =>  (reg_pair = 0x%08x, 0x%08x)\n",
1700 #else
1701    printf("%s (0x%016llx, 0x%016llx) =>  (reg_pair = 0x%016llx, 0x%016llx)\n",
1702 #endif
1703           name, mem_resv[0], mem_resv[1], r14, r15);
1704    if (verbose) printf("\n");
1705 
1706 }
1707 
test_av_dint_three_args(const char * name,test_func_t func,unused uint32_t test_flags)1708 static void test_av_dint_three_args (const char* name, test_func_t func,
1709                                      unused uint32_t test_flags)
1710 {
1711 
1712    unsigned long long * dst;
1713    int i,j, k;
1714    int family = test_flags & PPC_FAMILY;
1715    unsigned long long cin_vals[] = {
1716                                     // First pair of ULLs have LSB=0, so cin is '0'.
1717                                     // Second pair of ULLs have LSB=1, so cin is '1'.
1718                                     0xf000000000000000ULL, 0xf000000000000000ULL,
1719                                     0xf000000000000000ULL, 0xf000000000000001ULL
1720    };
1721    for (i = 0; i < NB_VDARGS - 1; i+=2) {
1722       if (isLE)
1723          vec_inA = (vector unsigned long long){ vdargs[i+1], vdargs[i] };
1724       else
1725          vec_inA = (vector unsigned long long){ vdargs[i], vdargs[i+1] };
1726       for (j = 0; j < NB_VDARGS - 1; j+=2) {
1727          if (isLE)
1728             vec_inB = (vector unsigned long long){ vdargs[j+1], vdargs[j] };
1729          else
1730             vec_inB = (vector unsigned long long){ vdargs[j], vdargs[j+1] };
1731          for (k = 0; k < 4 - 1; k+=2) {
1732             if (family == PPC_ALTIVECQ) {
1733                if (isLE)
1734                   vec_inC = (vector unsigned long long){ cin_vals[k+1], cin_vals[k] };
1735                else
1736                   vec_inC = (vector unsigned long long){ cin_vals[k], cin_vals[k+1] };
1737             } else {
1738                if (isLE)
1739                   vec_inC = (vector unsigned long long){ vdargs[k+1], vdargs[k] };
1740                else
1741                   vec_inC = (vector unsigned long long){ vdargs[k], vdargs[k+1] };
1742             }
1743             vec_out = (vector unsigned long long){ 0,0 };
1744 
1745             (*func)();
1746             dst  = (unsigned long long*)&vec_out;
1747             printf("%s: ", name);
1748             if (family == PPC_ALTIVECQ) {
1749                if (isLE)
1750                   printf("%016llx%016llx @@ %016llx%016llx @@ %llx ==> %016llx%016llx\n",
1751                          vdargs[i], vdargs[i+1], vdargs[j], vdargs[j+1], cin_vals[k+1],
1752                          dst[1], dst[0]);
1753                else
1754                   printf("%016llx%016llx @@ %016llx%016llx @@ %llx ==> %016llx%016llx\n",
1755                          vdargs[i], vdargs[i+1], vdargs[j], vdargs[j+1], cin_vals[k+1],
1756                          dst[0], dst[1]);
1757             } else {
1758                printf("%016llx @@ %016llx @@ %016llx ", vdargs[i], vdargs[j], vdargs[k]);
1759                if (isLE)
1760                   printf(" ==> %016llx\n", dst[1]);
1761                else
1762                   printf(" ==> %016llx\n", dst[0]);
1763                printf("\t%016llx @@ %016llx @@ %016llx ", vdargs[i+1], vdargs[j+1], vdargs[k+1]);
1764                if (isLE)
1765                   printf(" ==> %016llx\n", dst[0]);
1766                else
1767                   printf(" ==> %016llx\n", dst[1]);
1768             }
1769          }
1770       }
1771    }
1772 }
1773 
1774 
1775 /* The ALTIVEC_LOOPS and altive_loops defined below are used in do_tests.
1776  * Add new values to the end; do not change order, since the altivec_loops
1777  * array is indexed using the enumerated values defined by ALTIVEC_LOOPS.
1778  */
1779 enum ALTIVEC_LOOPS {
1780    ALTV_MOV,
1781    ALTV_DINT,
1782    ALTV_INT_DRES,
1783    ALTV_DINT_IRES,
1784    ALTV_ONE_INT_DRES,
1785    ALTV_DINT_THREE_ARGS,
1786    ALTV_DINT_ONE_ARG,
1787    ALTV_SHA,
1788    ATLV_BCD
1789 };
1790 
1791 static test_loop_t altivec_loops[] = {
1792    &test_move_special,
1793    &test_av_dint_two_args,
1794    &test_av_wint_two_args_dres,
1795    &test_av_dint_to_int_two_args,
1796    &test_av_wint_one_arg_dres,
1797    &test_av_dint_three_args,
1798    &test_av_dint_one_arg,
1799    &test_av_dint_one_arg_SHA,
1800    &test_av_bcd,
1801    NULL
1802 };
1803 
1804 /* Used in do_tests, indexed by flags->nb_args
1805    Elements correspond to enum test_flags::num args
1806 */
1807 static test_loop_t int_loops[] = {
1808   /* The #defines for the family, number registers need the array
1809    * to be properly indexed.  This test is for the new ISA 2.0.7
1810    * instructions.  The infrastructure has been left for the momemnt
1811    */
1812    NULL, //&test_int_one_arg,
1813    NULL, //&test_int_two_args,
1814    NULL, //&test_int_three_args,
1815    NULL, //&test_int_two_args,
1816    NULL, //&test_int_one_reg_imm16,
1817    NULL, //&test_int_one_reg_imm16,
1818    NULL, //&test_int_special,
1819    NULL, //&test_int_ld_one_reg_imm16,
1820    NULL, //&test_int_ld_two_regs,
1821    NULL, //&test_int_st_two_regs_imm16,
1822    NULL, //&test_int_st_three_regs,
1823    &test_int_stq_two_regs_imm16,
1824    &test_int_ldq_two_regs_imm16,
1825    &test_int_stq_three_regs,
1826    &test_int_ldq_three_regs,
1827 };
1828 
1829 /* Used in do_tests, indexed by flags->nb_args
1830    Elements correspond to enum test_flags::num args
1831    Must have NULL for last entry.
1832  */
1833 static test_loop_t float_loops[] = {
1834    NULL,
1835    &test_float_two_args,
1836 };
1837 
1838 
1839 static test_t tests_fa_ops_two[] = {
1840     { &test_fmrgew          , "fmrgew", },
1841     { &test_fmrgow          , "fmrgow", },
1842     { NULL,                   NULL,           },
1843 };
1844 
1845 static test_table_t all_tests[] = {
1846    {
1847        tests_move_ops_spe,
1848        "PPC VSR special move insns",
1849        PPC_ALTIVECD | PPC_MOV | PPC_ONE_ARG,
1850    },
1851    {
1852        tests_aa_dbl_ops_two_args,
1853        "PPC altivec double word integer insns (arith, compare) with two args",
1854        PPC_ALTIVECD | PPC_ARITH | PPC_TWO_ARGS,
1855    },
1856    {
1857        tests_aa_word_ops_two_args_dres,
1858        "PPC altivec integer word instructions with two input args, double word result",
1859        PPC_ALTIVEC | PPC_ARITH_DRES | PPC_TWO_ARGS,
1860    },
1861    {
1862        tests_aa_dbl_to_int_two_args,
1863        "PPC altivec doubleword-to-integer instructions with two input args, saturated integer result",
1864        PPC_ALTIVECD | PPC_DOUBLE_IN_IRES | PPC_TWO_ARGS,
1865    },
1866    {
1867        tests_aa_word_ops_one_arg_dres,
1868        "PPC altivec integer word instructions with one input arg, double word result",
1869        PPC_ALTIVEC | PPC_ARITH_DRES | PPC_ONE_ARG,
1870    },
1871    {
1872       tests_istq_ops_two_i16,
1873       "PPC store quadword insns\n    with one register + one 16 bits immediate args with flags update",
1874       0x0001050c,
1875    },
1876    {
1877       tests_ildq_ops_two_i16,
1878       "PPC load quadword insns\n    with one register + one 16 bits immediate args with flags update",
1879       0x0001050d,
1880    },
1881    {
1882        tests_ldq_ops_three,
1883        "PPC load quadword insns\n    with three register args",
1884        0x0001050f,
1885    },
1886    {
1887        tests_stq_ops_three,
1888        "PPC store quadword insns\n    with three register args",
1889        0x0001050e,
1890    },
1891    {
1892        tests_fa_ops_two,
1893        "PPC floating point arith insns with two args",
1894        0x00020102,
1895    },
1896    {
1897        tests_aa_ops_three    ,
1898        "PPC altivec integer logical insns with three args",
1899        0x00060203,
1900    },
1901    {
1902        tests_aa_dbl_ops_one_arg,
1903        "PPC altivec one vector input arg, hex result",
1904        0x00060201,
1905    },
1906    {
1907        tests_aa_SHA_ops,
1908        "PPC altivec SSH insns",
1909        0x00040B01,
1910    },
1911    {
1912        tests_aa_bcd_ops,
1913        "PPC altivec BCD insns",
1914        0x00040B02,
1915    },
1916    {
1917        tests_aa_quadword_two_args,
1918        "PPC altivec quadword insns, two input args",
1919        0x00070102,
1920    },
1921    {
1922        tests_aa_quadword_three_args,
1923        "PPC altivec quadword insns, three input args",
1924        0x00070103
1925    },
1926    { NULL,                   NULL,               0x00000000, },
1927 };
1928 
do_tests(insn_sel_flags_t seln_flags,char * filter)1929 static void do_tests ( insn_sel_flags_t seln_flags,
1930                        char *filter)
1931 {
1932    test_loop_t *loop;
1933    test_t *tests;
1934    int nb_args, type, family;
1935    int i, j, n;
1936    int exact;
1937 
1938    exact = check_filter(filter);
1939    n = 0;
1940    for (i=0; all_tests[i].name != NULL; i++) {
1941       nb_args = all_tests[i].flags & PPC_NB_ARGS;
1942 
1943       /* Check number of arguments */
1944       if ((nb_args == 1 && !seln_flags.one_arg) ||
1945           (nb_args == 2 && !seln_flags.two_args) ||
1946           (nb_args == 3 && !seln_flags.three_args)){
1947          continue;
1948       }
1949       /* Check instruction type */
1950       type = all_tests[i].flags & PPC_TYPE;
1951       if ((type == PPC_ARITH   && !seln_flags.arith)   ||
1952           (type == PPC_LOGICAL && !seln_flags.logical) ||
1953           (type == PPC_COMPARE && !seln_flags.compare) ||
1954           (type == PPC_LDST && !seln_flags.ldst)       ||
1955           (type == PPC_MOV && !seln_flags.ldst)       ||
1956           (type == PPC_POPCNT && !seln_flags.arith)) {
1957          continue;
1958       }
1959 
1960       /* Check instruction family */
1961       family = all_tests[i].flags & PPC_FAMILY;
1962       if ((family == PPC_INTEGER  && !seln_flags.integer) ||
1963           (family == PPC_FLOAT    && !seln_flags.floats)  ||
1964           (family == PPC_ALTIVEC && !seln_flags.altivec)  ||
1965           (family == PPC_ALTIVECD && !seln_flags.altivec)  ||
1966           (family == PPC_ALTIVECQ && !seln_flags.altivec)  ||
1967           (family == PPC_FALTIVEC && !seln_flags.faltivec)) {
1968          continue;
1969       }
1970       /* Check flags update */
1971       if (((all_tests[i].flags & PPC_CR)  && seln_flags.cr == 0) ||
1972           (!(all_tests[i].flags & PPC_CR) && seln_flags.cr == 1))
1973          continue;
1974 
1975       /* All passed, do the tests */
1976       tests = all_tests[i].tests;
1977 
1978       loop = NULL;
1979 
1980       /* Select the test loop */
1981       switch (family) {
1982       case PPC_INTEGER:
1983          mem_resv = memalign16(2 * sizeof(HWord_t));  // want 128-bits
1984          loop = &int_loops[nb_args - 1];
1985          break;
1986 
1987       case PPC_FLOAT:
1988          loop = &float_loops[nb_args - 1];
1989          break;
1990 
1991       case PPC_ALTIVECQ:
1992          if (nb_args == 2)
1993             loop = &altivec_loops[ALTV_DINT];
1994          else if (nb_args == 3)
1995             loop = &altivec_loops[ALTV_DINT_THREE_ARGS];
1996          break;
1997       case PPC_ALTIVECD:
1998          switch (type) {
1999          case PPC_MOV:
2000             loop = &altivec_loops[ALTV_MOV];
2001             break;
2002          case PPC_ARITH:
2003             loop = &altivec_loops[ALTV_DINT];
2004             break;
2005          case PPC_DOUBLE_IN_IRES:
2006             loop = &altivec_loops[ALTV_DINT_IRES];
2007             break;
2008          case PPC_LOGICAL:
2009             if (nb_args == 3)
2010                loop = &altivec_loops[ALTV_DINT_THREE_ARGS];
2011             else if (nb_args ==1)
2012                loop = &altivec_loops[ALTV_DINT_ONE_ARG];
2013             break;
2014          default:
2015             printf("No altivec test defined for type %x\n", type);
2016          }
2017          break;
2018 
2019       case PPC_FALTIVEC:
2020          printf("Currently there are no floating altivec tests in this testsuite.\n");
2021          break;
2022 
2023       case PPC_ALTIVEC:
2024          switch (type) {
2025          case PPC_ARITH_DRES:
2026          {
2027             switch (nb_args) {
2028             case 1:
2029                loop = &altivec_loops[ALTV_ONE_INT_DRES];
2030                break;
2031             case 2:
2032                loop = &altivec_loops[ALTV_INT_DRES];
2033                break;
2034             default:
2035                printf("No altivec test defined for number args %d\n", nb_args);
2036             }
2037             break;
2038          }
2039          case PPC_SHA_OR_BCD:
2040             if (nb_args == 1)
2041                loop = &altivec_loops[ALTV_SHA];
2042             else
2043                loop = &altivec_loops[ATLV_BCD];
2044             break;
2045          default:
2046             printf("No altivec test defined for type %x\n", type);
2047          }
2048          break;
2049 
2050       default:
2051          printf("ERROR: unknown insn family %08x\n", family);
2052          continue;
2053       }
2054       if (1 || verbose > 0)
2055       for (j=0; tests[j].name != NULL; j++) {
2056          if (check_name(tests[j].name, filter, exact)) {
2057             if (verbose > 1)
2058                printf("Test instruction %s\n", tests[j].name);
2059             if (loop != NULL)
2060                (*loop)(tests[j].name, tests[j].func, all_tests[i].flags);
2061             printf("\n");
2062             n++;
2063          }
2064         }
2065       if (verbose) printf("\n");
2066    }
2067    printf("All done. Tested %d different instructions\n", n);
2068 }
2069 
2070 
usage(void)2071 static void usage (void)
2072 {
2073    fprintf(stderr,
2074            "Usage: jm-insns [OPTION]\n"
2075            "\t-i: test integer instructions (default)\n"
2076            "\t-f: test floating point instructions\n"
2077            "\t-a: test altivec instructions\n"
2078            "\t-A: test all (int, fp, altivec) instructions\n"
2079            "\t-v: be verbose\n"
2080            "\t-h: display this help and exit\n"
2081            );
2082 }
2083 
2084 #endif
2085 
main(int argc,char ** argv)2086 int main (int argc, char **argv)
2087 {
2088 #ifdef HAS_ISA_2_07
2089    /* Simple usage:
2090       ./jm-insns -i   => int insns
2091       ./jm-insns -f   => fp  insns
2092       ./jm-insns -a   => av  insns
2093       ./jm-insns -A   => int, fp and avinsns
2094    */
2095    char *filter = NULL;
2096    insn_sel_flags_t flags;
2097    int c;
2098 
2099    // Args
2100    flags.one_arg    = 1;
2101    flags.two_args   = 1;
2102    flags.three_args = 1;
2103    // Type
2104    flags.arith      = 1;
2105    flags.logical    = 1;
2106    flags.compare    = 1;
2107    flags.ldst       = 1;
2108    // Family
2109    flags.integer    = 0;
2110    flags.floats     = 0;
2111    flags.altivec    = 0;
2112    flags.faltivec   = 0;
2113    // Flags
2114    flags.cr         = 2;
2115 
2116    while ((c = getopt(argc, argv, "ifahvA")) != -1) {
2117       switch (c) {
2118       case 'i':
2119          flags.integer  = 1;
2120          break;
2121       case 'f':
2122          build_fargs_table();
2123          flags.floats   = 1;
2124          break;
2125       case 'a':
2126          flags.altivec  = 1;
2127          flags.faltivec = 1;
2128          break;
2129       case 'A':
2130          flags.integer  = 1;
2131          flags.floats   = 1;
2132          flags.altivec  = 1;
2133          flags.faltivec = 1;
2134          break;
2135       case 'h':
2136          usage();
2137          return 0;
2138       case 'v':
2139          verbose++;
2140          break;
2141       default:
2142          usage();
2143          fprintf(stderr, "Unknown argument: '%c'\n", c);
2144          return 1;
2145       }
2146    }
2147 
2148    arg_list_size = 0;
2149 
2150    build_vargs_table();
2151    if (verbose > 1) {
2152       printf("\nInstruction Selection:\n");
2153       printf("  n_args: \n");
2154       printf("    one_arg    = %d\n", flags.one_arg);
2155       printf("    two_args   = %d\n", flags.two_args);
2156       printf("    three_args = %d\n", flags.three_args);
2157       printf("  type: \n");
2158       printf("    arith      = %d\n", flags.arith);
2159       printf("    logical    = %d\n", flags.logical);
2160       printf("    compare    = %d\n", flags.compare);
2161       printf("    ldst       = %d\n", flags.ldst);
2162       printf("  family: \n");
2163       printf("    integer    = %d\n", flags.integer);
2164       printf("    floats     = %d\n", flags.floats);
2165       printf("    altivec    = %d\n", flags.altivec);
2166       printf("    faltivec   = %d\n", flags.faltivec);
2167       printf("  cr update: \n");
2168       printf("    cr         = %d\n", flags.cr);
2169       printf("\n");
2170    }
2171 
2172    do_tests( flags, filter );
2173 #else
2174    printf("NO ISA 2.07 SUPPORT\n");
2175 #endif
2176    return 0;
2177 }
2178