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