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