Home | History | Annotate | Download | only in ppc64
      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 (at) us.ibm.com>
     19  *            Maynard Johnson <maynardj (at) 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 
    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 
    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;
    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 
    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 
    326 static void test_fmrgew (void)
    327 {
    328     __asm__ __volatile__ ("fmrgew        17,14,15");
    329 };
    330 
    331 static void test_fmrgow (void)
    332 {
    333     __asm__ __volatile__ ("fmrgow        17,14,15");
    334 };
    335 
    336 
    337 
    338 // VSX move instructions
    339 static void test_mfvsrd (void)
    340 {
    341    __asm__ __volatile__ ("mfvsrd %0,%x1" : "=r" (r14) : "ws" (vec_inA));
    342 };
    343 
    344 static void test_mfvsrwz (void)
    345 {
    346    __asm__ __volatile__ ("mfvsrwz %0,%x1" : "=r" (r14) : "ws" (vec_inA));
    347 };
    348 
    349 static void test_mtvsrd (void)
    350 {
    351    __asm__ __volatile__ ("mtvsrd %x0,%1" : "=ws" (vec_out) : "r" (r14));
    352 };
    353 
    354 static void test_mtvsrwz (void)
    355 {
    356    __asm__ __volatile__ ("mtvsrwz %x0,%1" : "=ws" (vec_out) : "r" (r14));
    357 };
    358 
    359 
    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  */
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 */
    468 static void test_vupkhsw (void)
    469 {
    470     __asm__ __volatile__ ("vupkhsw %0, %1" : "=v" (vec_out): "v" (vec_inB_wd));
    471 }
    472 
    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.*/
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    575 static void test_vclzb (void)
    576 {
    577     __asm__ __volatile__ ("vclzb %0, %1" : "=v" (vec_out): "v" (vec_inB));
    578 }
    579 
    580 static void test_vclzw (void)
    581 {
    582     __asm__ __volatile__ ("vclzw %0, %1" : "=v" (vec_out): "v" (vec_inB));
    583 }
    584 
    585 static void test_vclzh (void)
    586 {
    587     __asm__ __volatile__ ("vclzh %0, %1" : "=v" (vec_out): "v" (vec_inB));
    588 }
    589 
    590 static void test_vclzd (void)
    591 {
    592     __asm__ __volatile__ ("vclzd %0, %1" : "=v" (vec_out): "v" (vec_inB));
    593 }
    594 
    595 static void test_vpopcntb (void)
    596 {
    597     __asm__ __volatile__ ("vpopcntb %0, %1" : "=v" (vec_out): "v" (vec_inB));
    598 }
    599 
    600 static void test_vpopcnth (void)
    601 {
    602     __asm__ __volatile__ ("vpopcnth %0, %1" : "=v" (vec_out): "v" (vec_inB));
    603 }
    604 
    605 static void test_vpopcntw (void)
    606 {
    607     __asm__ __volatile__ ("vpopcntw %0, %1" : "=v" (vec_out): "v" (vec_inB));
    608 }
    609 
    610 static void test_vpopcntd (void)
    611 {
    612     __asm__ __volatile__ ("vpopcntd %0, %1" : "=v" (vec_out): "v" (vec_inB));
    613 }
    614 
    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;
    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 
    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;
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 twos-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 
   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 
   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 
   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 
   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 
   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 */
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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