• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
406 
test_mtfprwa(void)407 static void test_mtfprwa (void)
408 {
409    __asm__ __volatile__ ("mtfprwa %x0,%1" : "=ws" (vec_out) : "r" (r14));
410 };
411 
412 static test_t tests_move_ops_spe[] = {
413   { &test_mfvsrd          , "mfvsrd" },
414   { &test_mfvsrwz         , "mfvsrwz" },
415   { &test_mtvsrd          , "mtvsrd" },
416   { &test_mtvsrwz         , "mtvsrwz" },
417   { &test_mtfprwa         , "mtfprwa" },
418   { NULL,                   NULL }
419 };
420 
421 /* NOTE: Since these are "vector" instructions versus VSX, we must use
422  * vector constraints.
423  *
424  * Vector Double Word tests.
425  */
test_vpkudum(void)426 static void test_vpkudum (void)
427 {
428    __asm__ __volatile__ ("vpkudum %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
429 }
430 
test_vaddudm(void)431 static void test_vaddudm (void)
432 {
433    __asm__ __volatile__ ("vaddudm %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
434 }
435 
test_vsubudm(void)436 static void test_vsubudm (void)
437 {
438    __asm__ __volatile__ ("vsubudm %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
439 }
440 
test_vmaxud(void)441 static void test_vmaxud (void)
442 {
443    __asm__ __volatile__ ("vmaxud %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
444 }
445 
test_vmaxsd(void)446 static void test_vmaxsd (void)
447 {
448    __asm__ __volatile__ ("vmaxsd %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
449 }
450 
test_vminud(void)451 static void test_vminud (void)
452 {
453    __asm__ __volatile__ ("vminud %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
454 }
455 
test_vminsd(void)456 static void test_vminsd (void)
457 {
458    __asm__ __volatile__ ("vminsd %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
459 }
460 
test_vcmpequd(void)461 static void test_vcmpequd (void)
462 {
463    __asm__ __volatile__ ("vcmpequd %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
464 }
465 
test_vcmpgtud(void)466 static void test_vcmpgtud (void)
467 {
468    __asm__ __volatile__ ("vcmpgtud %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
469 }
470 
test_vcmpgtsd(void)471 static void test_vcmpgtsd (void)
472 {
473    __asm__ __volatile__ ("vcmpgtsd %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
474 }
475 
test_vrld(void)476 static void test_vrld (void)
477 {
478    __asm__ __volatile__ ("vrld %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
479 }
480 
test_vsld(void)481 static void test_vsld (void)
482 {
483    __asm__ __volatile__ ("vsld %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
484 }
485 
test_vsrad(void)486 static void test_vsrad (void)
487 {
488    __asm__ __volatile__ ("vsrad %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
489 }
490 
test_vsrd(void)491 static void test_vsrd (void)
492 {
493    __asm__ __volatile__ ("vsrd %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
494 }
495 
496 /* Vector Double Word saturate tests.*/
497 
test_vpkudus(void)498 static void test_vpkudus (void)
499 {
500    __asm__ __volatile__ ("vpkudus %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
501 }
502 
test_vpksdus(void)503 static void test_vpksdus (void)
504 {
505    __asm__ __volatile__ ("vpksdus %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
506 }
507 
test_vpksdss(void)508 static void test_vpksdss (void)
509 {
510    __asm__ __volatile__ ("vpksdss %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
511 }
512 
513 
514 /* Vector unpack two words from one vector arg */
test_vupkhsw(void)515 static void test_vupkhsw (void)
516 {
517     __asm__ __volatile__ ("vupkhsw %0, %1" : "=v" (vec_out): "v" (vec_inB_wd));
518 }
519 
test_vupklsw(void)520 static void test_vupklsw (void)
521 {
522     __asm__ __volatile__ ("vupklsw %0, %1" : "=v" (vec_out): "v" (vec_inB_wd));
523 }
524 
525 
526 /* Vector Integer Word tests.*/
test_vmulouw(void)527 static void test_vmulouw (void)
528 {
529   __asm__ __volatile__ ("vmulouw %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
530 }
531 
test_vmuluwm(void)532 static void test_vmuluwm (void)
533 {
534     __asm__ __volatile__ ("vmuluwm %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
535 }
536 
test_vmulosw(void)537 static void test_vmulosw (void)
538 {
539     __asm__ __volatile__ ("vmulosw %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
540 }
541 
test_vmuleuw(void)542 static void test_vmuleuw (void)
543 {
544     __asm__ __volatile__ ("vmuleuw %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
545 }
546 
test_vmulesw(void)547 static void test_vmulesw (void)
548 {
549     __asm__ __volatile__ ("vmulesw %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
550 }
551 
test_vmrgew(void)552 static void test_vmrgew (void)
553 {
554     __asm__ __volatile__ ("vmrgew %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
555 }
556 
test_vmrgow(void)557 static void test_vmrgow (void)
558 {
559     __asm__ __volatile__ ("vmrgow %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
560 }
561 
test_vpmsumb(void)562 static void test_vpmsumb (void)
563 {
564     __asm__ __volatile__ ("vpmsumb %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
565 }
566 
test_vpmsumh(void)567 static void test_vpmsumh (void)
568 {
569     __asm__ __volatile__ ("vpmsumh %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
570 }
571 
test_vpmsumw(void)572 static void test_vpmsumw (void)
573 {
574     __asm__ __volatile__ ("vpmsumw %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
575 }
576 
test_vpermxor(void)577 static void test_vpermxor (void)
578 {
579   __asm__ __volatile__ ("vpermxor %0, %1, %2, %3" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB),"v" (vec_inC));
580 }
581 
test_vpmsumd(void)582 static void test_vpmsumd (void)
583 {
584     __asm__ __volatile__ ("vpmsumd %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
585 }
586 
test_vnand(void)587 static void test_vnand (void)
588 {
589     __asm__ __volatile__ ("vnand %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
590 }
591 
test_vorc(void)592 static void test_vorc (void)
593 {
594     __asm__ __volatile__ ("vorc %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
595 }
596 
test_veqv(void)597 static void test_veqv (void)
598 {
599     __asm__ __volatile__ ("veqv %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
600 }
601 
test_vcipher(void)602 static void test_vcipher (void)
603 {
604     __asm__ __volatile__ ("vcipher %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
605 }
606 
test_vcipherlast(void)607 static void test_vcipherlast (void)
608 {
609     __asm__ __volatile__ ("vcipherlast %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
610 }
611 
test_vncipher(void)612 static void test_vncipher (void)
613 {
614     __asm__ __volatile__ ("vncipher %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
615 }
616 
test_vncipherlast(void)617 static void test_vncipherlast (void)
618 {
619     __asm__ __volatile__ ("vncipherlast %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
620 }
621 
test_vclzb(void)622 static void test_vclzb (void)
623 {
624     __asm__ __volatile__ ("vclzb %0, %1" : "=v" (vec_out): "v" (vec_inB));
625 }
626 
test_vclzw(void)627 static void test_vclzw (void)
628 {
629     __asm__ __volatile__ ("vclzw %0, %1" : "=v" (vec_out): "v" (vec_inB));
630 }
631 
test_vclzh(void)632 static void test_vclzh (void)
633 {
634     __asm__ __volatile__ ("vclzh %0, %1" : "=v" (vec_out): "v" (vec_inB));
635 }
636 
test_vclzd(void)637 static void test_vclzd (void)
638 {
639     __asm__ __volatile__ ("vclzd %0, %1" : "=v" (vec_out): "v" (vec_inB));
640 }
641 
test_vpopcntb(void)642 static void test_vpopcntb (void)
643 {
644     __asm__ __volatile__ ("vpopcntb %0, %1" : "=v" (vec_out): "v" (vec_inB));
645 }
646 
test_vpopcnth(void)647 static void test_vpopcnth (void)
648 {
649     __asm__ __volatile__ ("vpopcnth %0, %1" : "=v" (vec_out): "v" (vec_inB));
650 }
651 
test_vpopcntw(void)652 static void test_vpopcntw (void)
653 {
654     __asm__ __volatile__ ("vpopcntw %0, %1" : "=v" (vec_out): "v" (vec_inB));
655 }
656 
test_vpopcntd(void)657 static void test_vpopcntd (void)
658 {
659     __asm__ __volatile__ ("vpopcntd %0, %1" : "=v" (vec_out): "v" (vec_inB));
660 }
661 
test_vsbox(void)662 static void test_vsbox (void)
663 {
664     __asm__ __volatile__ ("vsbox %0, %1" : "=v" (vec_out): "v" (vec_inB));
665 }
666 
667 static int st_six;
test_vshasigmad(void)668 static void test_vshasigmad (void)
669 {
670    switch (st_six) {
671    case 0x00:
672       __asm__ __volatile__ ("vshasigmad %0, %1, 0, 0" : "=v" (vec_out): "v" (vec_inA));
673       break;
674    case 0x0f:
675       __asm__ __volatile__ ("vshasigmad %0, %1, 0, 15" : "=v" (vec_out): "v" (vec_inA));
676       break;
677    case 0x10:
678       __asm__ __volatile__ ("vshasigmad %0, %1, 1, 0" : "=v" (vec_out): "v" (vec_inA));
679       break;
680    case 0x1f:
681       __asm__ __volatile__ ("vshasigmad %0, %1, 1, 15" : "=v" (vec_out): "v" (vec_inA));
682       break;
683    }
684 }
685 
test_vshasigmaw(void)686 static void test_vshasigmaw (void)
687 {
688    switch (st_six) {
689    case 0x00:
690       __asm__ __volatile__ ("vshasigmaw %0, %1, 0, 0" : "=v" (vec_out): "v" (vec_inA));
691       break;
692    case 0x0f:
693       __asm__ __volatile__ ("vshasigmaw %0, %1, 0, 15" : "=v" (vec_out): "v" (vec_inA));
694       break;
695    case 0x10:
696       __asm__ __volatile__ ("vshasigmaw %0, %1, 1, 0" : "=v" (vec_out): "v" (vec_inA));
697       break;
698    case 0x1f:
699       __asm__ __volatile__ ("vshasigmaw %0, %1, 1, 15" : "=v" (vec_out): "v" (vec_inA));
700       break;
701    }
702 }
703 
704 static int PS_bit;
test_bcdadd(void)705 static void test_bcdadd (void)
706 {
707    if (PS_bit)
708       __asm__ __volatile__ ("bcdadd. %0, %1, %2, 1" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
709    else
710       __asm__ __volatile__ ("bcdadd. %0, %1, %2, 0" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
711 }
712 
test_bcdsub(void)713 static void test_bcdsub (void)
714 {
715    if (PS_bit)
716       __asm__ __volatile__ ("bcdsub. %0, %1, %2, 1" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
717    else
718       __asm__ __volatile__ ("bcdsub. %0, %1, %2, 0" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
719 }
720 
test_vaddcuq(void)721 static void test_vaddcuq (void)
722 {
723    __asm__ __volatile__ ("vaddcuq %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
724 }
725 
test_vadduqm(void)726 static void test_vadduqm (void)
727 {
728    __asm__ __volatile__ ("vadduqm %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
729 }
730 
test_vaddecuq(void)731 static void test_vaddecuq (void)
732 {
733   __asm__ __volatile__ ("vaddecuq %0, %1, %2, %3" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB),"v" (vec_inC));
734 }
735 
test_vaddeuqm(void)736 static void test_vaddeuqm (void)
737 {
738   __asm__ __volatile__ ("vaddeuqm %0, %1, %2, %3" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB),"v" (vec_inC));
739 }
740 
test_vsubcuq(void)741 static void test_vsubcuq (void)
742 {
743    __asm__ __volatile__ ("vsubcuq %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
744 }
745 
test_vsubuqm(void)746 static void test_vsubuqm (void)
747 {
748    __asm__ __volatile__ ("vsubuqm %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
749 }
750 
test_vsubecuq(void)751 static void test_vsubecuq (void)
752 {
753   __asm__ __volatile__ ("vsubecuq %0, %1, %2, %3" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB),"v" (vec_inC));
754 }
755 
test_vsubeuqm(void)756 static void test_vsubeuqm (void)
757 {
758   __asm__ __volatile__ ("vsubeuqm %0, %1, %2, %3" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB),"v" (vec_inC));
759 }
760 
test_vbpermq(void)761 static void test_vbpermq (void)
762 {
763    __asm__ __volatile__ ("vbpermq %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
764 }
765 
test_vgbbd(void)766 static void test_vgbbd (void)
767 {
768     __asm__ __volatile__ ("vgbbd %0, %1" : "=v" (vec_out): "v" (vec_inB));
769 }
770 
771 
772 static test_t tests_aa_quadword_two_args[] = {
773   { &test_vaddcuq       , "vaddcuq" },
774   { &test_vadduqm       , "vadduqm" },
775   { &test_vsubcuq       , "vsubcuq" },
776   { &test_vsubuqm       , "vsubuqm" },
777   { &test_vbpermq       , "vbpermq" },
778   { NULL                , NULL      },
779 };
780 
781 static test_t tests_aa_quadword_three_args[] = {
782   { &test_vaddecuq      , "vaddecuq" },
783   { &test_vaddeuqm      , "vaddeuqm" },
784   { &test_vsubecuq      , "vsubecuq" },
785   { &test_vsubeuqm      , "vsubeuqm" },
786   { NULL                , NULL      },
787 };
788 
789 static test_t tests_aa_bcd_ops[] = {
790   { &test_bcdadd        , "bcdadd." },
791   { &test_bcdsub        , "bcdsub." },
792   { NULL                , NULL      },
793 };
794 
795 static test_t tests_aa_SHA_ops[] = {
796   { &test_vshasigmad    , "vshasigmad" },
797   { &test_vshasigmaw    , "vshasigmaw" },
798   { NULL                , NULL         },
799 };
800 
801 static test_t tests_aa_ops_three[] = {
802   { &test_vpermxor        , "vpermxor" },
803   { NULL                  , NULL       },
804 };
805 
806 static test_t tests_aa_word_ops_one_arg_dres[] = {
807   { &test_vupkhsw         , "vupkhsw" },
808   { &test_vupklsw         , "vupklsw" },
809   { NULL                  , NULL      }
810 };
811 
812 static test_t tests_aa_word_ops_two_args_dres[] = {
813   { &test_vmulouw         , "vmulouw" },
814   { &test_vmuluwm         , "vmuluwm" },
815   { &test_vmulosw         , "vmulosw" },
816   { &test_vmuleuw         , "vmuleuw" },
817   { &test_vmulesw         , "vmulesw" },
818   { &test_vmrgew          , "vmrgew" },
819   { &test_vmrgow          , "vmrgow" },
820   { &test_vpmsumb         , "vpmsumb" },
821   { &test_vpmsumh         , "vpmsumh" },
822   { &test_vpmsumw         , "vpmsumw" },
823   { NULL                  , NULL      }
824 };
825 
826 static test_t tests_aa_dbl_ops_two_args[] = {
827   { &test_vaddudm         , "vaddudm", },
828   { &test_vsubudm         , "vsubudm", },
829   { &test_vmaxud          , "vmaxud", },
830   { &test_vmaxsd          , "vmaxsd", },
831   { &test_vminud          , "vminud", },
832   { &test_vminsd          , "vminsd", },
833   { &test_vcmpequd        , "vcmpequd", },
834   { &test_vcmpgtud        , "vcmpgtud", },
835   { &test_vcmpgtsd        , "vcmpgtsd", },
836   { &test_vrld            , "vrld", },
837   { &test_vsld            , "vsld", },
838   { &test_vsrad           , "vsrad", },
839   { &test_vsrd            , "vsrd", },
840   { &test_vpkudum         , "vpkudum", },
841   { &test_vpmsumd         , "vpmsumd", },
842   { &test_vnand           , "vnand", },
843   { &test_vorc            , "vorc", },
844   { &test_veqv            , "veqv", },
845   { &test_vcipher         , "vcipher" },
846   { &test_vcipherlast     , "vcipherlast" },
847   { &test_vncipher        , "vncipher" },
848   { &test_vncipherlast    , "vncipherlast" },
849   { NULL                  , NULL,      },
850 };
851 
852 static test_t tests_aa_dbl_ops_one_arg[] = {
853   { &test_vclzb           , "vclzb" },
854   { &test_vclzw           , "vclzw" },
855   { &test_vclzh           , "vclzh" },
856   { &test_vclzd           , "vclzd" },
857   { &test_vpopcntb        , "vpopcntb" },
858   { &test_vpopcnth        , "vpopcnth" },
859   { &test_vpopcntw        , "vpopcntw" },
860   { &test_vpopcntd        , "vpopcntd" },
861   { &test_vsbox           , "vsbox" },
862   { &test_vgbbd           , "vgbbd" },
863   { NULL                  , NULL,      }
864 };
865 
866 static test_t tests_aa_dbl_to_int_two_args[] = {
867   { &test_vpkudus         , "vpkudus", },
868   { &test_vpksdus         , "vpksdus", },
869   { &test_vpksdss         , "vpksdss", },
870   { NULL                  , NULL,      },
871 };
872 
873 static int verbose = 0;
874 static int arg_list_size = 0;
875 static unsigned long long * vdargs = NULL;
876 static unsigned long long * vdargs_x = NULL;
877 #define NB_VDARGS 4
878 
build_vdargs_table(void)879 static void build_vdargs_table (void)
880 {
881    // Each VSX register holds two doubleword integer values
882    vdargs = memalign16(NB_VDARGS * sizeof(unsigned long long));
883    vdargs[0] = 0x0102030405060708ULL;
884    vdargs[1] = 0x090A0B0C0E0D0E0FULL;
885    vdargs[2] = 0xF1F2F3F4F5F6F7F8ULL;
886    vdargs[3] = 0xF9FAFBFCFEFDFEFFULL;
887 
888    vdargs_x = memalign16(NB_VDARGS * sizeof(unsigned long long));
889    vdargs_x[0] = 0x000000007c118a2bULL;
890    vdargs_x[1] = 0x00000000f1112345ULL;
891    vdargs_x[2] = 0x01F2F3F4F5F6F7F8ULL;
892    vdargs_x[3] = 0xF9FAFBFCFEFDFEFFULL;
893 }
894 
895 static unsigned int * vwargs = NULL;
896 #define NB_VWARGS 8
897 
build_vwargs_table(void)898 static void build_vwargs_table (void)
899 {
900    // Each VSX register holds 4 integer word values
901    size_t i = 0;
902    vwargs = memalign(8, 8 * sizeof(int));
903    assert(vwargs);
904    assert(0 == ((8-1) & (unsigned long)vwargs));
905    vwargs[i++] = 0x01020304;
906    vwargs[i++] = 0x05060708;
907    vwargs[i++] = 0x090A0B0C;
908    vwargs[i++] = 0x0E0D0E0F;
909    vwargs[i++] = 0xF1F2F3F4;
910    vwargs[i++] = 0xF5F6F7F8;
911    vwargs[i++] = 0xF9FAFBFC;
912    vwargs[i++] = 0xFEFDFEFF;
913 }
914 
915 static unsigned long long vbcd_args[] __attribute__ ((aligned (16))) = {
916    0x8045090189321003ULL, // Negative BCD value
917    0x001122334556677dULL,
918    0x0000107600000001ULL, // Positive BCD value
919    0x319293945142031aULL,
920    0x0ULL,                // Valid BCD zero
921    0xaULL,
922    0x0ULL,                // Invalid BCD zero (no sign code)
923    0x0ULL
924 };
925 #define NUM_VBCD_VALS (sizeof vbcd_args/sizeof vbcd_args[0])
926 
build_vargs_table(void)927 static void build_vargs_table (void)
928 {
929    build_vdargs_table();
930    build_vwargs_table();
931 }
932 
933 static double *fargs = NULL;
934 static int nb_fargs = 0;
935 
register_farg(void * farg,int s,uint16_t _exp,uint64_t mant)936 static inline void register_farg (void *farg,
937                                   int s, uint16_t _exp, uint64_t mant)
938 {
939    uint64_t tmp;
940 
941    tmp = ((uint64_t)s << 63) | ((uint64_t)_exp << 52) | mant;
942    *(uint64_t *)farg = tmp;
943    AB_DPRINTF("%d %03x %013llx => %016llx %0e\n",
944               s, _exp, mant, *(uint64_t *)farg, *(double *)farg);
945 }
946 
build_fargs_table(void)947 static void build_fargs_table (void)
948 {
949    /* Double precision:
950     * Sign goes from zero to one               (1 bit)
951     * Exponent goes from 0 to ((1 << 12) - 1)  (11 bits)
952     * Mantissa goes from 1 to ((1 << 52) - 1)  (52 bits)
953     * + special values:
954     * +0.0      : 0 0x000 0x0000000000000 => 0x0000000000000000
955     * -0.0      : 1 0x000 0x0000000000000 => 0x8000000000000000
956     * +infinity : 0 0x7FF 0x0000000000000 => 0x7FF0000000000000
957     * -infinity : 1 0x7FF 0x0000000000000 => 0xFFF0000000000000
958     * +QNaN     : 0 0x7FF 0x8000000000000 => 0x7FF8000000000000
959     * -QNaN     : 1 0x7FF 0x8000000000000 => 0xFFF8000000000000
960     * +SNaN     : 0 0x7FF 0x7FFFFFFFFFFFF => 0x7FF7FFFFFFFFFFFF
961     * -SNaN     : 1 0x7FF 0x7FFFFFFFFFFFF => 0xFFF7FFFFFFFFFFFF
962     * (8 values)
963 
964     * Ref only:
965     * Single precision
966     * Sign:     1 bit
967     * Exponent: 8 bits
968     * Mantissa: 23 bits
969     * +0.0      : 0 0x00 0x000000 => 0x00000000
970     * -0.0      : 1 0x00 0x000000 => 0x80000000
971     * +infinity : 0 0xFF 0x000000 => 0x7F800000
972     * -infinity : 1 0xFF 0x000000 => 0xFF800000
973     * +QNaN     : 0 0xFF 0x400000 => 0x7FC00000
974     * -QNaN     : 1 0xFF 0x400000 => 0xFFC00000
975     * +SNaN     : 0 0xFF 0x3FFFFF => 0x7FBFFFFF
976     * -SNaN     : 1 0xFF 0x3FFFFF => 0xFFBFFFFF
977     */
978    uint64_t mant;
979    uint16_t _exp, e0, e1;
980    int s;
981    int i=0;
982 
983    /* Note: VEX isn't so hot with denormals, so don't bother
984       testing them: set _exp > 0
985    */
986 
987    if ( arg_list_size == 1 ) {   // Large
988       fargs = malloc(200 * sizeof(double));
989       for (s=0; s<2; s++) {
990          for (e0=0; e0<2; e0++) {
991             for (e1=0x001; ; e1 = ((e1 + 1) << 2) + 6) {
992                if (e1 >= 0x400)
993                   e1 = 0x3fe;
994                _exp = (e0 << 10) | e1;
995                for (mant = 0x0000000000001ULL; mant < (1ULL << 52);
996                     /* Add 'random' bits */
997                     mant = ((mant + 0x4A6) << 13) + 0x359) {
998                   register_farg(&fargs[i++], s, _exp, mant);
999                }
1000                if (e1 == 0x3fe)
1001                   break;
1002             }
1003          }
1004       }
1005    } else {                      // Default
1006       fargs = malloc(16 * sizeof(double));
1007       for (s=0; s<2; s++) {                                // x2
1008             for (e1=0x001; ; e1 = ((e1 + 1) << 13) + 7) {  // x2
1009                if (e1 >= 0x400)
1010                   e1 = 0x3fe;
1011                _exp = e1;
1012                for (mant = 0x0000000000001ULL; mant < (1ULL << 52);
1013                     /* Add 'random' bits */
1014                     mant = ((mant + 0x4A6) << 29) + 0x359) {  // x2
1015                   register_farg(&fargs[i++], s, _exp, mant);
1016                }
1017                if (e1 == 0x3fe)
1018                   break;
1019             }
1020       }
1021    }
1022 
1023    /* Special values */
1024    /* +0.0      : 0 0x000 0x0000000000000 */
1025    s = 0;
1026    _exp = 0x000;
1027    mant = 0x0000000000000ULL;
1028    register_farg(&fargs[i++], s, _exp, mant);
1029    /* -0.0      : 1 0x000 0x0000000000000 */
1030    s = 1;
1031    _exp = 0x000;
1032    mant = 0x0000000000000ULL;
1033    register_farg(&fargs[i++], s, _exp, mant);
1034    /* +infinity : 0 0x7FF 0x0000000000000  */
1035    s = 0;
1036    _exp = 0x7FF;
1037    mant = 0x0000000000000ULL;
1038    register_farg(&fargs[i++], s, _exp, mant);
1039    /* -infinity : 1 0x7FF 0x0000000000000 */
1040    s = 1;
1041    _exp = 0x7FF;
1042    mant = 0x0000000000000ULL;
1043    register_farg(&fargs[i++], s, _exp, mant);
1044    /* +QNaN     : 0 0x7FF 0x7FFFFFFFFFFFF */
1045    s = 0;
1046    _exp = 0x7FF;
1047    mant = 0x7FFFFFFFFFFFFULL;
1048    register_farg(&fargs[i++], s, _exp, mant);
1049    /* -QNaN     : 1 0x7FF 0x7FFFFFFFFFFFF */
1050    s = 1;
1051    _exp = 0x7FF;
1052    mant = 0x7FFFFFFFFFFFFULL;
1053    register_farg(&fargs[i++], s, _exp, mant);
1054    /* +SNaN     : 0 0x7FF 0x8000000000000 */
1055    s = 0;
1056    _exp = 0x7FF;
1057    mant = 0x8000000000000ULL;
1058    register_farg(&fargs[i++], s, _exp, mant);
1059    /* -SNaN     : 1 0x7FF 0x8000000000000 */
1060    s = 1;
1061    _exp = 0x7FF;
1062    mant = 0x8000000000000ULL;
1063    register_farg(&fargs[i++], s, _exp, mant);
1064    AB_DPRINTF("Registered %d fargs values\n", i);
1065 
1066    nb_fargs = i;
1067 }
1068 
1069 
1070 
check_filter(char * filter)1071 static int check_filter (char *filter)
1072 {
1073    char *c;
1074    int ret = 1;
1075 
1076    if (filter != NULL) {
1077       c = strchr(filter, '*');
1078       if (c != NULL) {
1079          *c = '\0';
1080          ret = 0;
1081       }
1082    }
1083    return ret;
1084 }
1085 
check_name(const char * name,const char * filter,int exact)1086 static int check_name (const char* name, const char *filter,
1087                        int exact)
1088 {
1089    int nlen, flen;
1090    int ret = 0;
1091 
1092    if (filter != NULL) {
1093       for (; isspace(*name); name++)
1094          continue;
1095       FDPRINTF("Check '%s' againt '%s' (%s match)\n",
1096                name, filter, exact ? "exact" : "starting");
1097       nlen = strlen(name);
1098       flen = strlen(filter);
1099       if (exact) {
1100          if (nlen == flen && memcmp(name, filter, flen) == 0)
1101             ret = 1;
1102       } else {
1103          if (flen <= nlen && memcmp(name, filter, flen) == 0)
1104             ret = 1;
1105       }
1106    } else {
1107       ret = 1;
1108    }
1109    return ret;
1110 }
1111 
1112 
1113 typedef struct insn_sel_flags_t_struct {
1114    int one_arg, two_args, three_args;
1115    int arith, logical, compare, ldst;
1116    int integer, floats, altivec, faltivec;
1117    int cr;
1118 } insn_sel_flags_t;
1119 
test_float_two_args(const char * name,test_func_t func,unused uint32_t test_flags)1120 static void test_float_two_args (const char* name, test_func_t func,
1121                                  unused uint32_t test_flags)
1122 {
1123    double res;
1124    Word_t u0, u1, ur;
1125    volatile uint32_t flags;
1126    int i, j;
1127 
1128    for (i=0; i<nb_fargs; i+=3) {
1129       for (j=0; j<nb_fargs; j+=5) {
1130          u0 = *(Word_t *)(&fargs[i]);
1131          u1 = *(Word_t *)(&fargs[j]);
1132          f14 = fargs[i];
1133          f15 = fargs[j];
1134 
1135          SET_FPSCR_ZERO;
1136          SET_CR_XER_ZERO;
1137          (*func)();
1138          GET_CR(flags);
1139          res = f17;
1140          ur = *(uint64_t *)(&res);
1141 
1142          printf("%s %016llx, %016llx => %016llx",
1143                 name, u0, u1, ur);
1144 #if defined TEST_FLOAT_FLAGS
1145          printf(" (%08x)", flags);
1146 #endif
1147          printf("\n");
1148       }
1149       if (verbose) printf("\n");
1150    }
1151 }
1152 
1153 
mfvs(const char * name,test_func_t func,unused uint32_t test_flags)1154 static void mfvs(const char* name, test_func_t func,
1155                  unused uint32_t test_flags)
1156 {
1157    /* This test is for move instructions where the input is a scalar register
1158     * and the destination is a vector register.
1159     */
1160    int i;
1161    volatile Word_t result;
1162    result = 0ULL;
1163 
1164    for (i=0; i < NB_VDARGS; i++) {
1165       r14 = ZERO;
1166       if (isLE)
1167          vec_inA = (vector unsigned long long){ 0ULL, vdargs[i] };
1168       else
1169          vec_inA = (vector unsigned long long){ vdargs[i], 0ULL };
1170 
1171       (*func)();
1172       result = r14;
1173       printf("%s: %016llx => %016llx\n", name, vdargs[i], result);
1174    }
1175 }
1176 
mtvs(const char * name,test_func_t func,unused uint32_t test_flags)1177 static void mtvs(const char* name, test_func_t func,
1178                  unused uint32_t test_flags)
1179 {
1180    /* This test is for move instructions where the input is a scalar register
1181     * and the destination is a vector register.
1182     */
1183    unsigned long long *dst;
1184    int i;
1185 
1186    for (i=0; i < NB_VDARGS; i++) {
1187       r14  = vdargs[i];
1188       vec_out = (vector unsigned long long){ 0ULL, 0ULL };
1189 
1190       (*func)();
1191       dst = (unsigned long long *) &vec_out;
1192       if (isLE)
1193          dst++;
1194       printf("%s: %016llx => %016llx\n", name, vdargs[i], *dst);
1195    }
1196 }
1197 
mtvs2s(const char * name,test_func_t func,unused uint32_t test_flags)1198 static void mtvs2s(const char* name, test_func_t func,
1199                  unused uint32_t test_flags)
1200 {
1201    /* This test is the mtvsrwa instruction.
1202     */
1203    unsigned long long *dst;
1204    int i;
1205 
1206    for (i=0; i < NB_VDARGS; i++) {
1207       // Only the lower half of the vdarg doubleword arg will be used as input by mtvsrwa
1208       unsigned int * src = (unsigned int *)&vdargs[i];
1209       if (!isLE)
1210          src++;
1211       r14  = vdargs[i];
1212       vec_out = (vector unsigned long long){ 0ULL, 0ULL };
1213 
1214       (*func)();
1215       // Only doubleword 0 is used in output
1216       dst = (unsigned long long *) &vec_out;
1217       if (isLE)
1218          dst++;
1219       printf("%s: %08x => %016llx\n", name, *src, *dst);
1220    }
1221 }
1222 
test_special(special_t * table,const char * name,test_func_t func,unused uint32_t test_flags)1223 static void test_special (special_t *table,
1224                           const char* name, test_func_t func,
1225                           unused uint32_t test_flags)
1226 {
1227    const char *tmp;
1228    int i;
1229 
1230    for (tmp = name; isspace(*tmp); tmp++)
1231       continue;
1232    for (i=0; table[i].name != NULL; i++) {
1233       if (strcmp(table[i].name, tmp) == 0) {
1234          (*table[i].test_cb)(name, func, test_flags);
1235          return;
1236       }
1237    }
1238    fprintf(stderr, "ERROR: no test found for op '%s'\n", name);
1239 }
1240 
1241 static special_t special_move_ops[] = {
1242    {
1243       "mfvsrd",  /* move from vector to scalar reg doubleword */
1244       &mfvs,
1245    },
1246    {
1247       "mtvsrd",  /* move from scalar to vector reg doubleword */
1248       &mtvs,
1249    },
1250    {
1251       "mtfprwa", /* (extended mnemonic for mtvsrwa) move from scalar to vector reg with two’s-complement */
1252       &mtvs2s,
1253    },
1254    {
1255       "mfvsrwz", /* move from vector to scalar reg word */
1256       &mfvs,
1257    },
1258    {
1259       "mtvsrwz", /* move from scalar to vector reg word */
1260       &mtvs2s,
1261    }
1262 };
1263 
test_move_special(const char * name,test_func_t func,uint32_t test_flags)1264 static void test_move_special(const char* name, test_func_t func,
1265                                 uint32_t test_flags)
1266 {
1267    test_special(special_move_ops, name, func, test_flags);
1268 }
1269 
1270 /* Vector Double Word tests */
1271 
test_av_dint_two_args(const char * name,test_func_t func,unused uint32_t test_flags)1272 static void test_av_dint_two_args (const char* name, test_func_t func,
1273                                    unused uint32_t test_flags)
1274 {
1275 
1276    unsigned long long * dst;
1277    unsigned int * dst_int;
1278    int i,j;
1279    int family = test_flags & PPC_FAMILY;
1280    int is_vpkudum, is_vpmsumd;
1281    if (strcmp(name, "vpkudum") == 0)
1282       is_vpkudum = 1;
1283    else
1284       is_vpkudum = 0;
1285 
1286    if (strcmp(name, "vpmsumd") == 0)
1287       is_vpmsumd = 1;
1288    else
1289       is_vpmsumd = 0;
1290 
1291    for (i = 0; i < NB_VDARGS; i+=2) {
1292       if (isLE && family == PPC_ALTIVECQ)
1293          vec_inA = (vector unsigned long long){ vdargs[i+1], vdargs[i] };
1294       else
1295          vec_inA = (vector unsigned long long){ vdargs[i], vdargs[i+1] };
1296       for (j = 0; j < NB_VDARGS; j+=2) {
1297          if (isLE && family == PPC_ALTIVECQ)
1298             vec_inB = (vector unsigned long long){ vdargs[j+1], vdargs[j] };
1299          else
1300             vec_inB = (vector unsigned long long){ vdargs[j], vdargs[j+1] };
1301          vec_out = (vector unsigned long long){ 0,0 };
1302 
1303          (*func)();
1304          dst_int = (unsigned int *)&vec_out;
1305          dst  = (unsigned long long*)&vec_out;
1306 
1307          printf("%s: ", name);
1308 
1309          if (is_vpkudum) {
1310             printf("Inputs: %08llx %08llx %08llx %08llx\n", vdargs[i] & 0x00000000ffffffffULL,
1311                    vdargs[i+1] & 0x00000000ffffffffULL, vdargs[j] & 0x00000000ffffffffULL,
1312                    vdargs[j+1] & 0x00000000ffffffffULL);
1313             if (isLE)
1314                printf("         Output: %08x %08x %08x %08x\n", dst_int[2], dst_int[3],
1315                       dst_int[0], dst_int[1]);
1316             else
1317                printf("         Output: %08x %08x %08x %08x\n", dst_int[0], dst_int[1],
1318                       dst_int[2], dst_int[3]);
1319          } else if (is_vpmsumd) {
1320             printf("%016llx @@ %016llx ", vdargs[i], vdargs[j]);
1321             if (isLE)
1322                printf(" ==> %016llx\n", dst[1]);
1323             else
1324                printf(" ==> %016llx\n", dst[0]);
1325             printf("\t%016llx @@ %016llx ", vdargs[i+1], vdargs[j+1]);
1326             if (isLE)
1327                printf(" ==> %016llx\n", dst[0]);
1328             else
1329                printf(" ==> %016llx\n", dst[1]);
1330          } else if (family == PPC_ALTIVECQ) {
1331             if (isLE)
1332                printf("%016llx%016llx @@ %016llx%016llx ==> %016llx%016llx\n",
1333                       vdargs[i], vdargs[i+1], vdargs[j], vdargs[j+1],
1334                       dst[1], dst[0]);
1335             else
1336                printf("%016llx%016llx @@ %016llx%016llx ==> %016llx%016llx\n",
1337                       vdargs[i], vdargs[i+1], vdargs[j], vdargs[j+1],
1338                       dst[0], dst[1]);
1339          } else {
1340             printf("%016llx @@ %016llx ", vdargs[i], vdargs[j]);
1341             printf(" ==> %016llx\n", dst[0]);
1342             printf("\t%016llx @@ %016llx ", vdargs[i+1], vdargs[j+1]);
1343             printf(" ==> %016llx\n", dst[1]);
1344          }
1345       }
1346    }
1347 }
1348 
test_av_dint_one_arg(const char * name,test_func_t func,unused uint32_t test_flags)1349 static void test_av_dint_one_arg (const char* name, test_func_t func,
1350                                   unused uint32_t test_flags)
1351 {
1352 
1353    unsigned long long * dst;
1354    int i;
1355 
1356    for (i = 0; i < NB_VDARGS; i+=2) {
1357       vec_inB = (vector unsigned long long){ vdargs[i], vdargs[i+1] };
1358       vec_out = (vector unsigned long long){ 0,0 };
1359 
1360       (*func)();
1361       dst  = (unsigned long long*)&vec_out;
1362 
1363       printf("%s: ", name);
1364       printf("%016llx @@ %016llx ", vdargs[i], vdargs[i + 1]);
1365       printf(" ==> %016llx%016llx\n", dst[0], dst[1]);
1366    }
1367 }
1368 
test_av_dint_one_arg_SHA(const char * name,test_func_t func,unused uint32_t test_flags)1369 static void test_av_dint_one_arg_SHA (const char* name, test_func_t func,
1370                                       unused uint32_t test_flags)
1371 {
1372    unsigned long long * dst;
1373    int i, st, six;
1374 
1375    for (i = 0; i < NB_VDARGS; i+=2) {
1376       vec_inA = (vector unsigned long long){ vdargs[i], vdargs[i+1] };
1377       vec_out = (vector unsigned long long){ 0,0 };
1378 
1379       for (st = 0; st < 2; st++) {
1380          for (six = 0; six < 16; six+=15) {
1381             st_six = (st << 4) | six;
1382             (*func)();
1383             dst  = (unsigned long long*)&vec_out;
1384 
1385             printf("%s: ", name);
1386             printf("%016llx @@ %016llx ", vdargs[i], vdargs[i + 1]);
1387             printf(" ==> %016llx || %016llx\n", dst[0], dst[1]);
1388          }
1389       }
1390    }
1391 }
1392 
test_av_bcd(const char * name,test_func_t func,unused uint32_t test_flags)1393 static void test_av_bcd (const char* name, test_func_t func,
1394                          unused uint32_t test_flags)
1395 {
1396    unsigned long long * dst;
1397    int i, j;
1398 
1399    for (i = 0; i < NUM_VBCD_VALS; i+=2) {
1400       if (isLE)
1401          vec_inA = (vector unsigned long long){ vbcd_args[i+1], vbcd_args[i] };
1402       else
1403          vec_inA = (vector unsigned long long){ vbcd_args[i], vbcd_args[i+1] };
1404       for (j = 0; j < NUM_VBCD_VALS; j+=2) {
1405          if (isLE)
1406             vec_inB = (vector unsigned long long){ vbcd_args[j+1], vbcd_args[j] };
1407          else
1408             vec_inB = (vector unsigned long long){ vbcd_args[j], vbcd_args[j+1] };
1409          vec_out = (vector unsigned long long){ 0, 0 };
1410 
1411          for (PS_bit = 0; PS_bit < 2; PS_bit++) {
1412             (*func)();
1413             dst  = (unsigned long long*)&vec_out;
1414             printf("%s: ", name);
1415             printf("%016llx || %016llx @@ %016llx || %016llx",
1416                    vbcd_args[i], vbcd_args[i + 1],
1417                    vbcd_args[j], vbcd_args[j + 1]);
1418             if (isLE)
1419                printf(" ==> %016llx || %016llx\n", dst[1], dst[0]);
1420             else
1421                printf(" ==> %016llx || %016llx\n", dst[0], dst[1]);
1422          }
1423       }
1424    }
1425 }
1426 
1427 /* 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)1428 static void test_av_dint_to_int_two_args (const char* name, test_func_t func,
1429                                           unused uint32_t test_flags)
1430 {
1431 
1432    unsigned int * dst_int;
1433    int i,j;
1434    for (i = 0; i < NB_VDARGS; i+=2) {
1435       vec_inA = (vector unsigned long long){ vdargs_x[i], vdargs_x[i+1] };
1436       for (j = 0; j < NB_VDARGS; j+=2) {
1437          vec_inB = (vector unsigned long long){ vdargs_x[j], vdargs_x[j+1] };
1438          vec_out = (vector unsigned long long){ 0,0 };
1439 
1440          (*func)();
1441          dst_int = (unsigned int *)&vec_out;
1442 
1443          printf("%s: ", name);
1444          printf("%016llx, %016llx @@ %016llx, %016llx ",
1445                 vdargs_x[i], vdargs_x[i+1],
1446                 vdargs_x[j], vdargs_x[j+1]);
1447          if (isLE)
1448             printf(" ==> %08x %08x %08x %08x\n", dst_int[2], dst_int[3],
1449                    dst_int[0], dst_int[1]);
1450          else
1451             printf(" ==> %08x %08x %08x %08x\n", dst_int[0], dst_int[1],
1452                    dst_int[2], dst_int[3]);
1453       }
1454    }
1455 }
1456 
1457 /* Vector Word tests; two integer args, with double word result */
1458 
test_av_wint_two_args_dres(const char * name,test_func_t func,unused uint32_t test_flags)1459 static void test_av_wint_two_args_dres (const char* name, test_func_t func,
1460                                         unused uint32_t test_flags)
1461 {
1462 
1463    unsigned long long * dst;
1464    int i,j;
1465 
1466    for (i = 0; i < NB_VWARGS; i+=4) {
1467       if (isLE)
1468          vec_inA_wd = (vector unsigned int){ vwargs[i+3], vwargs[i+2], vwargs[i+1], vwargs[i] };
1469       else
1470          vec_inA_wd = (vector unsigned int){ vwargs[i], vwargs[i+1], vwargs[i+2], vwargs[i+3] };
1471       for (j = 0; j < NB_VWARGS; j+=4) {
1472          if (isLE)
1473             vec_inB_wd = (vector unsigned int){ vwargs[j+3], vwargs[j+2], vwargs[j+1], vwargs[j] };
1474          else
1475             vec_inB_wd = (vector unsigned int){ vwargs[j], vwargs[j+1], vwargs[j+2], vwargs[j+3] };
1476          vec_out = (vector unsigned long long){ 0, 0 };
1477 
1478          (*func)();
1479          dst  = (unsigned long long *)&vec_out;
1480          printf("%s: ", name);
1481          if (isLE)
1482             printf("%08x %08x %08x %08x ==> %016llx %016llx\n",
1483                    vwargs[i], vwargs[i+1], vwargs[i+2], vwargs[i+3], dst[1], dst[0]);
1484          else
1485             printf("%08x %08x %08x %08x ==> %016llx %016llx\n",
1486                    vwargs[i], vwargs[i+1], vwargs[i+2], vwargs[i+3], dst[0], dst[1]);
1487       }
1488    }
1489 }
1490 
1491 /* Vector Word tests; one input arg, with double word result */
1492 
test_av_wint_one_arg_dres(const char * name,test_func_t func,unused uint32_t test_flags)1493 static void test_av_wint_one_arg_dres (const char* name, test_func_t func,
1494                                        unused uint32_t test_flags)
1495 {
1496    unsigned long long * dst;
1497    int i;
1498    for (i = 0; i < NB_VWARGS; i+=4) {
1499       if (isLE)
1500          vec_inB_wd = (vector unsigned int){ vwargs[i+3], vwargs[i+2], vwargs[i+1], vwargs[i] };
1501       else
1502          vec_inB_wd = (vector unsigned int){ vwargs[i], vwargs[i+1], vwargs[i+2], vwargs[i+3] };
1503       vec_out = (vector unsigned long long){ 0, 0 };
1504 
1505       (*func)();
1506       dst  = (unsigned long long *)&vec_out;
1507       printf("%s: ", name);
1508       if (isLE)
1509          printf("%08x %08x %08x %08x ==> %016llx %016llx\n",
1510                 vwargs[i], vwargs[i+1], vwargs[i+2], vwargs[i+3], dst[1], dst[0]);
1511       else
1512          printf("%08x %08x %08x %08x ==> %016llx %016llx\n",
1513                 vwargs[i], vwargs[i+1], vwargs[i+2], vwargs[i+3], dst[0], dst[1]);
1514    }
1515 }
1516 
1517 
test_int_stq_two_regs_imm16(const char * name,test_func_t func_IN,unused uint32_t test_flags)1518 static void test_int_stq_two_regs_imm16 (const char* name,
1519                                         test_func_t func_IN,
1520                                         unused uint32_t test_flags)
1521 {
1522    /* Store quad word from register pair */
1523    int offs, k;
1524    HWord_t base;
1525    Word_t *iargs_priv;
1526 
1527    // private iargs table to store to, note storing pair of regs
1528    iargs_priv = memalign16(2 * sizeof(Word_t));
1529 
1530    base = (HWord_t)&iargs_priv[0];
1531    for (k = 0; k < 2; k++)  // clear array
1532       iargs_priv[k] = 0;
1533 
1534    offs = 0;
1535 
1536    /* setup source register pair */
1537    r14 = (HWord_t) 0xABCDEF0123456789ULL;
1538    r15 = (HWord_t) 0x1133557722446688ULL;
1539 
1540    r16 = base;                 // store to r16 + offs
1541 
1542    (*func_IN)();
1543 
1544 #ifndef __powerpc64__
1545    printf("%s %08x,%08x, %2d => "
1546 #else
1547    printf("%s %016llx,%016llx, %3d => "
1548 #endif
1549             "%016llx,%016llx)\n",
1550             name, r14, r15, offs, iargs_priv[0], iargs_priv[1]);
1551 
1552    if (verbose) printf("\n");
1553    free(iargs_priv);
1554 }
1555 
1556 
test_int_stq_three_regs(const char * name,test_func_t func_IN,unused uint32_t test_flags)1557 static void test_int_stq_three_regs (const char* name,
1558                                      test_func_t func_IN,
1559                                      unused uint32_t test_flags)
1560 {
1561    /* Store quad word from register pair */
1562    volatile uint32_t flags, xer;
1563    int k;
1564    HWord_t base;
1565 
1566    base = (HWord_t)&mem_resv[0];
1567    for (k = 0; k < 2; k++)  // setup array for lqarx inst
1568       mem_resv[k] = k;
1569 
1570    /* setup source register pair for store */
1571    r14 = ZERO;
1572    r15 = ZERO;
1573    r16 = base;                 // store to r16 + r17
1574    r17 = ZERO;
1575 
1576    /* In order for the store to occur, the lqarx instruction must first
1577     * be used to load from the address thus creating a reservation at the
1578     * memory address.  The lqarx instruction is done in the test_stqcx(),
1579     * then registers 14, r15 are changed to the data to be stored in memory
1580     * by the stqcx instruction.
1581     */
1582    SET_CR_XER_ZERO;
1583    (*func_IN)();
1584    GET_CR_XER(flags,xer);
1585 #ifndef __powerpc64__
1586    printf("%s %08x,%08x, =>  "
1587 #else
1588    printf("%s %016llx,%016llx => "
1589 #endif
1590             "%016llx,%016llx; CR=%08x\n",
1591             name, r14, r15, mem_resv[0], mem_resv[1], flags);
1592 
1593    if (verbose) printf("\n");
1594 }
1595 
test_int_ldq_two_regs_imm16(const char * name,test_func_t func_IN,unused uint32_t test_flags)1596 static void test_int_ldq_two_regs_imm16 (const char* name,
1597                                         test_func_t func_IN,
1598                                         unused uint32_t test_flags)
1599 {
1600    /* load quad word from register pair */
1601    volatile uint32_t flags, xer;
1602    Word_t * mem_priv;
1603    HWord_t base;
1604 
1605    // private iargs table to store to, note storing pair of regs
1606    mem_priv = memalign16(2 * sizeof(Word_t));  // want 128-bits
1607 
1608    base = (HWord_t)&mem_priv[0];
1609 
1610    mem_priv[0] = 0xAACCEE0011335577ULL;
1611    mem_priv[1] = 0xABCDEF0123456789ULL;
1612 
1613    r14 = 0;
1614    r15 = 0;
1615    r16 = base;                 // fetch from r16 + offs
1616    SET_CR_XER_ZERO;
1617    (*func_IN)();
1618    GET_CR_XER(flags,xer);
1619 
1620 #ifndef __powerpc64__
1621    printf("%s (0x%016llx, 0x%016llx) =>  (reg_pair = %08x,%08x)\n",
1622 #else
1623    printf("%s (0x%016llx, 0x%016llx) =>  (reg_pair = 0x%016llx, 0x%016llx)\n",
1624 #endif
1625           name, mem_priv[0], mem_priv[1], r14, r15);
1626 
1627    if (verbose) printf("\n");
1628 
1629    free(mem_priv);
1630 }
1631 
test_int_ldq_three_regs(const char * name,test_func_t func_IN,unused uint32_t test_flags)1632 static void test_int_ldq_three_regs (const char* name,
1633                                      test_func_t func_IN,
1634                                      unused uint32_t test_flags)
1635 {
1636    /* load quad word from register pair */
1637    HWord_t base;
1638 
1639    base = (HWord_t)&mem_resv[0];
1640 
1641    mem_resv[0] = 0xAACCEE0011335577ULL;
1642    mem_resv[1] = 0xABCDEF0123456789ULL;
1643 
1644    r14 = 0;
1645    r15 = 0;
1646    r16 = base;                 // fetch from r16 + r17
1647    r17 = 0;
1648 
1649    (*func_IN)();
1650 
1651 #ifndef __powerpc64__
1652    printf("%s (0x%016llx, 0x%016llx) =>  (reg_pair = 0x%08x, 0x%08x)\n",
1653 #else
1654    printf("%s (0x%016llx, 0x%016llx) =>  (reg_pair = 0x%016llx, 0x%016llx)\n",
1655 #endif
1656           name, mem_resv[0], mem_resv[1], r14, r15);
1657    if (verbose) printf("\n");
1658 
1659 }
1660 
test_av_dint_three_args(const char * name,test_func_t func,unused uint32_t test_flags)1661 static void test_av_dint_three_args (const char* name, test_func_t func,
1662                                      unused uint32_t test_flags)
1663 {
1664 
1665    unsigned long long * dst;
1666    int i,j, k;
1667    int family = test_flags & PPC_FAMILY;
1668    unsigned long long cin_vals[] = {
1669                                     // First pair of ULLs have LSB=0, so cin is '0'.
1670                                     // Second pair of ULLs have LSB=1, so cin is '1'.
1671                                     0xf000000000000000ULL, 0xf000000000000000ULL,
1672                                     0xf000000000000000ULL, 0xf000000000000001ULL
1673    };
1674    for (i = 0; i < NB_VDARGS; i+=2) {
1675       if (isLE)
1676          vec_inA = (vector unsigned long long){ vdargs[i+1], vdargs[i] };
1677       else
1678          vec_inA = (vector unsigned long long){ vdargs[i], vdargs[i+1] };
1679       for (j = 0; j < NB_VDARGS; j+=2) {
1680          if (isLE)
1681             vec_inB = (vector unsigned long long){ vdargs[j+1], vdargs[j] };
1682          else
1683             vec_inB = (vector unsigned long long){ vdargs[j], vdargs[j+1] };
1684          for (k = 0; k < 4; k+=2) {
1685             if (family == PPC_ALTIVECQ) {
1686                if (isLE)
1687                   vec_inC = (vector unsigned long long){ cin_vals[k+1], cin_vals[k] };
1688                else
1689                   vec_inC = (vector unsigned long long){ cin_vals[k], cin_vals[k+1] };
1690             } else {
1691                if (isLE)
1692                   vec_inC = (vector unsigned long long){ vdargs[k+1], vdargs[k] };
1693                else
1694                   vec_inC = (vector unsigned long long){ vdargs[k], vdargs[k+1] };
1695             }
1696             vec_out = (vector unsigned long long){ 0,0 };
1697 
1698             (*func)();
1699             dst  = (unsigned long long*)&vec_out;
1700             printf("%s: ", name);
1701             if (family == PPC_ALTIVECQ) {
1702                if (isLE)
1703                   printf("%016llx%016llx @@ %016llx%016llx @@ %llx ==> %016llx%016llx\n",
1704                          vdargs[i], vdargs[i+1], vdargs[j], vdargs[j+1], cin_vals[k+1],
1705                          dst[1], dst[0]);
1706                else
1707                   printf("%016llx%016llx @@ %016llx%016llx @@ %llx ==> %016llx%016llx\n",
1708                          vdargs[i], vdargs[i+1], vdargs[j], vdargs[j+1], cin_vals[k+1],
1709                          dst[0], dst[1]);
1710             } else {
1711                printf("%016llx @@ %016llx @@ %016llx ", vdargs[i], vdargs[j], vdargs[k]);
1712                if (isLE)
1713                   printf(" ==> %016llx\n", dst[1]);
1714                else
1715                   printf(" ==> %016llx\n", dst[0]);
1716                printf("\t%016llx @@ %016llx @@ %016llx ", vdargs[i+1], vdargs[j+1], vdargs[k+1]);
1717                if (isLE)
1718                   printf(" ==> %016llx\n", dst[0]);
1719                else
1720                   printf(" ==> %016llx\n", dst[1]);
1721             }
1722          }
1723       }
1724    }
1725 }
1726 
1727 
1728 /* The ALTIVEC_LOOPS and altive_loops defined below are used in do_tests.
1729  * Add new values to the end; do not change order, since the altivec_loops
1730  * array is indexed using the enumerated values defined by ALTIVEC_LOOPS.
1731  */
1732 enum ALTIVEC_LOOPS {
1733    ALTV_MOV,
1734    ALTV_DINT,
1735    ALTV_INT_DRES,
1736    ALTV_DINT_IRES,
1737    ALTV_ONE_INT_DRES,
1738    ALTV_DINT_THREE_ARGS,
1739    ALTV_DINT_ONE_ARG,
1740    ALTV_SHA,
1741    ATLV_BCD
1742 };
1743 
1744 static test_loop_t altivec_loops[] = {
1745    &test_move_special,
1746    &test_av_dint_two_args,
1747    &test_av_wint_two_args_dres,
1748    &test_av_dint_to_int_two_args,
1749    &test_av_wint_one_arg_dres,
1750    &test_av_dint_three_args,
1751    &test_av_dint_one_arg,
1752    &test_av_dint_one_arg_SHA,
1753    &test_av_bcd,
1754    NULL
1755 };
1756 
1757 /* Used in do_tests, indexed by flags->nb_args
1758    Elements correspond to enum test_flags::num args
1759 */
1760 static test_loop_t int_loops[] = {
1761   /* The #defines for the family, number registers need the array
1762    * to be properly indexed.  This test is for the new ISA 2.0.7
1763    * instructions.  The infrastructure has been left for the momemnt
1764    */
1765    NULL, //&test_int_one_arg,
1766    NULL, //&test_int_two_args,
1767    NULL, //&test_int_three_args,
1768    NULL, //&test_int_two_args,
1769    NULL, //&test_int_one_reg_imm16,
1770    NULL, //&test_int_one_reg_imm16,
1771    NULL, //&test_int_special,
1772    NULL, //&test_int_ld_one_reg_imm16,
1773    NULL, //&test_int_ld_two_regs,
1774    NULL, //&test_int_st_two_regs_imm16,
1775    NULL, //&test_int_st_three_regs,
1776    &test_int_stq_two_regs_imm16,
1777    &test_int_ldq_two_regs_imm16,
1778    &test_int_stq_three_regs,
1779    &test_int_ldq_three_regs,
1780 };
1781 
1782 /* Used in do_tests, indexed by flags->nb_args
1783    Elements correspond to enum test_flags::num args
1784    Must have NULL for last entry.
1785  */
1786 static test_loop_t float_loops[] = {
1787    NULL,
1788    &test_float_two_args,
1789 };
1790 
1791 
1792 static test_t tests_fa_ops_two[] = {
1793     { &test_fmrgew          , "fmrgew", },
1794     { &test_fmrgow          , "fmrgow", },
1795     { NULL,                   NULL,           },
1796 };
1797 
1798 static test_table_t all_tests[] = {
1799    {
1800        tests_move_ops_spe,
1801        "PPC VSR special move insns",
1802        PPC_ALTIVECD | PPC_MOV | PPC_ONE_ARG,
1803    },
1804    {
1805        tests_aa_dbl_ops_two_args,
1806        "PPC altivec double word integer insns (arith, compare) with two args",
1807        PPC_ALTIVECD | PPC_ARITH | PPC_TWO_ARGS,
1808    },
1809    {
1810        tests_aa_word_ops_two_args_dres,
1811        "PPC altivec integer word instructions with two input args, double word result",
1812        PPC_ALTIVEC | PPC_ARITH_DRES | PPC_TWO_ARGS,
1813    },
1814    {
1815        tests_aa_dbl_to_int_two_args,
1816        "PPC altivec doubleword-to-integer instructions with two input args, saturated integer result",
1817        PPC_ALTIVECD | PPC_DOUBLE_IN_IRES | PPC_TWO_ARGS,
1818    },
1819    {
1820        tests_aa_word_ops_one_arg_dres,
1821        "PPC altivec integer word instructions with one input arg, double word result",
1822        PPC_ALTIVEC | PPC_ARITH_DRES | PPC_ONE_ARG,
1823    },
1824    {
1825       tests_istq_ops_two_i16,
1826       "PPC store quadword insns\n    with one register + one 16 bits immediate args with flags update",
1827       0x0001050c,
1828    },
1829    {
1830       tests_ildq_ops_two_i16,
1831       "PPC load quadword insns\n    with one register + one 16 bits immediate args with flags update",
1832       0x0001050d,
1833    },
1834    {
1835        tests_ldq_ops_three,
1836        "PPC load quadword insns\n    with three register args",
1837        0x0001050f,
1838    },
1839    {
1840        tests_stq_ops_three,
1841        "PPC store quadword insns\n    with three register args",
1842        0x0001050e,
1843    },
1844    {
1845        tests_fa_ops_two,
1846        "PPC floating point arith insns with two args",
1847        0x00020102,
1848    },
1849    {
1850        tests_aa_ops_three    ,
1851        "PPC altivec integer logical insns with three args",
1852        0x00060203,
1853    },
1854    {
1855        tests_aa_dbl_ops_one_arg,
1856        "PPC altivec one vector input arg, hex result",
1857        0x00060201,
1858    },
1859    {
1860        tests_aa_SHA_ops,
1861        "PPC altivec SSH insns",
1862        0x00040B01,
1863    },
1864    {
1865        tests_aa_bcd_ops,
1866        "PPC altivec BCD insns",
1867        0x00040B02,
1868    },
1869    {
1870        tests_aa_quadword_two_args,
1871        "PPC altivec quadword insns, two input args",
1872        0x00070102,
1873    },
1874    {
1875        tests_aa_quadword_three_args,
1876        "PPC altivec quadword insns, three input args",
1877        0x00070103
1878    },
1879    { NULL,                   NULL,               0x00000000, },
1880 };
1881 
do_tests(insn_sel_flags_t seln_flags,char * filter)1882 static void do_tests ( insn_sel_flags_t seln_flags,
1883                        char *filter)
1884 {
1885    test_loop_t *loop;
1886    test_t *tests;
1887    int nb_args, type, family;
1888    int i, j, n;
1889    int exact;
1890 
1891    exact = check_filter(filter);
1892    n = 0;
1893    for (i=0; all_tests[i].name != NULL; i++) {
1894       nb_args = all_tests[i].flags & PPC_NB_ARGS;
1895 
1896       /* Check number of arguments */
1897       if ((nb_args == 1 && !seln_flags.one_arg) ||
1898           (nb_args == 2 && !seln_flags.two_args) ||
1899           (nb_args == 3 && !seln_flags.three_args)){
1900          continue;
1901       }
1902       /* Check instruction type */
1903       type = all_tests[i].flags & PPC_TYPE;
1904       if ((type == PPC_ARITH   && !seln_flags.arith)   ||
1905           (type == PPC_LOGICAL && !seln_flags.logical) ||
1906           (type == PPC_COMPARE && !seln_flags.compare) ||
1907           (type == PPC_LDST && !seln_flags.ldst)       ||
1908           (type == PPC_MOV && !seln_flags.ldst)       ||
1909           (type == PPC_POPCNT && !seln_flags.arith)) {
1910          continue;
1911       }
1912 
1913       /* Check instruction family */
1914       family = all_tests[i].flags & PPC_FAMILY;
1915       if ((family == PPC_INTEGER  && !seln_flags.integer) ||
1916           (family == PPC_FLOAT    && !seln_flags.floats)  ||
1917           (family == PPC_ALTIVEC && !seln_flags.altivec)  ||
1918           (family == PPC_ALTIVECD && !seln_flags.altivec)  ||
1919           (family == PPC_ALTIVECQ && !seln_flags.altivec)  ||
1920           (family == PPC_FALTIVEC && !seln_flags.faltivec)) {
1921          continue;
1922       }
1923       /* Check flags update */
1924       if (((all_tests[i].flags & PPC_CR)  && seln_flags.cr == 0) ||
1925           (!(all_tests[i].flags & PPC_CR) && seln_flags.cr == 1))
1926          continue;
1927 
1928       /* All passed, do the tests */
1929       tests = all_tests[i].tests;
1930 
1931       loop = NULL;
1932 
1933       /* Select the test loop */
1934       switch (family) {
1935       case PPC_INTEGER:
1936          mem_resv = memalign16(2 * sizeof(HWord_t));  // want 128-bits
1937          loop = &int_loops[nb_args - 1];
1938          break;
1939 
1940       case PPC_FLOAT:
1941          loop = &float_loops[nb_args - 1];
1942          break;
1943 
1944       case PPC_ALTIVECQ:
1945          if (nb_args == 2)
1946             loop = &altivec_loops[ALTV_DINT];
1947          else if (nb_args == 3)
1948             loop = &altivec_loops[ALTV_DINT_THREE_ARGS];
1949          break;
1950       case PPC_ALTIVECD:
1951          switch (type) {
1952          case PPC_MOV:
1953             loop = &altivec_loops[ALTV_MOV];
1954             break;
1955          case PPC_ARITH:
1956             loop = &altivec_loops[ALTV_DINT];
1957             break;
1958          case PPC_DOUBLE_IN_IRES:
1959             loop = &altivec_loops[ALTV_DINT_IRES];
1960             break;
1961          case PPC_LOGICAL:
1962             if (nb_args == 3)
1963                loop = &altivec_loops[ALTV_DINT_THREE_ARGS];
1964             else if (nb_args ==1)
1965                loop = &altivec_loops[ALTV_DINT_ONE_ARG];
1966             break;
1967          default:
1968             printf("No altivec test defined for type %x\n", type);
1969          }
1970          break;
1971 
1972       case PPC_FALTIVEC:
1973          printf("Currently there are no floating altivec tests in this testsuite.\n");
1974          break;
1975 
1976       case PPC_ALTIVEC:
1977          switch (type) {
1978          case PPC_ARITH_DRES:
1979          {
1980             switch (nb_args) {
1981             case 1:
1982                loop = &altivec_loops[ALTV_ONE_INT_DRES];
1983                break;
1984             case 2:
1985                loop = &altivec_loops[ALTV_INT_DRES];
1986                break;
1987             default:
1988                printf("No altivec test defined for number args %d\n", nb_args);
1989             }
1990             break;
1991          }
1992          case PPC_SHA_OR_BCD:
1993             if (nb_args == 1)
1994                loop = &altivec_loops[ALTV_SHA];
1995             else
1996                loop = &altivec_loops[ATLV_BCD];
1997             break;
1998          default:
1999             printf("No altivec test defined for type %x\n", type);
2000          }
2001          break;
2002 
2003       default:
2004          printf("ERROR: unknown insn family %08x\n", family);
2005          continue;
2006       }
2007       if (1 || verbose > 0)
2008       for (j=0; tests[j].name != NULL; j++) {
2009          if (check_name(tests[j].name, filter, exact)) {
2010             if (verbose > 1)
2011                printf("Test instruction %s\n", tests[j].name);
2012             if (loop != NULL)
2013                (*loop)(tests[j].name, tests[j].func, all_tests[i].flags);
2014             printf("\n");
2015             n++;
2016          }
2017         }
2018       if (verbose) printf("\n");
2019    }
2020    printf("All done. Tested %d different instructions\n", n);
2021 }
2022 
2023 
usage(void)2024 static void usage (void)
2025 {
2026    fprintf(stderr,
2027            "Usage: jm-insns [OPTION]\n"
2028            "\t-i: test integer instructions (default)\n"
2029            "\t-f: test floating point instructions\n"
2030            "\t-a: test altivec instructions\n"
2031            "\t-A: test all (int, fp, altivec) instructions\n"
2032            "\t-v: be verbose\n"
2033            "\t-h: display this help and exit\n"
2034            );
2035 }
2036 
2037 #endif
2038 
main(int argc,char ** argv)2039 int main (int argc, char **argv)
2040 {
2041 #ifdef HAS_ISA_2_07
2042    /* Simple usage:
2043       ./jm-insns -i   => int insns
2044       ./jm-insns -f   => fp  insns
2045       ./jm-insns -a   => av  insns
2046       ./jm-insns -A   => int, fp and avinsns
2047    */
2048    char *filter = NULL;
2049    insn_sel_flags_t flags;
2050    int c;
2051 
2052    // Args
2053    flags.one_arg    = 1;
2054    flags.two_args   = 1;
2055    flags.three_args = 1;
2056    // Type
2057    flags.arith      = 1;
2058    flags.logical    = 1;
2059    flags.compare    = 1;
2060    flags.ldst       = 1;
2061    // Family
2062    flags.integer    = 0;
2063    flags.floats     = 0;
2064    flags.altivec    = 0;
2065    flags.faltivec   = 0;
2066    // Flags
2067    flags.cr         = 2;
2068 
2069    while ((c = getopt(argc, argv, "ifahvA")) != -1) {
2070       switch (c) {
2071       case 'i':
2072          flags.integer  = 1;
2073          break;
2074       case 'f':
2075          build_fargs_table();
2076          flags.floats   = 1;
2077          break;
2078       case 'a':
2079          flags.altivec  = 1;
2080          flags.faltivec = 1;
2081          break;
2082       case 'A':
2083          flags.integer  = 1;
2084          flags.floats   = 1;
2085          flags.altivec  = 1;
2086          flags.faltivec = 1;
2087          break;
2088       case 'h':
2089          usage();
2090          return 0;
2091       case 'v':
2092          verbose++;
2093          break;
2094       default:
2095          usage();
2096          fprintf(stderr, "Unknown argument: '%c'\n", c);
2097          return 1;
2098       }
2099    }
2100 
2101    arg_list_size = 0;
2102 
2103    build_vargs_table();
2104    if (verbose > 1) {
2105       printf("\nInstruction Selection:\n");
2106       printf("  n_args: \n");
2107       printf("    one_arg    = %d\n", flags.one_arg);
2108       printf("    two_args   = %d\n", flags.two_args);
2109       printf("    three_args = %d\n", flags.three_args);
2110       printf("  type: \n");
2111       printf("    arith      = %d\n", flags.arith);
2112       printf("    logical    = %d\n", flags.logical);
2113       printf("    compare    = %d\n", flags.compare);
2114       printf("    ldst       = %d\n", flags.ldst);
2115       printf("  family: \n");
2116       printf("    integer    = %d\n", flags.integer);
2117       printf("    floats     = %d\n", flags.floats);
2118       printf("    altivec    = %d\n", flags.altivec);
2119       printf("    faltivec   = %d\n", flags.faltivec);
2120       printf("  cr update: \n");
2121       printf("    cr         = %d\n", flags.cr);
2122       printf("\n");
2123    }
2124 
2125    do_tests( flags, filter );
2126 #else
2127    printf("NO ISA 2.07 SUPPORT\n");
2128 #endif
2129    return 0;
2130 }
2131