test_isa_2_07_part1.c revision 436e89c602e787e7a27dd6624b09beed41a0da8a
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__
131typedef uint32_t  HWord_t;
132#define ZERO 0
133#else
134typedef uint64_t  HWord_t;
135#define ZERO 0ULL
136#endif /* __powerpc64__ */
137
138typedef uint64_t Word_t;
139
140enum {
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
178static vector unsigned long long vec_out, vec_inA, vec_inB, vec_inC;
179static vector unsigned int vec_inA_wd, vec_inB_wd;
180
181/* XXXX these must all be callee-save regs! */
182register double f14 __asm__ ("fr14");
183register double f15 __asm__ ("fr15");
184register double f16 __asm__ ("fr16");
185register double f17 __asm__ ("fr17");
186register HWord_t r14 __asm__ ("r14");
187register HWord_t r15 __asm__ ("r15");
188register HWord_t r16 __asm__ ("r16");
189register HWord_t r17 __asm__ ("r17");
190
191typedef void (*test_func_t) (void);
192typedef struct _test test_t;
193typedef struct _test_table test_table_t;
194struct _test {
195    test_func_t func;
196    const char *name;
197};
198
199struct _test_table {
200    test_t *tests;
201    const char *name;
202    uint32_t flags;
203};
204
205typedef void (*test_loop_t) (const char *name, test_func_t func,
206                             uint32_t flags);
207
208enum 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
272typedef 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
278static void test_stq(void)
279{
280  __asm__ __volatile__ ("stq  %0, 0(%1)" : :"r" (r14), "r" (r16));
281}
282
283static test_t tests_istq_ops_two_i16[] = {
284    { &test_stq             , "stq", },
285    { NULL,                   NULL,           },
286};
287
288static void test_lq(void)
289{
290  __asm__ __volatile__ ("lq  %0, 0(%1)" : :"r" (r14), "r" (r16));
291}
292
293static test_t tests_ildq_ops_two_i16[] = {
294    { &test_lq              , "lq", },
295    { NULL,                   NULL,          },
296};
297
298
299Word_t * mem_resv;
300static 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
311static test_t tests_stq_ops_three[] = {
312    { &test_stqcx           , "stqcx.", },
313    { NULL,                   NULL,           },
314};
315
316static void test_lqarx(void)
317{
318  __asm__ __volatile__ ("lqarx  %0, %1, %2, 0" : :"r" (r14), "r" (r16),"r" (r17));
319}
320
321static test_t tests_ldq_ops_three[] = {
322    { &test_lqarx           , "lqarx", },
323    { NULL,                   NULL,           },
324};
325
326static void test_fmrgew (void)
327{
328    __asm__ __volatile__ ("fmrgew        17,14,15");
329};
330
331static void test_fmrgow (void)
332{
333    __asm__ __volatile__ ("fmrgow        17,14,15");
334};
335
336
337
338// VSX move instructions
339static void test_mfvsrd (void)
340{
341   __asm__ __volatile__ ("mfvsrd %0,%x1" : "=r" (r14) : "ws" (vec_inA));
342};
343
344static void test_mfvsrwz (void)
345{
346   __asm__ __volatile__ ("mfvsrwz %0,%x1" : "=r" (r14) : "ws" (vec_inA));
347};
348
349static void test_mtvsrd (void)
350{
351   __asm__ __volatile__ ("mtvsrd %x0,%1" : "=ws" (vec_out) : "r" (r14));
352};
353
354static void test_mtvsrwz (void)
355{
356   __asm__ __volatile__ ("mtvsrwz %x0,%1" : "=ws" (vec_out) : "r" (r14));
357};
358
359
360static void test_mtfprwa (void)
361{
362   __asm__ __volatile__ ("mtfprwa %x0,%1" : "=ws" (vec_out) : "r" (r14));
363};
364
365static 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 */
379static void test_vpkudum (void)
380{
381   __asm__ __volatile__ ("vpkudum %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
382}
383
384static void test_vaddudm (void)
385{
386   __asm__ __volatile__ ("vaddudm %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
387}
388
389static void test_vsubudm (void)
390{
391   __asm__ __volatile__ ("vsubudm %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
392}
393
394static void test_vmaxud (void)
395{
396   __asm__ __volatile__ ("vmaxud %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
397}
398
399static void test_vmaxsd (void)
400{
401   __asm__ __volatile__ ("vmaxsd %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
402}
403
404static void test_vminud (void)
405{
406   __asm__ __volatile__ ("vminud %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
407}
408
409static void test_vminsd (void)
410{
411   __asm__ __volatile__ ("vminsd %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
412}
413
414static void test_vcmpequd (void)
415{
416   __asm__ __volatile__ ("vcmpequd %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
417}
418
419static void test_vcmpgtud (void)
420{
421   __asm__ __volatile__ ("vcmpgtud %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
422}
423
424static void test_vcmpgtsd (void)
425{
426   __asm__ __volatile__ ("vcmpgtsd %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
427}
428
429static void test_vrld (void)
430{
431   __asm__ __volatile__ ("vrld %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
432}
433
434static void test_vsld (void)
435{
436   __asm__ __volatile__ ("vsld %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
437}
438
439static void test_vsrad (void)
440{
441   __asm__ __volatile__ ("vsrad %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
442}
443
444static 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
451static void test_vpkudus (void)
452{
453   __asm__ __volatile__ ("vpkudus %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
454}
455
456static void test_vpksdus (void)
457{
458   __asm__ __volatile__ ("vpksdus %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
459}
460
461static 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 */
468static void test_vupkhsw (void)
469{
470    __asm__ __volatile__ ("vupkhsw %0, %1" : "=v" (vec_out): "v" (vec_inB_wd));
471}
472
473static 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.*/
480static 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
485static 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
490static 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
495static 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
500static 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
505static 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
510static 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
515static 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
520static 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
525static 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
530static 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
535static void test_vpmsumd (void)
536{
537    __asm__ __volatile__ ("vpmsumd %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
538}
539
540static void test_vnand (void)
541{
542    __asm__ __volatile__ ("vnand %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
543}
544
545static void test_vorc (void)
546{
547    __asm__ __volatile__ ("vorc %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
548}
549
550static void test_veqv (void)
551{
552    __asm__ __volatile__ ("veqv %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
553}
554
555static void test_vcipher (void)
556{
557    __asm__ __volatile__ ("vcipher %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
558}
559
560static void test_vcipherlast (void)
561{
562    __asm__ __volatile__ ("vcipherlast %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
563}
564
565static void test_vncipher (void)
566{
567    __asm__ __volatile__ ("vncipher %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
568}
569
570static void test_vncipherlast (void)
571{
572    __asm__ __volatile__ ("vncipherlast %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
573}
574
575static void test_vclzb (void)
576{
577    __asm__ __volatile__ ("vclzb %0, %1" : "=v" (vec_out): "v" (vec_inB));
578}
579
580static void test_vclzw (void)
581{
582    __asm__ __volatile__ ("vclzw %0, %1" : "=v" (vec_out): "v" (vec_inB));
583}
584
585static void test_vclzh (void)
586{
587    __asm__ __volatile__ ("vclzh %0, %1" : "=v" (vec_out): "v" (vec_inB));
588}
589
590static void test_vclzd (void)
591{
592    __asm__ __volatile__ ("vclzd %0, %1" : "=v" (vec_out): "v" (vec_inB));
593}
594
595static void test_vpopcntb (void)
596{
597    __asm__ __volatile__ ("vpopcntb %0, %1" : "=v" (vec_out): "v" (vec_inB));
598}
599
600static void test_vpopcnth (void)
601{
602    __asm__ __volatile__ ("vpopcnth %0, %1" : "=v" (vec_out): "v" (vec_inB));
603}
604
605static void test_vpopcntw (void)
606{
607    __asm__ __volatile__ ("vpopcntw %0, %1" : "=v" (vec_out): "v" (vec_inB));
608}
609
610static void test_vpopcntd (void)
611{
612    __asm__ __volatile__ ("vpopcntd %0, %1" : "=v" (vec_out): "v" (vec_inB));
613}
614
615static void test_vsbox (void)
616{
617    __asm__ __volatile__ ("vsbox %0, %1" : "=v" (vec_out): "v" (vec_inB));
618}
619
620static int st_six;
621static 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
639static 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
657static int PS_bit;
658static 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
666static 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
674static void test_vaddcuq (void)
675{
676   __asm__ __volatile__ ("vaddcuq %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
677}
678
679static void test_vadduqm (void)
680{
681   __asm__ __volatile__ ("vadduqm %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
682}
683
684static 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
689static 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
694static void test_vsubcuq (void)
695{
696   __asm__ __volatile__ ("vsubcuq %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
697}
698
699static void test_vsubuqm (void)
700{
701   __asm__ __volatile__ ("vsubuqm %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
702}
703
704static 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
709static 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
714static void test_vbpermq (void)
715{
716   __asm__ __volatile__ ("vbpermq %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
717}
718
719static void test_vgbbd (void)
720{
721    __asm__ __volatile__ ("vgbbd %0, %1" : "=v" (vec_out): "v" (vec_inB));
722}
723
724
725static 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
734static 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
742static test_t tests_aa_bcd_ops[] = {
743  { &test_bcdadd        , "bcdadd." },
744  { &test_bcdsub        , "bcdsub." },
745  { NULL                , NULL      },
746};
747
748static test_t tests_aa_SHA_ops[] = {
749  { &test_vshasigmad    , "vshasigmad" },
750  { &test_vshasigmaw    , "vshasigmaw" },
751  { NULL                , NULL         },
752};
753
754static test_t tests_aa_ops_three[] = {
755  { &test_vpermxor        , "vpermxor" },
756  { NULL                  , NULL       },
757};
758
759static test_t tests_aa_word_ops_one_arg_dres[] = {
760  { &test_vupkhsw         , "vupkhsw" },
761  { &test_vupklsw         , "vupklsw" },
762  { NULL                  , NULL      }
763};
764
765static 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
779static 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
805static 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
819static 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
826static int verbose = 0;
827static int arg_list_size = 0;
828static unsigned long long * vdargs = NULL;
829static unsigned long long * vdargs_x = NULL;
830#define NB_VDARGS 4
831
832static 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
848static unsigned int * vwargs = NULL;
849#define NB_VWARGS 8
850
851static 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
868static 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
880static void build_vargs_table (void)
881{
882   build_vdargs_table();
883   build_vwargs_table();
884}
885
886static double *fargs = NULL;
887static int nb_fargs = 0;
888
889static 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
900static 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
1024static 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
1039static 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
1066typedef 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
1073static 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
1107static 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
1127static 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
1146static 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
1168static 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
1186static 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
1209static 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
1217static 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
1263static 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
1283static 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
1307static 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 */
1333static 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
1360static 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
1384static 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
1402static 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
1441static 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
1480static 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
1516static 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
1545static 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 */
1592enum 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
1604static 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*/
1620static 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 */
1646static test_loop_t float_loops[] = {
1647   NULL,
1648   &test_float_two_args,
1649};
1650
1651
1652static test_t tests_fa_ops_two[] = {
1653    { &test_fmrgew          , "fmrgew", },
1654    { &test_fmrgow          , "fmrgow", },
1655    { NULL,                   NULL,           },
1656};
1657
1658static 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
1742static 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
1884static 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
1899int 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