• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* HOW TO COMPILE:
2  * 64bit build:
3  *    gcc -Winline -Wall -g -O -mregnames -maltivec -m64
4  */
5 
6 /*
7  * test_isa_3_0.c:
8  * Copyright (C) 2016-2017 Carl Love <cel@us.ibm.com>
9  * Copyright (C) 2016-2017 Will Schmidt <will_schmidt@vnet.ibm.com>
10  *
11  * This testfile contains tests for the ISA 3.0 instructions.
12  * The framework of this test file was based on the framework
13  * of the jm-insns.c testfile, whose original author was
14  * Jocelyn Mayer.
15  */
16 
17 /*
18  *   This program is free software; you can redistribute it and/or
19  *   modify it under the terms of the GNU General Public License V2
20  *   as published by the Free Software Foundation
21  *
22  *   This program is distributed in the hope that it will be useful,
23  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
24  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25  *   GNU General Public License for more details.
26  *
27  *   You should have received a copy of the GNU General Public License
28  *   along with this program; if not, write to the Free Software
29  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
30  */
31 
32 /*
33  * Theory of operations:
34  * a few registers are reserved for the test program:
35  * r14...r18
36  * f14...f18
37  * - pre-load test values in r14 through r17
38  * - patch the test opcode if any immediate operands are
39  *   required
40  * - execute the tested opcode.
41  * CR and FPSCR are cleared before every test.
42  * results in {r,f}17
43  * check FPSCR for floating point operations.
44  */
45 
46 /*
47  * Operation details
48  * -----------------
49  * The 'test' functions (via all_tests[]) are wrappers of
50  * single __asm__ instructions
51  *
52  * The 'loops' (e.g. int_loops) do the actual work:
53  *  - loops over as many arguments as the instruction needs (regs | imms)
54  *     - sets up the environment (reset cr, assign src regs...)
55  *     - maybe modifies the asm instruction to test different immediate args
56  *     - call the test function
57  *     - retrieve relevant register data (rD,cr,...)
58  *     - prints argument and result data.
59  *
60  * all_tests[i] holds instruction tests
61  *  - of which each holds: {instn_test_arr[], description, flags}
62  *
63  * flags hold 3 instruction classifiers: {family, type, arg_type}
64  *
65  * // The main test loop:
66  * do_tests( user_ctl_flags ) {
67  *    foreach(curr_test = all_test[i]) {
68  *
69  *       // flags are used to control what tests are run:
70  *       if (curr_test->flags && !user_ctl_flags)
71  *          continue;
72  *
73  *       // a 'loop_family_arr' is chosen based on the 'family' flag...
74  *       switch(curr_test->flags->family) {
75  *       case x: loop_family_arr = int_loops;
76  *      ...
77  *       }
78  *
79  *       // ...and the actual test_loop to run is found by indexing into
80  *       // the loop_family_arr with the 'arg_type' flag:
81  *       test_loop = loop_family[curr_test->flags->arg_type]
82  *
83  *       // finally, loop over all instn tests for this test:
84  *       foreach (instn_test = curr_test->instn_test_arr[i]) {
85  *
86  *          // and call the test_loop with the current instn_test function,name
87  *          test_loop( instn_test->func, instn_test->name )
88  *       }
89  *    }
90  * }
91  */
92 
93 #include <stdio.h>
94 #include <stdint.h>
95 
96 /* This test is only valid on machines that support IBM POWER ISA 3.0. */
97 #ifdef HAS_ISA_3_00
98 
99 #include <assert.h>
100 #include <ctype.h>     // isspace
101 #include <stdlib.h>
102 #include <string.h>
103 #include <unistd.h>    // getopt
104 #include <altivec.h> // vector
105 
106 #undef DEBUG_VECTOR_PERMUTE
107 static int verbose = 0;
108 
109 #include "../ppc64/ppc64_helpers.h" // SET_CR() and friends.
110 
111 #define VERBOSE_FUNCTION_CALLOUT \
112    if (verbose) \
113       printf("Test Harness Function: %s\n", __FUNCTION__);
114 
115 /* generic out-of-range reporting.
116  * Note: results are typically 'undefined' in these cases, so rather than
117  * pushing through and getting potentially random results, avoid the check.
118  * The caller should suppress output when insert_extract_error is set. */
119 #define vinsertextract_err    \
120    insert_extract_error = 1;  \
121    if (verbose > 1)           \
122       printf("Expected error - index out of range in %s (%d)\n", \
123              __FUNCTION__, x_index);
124 
125 #define MAX(x, y) (x > y ? x : y)
126 
127 /* Used in do_tests, indexed by flags->nb_args
128    Elements correspond to enum test_flags::num args
129 */
130 
131 /* XXXX these must all be callee-save regs! */
132 register HWord_t r14 __asm__ ("r14");
133 register HWord_t r15 __asm__ ("r15");
134 register HWord_t r16 __asm__ ("r16");
135 register HWord_t r17 __asm__ ("r17");
136 register double  f14 __asm__ ("fr14");
137 register double  f15 __asm__ ("fr15");
138 
139 /* globals used for vector tests */
140 static vector unsigned long vec_xa, vec_xb, vec_xc, vec_xt;
141 
142 /* globals for the condition register fields.  These are used to
143  * capture the condition register values immediately after the
144  * instruction under test is tested.
145  * This is to help prevent other test overhead, switch statements,
146  * compares, what-not from interfering.
147  */
148 unsigned long local_cr;
149 unsigned long local_fpscr;
150 unsigned long local_xer;
151 volatile unsigned int cr_value;
152 
153 /* global for holding the DFP values */
154 dfp_val_t dfp_value;
155 
156 /* individual instruction tests */
157 typedef void (*test_func_t) (void);
158 struct test_list_t {
159    test_func_t func;
160    const char *name;
161 };
162 typedef struct test_list_t test_list_t;
163 
164 /* global variable, used to pass shift info down to the test functions.*/
165 volatile int x_shift;
166 
167 /* Indicator for DCMX (Data Class Mask) matches. */
168 volatile int dcmx_match;
169 
170 /* Error indicator to determine of the UIN (Unsigned Immediate) field
171  * from insert/extract was out of range */
172 volatile int insert_extract_error;
173 
174 /* vector splat value */
175 volatile int x_splat;
176 volatile int dfp_significance;
177 
178 /* global variable, ... vector insert functions. */
179 volatile int x_index;
180 
181 /* global variable, used to pass shift info down to the test functions.*/
182 /* Also used to control DRM,RM values for mffs* functions. */
183 volatile int x_shift;
184 
185 /* groups of instruction tests, calling individual tests */
186 typedef void (*test_group_t) (const char *name, test_func_t func,
187                               unsigned int test_flags);
188 
189 enum test_flags {
190    /* Nb arguments */
191    PPC_ONE_ARG        = 0x00000001,
192    PPC_TWO_ARGS       = 0x00000002,
193    PPC_THREE_ARGS     = 0x00000003,
194    PPC_FOUR_ARGS      = 0x00000004,
195    PPC_COMPARE_ARGS   = 0x00000005,
196    PPC_LD_ARGS        = 0x00000006,
197    PPC_ST_ARGS        = 0x00000007,
198    PPC_ONE_IMM        = 0x00000008,
199    PPC_NB_ARGS_MASK   = 0x0000000F,
200 
201    /* Type */
202    PPC_ARITH          = 0x00000100,
203    PPC_LOGICAL        = 0x00000200,
204    PPC_COMPARE        = 0x00000300,
205    PPC_LDST           = 0x00000400,
206    PPC_POPCNT         = 0x00000500,
207    PPC_INSERTEXTRACT  = 0x00000600,
208    PPC_PERMUTE        = 0x00000700,
209    PPC_ROUND          = 0x00000800,
210    PPC_TYPE_MASK      = 0x00000F00,
211 
212    /* Family */
213    PPC_INTEGER        = 0x00010000,
214    PPC_ALTIVEC        = 0x00030000,
215    PPC_ALTIVEC_QUAD   = 0x00040000,
216    PPC_ALTIVEC_DOUBLE = 0x00050000,
217    PPC_DFP            = 0x00060000,
218    PPC_BCD            = 0x00070000,
219    PPC_MISC           = 0x00080000,
220    PPC_NO_OP          = 0x00090000,
221    PPC_PC_IMMEDIATE   = 0x000A0000,
222    PPC_MFFS           = 0x000B0000,
223    PPC_FAMILY_MASK    = 0x000F0000,
224 
225    /* Flags: these may be combined, so use separate bit-fields. */
226    PPC_CR             = 0x01000000,
227    PPC_XER_CA         = 0x02000000,
228 };
229 
test_cnttzw(void)230 static void test_cnttzw (void)
231 {
232    __asm__ __volatile__ ("cnttzw       17, 14");
233 }
234 
test_cnttzd(void)235 static void test_cnttzd (void)
236 {
237    __asm__ __volatile__ ("cnttzd       17, 14");
238 }
239 
test_dotted_cnttzw(void)240 static void test_dotted_cnttzw (void)
241 {
242    __asm__ __volatile__ ("cnttzw.      17, 14");
243 }
244 
test_dotted_cnttzd(void)245 static void test_dotted_cnttzd (void)
246 {
247    __asm__ __volatile__ ("cnttzd.      17, 14");
248 }
249 
250 static test_list_t testgroup_logical_one[] = {
251    { &test_cnttzw       , "cnttzw"  },
252    { &test_cnttzd       , "cnttzd"  },
253    { &test_dotted_cnttzw, "cnttzw." },
254    { &test_dotted_cnttzd, "cnttzd." },
255    { NULL               , NULL      },
256 };
257 
test_modsw(void)258 static void test_modsw (void)
259 {
260    __asm__ __volatile__ ("modsw          17, 14, 15");
261 }
262 
test_moduw(void)263 static void test_moduw (void)
264 {
265    __asm__ __volatile__ ("moduw          17, 14, 15");
266 }
267 
test_modsd(void)268 static void test_modsd (void)
269 {
270    __asm__ __volatile__ ("modsd          17, 14, 15");
271 }
272 
test_modud(void)273 static void test_modud (void)
274 {
275    __asm__ __volatile__ ("modud          17, 14, 15");
276 }
277 
test_addex(void)278 static void test_addex(void) {
279    /* addex RT,RA,RB,CY  # at the time of this writing, only CY=0 is valid.  CY values of 1,2,3 are reserved. */
280    __asm__ __volatile__ ("addex   %0, %1, %2, 0" : "=r" (r17) : "r" (r14), "r" (r15) );
281 }
282 
283 static test_list_t testgroup_ia_ops_two[] = {
284    { &test_modsw, "modsw" },
285    { &test_moduw, "moduw" },
286    { &test_modsd, "modsd" },
287    { &test_modud, "modud" },
288    //{ &test_addex, "addex" },
289    { NULL       , NULL             },
290 };
291 
test_dotted_extswsli(void)292 static void test_dotted_extswsli (void)
293 {
294    switch(x_shift) {
295    case SH_0:
296       __asm__ __volatile__ ("extswsli. %0, %1, %2" : "=r" (r17) : "r" (r14), "i" (SH_0) );
297       break;
298 
299    case SH_1:
300       __asm__ __volatile__ ("extswsli. %0, %1, %2" : "=r" (r17) : "r" (r14), "i" (SH_1) );
301       break;
302 
303    case SH_2:
304       __asm__ __volatile__ ("extswsli. %0, %1, %2" : "=r" (r17) : "r" (r14), "i" (SH_2) );
305       break;
306 
307    case SH_3:
308       __asm__ __volatile__ ("extswsli. %0, %1, %2" : "=r" (r17) : "r" (r14), "i" (SH_3) );
309       break;
310 
311    default:
312       printf("Unhandled shift value for extswsli. %d\n", x_shift);
313    }
314 }
315 
test_extswsli(void)316 static void test_extswsli (void)
317 {
318    switch(x_shift) {
319    case SH_0:
320       __asm__ __volatile__ ("extswsli %0, %1, %2" : "=r" (r17) : "r" (r14), "i"(SH_0));
321       break;
322 
323    case SH_1:
324       __asm__ __volatile__ ("extswsli %0, %1, %2" : "=r" (r17) : "r" (r14), "i"(SH_1));
325       break;
326 
327    case SH_2:
328       __asm__ __volatile__ ("extswsli %0, %1, %2" : "=r" (r17) : "r" (r14), "i"(SH_2));
329       break;
330 
331    case SH_3:
332       __asm__ __volatile__ ("extswsli %0, %1, %2" : "=r" (r17) : "r" (r14), "i"(SH_3));
333       break;
334 
335    default:
336       printf("Unhandled shift value for extswsli %d\n", x_shift);
337    }
338 }
339 
340 static test_list_t testgroup_shifted_one[] = {
341       { &test_extswsli       , "extswsli " },
342       { &test_dotted_extswsli, "extswsli." },
343       { NULL                 , NULL        },
344 };
345 
test_maddhd(void)346 static void test_maddhd (void)
347 {
348    __asm__ __volatile__ ("maddhd 17, 14, 15, 16");
349 }
test_maddhdu(void)350 static void test_maddhdu (void)
351 {
352    __asm__ __volatile__ ("maddhdu 17, 14, 15, 16");
353 }
test_maddld(void)354 static void test_maddld (void)
355 {
356    __asm__ __volatile__ ("maddld 17, 14, 15, 16");
357 }
358 
359 static test_list_t testgroup_three_args[] = {
360    { &test_maddhd , "maddhd " },
361    { &test_maddhdu, "maddhdu" },
362    { &test_maddld , "maddld " },
363    { NULL         , NULL      },
364 };
365 
366 /* VSX vector permutes. */
test_xxperm(void)367 static void test_xxperm (void)
368 {
369    __asm__ __volatile__ ("xxperm     %x0, %x1, %x2" : "+wa" (vec_xt): "wa" (vec_xa), "wa" (vec_xb));
370 }
371 
372 /* VSX vector permute, right indexed. */
test_xxpermr(void)373 static void test_xxpermr (void)
374 {
375    __asm__ __volatile__ ("xxpermr    %x0, %x1, %x2" : "+wa" (vec_xt): "wa" (vec_xa), "wa" (vec_xb));
376 }
377 
378 static test_list_t testgroup_vsx_xxpermute[] = {
379    { &test_xxperm , "xxperm"  },
380    { &test_xxpermr, "xxpermr" },
381    { NULL         , NULL      },
382 };
383 
test_vabsdub(void)384 static void test_vabsdub(void) {
385    __asm__ __volatile__ ("vabsdub    %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
386 }
387 
test_vabsduh(void)388 static void test_vabsduh(void) {
389    __asm__ __volatile__ ("vabsduh    %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
390 }
391 
test_vabsduw(void)392 static void test_vabsduw(void) {
393    __asm__ __volatile__ ("vabsduw    %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
394 }
395 
test_vcmpneb(void)396 static void test_vcmpneb(void) {
397    __asm__ __volatile__ ("vcmpneb    %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
398 }
399 
test_dotted_vcmpneb(void)400 static void test_dotted_vcmpneb(void) {
401    __asm__ __volatile__ ("vcmpneb.    %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
402 }
403 
test_vcmpnezb(void)404 static void test_vcmpnezb(void) {
405    __asm__ __volatile__ ("vcmpnezb    %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
406 }
407 
test_dotted_vcmpnezb(void)408 static void test_dotted_vcmpnezb(void) {
409    __asm__ __volatile__ ("vcmpnezb.    %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
410 }
411 
test_vcmpneh(void)412 static void test_vcmpneh(void) {
413    __asm__ __volatile__ ("vcmpneh    %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
414 }
415 
test_dotted_vcmpneh(void)416 static void test_dotted_vcmpneh(void) {
417    __asm__ __volatile__ ("vcmpneh.    %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
418 }
419 
test_vcmpnezh(void)420 static void test_vcmpnezh(void) {
421    __asm__ __volatile__ ("vcmpnezh    %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
422 }
423 
test_dotted_vcmpnezh(void)424 static void test_dotted_vcmpnezh(void) {
425    __asm__ __volatile__ ("vcmpnezh.    %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
426 }
427 
test_vcmpnew(void)428 static void test_vcmpnew(void) {
429    __asm__ __volatile__ ("vcmpnew    %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
430 }
431 
test_dotted_vcmpnew(void)432 static void test_dotted_vcmpnew(void) {
433    __asm__ __volatile__ ("vcmpnew.    %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
434 }
435 
test_vcmpnezw(void)436 static void test_vcmpnezw(void) {
437    __asm__ __volatile__ ("vcmpnezw    %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
438 }
439 
test_dotted_vcmpnezw(void)440 static void test_dotted_vcmpnezw(void) {
441    __asm__ __volatile__ ("vcmpnezw.    %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
442 }
443 
test_vrlwmi(void)444 static void test_vrlwmi(void) {
445    __asm__ __volatile__ ("vrlwmi    %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
446 }
447 
test_vrldmi(void)448 static void test_vrldmi(void) {
449    __asm__ __volatile__ ("vrldmi    %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
450 }
451 
test_vbpermd(void)452 static void test_vbpermd(void) {
453 /* vector bit permute doubleword */
454     __asm__ __volatile__ ("vbpermd   %0, %1, %2 " : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
455 }
456 
test_vrlwnm(void)457 static void test_vrlwnm(void) {
458    __asm__ __volatile__ ("vrlwnm    %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
459 }
460 
test_vrldnm(void)461 static void test_vrldnm(void) {
462    __asm__ __volatile__ ("vrldnm    %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
463 }
464 
test_xviexpdp(void)465 static void test_xviexpdp(void) {
466    __asm__ __volatile__ ("xviexpdp   %0, %1, %2 " : "+wa" (vec_xt): "wa" (vec_xa), "wa" (vec_xb));
467 }
468 
test_xviexpsp(void)469 static void test_xviexpsp(void) {
470    __asm__ __volatile__ ("xviexpsp   %0, %1, %2 " : "+wa" (vec_xt): "wa" (vec_xa), "wa" (vec_xb));
471 }
472 
473 static test_list_t testgroup_vsx_absolute[] = {
474    { &test_vabsdub        , "vabsdub"   },
475    { &test_vabsduh        , "vabsduh"   },
476    { &test_vabsduw        , "vabsduw"   },
477    { &test_vcmpneb        , "vcmpneb"   },
478    { &test_dotted_vcmpneb , "vcmpneb."  },
479    { &test_vcmpnezb       , "vcmpnezb"  },
480    { &test_dotted_vcmpnezb, "vcmpnezb." },
481    { &test_vcmpneh        , "vcmpneh"   },
482    { &test_dotted_vcmpneh , "vcmpneh."  },
483    { &test_vcmpnezh       , "vcmpnezh"  },
484    { &test_dotted_vcmpnezh, "vcmpnezh." },
485    { &test_vcmpnew        , "vcmpnew"   },
486    { &test_dotted_vcmpnew , "vcmpnew."  },
487    { &test_vcmpnezw       , "vcmpnezw"  },
488    { &test_dotted_vcmpnezw, "vcmpnezw." },
489    { &test_vrlwnm         , "vrlwnm"    },
490    { &test_vrlwmi         , "vrlwmi"    },
491    { &test_vrldnm         , "vrldnm"    },
492    { &test_vrldmi         , "vrldmi"    },
493    { &test_vbpermd        , "vbpermd"   },
494    { &test_xviexpdp       , "xviexpdp"  },
495    { &test_xviexpsp       , "xviexpsp"  },
496    { NULL                 , NULL        },
497 };
498 
test_vpermr(void)499 static void test_vpermr(void)
500 { /* vector permute right-indexed */
501     __asm__ __volatile__ ("vpermr   %0, %1, %2, %3 " : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb), "v" (vec_xc));
502 }
503 
test_vmsumudm(void)504 static void test_vmsumudm(void)
505 { /* vector multiply-sum unsigned byte modulo. */
506     __asm__ __volatile__ ("vmsumudm  %0, %1, %2, %3 " : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb), "v" (vec_xc));
507 }
508 
509 /* vector, 3->1 unique; four arguments. xt, xa, xb, xc (xc = permute) */
510 static test_list_t testgroup_vector_four[] = {
511    { &test_vpermr,   "vpermr" },
512    //   { &test_vmsumudm, "vmsumudm" },
513    { NULL        , NULL     },
514 };
515 
516 /* vector insert instructions */
517 #define VINSERTB(X)    __asm__ __volatile__ ("vinsertb    %0, %1, %2" : "+v" (vec_xt) : "v" (vec_xb), "i"(X));
518 
519 #define VINSERTH(X)    __asm__ __volatile__ ("vinserth    %0, %1, %2" : "+v" (vec_xt) : "v" (vec_xb), "i"(X));
520 
521 #define VINSERTW(X)    __asm__ __volatile__ ("vinsertw    %0, %1, %2" : "+v" (vec_xt) : "v" (vec_xb), "i"(X));
522 
523 #define VINSERTD(X)    __asm__ __volatile__ ("vinsertd    %0, %1, %2" : "+v" (vec_xt) : "v" (vec_xb), "i"(X));
524 
525 #define VEXTRACTUB(X)  __asm__ __volatile__ ("vextractub  %0, %1, %2" : "+v" (vec_xt) : "v" (vec_xb), "i"(X));
526 
527 #define VEXTRACTUH(X)  __asm__ __volatile__ ("vextractuh  %0, %1, %2" : "+v" (vec_xt) : "v" (vec_xb), "i"(X));
528 
529 #define VEXTRACTUW(X)  __asm__ __volatile__ ("vextractuw  %0, %1, %2" : "+v" (vec_xt) : "v" (vec_xb), "i"(X));
530 
531 #define VEXTRACTD(X)   __asm__ __volatile__ ("vextractd   %0, %1, %2" : "+v" (vec_xt) : "v" (vec_xb), "i"(X));
532 
533 #define XXINSERTW(X)   __asm__ __volatile__ ("xxinsertw   %0, %1, %2" : "+wa" (vec_xt) : "wa" (vec_xb), "i"(X));
534 
535 #define XXEXTRACTUW(X) __asm__ __volatile__ ("xxextractuw %0, %1, %2" : "+wa" (vec_xt) : "wa" (vec_xb), "i"(X));
536 
test_vinsertb(void)537 static void test_vinsertb (void)
538 {
539    switch(x_index) {
540    case  0: VINSERTB( 0); break;
541    case  1: VINSERTB( 1); break;
542    case  2: VINSERTB( 2); break;
543    case  3: VINSERTB( 3); break;
544    case  4: VINSERTB( 4); break;
545    case  5: VINSERTB( 5); break;
546    case  6: VINSERTB( 6); break;
547    case  7: VINSERTB( 7); break;
548    case  8: VINSERTB( 8); break;
549    case  9: VINSERTB( 9); break;
550    case 10: VINSERTB(10); break;
551    case 11: VINSERTB(11); break;
552    case 12: VINSERTB(12); break;
553    case 13: VINSERTB(13); break;
554    case 14: VINSERTB(14); break;
555    case 15: VINSERTB(15); break;
556    default:
557       vinsertextract_err;
558       break;
559    }
560 }
561 
test_vinserth(void)562 static void test_vinserth (void)
563 {
564    switch(x_index) {
565    case 0:  VINSERTH(0); break;
566    case 1:  VINSERTH(1); break;
567    case 2:  VINSERTH(2); break;
568    case 3:  VINSERTH(3); break;
569    case 4:  VINSERTH(4); break;
570    case 5:  VINSERTH(5); break;
571    case 6:  VINSERTH(6); break;
572    case 7:  VINSERTH(7); break;
573    case 8:  VINSERTH(8); break;
574    case 9:  VINSERTH(9); break;
575    case 10: VINSERTH(10); break;
576    case 11: VINSERTH(11); break;
577    case 12: VINSERTH(12); break;
578    case 13: VINSERTH(13); break;
579    case 14: VINSERTH(14); break;
580    default:
581       vinsertextract_err;
582       break;
583    }
584 }
585 
test_vinsertw(void)586 static void test_vinsertw (void)
587 {
588    switch(x_index) {
589    case 0:  VINSERTW(0); break;
590    case 1:  VINSERTW(1); break;
591    case 2:  VINSERTW(2); break;
592    case 3:  VINSERTW(3); break;
593    case 4:  VINSERTW(4); break;
594    case 5:  VINSERTW(5); break;
595    case 6:  VINSERTW(6); break;
596    case 7:  VINSERTW(7); break;
597    case 8:  VINSERTW(8); break;
598    case 9:  VINSERTW(9); break;
599    case 10: VINSERTW(10); break;
600    case 11: VINSERTW(11); break;
601    case 12: VINSERTW(12); break;
602    default:
603       vinsertextract_err;
604       break;
605    }
606 }
607 
test_vinsertd(void)608 static void test_vinsertd (void)
609 {
610    switch(x_index) {
611    case 0:  VINSERTD(0); break;
612    case 1:  VINSERTD(1); break;
613    case 2:  VINSERTD(2); break;
614    case 3:  VINSERTD(3); break;
615    case 4:  VINSERTD(4); break;
616    case 5:  VINSERTD(5); break;
617    case 6:  VINSERTD(6); break;
618    case 7:  VINSERTD(7); break;
619    case 8:  VINSERTD(8); break;
620    default:
621       vinsertextract_err;
622       break;
623    }
624 }
625 
626 /* extracts */
test_vextractub(void)627 static void test_vextractub (void)
628 {
629    switch(x_index) {
630       case  0: VEXTRACTUB( 0); break;
631       case  1: VEXTRACTUB( 1); break;
632       case  2: VEXTRACTUB( 2); break;
633       case  3: VEXTRACTUB( 3); break;
634       case  4: VEXTRACTUB( 4); break;
635       case  5: VEXTRACTUB( 5); break;
636       case  6: VEXTRACTUB( 6); break;
637       case  7: VEXTRACTUB( 7); break;
638       case  8: VEXTRACTUB( 8); break;
639       case  9: VEXTRACTUB( 9); break;
640       case 10: VEXTRACTUB(10); break;
641       case 11: VEXTRACTUB(11); break;
642       case 12: VEXTRACTUB(12); break;
643       case 13: VEXTRACTUB(13); break;
644       case 14: VEXTRACTUB(14); break;
645       case 15: VEXTRACTUB(15); break;
646       default:
647          vinsertextract_err;
648          break;
649    }
650 }
651 
test_vextractuh(void)652 static void test_vextractuh (void)
653 {
654    switch(x_index) {
655       case  0: VEXTRACTUH( 0); break;
656       case  1: VEXTRACTUH( 1); break;
657       case  2: VEXTRACTUH( 2); break;
658       case  3: VEXTRACTUH( 3); break;
659       case  4: VEXTRACTUH( 4); break;
660       case  5: VEXTRACTUH( 5); break;
661       case  6: VEXTRACTUH( 6); break;
662       case  7: VEXTRACTUH( 7); break;
663       case  8: VEXTRACTUH( 8); break;
664       case  9: VEXTRACTUH( 9); break;
665       case 10: VEXTRACTUH(10); break;
666       case 11: VEXTRACTUH(11); break;
667       case 12: VEXTRACTUH(12); break;
668       case 13: VEXTRACTUH(13); break;
669       case 14: VEXTRACTUH(14); break;
670       default:
671          vinsertextract_err;
672          break;
673    }
674 }
675 
test_vextractuw(void)676 static void test_vextractuw (void)
677 {
678    switch(x_index) {
679       case  0: VEXTRACTUW( 0); break;
680       case  1: VEXTRACTUW( 1); break;
681       case  2: VEXTRACTUW( 2); break;
682       case  3: VEXTRACTUW( 3); break;
683       case  4: VEXTRACTUW( 4); break;
684       case  5: VEXTRACTUW( 5); break;
685       case  6: VEXTRACTUW( 6); break;
686       case  7: VEXTRACTUW( 7); break;
687       case  8: VEXTRACTUW( 8); break;
688       case  9: VEXTRACTUW( 9); break;
689       case 10: VEXTRACTUW(10); break;
690       case 11: VEXTRACTUW(11); break;
691       default:
692          vinsertextract_err;
693          break;
694    }
695 }
696 
test_vextractd(void)697 static void test_vextractd (void)
698 {
699    switch(x_index) {
700       case  0: VEXTRACTD( 0); break;
701       case  1: VEXTRACTD( 1); break;
702       case  2: VEXTRACTD( 2); break;
703       case  3: VEXTRACTD( 3); break;
704       case  4: VEXTRACTD( 4); break;
705       case  5: VEXTRACTD( 5); break;
706       case  6: VEXTRACTD( 6); break;
707       case  7: VEXTRACTD( 7); break;
708       case  8: VEXTRACTD( 8); break;
709       default:
710          vinsertextract_err;
711          break;
712    }
713 }
714 
test_xxinsertw(void)715 static void test_xxinsertw (void)
716 {
717    switch(x_index) {
718       case  0: XXINSERTW( 0); break;
719       case  1: XXINSERTW( 1); break;
720       case  2: XXINSERTW( 2); break;
721       case  3: XXINSERTW( 3); break;
722       case  4: XXINSERTW( 4); break;
723       case  5: XXINSERTW( 5); break;
724       case  6: XXINSERTW( 6); break;
725       case  7: XXINSERTW( 7); break;
726       case  8: XXINSERTW( 8); break;
727       case  9: XXINSERTW( 9); break;
728       case 10: XXINSERTW(10); break;
729       case 11: XXINSERTW(11); break;
730       case 12: XXINSERTW(12); break;
731       default:
732          vinsertextract_err;
733          break;
734    }
735 }
736 
test_xxextractuw(void)737 static void test_xxextractuw (void)
738 {
739    switch(x_index) {
740       case  0: XXEXTRACTUW( 0); break;
741       case  1: XXEXTRACTUW( 1); break;
742       case  2: XXEXTRACTUW( 2); break;
743       case  3: XXEXTRACTUW( 3); break;
744       case  4: XXEXTRACTUW( 4); break;
745       case  5: XXEXTRACTUW( 5); break;
746       case  6: XXEXTRACTUW( 6); break;
747       case  7: XXEXTRACTUW( 7); break;
748       case  8: XXEXTRACTUW( 8); break;
749       case  9: XXEXTRACTUW( 9); break;
750       case 10: XXEXTRACTUW(10); break;
751       case 11: XXEXTRACTUW(11); break;
752       case 12: XXEXTRACTUW(12); break;
753       default:
754          vinsertextract_err;
755          break;
756    }
757 }
758 
759 static test_list_t testgroup_vector_inserts[] = {
760    { &test_vinsertb   , "vinsertb   " },
761    { &test_vinserth   , "vinserth   " },
762    { &test_vinsertw   , "vinsertw   " },
763    { &test_vinsertd   , "vinsertd   " },
764    { &test_vextractub , "vextractub " },
765    { &test_vextractuh , "vextractuh " },
766    { &test_vextractuw , "vextractuw " },
767    { &test_vextractd  , "vextractd  " },
768    { &test_xxinsertw  , "xxinsertw  " },
769    { &test_xxextractuw, "xxextractuw" },
770    { NULL             , NULL          },
771 };
772 
test_xxspltib(void)773 static void test_xxspltib(void)
774 { /* vector splat byte */
775    switch(x_splat) {
776       case SPLAT0:     __asm__ __volatile__ ("xxspltib  %x0, %1 " : "=wa"(vec_xt) : "i"(SPLAT0)); break;
777 
778       case SPLAT1:     __asm__ __volatile__ ("xxspltib  %x0, %1 " : "=wa"(vec_xt) : "i"(SPLAT1)); break;
779 
780       case SPLAT2:     __asm__ __volatile__ ("xxspltib  %x0, %1 " : "=wa"(vec_xt) : "i"(SPLAT2)); break;
781 
782       case SPLAT3:     __asm__ __volatile__ ("xxspltib  %x0, %1 " : "=wa"(vec_xt) : "i"(SPLAT3)); break;
783 
784       case SPLAT4:     __asm__ __volatile__ ("xxspltib  %x0, %1 " : "=wa"(vec_xt) : "i"(SPLAT4)); break;
785 
786       default:
787          printf("Unhandled splat value for %s %d\n", __FUNCTION__, x_splat);
788    }
789 };
790 
791 static test_list_t testgroup_vector_immediate[] = {
792    { &test_xxspltib, "xxspltib" },
793    { NULL          , NULL       },
794 };
795 
796 /* vector reverse bytes ... */
test_xxbrh(void)797 static void test_xxbrh(void)
798 { /* vector reverse byte halfword*/
799    __asm__ __volatile__ ("xxbrh %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa));
800 }
801 
test_xxbrw(void)802 static void test_xxbrw(void)
803 { /* vector reverse byte word*/
804    __asm__ __volatile__ ("xxbrw %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa));
805 }
806 
test_xxbrd(void)807 static void test_xxbrd(void)
808 { /* vector reverse byte double*/
809    __asm__ __volatile__ ("xxbrd %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa));
810 }
811 
test_xxbrq(void)812 static void test_xxbrq(void)
813 { /* vector reverse byte */
814    __asm__ __volatile__ ("xxbrq %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa));
815 }
816 
test_xvxexpdp(void)817 static void test_xvxexpdp(void) {
818    __asm__ __volatile__ ("xvxexpdp %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa));
819 }
820 
test_xvxexpsp(void)821 static void test_xvxexpsp(void) {
822    __asm__ __volatile__ ("xvxexpsp %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa));
823 }
824 
test_xvxsigdp(void)825 static void test_xvxsigdp(void) {
826    __asm__ __volatile__ ("xvxsigdp %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa));
827 }
828 
test_xvxsigsp(void)829 static void test_xvxsigsp(void) {
830    __asm__ __volatile__ ("xvxsigsp %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa));
831 }
832 
test_xsxexpdp(void)833 static void test_xsxexpdp(void) {
834    __asm__ __volatile__ ("xsxexpdp %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa));
835 }
836 
test_xsxsigdp(void)837 static void test_xsxsigdp(void) {
838    __asm__ __volatile__ ("xsxsigdp %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa));
839 }
840 
841 static test_list_t testgroup_vector_logical_one[] = {
842    { &test_xxbrh   , "xxbrh"    },
843    { &test_xxbrw   , "xxbrw"    },
844    { &test_xxbrd   , "xxbrd"    },
845    { &test_xxbrq   , "xxbrq"    },
846    { &test_xvxexpdp, "xvxexpdp" },
847    { &test_xvxexpsp, "xvxexpsp" },
848    { &test_xvxsigdp, "xvxsigdp" },
849    { &test_xvxsigsp, "xvxsigsp" },
850    { &test_xsxexpdp, "xsxexpdp" },
851    { &test_xsxsigdp, "xsxsigdp" },
852    { NULL          , NULL       },
853 };
854 
test_lxvx(void)855 static void test_lxvx(void)     {
856    __asm__ __volatile__ ("lxvx %x0, 14, 15" : "=wa" (vec_xt));
857 }
858 
test_lxvwsx(void)859 static void test_lxvwsx(void)   {
860    __asm__ __volatile__ ("lxvwsx %x0, 14, 15" : "=wa" (vec_xt));
861 }
862 
test_lxvh8x(void)863 static void test_lxvh8x(void)   {
864    __asm__ __volatile__ ("lxvh8x %x0, 14, 15" : "=wa" (vec_xt));
865 }
866 
test_lxvb16x(void)867 static void test_lxvb16x(void)  {
868    __asm__ __volatile__ ("lxvb16x %x0, 14, 15" : "=wa" (vec_xt));
869 }
870 
test_stxvx(void)871 static void test_stxvx(void)    {
872    __asm__ __volatile__ ("stxvx %x0, 14, 15" : "=wa" (vec_xt));
873 }
874 
test_stxvh8x(void)875 static void test_stxvh8x(void)  {
876    __asm__ __volatile__ ("stxvh8x %x0, 14, 15" : "=wa" (vec_xt));
877 }
878 
test_stxvb16x(void)879 static void test_stxvb16x(void) {
880    __asm__ __volatile__ ("stxvb16x %x0, 14, 15" : "=wa" (vec_xt));
881 }
882 
883 static test_list_t testgroup_vector_loadstore[] = {
884    { &test_lxvx    , "lxvx"     },
885    { &test_lxvwsx  , "lxvwsx"   },
886    { &test_lxvh8x  , "lxvh8x"   },
887    { &test_lxvb16x , "lxvb16x"  },
888    { &test_stxvx   , "stxvx"    },
889    { &test_stxvh8x , "stxvh8x"  },
890    { &test_stxvb16x, "stxvb16x" },
891    { NULL          , NULL       },
892 };
893 
test_lxvl(void)894 static void test_lxvl(void) {
895    __asm__ __volatile__ ("lxvl %0, 14, 15" : "=wa" (vec_xt));
896 }
897 
test_stxvl(void)898 static void test_stxvl(void) {
899    __asm__ __volatile__ ("stxvl %0, 14, 15" : "=wa" (vec_xt));
900 }
901 
test_lxvll(void)902 static void test_lxvll(void) {
903    __asm__ __volatile__ ("lxvll %0, 14, 15" : "=wa" (vec_xt));
904 }
905 
test_stxvll(void)906 static void test_stxvll(void) {
907    __asm__ __volatile__ ("stxvll %0, 14, 15" : "=wa" (vec_xt));
908 }
909 
test_lxsibzx(void)910 static void test_lxsibzx(void) {
911    __asm__ __volatile__ ("lxsibzx %x0, 14, 15" : "=wa" (vec_xt));
912 }
913 
test_lxsihzx(void)914 static void test_lxsihzx(void) {
915    __asm__ __volatile__ ("lxsihzx %x0, 14, 15" : "=wa" (vec_xt));
916 }
917 
test_stxsibx(void)918 static void test_stxsibx(void) {
919    __asm__ __volatile__ ("stxsibx %x0, 14, 15" : "=wa" (vec_xt));
920 }
921 
test_stxsihx(void)922 static void test_stxsihx(void) {
923    __asm__ __volatile__ ("stxsihx %x0, 14, 15" : "=wa" (vec_xt));
924 }
925 
926 /* d-form vsx load/store */
test_lxsd_0(void)927 static void test_lxsd_0(void) {
928    __asm__ __volatile__ ("lxsd %0, 0(%1) " : "=v"(vec_xt) : "r"(r14));
929 }
930 
test_stxsd_0(void)931 static void test_stxsd_0(void) {
932    __asm__ __volatile__ ("stxsd %0, 0(%1)" : "=v"(vec_xt) : "r"(r14));
933 }
934 
test_lxsd_16(void)935 static void test_lxsd_16(void) {
936    __asm__ __volatile__ ("lxsd %0, 16(%1)" : "=v"(vec_xt) : "r"(r14));
937 }
938 
test_stxsd_16(void)939 static void test_stxsd_16(void) {
940    __asm__ __volatile__ ("stxsd %0, 16(%1)" : "=v"(vec_xt) : "r"(r14));
941 }
942 
test_lxssp_0(void)943 static void test_lxssp_0(void) {
944    __asm__ __volatile__ ("lxssp %0, 0(%1)" : "=wa"(vec_xt) : "r"(r14));
945 }
946 
test_stxssp_0(void)947 static void test_stxssp_0(void) {
948    __asm__ __volatile__ ("stxssp %0, 0(%1)" : "=wa"(vec_xt) : "r"(r14));
949 }
950 
test_lxssp_16(void)951 static void test_lxssp_16(void) {
952    __asm__ __volatile__ ("lxssp %0, 16(%1)" : "=wa"(vec_xt) : "r"(r14));
953 }
954 
test_stxssp_16(void)955 static void test_stxssp_16(void) {
956    __asm__ __volatile__ ("stxssp %0, 16(%1)" : "=wa"(vec_xt) : "r"(r14));
957 }
958 
test_lxv_0(void)959 static void test_lxv_0(void) {
960    __asm__ __volatile__ ("lxv %0, 0(%1)" : "=wa"(vec_xt) : "r"(r14));
961 }
962 
test_stxv_0(void)963 static void test_stxv_0(void) {
964    __asm__ __volatile__ ("stxv %0, 0(%1)" : "=wa"(vec_xt) : "r"(r14));
965 }
966 
test_lxv_16(void)967 static void test_lxv_16(void) {
968    __asm__ __volatile__ ("lxv %0, 16(%1)" : "=wa"(vec_xt) : "r"(r14));
969 }
970 
test_stxv_16(void)971 static void test_stxv_16(void) {
972    __asm__ __volatile__ ("stxv %0, 16(%1)" : "=wa"(vec_xt) : "r"(r14));
973 }
974 
975 static test_list_t testgroup_vector_scalar_loadstore_length[] = {
976    { &test_lxvl     , "lxvl     " },
977    { &test_lxvll    , "lxvll    " },
978    { &test_lxsibzx  , "lxsibzx  " },
979    { &test_lxsihzx  , "lxsihzx  " },
980    { &test_stxvl    , "stxvl    " },
981    { &test_stxvll   , "stxvll   " },
982    { &test_stxsibx  , "stxsibx  " },
983    { &test_stxsihx  , "stxsihx  " },
984    { &test_lxsd_0   , "lxsd 0   " },
985    { &test_stxsd_0  , "stxsd 0  " },
986    { &test_lxsd_16  , "lxsd 16  " },
987    { &test_stxsd_16 , "stxsd 16 " },
988    { &test_lxssp_0  , "lxssp 0  " },
989    { &test_stxssp_0 , "stxssp 0 " },
990    { &test_lxssp_16 , "lxssp 16 " },
991    { &test_stxssp_16, "stxssp 16" },
992    { &test_lxv_0    , "lxv 0    " },
993    { &test_stxv_0   , "stxv 0   " },
994    { &test_lxv_16   , "lxv 16   " },
995    { &test_stxv_16  , "stxv 16  " },
996    { NULL           , NULL        },
997 };
998 
999 /* move from/to VSR */
test_mfvsrld(void)1000 static void test_mfvsrld (void)
1001 {
1002    __asm__ __volatile__ ("mfvsrld %0, %x1" : "=r" (r14) : "wa" (vec_xt));
1003 };
1004 
test_mtvsrdd(void)1005 static void test_mtvsrdd (void)
1006 {
1007    __asm__ __volatile__ ("mtvsrdd %x0, 14, 15" : "=wa" (vec_xt));
1008 };
1009 
test_mtvsrws(void)1010 static void test_mtvsrws (void)
1011 { /* To fit in better with the caller for the mfvsrdd test, use r15
1012    * instead of r14 as input here.
1013    */
1014    __asm__ __volatile__ ("mtvsrws %0, 15" : "=wa" (vec_xt));
1015 };
1016 
1017 static test_list_t testgroup_vectorscalar_move_tofrom[] = {
1018    { &test_mfvsrld, "mfvsrld" }, /* RA, XS */
1019    { &test_mtvsrdd, "mtvsrdd" }, /* XT, RA, RB */
1020    { &test_mtvsrws, "mtvsrws" }, /* XT, RA */
1021    { NULL         , NULL      },
1022 };
1023 
1024 /* vector count {leading, trailing} zero least-significant bits byte.
1025  * roughly...  how many leading/trailing bytes are even. */
test_vclzlsbb(void)1026 static void test_vclzlsbb(void) {
1027    __asm__ __volatile__ ("vclzlsbb %0, %1" : "=r"(r14) : "v"(vec_xb));
1028 }
1029 
test_vctzlsbb(void)1030 static void test_vctzlsbb(void) {
1031    __asm__ __volatile__ ("vctzlsbb %0, %1" : "=r"(r14) : "v"(vec_xb));
1032 }
1033 
1034 static test_list_t testgroup_vector_count_bytes[] = {
1035    { &test_vclzlsbb, "vclzlsbb" },
1036    { &test_vctzlsbb, "vctzlsbb" },
1037    { NULL          , NULL       },
1038 };
1039 
test_vextsb2w(void)1040 static void test_vextsb2w(void) {
1041    __asm__ __volatile__ ("vextsb2w %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1042 }
1043 
test_vextsb2d(void)1044 static void test_vextsb2d(void) {
1045    __asm__ __volatile__ ("vextsb2d %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1046 }
1047 
test_vextsh2w(void)1048 static void test_vextsh2w(void) {
1049    __asm__ __volatile__ ("vextsh2w %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1050 }
1051 
test_vextsh2d(void)1052 static void test_vextsh2d(void) {
1053    __asm__ __volatile__ ("vextsh2d %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1054 }
1055 
test_vextsw2d(void)1056 static void test_vextsw2d(void) {
1057    __asm__ __volatile__ ("vextsw2d %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1058 }
1059 
test_vnegw(void)1060 static void test_vnegw(void) {
1061    __asm__ __volatile__ ("vnegw %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1062 }
1063 
test_vnegd(void)1064 static void test_vnegd(void) {
1065    __asm__ __volatile__ ("vnegd %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1066 }
1067 
test_vprtybw(void)1068 static void test_vprtybw(void) {
1069    __asm__ __volatile__ ("vprtybw %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1070 }
1071 
test_vprtybd(void)1072 static void test_vprtybd(void) {
1073    __asm__ __volatile__ ("vprtybd %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1074 }
1075 
test_vprtybq(void)1076 static void test_vprtybq(void) {
1077    __asm__ __volatile__ ("vprtybq %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1078 }
1079 
test_vctzb(void)1080 static void test_vctzb(void) {
1081    __asm__ __volatile__ ("vctzb %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1082 }
1083 
test_vctzh(void)1084 static void test_vctzh(void) {
1085    __asm__ __volatile__ ("vctzh %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1086 }
1087 
test_vctzw(void)1088 static void test_vctzw(void) {
1089    __asm__ __volatile__ ("vctzw %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1090 }
1091 
test_vctzd(void)1092 static void test_vctzd(void) {
1093    __asm__ __volatile__ ("vctzd %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1094 }
1095 
1096 static test_list_t testgroup_vector_extend_sign[] = {
1097    { &test_vextsb2w, "vextsb2w" },
1098    { &test_vextsb2d, "vextsb2d" },
1099    { &test_vextsh2w, "vextsh2w" },
1100    { &test_vextsh2d, "vextsh2d" },
1101    { &test_vextsw2d, "vextsw2d" },
1102    { &test_vnegw   , "vnegw   " },
1103    { &test_vnegd   , "vnegd   " },
1104    { &test_vprtybw , "vprtybw " },
1105    { &test_vprtybd , "vprtybd " },
1106    { &test_vprtybq , "vprtybq " },
1107    { &test_vctzb   , "vctzb   " },
1108    { &test_vctzh   , "vctzh   " },
1109    { &test_vctzw   , "vctzw   " },
1110    { &test_vctzd   , "vctzd   " },
1111    { NULL          , NULL       },
1112 };
1113 
test_vextublx(void)1114 static void test_vextublx(void) {
1115    __asm__ __volatile__ ("vextublx %0, %1, %2" : "=r"(r14) : "r" (r15), "v" (vec_xb));
1116 }
1117 
test_vextubrx(void)1118 static void test_vextubrx(void) {
1119    __asm__ __volatile__ ("vextubrx %0, %1, %2" : "=r"(r14) : "r"(r15), "v"(vec_xb));
1120 }
1121 
test_vextuhlx(void)1122 static void test_vextuhlx(void) {
1123    if (r15 > 14) return; // limit to 14 halfwords
1124    __asm__ __volatile__ ("vextuhlx %0, %1, %2" : "=r"(r14) : "r"(r15), "v"(vec_xb));
1125 }
1126 
test_vextuhrx(void)1127 static void test_vextuhrx(void) {
1128    if (r15 > 14) return; // limit to 14 halfwords
1129    __asm__ __volatile__ ("vextuhrx %0, %1, %2" : "=r"(r14) : "r"(r15), "v"(vec_xb));
1130 }
1131 
test_vextuwlx(void)1132 static void test_vextuwlx(void) {
1133    if (r15 > 12) return; // limit to 12 words
1134    __asm__ __volatile__ ("vextuwlx %0, %1, %2" : "=r"(r14) : "r"(r15), "v"(vec_xb));
1135 }
1136 
test_vextuwrx(void)1137 static void test_vextuwrx(void) {
1138    if (r15 > 12) return; // limit to 12 words
1139    __asm__ __volatile__ ("vextuwrx %0, %1, %2" : "=r"(r14) : "r"(r15), "v"(vec_xb));
1140 }
1141 
1142 static test_list_t testgroup_vector_extract[] = {
1143    { &test_vextublx, "vextublx" },
1144    { &test_vextubrx, "vextubrx" },
1145    { &test_vextuhlx, "vextuhlx" },
1146    { &test_vextuhrx, "vextuhrx" },
1147    { &test_vextuwlx, "vextuwlx" },
1148    { &test_vextuwrx, "vextuwrx" },
1149    { NULL          , NULL       },
1150 };
1151 
1152 #define XSCMPEXPDP(x)                                             \
1153    SET_FPSCR_ZERO                                                 \
1154    SET_CR_ZERO                                                    \
1155    __asm__ __volatile__                                           \
1156       ("xscmpexpdp %0, %1, %2"::"i"(x), "wa"(vec_xa), "wa"(vec_xb));\
1157    GET_CR(local_cr);                                              \
1158    GET_FPSCR(local_fpscr);
1159 
test_xscmpexpdp(void)1160 static void test_xscmpexpdp(void) {
1161    switch(x_index) {
1162    case 0: XSCMPEXPDP(0); break;
1163    case 1: XSCMPEXPDP(1); break;
1164    case 2: XSCMPEXPDP(2); break;
1165    case 3: XSCMPEXPDP(3); break;
1166    case 4: XSCMPEXPDP(4); break;
1167    case 5: XSCMPEXPDP(5); break;
1168    case 6: XSCMPEXPDP(6); break;
1169    case 7: XSCMPEXPDP(7); break;
1170    default:
1171       printf("Unhandled shift value for %s %x\n", __FUNCTION__, x_index);
1172    };
1173 }
1174 
1175 static test_list_t testgroup_vector_scalar_compare_exp_double[] = {
1176    { &test_xscmpexpdp , "xscmpexpdp " },
1177    { NULL             , NULL          },
1178 };
1179 
1180 #define XSTSTDCQP(R,DCMX)                                                \
1181    SET_FPSCR_ZERO                                                        \
1182    SET_CR_ZERO                                                           \
1183    __asm__ __volatile__                                                  \
1184       ("xststdcqp %0, %1, %2":: "i"(R), "wa"(vec_xb), "i"(DCMX));        \
1185    GET_CR(local_cr);                                                     \
1186    GET_FPSCR(local_fpscr);
1187 
1188 #define XSTSTDCDP(R,DCMX)                                                \
1189    SET_FPSCR_ZERO                                                        \
1190    SET_CR_ZERO                                                           \
1191    __asm__ __volatile__                                                  \
1192       ("xststdcdp %0, %1, %2":: "i"(R), "wa"(vec_xb), "i"(DCMX));        \
1193    GET_CR(local_cr);                                                     \
1194    GET_FPSCR(local_fpscr);
1195 
1196 #define XSTSTDCSP(R,DCMX)                                                \
1197    SET_FPSCR_ZERO                                                        \
1198    SET_CR_ZERO                                                           \
1199    __asm__ __volatile__                                                  \
1200       ("xststdcsp %0, %1, %2":: "i"(R), "wa"(vec_xb), "i"(DCMX));        \
1201    GET_CR(local_cr);                                                     \
1202    GET_FPSCR(local_fpscr);
1203 
1204 #define XVTSTDCDP(R,DCMX)                                                \
1205    SET_FPSCR_ZERO                                                        \
1206    SET_CR_ZERO                                                           \
1207    __asm__ __volatile__                                                  \
1208       ("xvtstdcdp %0, %1, %2": "=wa"(vec_xt) : "wa"(vec_xb), "i"(DCMX)); \
1209    GET_CR(local_cr);                                                     \
1210    GET_FPSCR(local_fpscr);
1211 
1212 #define XVTSTDCSP(R,DCMX)                                                \
1213    SET_FPSCR_ZERO                                                        \
1214    SET_CR_ZERO                                                           \
1215    __asm__ __volatile__                                                  \
1216       ("xvtstdcsp %0, %1, %2": "=wa"(vec_xt) : "wa"(vec_xb), "i"(DCMX)); \
1217    GET_CR(local_cr);                                                     \
1218    GET_FPSCR(local_fpscr);
1219 
test_xststdcqp(void)1220 static void test_xststdcqp(void) {
1221    switch(x_index) {
1222    case 1: XSTSTDCQP(3, 0x01); break; /* NaN */
1223    case 2: XSTSTDCQP(3, 0x02); break; /* +inf */
1224    case 3: XSTSTDCQP(3, 0x04); break; /* -inf */
1225    case 4: XSTSTDCQP(3, 0x08); break; /* +zero */
1226    case 5: XSTSTDCQP(3, 0x10); break; /* -zero */
1227    case 6: XSTSTDCQP(3, 0x20); break; /* +denormal */
1228    case 7: XSTSTDCQP(3, 0x40); break; /* -denormal */
1229    case 0: XSTSTDCQP(3, 0x7f); break; /* all of the above */
1230    }
1231 }
1232 
test_xststdcdp(void)1233 static void test_xststdcdp(void) {
1234    switch(x_index) {
1235    case 1: XSTSTDCDP(3, 0x01); break; /* NaN */
1236    case 2: XSTSTDCDP(3, 0x02); break; /* +inf */
1237    case 3: XSTSTDCDP(3, 0x04); break; /* -inf */
1238    case 4: XSTSTDCDP(3, 0x08); break; /* +zero */
1239    case 5: XSTSTDCDP(3, 0x10); break; /* -zero */
1240    case 6: XSTSTDCDP(3, 0x20); break; /* +denormal */
1241    case 7: XSTSTDCDP(3, 0x40); break; /* -denormal */
1242    case 0: XSTSTDCDP(3, 0x7f); break; /* all of the above */
1243    }
1244 }
1245 
test_xststdcsp(void)1246 static void test_xststdcsp(void) {
1247    switch(x_index) {
1248    case 1: XSTSTDCSP(3, 0x01); break; /* NaN */
1249    case 2: XSTSTDCSP(3, 0x02); break; /* +inf */
1250    case 3: XSTSTDCSP(3, 0x04); break; /* -inf */
1251    case 4: XSTSTDCSP(3, 0x08); break; /* +zero */
1252    case 5: XSTSTDCSP(3, 0x10); break; /* -zero */
1253    case 6: XSTSTDCSP(3, 0x20); break; /* +denormal */
1254    case 7: XSTSTDCSP(3, 0x40); break; /* -denormal */
1255    case 0: XSTSTDCSP(3, 0x7f); break; /* all of the above */
1256    }
1257 }
1258 
test_xvtstdcdp(void)1259 static void test_xvtstdcdp(void) {
1260    switch(x_index) {
1261    case 1: XVTSTDCDP(3, 0x01); break; /* NaN */
1262    case 2: XVTSTDCDP(3, 0x02); break; /* +inf */
1263    case 3: XVTSTDCDP(3, 0x04); break; /* -inf */
1264    case 4: XVTSTDCDP(3, 0x08); break; /* +zero */
1265    case 5: XVTSTDCDP(3, 0x10); break; /* -zero */
1266    case 6: XVTSTDCDP(3, 0x20); break; /* +denormal */
1267    case 7: XVTSTDCDP(3, 0x40); break; /* -denormal */
1268    case 0: XVTSTDCDP(3, 0x7f); break; /* all of the above */
1269    }
1270 }
1271 
1272 /* Note: Due to the test groupings, the input for the xvtstdcsp test is
1273  * actually 'double'.  It is good enough for this test, but may wish to break
1274  * this one out eventually.
1275  */
test_xvtstdcsp(void)1276 static void test_xvtstdcsp(void) {
1277    switch(x_index) {
1278    case 1: XVTSTDCSP(3, 0x01); break; /* NaN */
1279    case 2: XVTSTDCSP(3, 0x02); break; /* +inf */
1280    case 3: XVTSTDCSP(3, 0x04); break; /* -inf */
1281    case 4: XVTSTDCSP(3, 0x08); break; /* +zero */
1282    case 5: XVTSTDCSP(3, 0x10); break; /* -zero */
1283    case 6: XVTSTDCSP(3, 0x20); break; /* +denormal */
1284    case 7: XVTSTDCSP(3, 0x40); break; /* -denormal */
1285    case 0: XVTSTDCSP(3, 0x7f); break; /* all of the above */
1286    }
1287 }
1288 
1289 static test_list_t testgroup_vector_scalar_data_class[] = {
1290    { &test_xststdcqp, "xststdcqp " },
1291    { &test_xststdcdp, "xststdcdp " },
1292    { &test_xststdcsp, "xststdcsp " },
1293    { &test_xvtstdcsp, "xvtstdcsp " },
1294    { &test_xvtstdcdp, "xvtstdcdp " },
1295    { NULL           , NULL         },
1296 };
1297 
test_setb(void)1298 static void test_setb (void) {
1299    /* setb RT,BFA
1300     * BFA is a 3-bit field. */
1301 
1302    switch(x_index) {
1303    case 0:SET_CR0_FIELD(cr_value);
1304       __asm__ __volatile__ ("setb %0, 0" : "=r" (r14)); break;
1305 
1306    case 1:SET_CR1_FIELD(cr_value);
1307       __asm__ __volatile__ ("setb %0, 1" : "=r" (r14)); break;
1308 
1309    case 2:SET_CR2_FIELD(cr_value);
1310       __asm__ __volatile__ ("setb %0, 2" : "=r" (r14)); break;
1311 
1312    case 3:SET_CR3_FIELD(cr_value);
1313       __asm__ __volatile__ ("setb %0, 3" : "=r" (r14)); break;
1314 
1315    case 4:SET_CR4_FIELD(cr_value);
1316       __asm__ __volatile__ ("setb %0, 4" : "=r" (r14)); break;
1317 
1318    case 5:SET_CR5_FIELD(cr_value);
1319       __asm__ __volatile__ ("setb %0, 5" : "=r" (r14)); break;
1320 
1321    case 6:SET_CR6_FIELD(cr_value);
1322       __asm__ __volatile__ ("setb %0, 6" : "=r" (r14)); break;
1323 
1324    case 7:SET_CR7_FIELD(cr_value);
1325       __asm__ __volatile__ ("setb %0, 7" : "=r" (r14)); break;
1326     }
1327 
1328     GET_CR(local_cr);
1329 
1330     if (verbose) {
1331        dissect_cr(local_cr);
1332     }
1333 }
1334 
1335 static test_list_t testgroup_set_boolean[] = {
1336    { &test_setb, "setb"},
1337    { NULL      , NULL  },
1338 };
1339 
1340 /* cmprb l = 0:
1341  * compares r14 = src with range specified by values in r15
1342  *      bits (48:55 - 56:63)].
1343  *
1344  *  cmprb l=1:
1345  *  compares r14 = src with ranges between two pairs of values, as above and
1346  *  also in r15 bits (32:39 - 40:47 .
1347  */
test_cmprb_l0()1348 static void test_cmprb_l0() {
1349    switch(x_index) {
1350    case 0: __asm__ __volatile__ ("cmprb 0, 0, %0, %1" : : "r"(r14), "r"(r15));
1351       GET_CR(local_cr); break;
1352 
1353    case 1: __asm__ __volatile__ ("cmprb 1, 0, %0, %1" : : "r"(r14), "r"(r15));
1354       GET_CR(local_cr); break;
1355 
1356    case 2: __asm__ __volatile__ ("cmprb 2, 0, %0, %1" : : "r"(r14), "r"(r15));
1357       GET_CR(local_cr); break;
1358 
1359    case 3: __asm__ __volatile__ ("cmprb 3, 0, %0, %1" : : "r"(r14), "r"(r15));
1360       GET_CR(local_cr); break;
1361 
1362    case 4: __asm__ __volatile__ ("cmprb 4, 0, %0, %1" : : "r"(r14), "r"(r15));
1363       GET_CR(local_cr); break;
1364 
1365    case 5: __asm__ __volatile__ ("cmprb 5, 0, %0, %1" : : "r"(r14), "r"(r15));
1366       GET_CR(local_cr); break;
1367 
1368    case 6: __asm__ __volatile__ ("cmprb 6, 0, %0, %1" : : "r"(r14), "r"(r15));
1369       GET_CR(local_cr); break;
1370 
1371    case 7: __asm__ __volatile__ ("cmprb 7, 0, %0, %1" : : "r"(r14), "r"(r15));
1372       GET_CR(local_cr); break;
1373     }
1374 }
1375 
test_cmprb_l1()1376 static void test_cmprb_l1() {
1377    switch(x_index) {
1378    case 0: __asm__ __volatile__ ("cmprb 0, 1 ,%0, %1" : : "r"(r14), "r"(r15));
1379       GET_CR(local_cr); break;
1380 
1381    case 1: __asm__ __volatile__ ("cmprb 1, 1, %0, %1" : : "r"(r14), "r"(r15));
1382       GET_CR(local_cr); break;
1383 
1384    case 2: __asm__ __volatile__ ("cmprb 2, 1, %0, %1" : : "r"(r14), "r"(r15));
1385       GET_CR(local_cr); break;
1386 
1387    case 3: __asm__ __volatile__ ("cmprb 3, 1, %0, %1" : : "r"(r14), "r"(r15));
1388       GET_CR(local_cr); break;
1389 
1390    case 4: __asm__ __volatile__ ("cmprb 4, 1, %0, %1" : : "r"(r14), "r"(r15));
1391       GET_CR(local_cr); break;
1392 
1393    case 5: __asm__ __volatile__ ("cmprb 5, 1, %0, %1" : : "r"(r14), "r"(r15));
1394       GET_CR(local_cr); break;
1395 
1396    case 6: __asm__ __volatile__ ("cmprb 6, 1, %0, %1" : : "r"(r14), "r"(r15));
1397       GET_CR(local_cr); break;
1398 
1399    case 7: __asm__ __volatile__ ("cmprb 7, 1, %0, %1" : : "r"(r14), "r"(r15));
1400       GET_CR(local_cr); break;
1401     }
1402 }
1403 
test_cmpeqb()1404 static void test_cmpeqb() {
1405    switch(x_index) {
1406    case 0: __asm__ __volatile__ ("cmpeqb 0,%0, %1" : : "r"(r14), "r"(r15));
1407       GET_CR(local_cr); break;
1408 
1409    case 1: __asm__ __volatile__ ("cmpeqb 1,%0, %1" : : "r"(r14), "r"(r15));
1410       GET_CR(local_cr); break;
1411 
1412    case 2: __asm__ __volatile__ ("cmpeqb 2,%0, %1" : : "r"(r14), "r"(r15));
1413       GET_CR(local_cr); break;
1414 
1415    case 3: __asm__ __volatile__ ("cmpeqb 3,%0, %1" : : "r"(r14), "r"(r15));
1416       GET_CR(local_cr); break;
1417 
1418    case 4: __asm__ __volatile__ ("cmpeqb 4,%0, %1" : : "r"(r14), "r"(r15));
1419       GET_CR(local_cr); break;
1420 
1421    case 5: __asm__ __volatile__ ("cmpeqb 5,%0, %1" : : "r"(r14), "r"(r15));
1422       GET_CR(local_cr); break;
1423 
1424    case 6: __asm__ __volatile__ ("cmpeqb 6,%0, %1" : : "r"(r14), "r"(r15));
1425       GET_CR(local_cr); break;
1426 
1427    case 7: __asm__ __volatile__ ("cmpeqb 7,%0, %1" : : "r"(r14), "r"(r15));
1428       GET_CR(local_cr); break;
1429     }
1430 }
1431 
1432 static test_list_t testgroup_char_compare[] = {
1433    { &test_cmprb_l0, "cmprb l=0" },
1434    { &test_cmprb_l1, "cmprb l=1" },
1435    { &test_cmpeqb  , "cmpeqb"    },
1436    { NULL          , NULL        },
1437 };
1438 
test_bcdtrunc_p0(void)1439 static void test_bcdtrunc_p0(void) {
1440    __asm__ __volatile__ ("bcdtrunc.  %0, %1, %2, 0": "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1441 }
1442 
test_bcdtrunc_p1(void)1443 static void test_bcdtrunc_p1(void) {
1444    __asm__ __volatile__ ("bcdtrunc.  %0, %1, %2, 1": "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1445 }
1446 
test_bcdutrunc(void)1447 static void test_bcdutrunc(void) {
1448    __asm__ __volatile__ ("bcdutrunc. %0, %1, %2  ": "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1449 }
1450 
test_bcdadd_p0(void)1451 static void test_bcdadd_p0(void) {
1452    __asm__ __volatile__ ("bcdadd.   %0, %1, %2, 0" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1453 }
1454 
test_bcdadd_p1(void)1455 static void test_bcdadd_p1(void) {
1456    __asm__ __volatile__ ("bcdadd.   %0, %1, %2, 1" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1457 }
1458 
test_bcdsub_p0(void)1459 static void test_bcdsub_p0(void) {
1460    __asm__ __volatile__ ("bcdsub.   %0, %1, %2, 0" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1461 }
1462 
test_bcdsub_p1(void)1463 static void test_bcdsub_p1(void) {
1464    __asm__ __volatile__ ("bcdsub.   %0, %1, %2, 1" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1465 }
1466 
test_bcdcpsgn(void)1467 static void test_bcdcpsgn(void)  {
1468    __asm__ __volatile__ ("bcdcpsgn.  %0, %1, %2  ": "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1469 }
1470 
test_bcdctz_p0(void)1471 static void test_bcdctz_p0(void) {
1472    __asm__ __volatile__ ("bcdctz.   %0, %1, 0   " : "=v"(vec_xt) : "v"(vec_xb));
1473 }
1474 
test_bcdctz_p1(void)1475 static void test_bcdctz_p1(void) {
1476    __asm__ __volatile__ ("bcdctz.   %0, %1, 1   " : "=v"(vec_xt) : "v"(vec_xb));
1477 }
1478 
test_bcdsetsgn_p0(void)1479 static void test_bcdsetsgn_p0(void) {
1480    __asm__ __volatile__ ("bcdsetsgn. %0, %1, 0   " : "=v"(vec_xt) : "v"(vec_xb));
1481 }
1482 
test_bcdsetsgn_p1(void)1483 static void test_bcdsetsgn_p1(void) {
1484    __asm__ __volatile__ ("bcdsetsgn. %0, %1, 1   " : "=v"(vec_xt) : "v"(vec_xb));
1485 }
1486 
test_bcds_p0(void)1487 static void test_bcds_p0(void) {
1488    __asm__ __volatile__ ("bcds.     %0, %1, %2, 0" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1489 }
1490 
test_bcds_p1(void)1491 static void test_bcds_p1(void) {
1492    __asm__ __volatile__ ("bcds.     %0, %1, %2, 1" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1493 }
1494 
test_bcdus(void)1495 static void test_bcdus(void) {
1496    __asm__ __volatile__ ("bcdus.    %0, %1, %2  " : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1497 }
1498 
test_bcdsr_p0(void)1499 static void test_bcdsr_p0(void) {
1500    __asm__ __volatile__ ("bcdsr.    %0, %1, %2, 0" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1501 }
1502 
test_bcdsr_p1(void)1503 static void test_bcdsr_p1(void) {
1504    __asm__ __volatile__ ("bcdsr.    %0, %1, %2, 1" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1505 }
1506 
test_bcdcfn_p0(void)1507 static void test_bcdcfn_p0(void) {
1508    __asm__ __volatile__ ("bcdcfn.   %0, %1, 0   " : "=v"(vec_xt) : "v"(vec_xb));
1509 }
1510 
test_bcdcfn_p1(void)1511 static void test_bcdcfn_p1(void) {
1512    __asm__ __volatile__ ("bcdcfn.   %0, %1, 1   " : "=v"(vec_xt) : "v"(vec_xb));
1513 }
1514 
test_bcdcfz_p0(void)1515 static void test_bcdcfz_p0(void) {
1516    __asm__ __volatile__ ("bcdcfz.   %0, %1, 0   " : "=v"(vec_xt) : "v"(vec_xb));
1517 }
1518 
test_bcdcfz_p1(void)1519 static void test_bcdcfz_p1(void) {
1520    __asm__ __volatile__ ("bcdcfz.   %0, %1, 1   " : "=v"(vec_xt) : "v"(vec_xb));
1521 }
1522 
test_bcdctn(void)1523 static void test_bcdctn(void) {
1524    __asm__ __volatile__ ("bcdctn.   %0, %1     " : "=v"(vec_xt) : "v"(vec_xb));
1525 }
1526 
test_vmul10uq(void)1527 static void test_vmul10uq(void) {
1528    __asm__ __volatile__ ("vmul10uq   %0, %1     " : "=v"(vec_xt) : "v"(vec_xa));
1529 }
1530 
test_vmul10cuq(void)1531 static void test_vmul10cuq(void) {
1532    __asm__ __volatile__ ("vmul10cuq  %0, %1     " : "=v"(vec_xt) : "v"(vec_xa));
1533 }
1534 
test_vmul10euq(void)1535 static void test_vmul10euq(void) {
1536    __asm__ __volatile__ ("vmul10euq  %0, %1, %2  " : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1537 }
1538 
test_vmul10ecuq(void)1539 static void test_vmul10ecuq(void) {
1540    __asm__ __volatile__ ("vmul10ecuq %0, %1, %2  " : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1541 }
1542 
test_bcdctsq(void)1543 static void test_bcdctsq(void) {
1544    __asm__ __volatile__ ("bcdctsq.   %0, %1     " : "=v"(vec_xt) : "v"(vec_xb));
1545 }
1546 
test_bcdcfsq_p0(void)1547 static void test_bcdcfsq_p0(void) {
1548    __asm__ __volatile__ ("bcdcfsq.   %0, %1, 0   " : "=v"(vec_xt) : "v"(vec_xb));
1549 }
1550 
test_bcdcfsq_p1(void)1551 static void test_bcdcfsq_p1(void) {
1552    __asm__ __volatile__ ("bcdcfsq.   %0, %1, 1   " : "=v"(vec_xt) : "v"(vec_xb));
1553 }
1554 
1555 static test_list_t testgroup_bcd_misc[] = {
1556    { &test_bcdadd_p0   , "bcdadd. p0"    },
1557    { &test_bcdadd_p1   , "bcdadd. p1"    },
1558    { &test_bcdsub_p0   , "bcdsub. p0"    },
1559    { &test_bcdsub_p1   , "bcdsub. p1"    },
1560    { &test_bcdcfn_p0   , "bcdcfn. p0"    },
1561    { &test_bcdcfn_p1   , "bcdcfn. p1"    },
1562    { &test_bcdcfz_p0   , "bcdcfz. p0"    }, /* The p0, p1 substrings are used later */
1563    { &test_bcdcfz_p1   , "bcdcfz. p1"    }, /* " " */
1564    { &test_bcdctn      , "bcdctn.   "    },
1565    { &test_bcdctz_p0   , "bcdctz. p0"    }, /* note: p0, p1 substrings are used later */
1566    { &test_bcdctz_p1   , "bcdctz. p1"    }, /* " " */
1567    { &test_bcdcpsgn    , "bcdcpsgn."     },
1568    { &test_bcdsetsgn_p0, "bcdsetsgn. p0" },
1569    { &test_bcdsetsgn_p1, "bcdsetsgn. p1" },
1570    { &test_bcds_p0     , "bcds. p0"      },
1571    { &test_bcds_p1     , "bcds. p1"      },
1572    { &test_bcdus       , "bcdus. "       },
1573    { &test_bcdsr_p0    , "bcdsr. p0"     },
1574    { &test_bcdsr_p1    , "bcdsr. p1"     },
1575    { &test_bcdtrunc_p0 , "bcdtrunc. p0"  },
1576    { &test_bcdtrunc_p1 , "bcdtrunc. p1"  },
1577    { &test_bcdutrunc   , "bcdutrunc. "   },
1578    { &test_vmul10uq    , "vmul10uq "     },
1579    { &test_vmul10cuq   , "vmul10cuq "    },
1580    { &test_vmul10euq   , "vmul10euq "    },
1581    { &test_vmul10ecuq  , "vmul10ecuq "   },
1582    { &test_bcdctsq     , "bcdctsq."      },
1583    { &test_bcdcfsq_p0  , "bcdcfsq. p0"   },
1584    { &test_bcdcfsq_p1  , "bcdcfsq. p1"   },
1585    { NULL              , NULL            },
1586 };
1587 
test_wait(void)1588 static void test_wait(void) {
1589    __asm__ __volatile__ ("wait 0" : :);
1590 }
1591 
1592 static test_list_t testgroup_noop_misc[] = {
1593    { &test_wait, "wait ",},
1594    { NULL      , NULL,   },
1595 };
1596 
1597 /* The significance field can be any values within bits 10-15 of the
1598  * instruction.  For this test, limiting the values to one per bit location.
1599  */
test_dtstsfi()1600 static void test_dtstsfi() {
1601    _Decimal128 df14 = dfp_value.dec_val128;
1602    switch(dfp_significance) {
1603    case 0x00: __asm__ __volatile__ ("dtstsfi 3, 0x00, %0" : : "f" (df14));
1604       GET_CR(local_cr); break;
1605 
1606    case 0x01: __asm__ __volatile__ ("dtstsfi 3, 0x01, %0" : : "f" (df14));
1607       GET_CR(local_cr); break;
1608 
1609    case 0x02: __asm__ __volatile__ ("dtstsfi 3, 0x02, %0" : : "f" (df14));
1610       GET_CR(local_cr); break;
1611 
1612    case 0x03: __asm__ __volatile__ ("dtstsfi 3, 0x03, %0" : : "f" (df14));
1613       GET_CR(local_cr); break;
1614 
1615    case 0x04: __asm__ __volatile__ ("dtstsfi 3, 0x04, %0" : : "f" (df14));
1616       GET_CR(local_cr); break;
1617 
1618    case 0x06: __asm__ __volatile__ ("dtstsfi 3, 0x06, %0" : : "f" (df14));
1619       GET_CR(local_cr); break;
1620 
1621    case 0x08: __asm__ __volatile__ ("dtstsfi 3, 0x08, %0" : : "f" (df14));
1622       GET_CR(local_cr); break;
1623 
1624    case 0x0c: __asm__ __volatile__ ("dtstsfi 3, 0x0c, %0" : : "f" (df14));
1625       GET_CR(local_cr); break;
1626 
1627    case 0x10: __asm__ __volatile__ ("dtstsfi 3, 0x10, %0" : : "f" (df14));
1628       GET_CR(local_cr); break;
1629 
1630    case 0x18: __asm__ __volatile__ ("dtstsfi 3, 0x18, %0" : : "f" (df14));
1631       GET_CR(local_cr); break;
1632 
1633    case 0x20: __asm__ __volatile__ ("dtstsfi 3, 0x20, %0" : : "f" (df14));
1634       GET_CR(local_cr); break;
1635    }
1636 }
1637 
test_dtstsfiq()1638 static void test_dtstsfiq() {
1639    _Decimal128 df14 = dfp_value.dec_val128;
1640    switch(dfp_significance) {
1641    case 0x00: __asm__ __volatile__ ("dtstsfiq 3, 0x00, %0" : : "f" (df14));
1642       GET_CR(local_cr); break;
1643 
1644    case 0x01: __asm__ __volatile__ ("dtstsfiq 3, 0x01, %0" : : "f" (df14));
1645       GET_CR(local_cr); break;
1646 
1647    case 0x02: __asm__ __volatile__ ("dtstsfiq 3, 0x02, %0" : : "f" (df14));
1648       GET_CR(local_cr); break;
1649 
1650    case 0x03: __asm__ __volatile__ ("dtstsfiq 3, 0x03, %0" : : "f" (df14));
1651       GET_CR(local_cr); break;
1652 
1653    case 0x04: __asm__ __volatile__ ("dtstsfiq 3, 0x04, %0" : : "f" (df14));
1654       GET_CR(local_cr); break;
1655 
1656    case 0x06: __asm__ __volatile__ ("dtstsfiq 3, 0x06, %0" : : "f" (df14));
1657       GET_CR(local_cr); break;
1658 
1659    case 0x08: __asm__ __volatile__ ("dtstsfiq 3, 0x08, %0" : : "f" (df14));
1660       GET_CR(local_cr); break;
1661 
1662    case 0x0c: __asm__ __volatile__ ("dtstsfiq 3, 0x0c, %0" : : "f" (df14));
1663       GET_CR(local_cr); break;
1664 
1665    case 0x10: __asm__ __volatile__ ("dtstsfiq 3, 0x10, %0" : : "f" (df14));
1666       GET_CR(local_cr); break;
1667 
1668    case 0x18: __asm__ __volatile__ ("dtstsfiq 3, 0x18, %0" : : "f" (df14));
1669       GET_CR(local_cr); break;
1670 
1671    case 0x20: __asm__ __volatile__ ("dtstsfiq 3, 0x20, %0" : : "f" (df14));
1672       GET_CR(local_cr); break;
1673    }
1674 }
1675 
1676 static test_list_t testgroup_dfp_significance[] = {
1677    { &test_dtstsfi , "dtstsfi"  },
1678    { &test_dtstsfiq, "dtstsfiq" },
1679    { NULL          , NULL       },
1680 };
1681 
test_addpcis(void)1682 static void test_addpcis(void)  {
1683    switch (x_index) {
1684    case 0x0: __asm__ __volatile__ ("addpcis 14, %0"  : : "i"(0x0) ); break;
1685    case 0x1: __asm__ __volatile__ ("addpcis 14, %0"  : : "i"(0x1) ); break;
1686    case 0x2: __asm__ __volatile__ ("addpcis 14, %0"  : : "i"(0x2) ); break;
1687    case 0x3: __asm__ __volatile__ ("addpcis 14, %0"  : : "i"(0x40) ); break;
1688    case 0x4: __asm__ __volatile__ ("addpcis 14, %0"  : : "i"(0x800) ); break;
1689    case 0x5: __asm__ __volatile__ ("addpcis 14, %0"  : : "i"(0x2000) ); break;
1690    case 0x6: __asm__ __volatile__ ("addpcis 14, %0"  : : "i"(0x7fff) ); break;
1691    case 0x7: __asm__ __volatile__ ("addpcis 14, %0"  : : "i"(0x8000) ); break;
1692    case 0x8: __asm__ __volatile__ ("addpcis 14, -%0" : : "i"(0x0) ); break;
1693    case 0x9: __asm__ __volatile__ ("addpcis 14, -%0" : : "i"(0x1) ); break;
1694    case 0xa: __asm__ __volatile__ ("addpcis 14, -%0" : : "i"(0x2) ); break;
1695    case 0xb: __asm__ __volatile__ ("addpcis 14, -%0" : : "i"(0x40) ); break;
1696    case 0xc: __asm__ __volatile__ ("addpcis 14, -%0" : : "i"(0x800) ); break;
1697    case 0xd: __asm__ __volatile__ ("addpcis 14, -%0" : : "i"(0x2000) ); break;
1698    case 0xe: __asm__ __volatile__ ("addpcis 14, -%0" : : "i"(0x7fff) ); break;
1699    case 0xf: __asm__ __volatile__ ("addpcis 14, -%0" : : "i"(0x8000) ); break;
1700    }
1701 }
1702 
test_subpcis(void)1703 static void test_subpcis(void)  {
1704    switch (x_index) {
1705    case 0x0:  __asm__ __volatile__ ("subpcis 14, %0"  : : "i"(0x0) ); break;
1706    case 0x1:  __asm__ __volatile__ ("subpcis 14, %0"  : : "i"(0x1) ); break;
1707    case 0x2:  __asm__ __volatile__ ("subpcis 14, %0"  : : "i"(0x2) ); break;
1708    case 0x3:  __asm__ __volatile__ ("subpcis 14, %0"  : : "i"(0x40) ); break;
1709    case 0x4:  __asm__ __volatile__ ("subpcis 14, %0"  : : "i"(0x800) ); break;
1710    case 0x5:  __asm__ __volatile__ ("subpcis 14, %0"  : : "i"(0x2000) ); break;
1711    case 0x6:  __asm__ __volatile__ ("subpcis 14, %0"  : : "i"(0x7fff) ); break;
1712    case 0x7:  __asm__ __volatile__ ("subpcis 14, %0"  : : "i"(0x8000) ); break;
1713    case 0x8:  __asm__ __volatile__ ("subpcis 14, -%0" : : "i"(0x0) ); break;
1714    case 0x9:  __asm__ __volatile__ ("subpcis 14, -%0" : : "i"(0x1) ); break;
1715    case 0xa:  __asm__ __volatile__ ("subpcis 14, -%0" : : "i"(0x2) ); break;
1716    case 0xb:  __asm__ __volatile__ ("subpcis 14, -%0" : : "i"(0x40) ); break;
1717    case 0xc:  __asm__ __volatile__ ("subpcis 14, -%0" : : "i"(0x80) ); break;
1718    case 0xd:  __asm__ __volatile__ ("subpcis 14, -%0" : : "i"(0x200) ); break;
1719    case 0xe:  __asm__ __volatile__ ("subpcis 14, -%0" : : "i"(0x7fff) ); break;
1720    case 0xf:  __asm__ __volatile__ ("subpcis 14, -%0" : : "i"(0x8000) ); break;
1721    }
1722 }
1723 
1724 static test_list_t testgroup_pc_immediate_misc[] = {
1725    { &test_addpcis, "addpcis " },
1726    { &test_subpcis, "subpcis " },
1727    { NULL         , NULL       },
1728 };
1729 
test_xsiexpdp(void)1730 static void test_xsiexpdp(void) {
1731    __asm__ __volatile__ ("xsiexpdp   %0, %1, %2 " : "+wa" (vec_xt): "r" (r14), "r" (r15));
1732 }
1733 
test_xscvhpdp(void)1734 static void test_xscvhpdp(void) {
1735    __asm__ __volatile__ ("xscvhpdp %x0, %x1 " : "+wa" (vec_xt) : "wa" (vec_xb));
1736 }
1737 
test_xscvdphp(void)1738 static void test_xscvdphp(void) {
1739    __asm__ __volatile__ ("xscvdphp %x0, %x1 " : "+wi" (vec_xt) : "wi" (vec_xb));
1740 }
1741 
test_xvcvhpsp(void)1742 static void test_xvcvhpsp(void) {
1743    __asm__ __volatile__ ("xvcvhpsp %x0, %x1 " : "+ww" (vec_xt) : "ww" (vec_xb));
1744 }
1745 
test_xvcvsphp(void)1746 static void test_xvcvsphp(void) {
1747    __asm__ __volatile__ ("xvcvsphp %x0, %x1 " : "+ww" (vec_xt) : "ww" (vec_xb));
1748 }
1749 
1750 static test_list_t testgroup_vector_scalar_two_double[] = {
1751    { &test_xsiexpdp, "xsiexpdp" },
1752    { &test_xscvhpdp, "xscvhpdp" },
1753    { &test_xscvdphp, "xscvdphp" },
1754    { &test_xvcvhpsp, "xvcvhpsp" },
1755    { &test_xvcvsphp, "xvcvsphp" },
1756    { NULL          , NULL       },
1757 };
1758 
1759 
test_xsabsqp(void)1760 static void test_xsabsqp(void) {
1761    __asm__ __volatile__ ("xsabsqp %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1762 }
1763 
test_xscvdpqp(void)1764 static void test_xscvdpqp(void) {
1765    __asm__ __volatile__ ("xscvdpqp %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1766 }
1767 
test_xscvqpdp(void)1768 static void test_xscvqpdp(void) {
1769    __asm__ __volatile__ ("xscvqpdp %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1770 }
1771 
test_xscvqpdpo(void)1772 static void test_xscvqpdpo(void) {
1773    __asm__ __volatile__ ("xscvqpdpo %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1774 }
1775 
test_xscvqpsdz(void)1776 static void test_xscvqpsdz(void) {
1777    __asm__ __volatile__ ("xscvqpsdz %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1778 }
1779 
test_xscvqpswz(void)1780 static void test_xscvqpswz(void) {
1781    __asm__ __volatile__ ("xscvqpswz %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1782 }
1783 
test_xscvqpudz(void)1784 static void test_xscvqpudz(void) {
1785    __asm__ __volatile__ ("xscvqpudz %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1786 }
1787 
test_xscvqpuwz(void)1788 static void test_xscvqpuwz(void) {
1789    __asm__ __volatile__ ("xscvqpuwz %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1790 }
1791 
test_xscvsdqp(void)1792 static void test_xscvsdqp(void) {
1793    __asm__ __volatile__ ("xscvsdqp %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1794 }
1795 
test_xscvudqp(void)1796 static void test_xscvudqp(void) {
1797    __asm__ __volatile__ ("xscvudqp %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1798 }
1799 
test_xsxexpqp(void)1800 static void test_xsxexpqp(void) {
1801    __asm__ __volatile__ ("xsxexpqp %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1802 }
1803 
test_xsxsigqp(void)1804 static void test_xsxsigqp(void) {
1805    __asm__ __volatile__ ("xsxsigqp %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1806 }
1807 
test_xsnegqp(void)1808 static void test_xsnegqp(void) {
1809    __asm__ __volatile__ ("xsnegqp %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1810 }
1811 
test_xsnabsqp(void)1812 static void test_xsnabsqp(void) {
1813    __asm__ __volatile__ ("xsnabsqp %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1814 }
1815 
test_xssqrtqp(void)1816 static void test_xssqrtqp(void) {
1817    __asm__ __volatile__ ("xssqrtqp %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1818 }
1819 
test_xssqrtqpo(void)1820 static void test_xssqrtqpo(void) {
1821    __asm__ __volatile__ ("xssqrtqpo %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1822 }
1823 
1824 static test_list_t testgroup_vector_scalar_two_quad[] = {
1825    { &test_xsabsqp  , "xsabsqp "   },
1826    { &test_xscvdpqp , "xscvdpqp "  },
1827    { &test_xscvqpdp , "xscvqpdp "  },
1828    { &test_xscvqpdpo, "xscvqpdpo " },
1829    { &test_xscvqpsdz, "xscvqpsdz " },
1830    { &test_xscvqpswz, "xscvqpswz " },
1831    { &test_xscvqpudz, "xscvqpudz " },
1832    { &test_xscvqpuwz, "xscvqpuwz " },
1833    { &test_xscvsdqp , "xscvsdqp "  },
1834    { &test_xscvudqp , "xscvudqp "  },
1835    { &test_xsxexpqp , "xsxexpqp "  },
1836    { &test_xsxsigqp , "xsxsigqp "  },
1837    { &test_xsnegqp  , "xsnegqp "   },
1838    { &test_xsnabsqp , "xsnabsqp "  },
1839    { &test_xssqrtqp , "xssqrtqp "  },
1840    { &test_xssqrtqpo, "xssqrtqpo " },
1841    { NULL           , NULL         },
1842 };
1843 
test_xsaddqp(void)1844 static void test_xsaddqp(void) {
1845    __asm__ __volatile__ ("xsaddqp    %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1846 }
1847 
test_xsaddqpo(void)1848 static void test_xsaddqpo(void) {
1849    __asm__ __volatile__ ("xsaddqpo   %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1850 }
1851 
test_xscpsgnqp(void)1852 static void test_xscpsgnqp(void) {
1853    __asm__ __volatile__ ("xscpsgnqp  %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1854 }
1855 
test_xsdivqp(void)1856 static void test_xsdivqp(void) {
1857    __asm__ __volatile__ ("xsdivqp    %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1858 }
1859 
test_xsdivqpo(void)1860 static void test_xsdivqpo(void) {
1861    __asm__ __volatile__ ("xsdivqpo   %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1862 }
1863 
test_xsiexpqp(void)1864 static void test_xsiexpqp(void) {
1865    __asm__ __volatile__ ("xsiexpqp   %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1866 }
1867 
test_xsmaddqp(void)1868 static void test_xsmaddqp(void) {
1869    __asm__ __volatile__ ("xsmaddqp   %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1870 }
1871 
test_xsmaddqpo(void)1872 static void test_xsmaddqpo(void) {
1873    __asm__ __volatile__ ("xsmaddqpo  %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1874 }
1875 
test_xsmsubqp(void)1876 static void test_xsmsubqp(void) {
1877    __asm__ __volatile__ ("xsmsubqp   %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1878 }
1879 
test_xsmsubqpo(void)1880 static void test_xsmsubqpo(void) {
1881    __asm__ __volatile__ ("xsmsubqpo  %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1882 }
1883 
test_xsmulqp(void)1884 static void test_xsmulqp(void) {
1885    __asm__ __volatile__ ("xsmulqp   %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1886 }
1887 
test_xsmulqpo(void)1888 static void test_xsmulqpo(void) {
1889    __asm__ __volatile__ ("xsmulqpo  %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1890 }
1891 
test_xsnmaddqp(void)1892 static void test_xsnmaddqp(void) {
1893    __asm__ __volatile__ ("xsnmaddqp  %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1894 }
1895 
test_xsnmaddqpo(void)1896 static void test_xsnmaddqpo(void) {
1897    __asm__ __volatile__ ("xsnmaddqpo %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1898 }
1899 
test_xsnmsubqp(void)1900 static void test_xsnmsubqp(void) {
1901    __asm__ __volatile__ ("xsnmsubqp  %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1902 }
1903 
test_xsnmsubqpo(void)1904 static void test_xsnmsubqpo(void) {
1905    __asm__ __volatile__ ("xsnmsubqpo %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1906 }
1907 
test_xssubqp(void)1908 static void test_xssubqp(void) {
1909    __asm__ __volatile__ ("xssubqp    %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1910 }
1911 
test_xssubqpo(void)1912 static void test_xssubqpo(void) {
1913    __asm__ __volatile__ ("xssubqpo   %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1914 }
1915 
1916 static test_list_t testgroup_vector_three_quad[] = {
1917    { &test_xsaddqp   , "xsaddqp "    },
1918    { &test_xsaddqpo  , "xsaddqpo "   },
1919    { &test_xscpsgnqp , "xscpsgnqp "  },
1920    { &test_xsdivqp   , "xsdivqp "    },
1921    { &test_xsdivqpo  , "xsdivqpo "   },
1922    { &test_xsiexpqp  , "xsiexpqp "   },
1923    { &test_xsmaddqp  , "xsmaddqp "   },
1924    { &test_xsmaddqpo , "xsmaddqpo "  },
1925    { &test_xsmsubqp  , "xsmsubqp "   },
1926    { &test_xsmsubqpo , "xsmsubqpo "  },
1927    { &test_xsmulqp   , "xsmulqp "    },
1928    { &test_xsmulqpo  , "xsmulqpo "   },
1929    { &test_xsnmaddqp , "xsnmaddqp "  },
1930    { &test_xsnmaddqpo, "xsnmaddqpo " },
1931    { &test_xsnmsubqp , "xsnmsubqp "  },
1932    { &test_xsnmsubqpo, "xsnmsubqpo " },
1933    { &test_xssubqp   , "xssubqp "    },
1934    { &test_xssubqpo  , "xssubqpo "   },
1935    { NULL            , NULL          },
1936 };
1937 
1938 #define XSCMPEXPQP(x)                                                       \
1939    SET_FPSCR_ZERO                                                           \
1940    SET_CR_ZERO                                                              \
1941    __asm__ __volatile__                                                     \
1942       ("xscmpexpqp %0, %1, %2" :: "i"(x), "v"(vec_xa), "v"(vec_xb));        \
1943    GET_CR(local_cr);                                                        \
1944    GET_FPSCR(local_fpscr);
1945 
1946 #define XSCMPOQP(x)                                                         \
1947    SET_FPSCR_ZERO                                                           \
1948    SET_CR_ZERO                                                              \
1949    __asm__ __volatile__                                                     \
1950       ("xscmpoqp %0, %1, %2" :: "i"(x), "v"(vec_xa), "v"(vec_xb));          \
1951    GET_CR(local_cr);                                                        \
1952    GET_FPSCR(local_fpscr);
1953 
1954 #define XSCMPUQP(x)                                                         \
1955    SET_FPSCR_ZERO                                                           \
1956    SET_CR_ZERO                                                              \
1957    __asm__ __volatile__                                                     \
1958       ("xscmpuqp %0, %1, %2"::"i"(x), "v"(vec_xa), "v"(vec_xb));            \
1959    GET_CR(local_cr);                                                        \
1960    GET_FPSCR(local_fpscr);
1961 
test_xscmpexpqp(void)1962 static void test_xscmpexpqp(void) {
1963    switch(x_index) {
1964    case 0: XSCMPEXPQP(0); break;
1965    case 1: XSCMPEXPQP(1); break;
1966    case 2: XSCMPEXPQP(2); break;
1967    case 3: XSCMPEXPQP(3); break;
1968    case 4: XSCMPEXPQP(4); break;
1969    case 5: XSCMPEXPQP(5); break;
1970    case 6: XSCMPEXPQP(6); break;
1971    case 7: XSCMPEXPQP(7); break;
1972    default:
1973       printf("Unhandled shift value for %s %x\n", __FUNCTION__, x_index);
1974    };
1975 }
1976 
test_xscmpoqp(void)1977 static void test_xscmpoqp(void) {
1978    switch(x_index) {
1979    case 0: XSCMPOQP(0); break;
1980    case 1: XSCMPOQP(1); break;
1981    case 2: XSCMPOQP(2); break;
1982    case 3: XSCMPOQP(3); break;
1983    case 4: XSCMPOQP(4); break;
1984    case 5: XSCMPOQP(5); break;
1985    case 6: XSCMPOQP(6); break;
1986    case 7: XSCMPOQP(7); break;
1987    default:
1988       printf("Unhandled shift value for %s %x\n", __FUNCTION__, x_index);
1989    };
1990 }
1991 
test_xscmpuqp(void)1992 static void test_xscmpuqp(void) {
1993    switch(x_index) {
1994    case 0: XSCMPUQP(0); break;
1995    case 1: XSCMPUQP(1); break;
1996    case 2: XSCMPUQP(2); break;
1997    case 3: XSCMPUQP(3); break;
1998    case 4: XSCMPUQP(4); break;
1999    case 5: XSCMPUQP(5); break;
2000    case 6: XSCMPUQP(6); break;
2001    case 7: XSCMPUQP(7); break;
2002    default:
2003       printf("Unhandled shift value for %s %x\n", __FUNCTION__, x_index);
2004    };
2005 }
2006 
2007 static test_list_t testgroup_vector_scalar_compare_quads[] = {
2008    { &test_xscmpexpqp, "xscmpexpqp" },
2009    { &test_xscmpoqp  , "xscmpoqp  " },
2010    { &test_xscmpuqp  , "xscmpuqp  " },
2011    { NULL            , NULL         },
2012 };
2013 
2014 #define XSRQPI(R,RMC)                                                        \
2015    SET_FPSCR_ZERO                                                            \
2016    SET_CR_ZERO                                                               \
2017    __asm__ __volatile__                                                      \
2018       ("xsrqpi %1, %0, %2, %3" : "=v"(vec_xt) : "i"(R), "v"(vec_xb), "i"(RMC)); \
2019    GET_CR(local_cr);                                                         \
2020    GET_FPSCR(local_fpscr);
2021 
2022 #define XSRQPIX(R,RMC)                                                       \
2023    SET_FPSCR_ZERO                                                            \
2024    SET_CR_ZERO                                                               \
2025    __asm__ __volatile__                                                      \
2026       ("xsrqpix %1, %0, %2, %3" : "=v"(vec_xt) : "i"(R), "v"(vec_xb), "i"(RMC));\
2027    GET_CR(local_cr);                                                         \
2028    GET_FPSCR(local_fpscr);
2029 
2030 #define XSRQPXP(R,RMC)                                                       \
2031    SET_FPSCR_ZERO                                                            \
2032    SET_CR_ZERO                                                               \
2033    __asm__ __volatile__                                                      \
2034       ("xsrqpxp %1, %0, %2, %3" : "=v"(vec_xt) : "i"(R), "v"(vec_xb), "i"(RMC));\
2035    GET_CR(local_cr);                                                         \
2036    GET_FPSCR(local_fpscr);
2037 
2038 /* For the scalar round to quad instructions, x_index is used to key into
2039  * two fields; x_index bit [2] becomes the one-bit 'R' and x_index bits [0, 1]
2040  * becomes the two-bit 'RMC'.
2041  */
test_xsrqpi(void)2042 static void test_xsrqpi(void) {
2043    switch(x_index) {
2044    case 0: XSRQPI(0, 0); break;
2045    case 1: XSRQPI(0, 1); break;
2046    case 2: XSRQPI(0, 2); break;
2047    case 3: XSRQPI(0, 3); break;
2048    case 4: XSRQPI(1, 0); break;
2049    case 5: XSRQPI(1, 1); break;
2050    case 6: XSRQPI(1, 2); break;
2051    case 7: XSRQPI(1, 3); break;
2052    }
2053 }
test_xsrqpix(void)2054 static void test_xsrqpix(void) {
2055    switch(x_index) {
2056    case 0: XSRQPIX(0, 0); break;
2057    case 1: XSRQPIX(0, 1); break;
2058    case 2: XSRQPIX(0, 2); break;
2059    case 3: XSRQPIX(0, 3); break;
2060    case 4: XSRQPIX(1, 0); break;
2061    case 5: XSRQPIX(1, 1); break;
2062    case 6: XSRQPIX(1, 2); break;
2063    case 7: XSRQPIX(1, 3); break;
2064    }
2065 }
2066 
test_xsrqpxp(void)2067 static void test_xsrqpxp(void) {
2068    switch(x_index) {
2069    case 0: XSRQPXP(0, 0); break;
2070    case 1: XSRQPXP(0, 1); break;
2071    case 2: XSRQPXP(0, 2); break;
2072    case 3: XSRQPXP(0, 3); break;
2073    case 4: XSRQPXP(1, 0); break;
2074    case 5: XSRQPXP(1, 1); break;
2075    case 6: XSRQPXP(1, 2); break;
2076    case 7: XSRQPXP(1, 3); break;
2077    }
2078 }
2079 
2080 static test_list_t testgroup_vector_scalar_rounding_quads[] = {
2081    { &test_xsrqpi , "xsrqpi " },
2082    { &test_xsrqpix, "xsrqpix" },
2083    { &test_xsrqpxp, "xsrqpxp" },
2084    { NULL         , NULL      },
2085 };
2086 
2087 /* Move From FPSCR variants:
2088  * Move From FpScr [ &
2089  *                    Clear Enables |
2090  *                    Lightweight |
2091  *                    Control    [&
2092  *                                 set DRN [ Immediate] |
2093  *                                 set RN  [ Immediate ] ]]
2094  */
2095 /* mffs FRT # Move From FPSCR*/
test_mffs(void)2096 static void test_mffs (void) {
2097    __asm__ __volatile__ ("mffs %0"  : "=f"(f14) );
2098    GET_FPSCR(local_fpscr);
2099 }
2100 
2101 /* mffsce FRT # Move From FPSCR and Clear Enables */
test_mffsce(void)2102 static void test_mffsce (void) {
2103    __asm__ __volatile__ ("mffsce %0"  : "=f"(f14) );
2104    GET_FPSCR(local_fpscr);
2105 }
2106 
2107 /* mffscdrn FRT,FRB # Move From FpScr and Control &set DRN */
test_mffscdrn(void)2108 static void test_mffscdrn (void) {
2109    __asm__ __volatile__ ("mffscdrn %0,%1"  : "=f"(f14): "f"(f15) );
2110    GET_FPSCR(local_fpscr);
2111 }
2112 
2113 /* mffscdrni FRT,DRM # Move From FpScr & Control &set DRN Immediate*/
test_mffscdrni(void)2114 static void test_mffscdrni (void) {
2115    switch(x_shift) {
2116       default:
2117       case 0:
2118          __asm__ __volatile__ ("mffscdrni %0,0"  : "=f"(f14) );
2119          GET_FPSCR(local_fpscr);
2120          break;
2121       case 1:
2122          __asm__ __volatile__ ("mffscdrni %0,1"  : "=f"(f14) );
2123          GET_FPSCR(local_fpscr);
2124          break;
2125       case 2:
2126          __asm__ __volatile__ ("mffscdrni %0,2"  : "=f"(f14) );
2127          GET_FPSCR(local_fpscr);
2128          break;
2129    }
2130 }
2131 
2132 /* mffscrn FRT,FRB # Move From FpScr and Control &set RN*/
test_mffscrn(void)2133 static void test_mffscrn (void) {
2134    __asm__ __volatile__ ("mffscrn %0,%1"  : "=f"(f14):"f"(f15));
2135    GET_FPSCR(local_fpscr);
2136 }
2137 
2138 /* mffscrni FRT,RM # Move from FpScr and Control &set RN Immediate*/
test_mffscrni(void)2139 static void test_mffscrni (void) {
2140    switch(x_shift) {
2141       case 0:
2142          __asm__ __volatile__ ("mffscrni %0,0"  : "=f"(f14) );
2143          GET_FPSCR(local_fpscr);
2144          break;
2145       case 1:
2146          __asm__ __volatile__ ("mffscrni %0,1"  : "=f"(f14) );
2147          GET_FPSCR(local_fpscr);
2148          break;
2149       case 2:
2150          __asm__ __volatile__ ("mffscrni %0,2"  : "=f"(f14) );
2151          GET_FPSCR(local_fpscr);
2152          break;
2153    }
2154 }
2155 
2156 /* mffsl FRT  # Move From FpScr Lightweight */
test_mffsl(void)2157 static void test_mffsl (void) {
2158    __asm__ __volatile__ ("mffsl %0"  : "=f"(f14) );
2159    GET_FPSCR(local_fpscr);
2160 }
2161 
2162 /* mffs* instructions using FRT only. */
2163 /* Note to self - Watch DRM,RM fields. */
2164 static test_list_t testgroup_mffs_misc[] = {
2165    //   { &test_mffsce,    "mffsce" },
2166    //   { &test_mffsl,     "mffsl" },
2167    { &test_mffs,      "mffs" },
2168    { NULL               , NULL      },
2169 };
2170 
2171 /* mffs* instructions using FRT,FRB. */
2172 static test_list_t testgroup_mffs_misc_one[] = {
2173    //   { &test_mffscdrni, "mffscdrni" },
2174    //   { &test_mffscdrn,  "mffscdrn" },
2175    //   { &test_mffscrni,  "mffscrni" },
2176    //   { &test_mffscrn,   "mffscrn" },
2177    { NULL               , NULL      },
2178 };
2179 
2180 
2181 /* ###### begin all_tests table.  */
2182 
2183 /* table containing all of the instruction groups */
2184 struct test_group_table_t {
2185    test_list_t *tests;
2186    const char *name;
2187    unsigned int flags;
2188 };
2189 
2190 typedef struct test_group_table_t test_group_table_t;
2191 
2192 static test_group_table_t all_tests[] = {
2193    {
2194       testgroup_ia_ops_two,
2195       "PPC integer arith instructions with two args",
2196       PPC_INTEGER | PPC_ARITH | PPC_TWO_ARGS,
2197    },
2198    {
2199       testgroup_shifted_one,
2200       "ppc one argument plus shift",
2201       PPC_MISC | PPC_CR | PPC_TWO_ARGS,
2202    },
2203    {
2204       testgroup_three_args,
2205       "ppc three parameter ops",
2206       PPC_INTEGER | PPC_ARITH | PPC_THREE_ARGS,
2207    },
2208    {
2209       testgroup_logical_one,
2210       "ppc count zeros",
2211       PPC_INTEGER | PPC_LOGICAL | PPC_ONE_ARG,
2212    },
2213    {
2214       testgroup_set_boolean,
2215       "ppc set boolean",
2216       PPC_INTEGER | PPC_LOGICAL | PPC_ONE_IMM,
2217    },
2218    {
2219       testgroup_char_compare,
2220       "ppc char compare",
2221       PPC_INTEGER | PPC_COMPARE,
2222    },
2223    {
2224       testgroup_vsx_absolute,
2225       "ppc vector absolutes",
2226       PPC_ALTIVEC | PPC_ARITH | PPC_TWO_ARGS,
2227    },
2228    {
2229       testgroup_vector_immediate,
2230       "ppc vector logical immediate",
2231       PPC_ALTIVEC | PPC_LOGICAL | PPC_ONE_IMM,
2232    },
2233    {
2234       testgroup_vector_logical_one,
2235       "ppc vector logical one",
2236       PPC_ALTIVEC | PPC_LOGICAL | PPC_ONE_ARG,
2237    },
2238    {
2239       testgroup_vector_extend_sign,
2240       "ppc vector extend sign",
2241       PPC_ALTIVEC | PPC_LOGICAL | PPC_TWO_ARGS,
2242    },
2243    {
2244       testgroup_vector_three_quad,
2245       "ppc vector three quad",
2246       PPC_ALTIVEC | PPC_LOGICAL | PPC_THREE_ARGS,
2247    },
2248    {
2249       testgroup_vector_scalar_two_quad,
2250       "ppc vector scalar quad",
2251       PPC_ALTIVEC_QUAD | PPC_LOGICAL | PPC_TWO_ARGS,
2252    },
2253    {
2254       testgroup_vector_scalar_compare_quads,
2255       "ppc vector scalar compare exponents quads",
2256       PPC_ALTIVEC_QUAD | PPC_COMPARE | PPC_COMPARE_ARGS,
2257    },
2258    {
2259       testgroup_vector_scalar_rounding_quads,
2260       "ppc vector scalar rounding quads",
2261       PPC_ALTIVEC_QUAD | PPC_ROUND,
2262    },
2263    {
2264       testgroup_vsx_xxpermute,
2265       "ppc vector permutes",
2266       PPC_ALTIVEC | PPC_PERMUTE,
2267    },
2268    {
2269       testgroup_vector_four,
2270       "ppc vector three args + dest",
2271       PPC_ALTIVEC | PPC_LOGICAL | PPC_FOUR_ARGS,
2272    },
2273    {
2274       testgroup_vector_inserts,
2275       "ppc vector inserts",
2276       PPC_ALTIVEC | PPC_INSERTEXTRACT | PPC_ONE_IMM,
2277    },
2278    {
2279       testgroup_vector_extract,
2280       "ppc vector extract from vector to reg",
2281       PPC_ALTIVEC | PPC_INSERTEXTRACT | PPC_TWO_ARGS,
2282    },
2283    {
2284       testgroup_vector_count_bytes,
2285       "ppc vector count leading/trailing bytes",
2286       PPC_ALTIVEC | PPC_POPCNT,
2287    },
2288    {
2289       testgroup_vector_scalar_loadstore_length,
2290       "ppc vector load/store",
2291       PPC_ALTIVEC | PPC_LDST | PPC_ONE_IMM,
2292    },
2293    {
2294       testgroup_vector_loadstore,
2295       "ppc vector load/store",
2296       PPC_ALTIVEC | PPC_LDST | PPC_TWO_ARGS,
2297    },
2298    {
2299       testgroup_vectorscalar_move_tofrom,
2300       "ppc vector scalar move to/from",
2301       PPC_MISC | PPC_TWO_ARGS,
2302    },
2303    {
2304       testgroup_vector_scalar_compare_exp_double,
2305       "ppc vector scalar compare exponents doubles",
2306       PPC_ALTIVEC_DOUBLE | PPC_COMPARE | PPC_COMPARE_ARGS,
2307    },
2308    {
2309       testgroup_vector_scalar_data_class,
2310       "ppc vector scalar test data class tests",
2311       PPC_ALTIVEC_DOUBLE | PPC_COMPARE | PPC_ONE_ARG,
2312    },
2313    {
2314       testgroup_vector_scalar_two_double,
2315       "ppc vector scalar tests against float double two args ",
2316       PPC_ALTIVEC_DOUBLE | PPC_COMPARE | PPC_TWO_ARGS,
2317    },
2318    {
2319       testgroup_dfp_significance,
2320       "ppc dfp significance",
2321       PPC_DFP,
2322    },
2323    {
2324       testgroup_bcd_misc,
2325       "ppc bcd misc",
2326       PPC_BCD,
2327    },
2328    {
2329       testgroup_noop_misc,
2330       "ppc noop misc",
2331       PPC_NO_OP,
2332    },
2333    {
2334       testgroup_pc_immediate_misc,
2335       "ppc addpc_misc",
2336       PPC_PC_IMMEDIATE,
2337    },
2338    {
2339       testgroup_mffs_misc,
2340       "ppc mffpscr",
2341       PPC_MFFS,
2342    },
2343    {
2344       testgroup_mffs_misc_one,
2345       "ppc mffpscr",
2346       PPC_MFFS,
2347    },
2348    { NULL,                   NULL,               0x00000000, },
2349 };
2350 
2351 #define instruction_touches_xer(instruction_name) \
2352    (strncmp(instruction_name, "addex", 5) == 0)
2353 
testfunction_int_two_args(const char * instruction_name,test_func_t func,unsigned int test_flags)2354 static void testfunction_int_two_args (const char* instruction_name,
2355                                        test_func_t func,
2356                                        unsigned int test_flags)
2357 {
2358    volatile HWord_t res;
2359    volatile unsigned int cr;
2360    int i, j;
2361 
2362    VERBOSE_FUNCTION_CALLOUT
2363 
2364    for (i = 0; i < nb_iargs; i++) {
2365       for (j = 0; j < nb_iargs; j++) {
2366 
2367          r14 = iargs[i];
2368          r15 = iargs[j];
2369 
2370          SET_CR_ZERO;
2371          (*func)();
2372          GET_CR(cr);
2373          GET_XER(local_xer);
2374          res = r17;
2375 
2376          printf("%s %016lx, %016lx => %016lx (%08x)",
2377                 instruction_name, (long unsigned)iargs[i],
2378                 (long unsigned)iargs[j], (long unsigned)res,
2379                 cr);
2380          if (instruction_touches_xer(instruction_name)) {
2381             dissect_xer(local_xer);
2382          }
2383          printf("\n");
2384       }
2385       if (verbose) printf("\n");
2386    }
2387 }
2388 
2389 #define instruction_sets_cr0_to_zero(inst_name)   \
2390    ( (strncmp(inst_name, "cnttzw.", 7) == 0 ) ||   \
2391      (strncmp(inst_name, "cnttzd.", 7) == 0 ) )
2392 
testfunction_logical_one(const char * instruction_name,test_func_t func,unsigned int test_flags)2393 static void testfunction_logical_one (const char* instruction_name,
2394                                       test_func_t func,
2395                                       unsigned int test_flags) {
2396    int i;
2397    volatile HWord_t res;
2398    volatile unsigned int cr;
2399 
2400    VERBOSE_FUNCTION_CALLOUT
2401 
2402    for (i = 0; i < nb_iargs; i++) {
2403 
2404       r14 = iargs[i];
2405 
2406       /* The logical instructions will set CR fields to zero, so
2407        * lets start with some non zero content in CR0.
2408        */
2409       SET_CR0_FIELD(0xF);
2410 
2411       (*func)();
2412 
2413       res = r17;
2414       GET_CR(cr);
2415 
2416       printf("%s %016lx => %016lx",
2417              instruction_name, (long unsigned)iargs[i], (long unsigned)res);
2418 
2419       if (instruction_sets_cr0_to_zero(instruction_name)
2420           && ((cr & 0xF0000000) != 0 )) {
2421          /* The dotted version sets the CR0 to 0, verify */
2422          printf(" Expected cr0 to be zero, it is (%08x)\n", cr & 0xF0000000);
2423       }
2424       printf("\n");
2425 
2426       if (verbose) printf("\n");
2427    }
2428 }
2429 
testfunction_one_arg_with_shift(const char * instruction_name,test_func_t test_function,unsigned int ignore_test_flags)2430 void testfunction_one_arg_with_shift (const char* instruction_name,
2431                                       test_func_t test_function,
2432                                       unsigned int ignore_test_flags)
2433 {
2434    /*This function uses global variable x_shift */
2435    volatile HWord_t res;
2436    volatile unsigned int cr;
2437    int i, j;
2438 
2439    VERBOSE_FUNCTION_CALLOUT
2440 
2441    for (i = 0; i < SHIFT_VALUES_SIZE; i++) {
2442       for (j = 0; j < SHIFT_ARRAY_SIZE; j++) {
2443 
2444          r14 = values_to_shift[i];
2445          x_shift = shift_amounts[j];
2446 
2447          SET_CR_ZERO;
2448 
2449          (*test_function)();
2450 
2451          GET_CR(cr);
2452          res = r17;
2453 
2454          printf("%s %016lx, %016lx => %016lx (%08x)\n",
2455                 instruction_name, (long unsigned)values_to_shift[i],
2456                 (long unsigned)x_shift, (long unsigned)res, cr);
2457       }
2458    }
2459 }
2460 
testfunction_three_args(const char * instruction_name,test_func_t test_function,unsigned int ignore_test_flags)2461 static void testfunction_three_args (const char* instruction_name,
2462                                      test_func_t test_function,
2463                                      unsigned int ignore_test_flags)
2464 {
2465    volatile HWord_t res;
2466    volatile unsigned int cr;
2467    int i, j, l;
2468 
2469    VERBOSE_FUNCTION_CALLOUT
2470 
2471    for (i = 0; i < nb_iargs; i++) {
2472       for (j = 0; j < nb_iargs; j++) {
2473          for (l = 0; l < nb_iargs; l++) {
2474             r14 = iargs[i];
2475             r15 = iargs[j];
2476             r16 = iargs[l];
2477 
2478             SET_CR_ZERO;
2479 
2480             (*test_function)();
2481 
2482             GET_CR(cr);
2483             res = r17;
2484 
2485             printf("%s %016lx, %016lx, %016lx  => %016lx (%08x)\n",
2486                    instruction_name,
2487                    (long unsigned)r14, (long unsigned)r15,
2488                    (long unsigned)r16, (long unsigned)res,
2489                    cr);
2490          }
2491       }
2492    }
2493 }
2494 
testfunction_vector_absolute(const char * instruction_name,test_func_t test_function,unsigned int ignore_test_flags)2495 static void testfunction_vector_absolute (const char* instruction_name,
2496                                           test_func_t test_function,
2497                                           unsigned int ignore_test_flags)
2498 {
2499    /* Notes:
2500     *   iterate across xa, xb values.
2501     *   Results are in xt.
2502     */
2503    volatile unsigned int cr;
2504    int i, j;
2505 
2506    VERBOSE_FUNCTION_CALLOUT
2507 
2508    for (i = 0; i < nb_vargs; i += 4) {
2509       /* patterns more interesting when shifted like so.. */
2510       for (j = 0; j < nb_vpcv; j += 2) {
2511 
2512          vec_xa = (vector unsigned long){vsxargs[i], vsxargs[i+1]};
2513          vec_xb = (vector unsigned long){vsxargs[j], vsxargs[j]};
2514          vec_xt = (vector unsigned long){0, 0};
2515 
2516          printf("%s xa:%016lx %016lx xb:%016lx %016lx ",
2517                 instruction_name,
2518                 vec_xa[1],vec_xa[0],
2519                 vec_xb[0],vec_xb[1]
2520                 );
2521          printf(" => ");
2522 
2523          SET_CR_ZERO;
2524 
2525          (*test_function)();
2526 
2527          GET_CR(cr);
2528 
2529          printf(" xt:%016lx %016lx (%08x)\n", vec_xt[0], vec_xt[1], cr);
2530       }
2531       if (verbose) printf("\n");
2532    }
2533 }
2534 
testfunction_vector_xxpermute(const char * instruction_name,test_func_t test_function,unsigned int ignore_test_flags)2535 static void testfunction_vector_xxpermute (const char* instruction_name,
2536                                            test_func_t test_function,
2537                                            unsigned int ignore_test_flags)
2538 {
2539    /* Notes:
2540     *   VSX permute uses both xt and xa as source registers.
2541     *   Permute control vector is in xb.
2542     *   Results are in xt.
2543     */
2544    volatile unsigned int cr;
2545    int i, j;
2546 
2547    VERBOSE_FUNCTION_CALLOUT
2548 
2549    for (i = 0; i < nb_vargs; i += 4) {
2550       for (j = 0; j < nb_vpcv; j += 2) {
2551 
2552          vec_xa = (vector unsigned long){vsxargs[i], vsxargs[i+1]};
2553          vec_xt = (vector unsigned long){vsxargs[i+2], vsxargs[i+3]};
2554          vec_xb = (vector unsigned long){vpcv[j], vpcv[j+1]};
2555 
2556          printf("%s %016lx %016lx %016lx %016lx, pcv[%016lx %016lx] => ",
2557                 instruction_name,
2558                 vec_xa[1], vec_xa[0],
2559                 vec_xt[1], vec_xt[0],
2560                 vec_xb[0], vec_xb[1]);
2561 
2562          SET_CR_ZERO;
2563 
2564          (*test_function)();
2565 
2566          GET_CR(cr);
2567 
2568          printf(" %016lx %016lx (%08x)\n", vec_xt[0], vec_xt[1], cr);
2569 
2570 #if defined (DEBUG_VECTOR_PERMUTE)
2571          printf("DEBUG:%s %016lx %016lx %016lx %016lx, pcv[%016lx %016lx]\n",
2572                 ignore_name,
2573                 vec_xa[0], vec_xa[1],
2574                 vec_xt[0], vec_xt[1],
2575                 vec_xb[0], vec_xb[1]);
2576 #endif
2577       }
2578       if (verbose) printf("\n");
2579    }
2580 }
2581 
testfunction_vector_logical_one(const char * instruction_name,test_func_t test_function,unsigned int ignore_test_flags)2582 static void testfunction_vector_logical_one (const char* instruction_name,
2583                                              test_func_t test_function,
2584                                              unsigned int ignore_test_flags)
2585 {
2586    /* Notes:
2587     *   vector instructions with one input, one output.
2588     *   xt, xa
2589     */
2590    int i;
2591    int t;
2592 
2593    VERBOSE_FUNCTION_CALLOUT
2594 
2595    for (i = 0; i < nb_vargs; i += 2) {
2596 
2597       vec_xa = (vector unsigned long){vsxargs[i], vsxargs[i+1]};
2598       for (t = 0; t < 2; t++) {
2599          vec_xt[0] = (t == 0) ? 0 : 0xffffffffffffffff;
2600          vec_xt[1] = (t == 0) ? 0 : 0xffffffffffffffff;
2601 
2602          printf("%s xa:%016lx %016lx xt:%016lx %016lx => ",
2603                 instruction_name,
2604                 vec_xa[0], vec_xa[1],
2605                 vec_xt[0], vec_xt[1]);
2606 
2607          (*test_function)();
2608 
2609          printf(" xt:%016lx %016lx\n",
2610                 vec_xt[0], vec_xt[1]);
2611       }
2612    }
2613    if (verbose) printf("\n");
2614 }
2615 
testfunction_vector_logical_four(const char * instruction_name,test_func_t test_function,unsigned int ignore_test_flags)2616 static void testfunction_vector_logical_four (const char* instruction_name,
2617                                               test_func_t test_function,
2618                                               unsigned int ignore_test_flags) {
2619    /* Notes:
2620     *   vector instructions with three input arguments, one output.
2621     *   xt, xa, xb, xc.
2622     *   Permute control vector is in xc.
2623     *   Results are in xt.
2624     */
2625    volatile unsigned int cr;
2626    int i, j;
2627    int p;
2628 
2629    VERBOSE_FUNCTION_CALLOUT
2630 
2631    for (i = 0; i < nb_vargs; i += 4) {
2632       for (j = 0; j < nb_vargs; j += 4) {
2633          for (p = 0; p < nb_vpcv; p += 2) {
2634 
2635             vec_xa = (vector unsigned long){vsxargs[i], vsxargs[i+1]};
2636             vec_xb = (vector unsigned long){vsxargs[j], vsxargs[j+1]};
2637             vec_xc = (vector unsigned long){vpcv[p], vpcv[p+1]};
2638 
2639             printf("%s %016lx %016lx %016lx %016lx, pcv[%016lx %016lx] => ",
2640                    instruction_name,
2641                    vec_xa[1], vec_xa[0],
2642                    vec_xb[1], vec_xb[0],
2643                    vec_xc[0], vec_xc[1]);
2644 
2645             SET_CR_ZERO;
2646 
2647             (*test_function)();
2648 
2649             GET_CR(cr);
2650 
2651             printf(" %016lx %016lx (%08x)\n", vec_xt[0], vec_xt[1], cr);
2652          }
2653       }
2654 
2655       if (verbose) printf("\n");
2656    }
2657 }
2658 
2659 static
testfunction_vector_insert_or_extract_immediate(const char * instruction_name,test_func_t test_function,unsigned int ignore_test_flags)2660 void testfunction_vector_insert_or_extract_immediate (const char* instruction_name,
2661                                                       test_func_t test_function,
2662                                                       unsigned int ignore_test_flags) {
2663    /* Uses global variable x_index */
2664    /* uses global variable insert_extract_error */
2665    int i;
2666    int t;
2667 
2668    VERBOSE_FUNCTION_CALLOUT
2669 
2670    /* for the insert and extract tests, we deliberately use only a
2671     * subset of the vsxargs array as input data.
2672     */
2673    for (i = 2; i < 9 ; i += 4) { /* index into vsxargs[] array */
2674 
2675       /* Note:
2676        * Determining the proper offset for {extract, insert} byte, halfword,
2677        * word, double would complicate things.  For simplicity, allow the
2678        * sub-functions to ignore input that would be invalid.  Catch and
2679        * suppress output for those cases per the global variable.
2680        */
2681       for (x_index = 0; x_index < 16 ; x_index++) {
2682          vec_xb[0] = (unsigned long) vsxargs[i];
2683          vec_xb[1] = (unsigned long) vsxargs[i+1];
2684 
2685          /* Run each test against all zeros and then all ones,
2686           * This is intended to help any bitfield changes stand out.
2687           */
2688          for (t = 0; t < 2; t++) {
2689 
2690             vec_xt[0] = (t == 0) ? 0 : 0xffffffffffffffff;
2691             vec_xt[1] = (t == 0) ? 0 : 0xffffffffffffffff;
2692 
2693             insert_extract_error = 0;
2694 
2695             (*test_function)();
2696 
2697             if (!insert_extract_error) {
2698                printf("%s %016lx %016lx [%d] (into%s) => ",
2699                       instruction_name, vec_xb[1], vec_xb[0], x_index,
2700                       (t == 0 ? " zeros" : "  ones") );
2701 
2702                printf("%016lx %016lx\n", vec_xt[1], vec_xt[0]);
2703             }
2704          }
2705       }
2706    }
2707 }
2708 
2709 
testfunction_vector_immediate(const char * instruction_name,test_func_t test_function,unsigned int ignore_test_flags)2710 static void testfunction_vector_immediate (const char * instruction_name,
2711                                            test_func_t test_function,
2712                                            unsigned int ignore_test_flags) {
2713    /* Uses global variable x_splat */
2714    int i;
2715    int t;
2716 
2717    VERBOSE_FUNCTION_CALLOUT
2718 
2719    for (i = 0; i < SPLAT_ARRAY_SIZE; i++) {
2720       x_splat = splat_values[i];
2721       for (t = 0; t < 2; t++) {
2722          vec_xt[0] = (t == 0) ? 0 : 0xffffffffffffffff;
2723          vec_xt[1] = (t == 0) ? 0 : 0xffffffffffffffff;
2724 
2725          printf("%s %016lx %016lx [%2x] => ",
2726                 instruction_name, vec_xt[1], vec_xt[0], x_splat);
2727 
2728          (*test_function)();
2729 
2730          printf("%016lx %016lx\n", vec_xt[1], vec_xt[0]);
2731       }
2732    }
2733 }
2734 
testfunction_vector_loadstore(const char * instruction_name,test_func_t test_function,unsigned int ignore_flags)2735 static void testfunction_vector_loadstore (const char* instruction_name,
2736                                            test_func_t test_function,
2737                                            unsigned int ignore_flags) {
2738    /* exercises vector loads from memory, and vector stores from memory.
2739     * <load or store instruction>  XS, RA, RB
2740     * For these tests, RA will be zero.
2741     * EA is then, simply, RB.
2742     */
2743    int i;
2744    int buffer_pattern;
2745 
2746    VERBOSE_FUNCTION_CALLOUT
2747 
2748    for (i = 0; i < nb_vargs; i += 2) {
2749 
2750       vec_xt = (vector unsigned long){vsxargs[i], vsxargs[i+1]};
2751       r14 = 0;
2752       r15 = (unsigned long) & buffer;
2753 
2754       for (buffer_pattern = 0; buffer_pattern < MAX_BUFFER_PATTERNS;
2755            buffer_pattern++) {
2756 
2757          /* set patterns on both ends */
2758          initialize_buffer(buffer_pattern);
2759 
2760          printf("%s ", instruction_name);
2761          printf("%016lx %016lx ", vec_xt[1], vec_xt[0]);
2762          dump_small_buffer();
2763          printf(" =>\n");
2764 
2765          (*test_function)();
2766 
2767          printf("    %016lx %016lx ", vec_xt[1], vec_xt[0]);
2768          dump_small_buffer();
2769          printf("\n");
2770       }
2771    }
2772 }
2773 
2774 
testfunction_vectorscalar_move_tofrom(const char * instruction_name,test_func_t test_function,unsigned int ignore_test_flags)2775 static void testfunction_vectorscalar_move_tofrom (const char * instruction_name,
2776                                                    test_func_t test_function,
2777                                                    unsigned int ignore_test_flags) {
2778    /* Move to / move from vector scalar.  spin through simple variants of
2779     * both the VSR and the register.
2780     * for simplicity, RA from 'mtvsrdd xt, ra, rb' is 0.
2781     */
2782    int i, v;
2783 
2784    VERBOSE_FUNCTION_CALLOUT
2785 
2786    for (i = 0; i < PATTERN_SIZE; i++) {
2787       for (v = 0; v < PATTERN_SIZE; v++) {
2788          /* if i==v, patterns will match, so just skip these as
2789           * non-interesting..
2790           */
2791          if (i == v) continue;
2792          r14 = 0;
2793          r15 = pattern[i%PATTERN_SIZE];
2794          vec_xt[0] = pattern[v%PATTERN_SIZE];
2795          vec_xt[1] = pattern[v%PATTERN_SIZE];
2796 
2797          printf("%s ", instruction_name);
2798          printf("%016lx %016lx %lx %016lx ", vec_xt[1], vec_xt[0],
2799                 (long unsigned)r14,  (long unsigned)r15 );
2800 
2801          (*test_function)();
2802 
2803          printf("=> %016lx %016lx %lx %016lx", vec_xt[1], vec_xt[0],
2804                 (long unsigned)r14,  (long unsigned)r15 );
2805          printf("\n");
2806       }
2807    }
2808 }
2809 
2810 /* Some of the load/store vector instructions use a length value that
2811  * is stored in bits 0:7 of RB.  */
2812 #define uses_bits_0to7(instruction_name) (                  \
2813            (strncmp(instruction_name, "lxvl "  ,5) == 0) || \
2814            (strncmp(instruction_name, "lxvll " ,6) == 0) || \
2815            (strncmp(instruction_name, "stxvl " ,6) == 0) || \
2816            (strncmp(instruction_name, "stxvll ",7) == 0) )
2817 
testfunction_vector_scalar_loadstore_length(const char * instruction_name,test_func_t test_function,unsigned int ignore_flags)2818 static void testfunction_vector_scalar_loadstore_length (const char* instruction_name,
2819                                                          test_func_t test_function,
2820                                                          unsigned int ignore_flags) {
2821    /* exercises vector loads from memory, and vector stores from memory.
2822     * with length specification.
2823     * <load or store instruction>  XS, RA, RB
2824     * For these tests, RA (i.e. EA) is address of source/dest and can
2825     * not be zero.
2826     * The length value is in rb.  For a subset of these instructions,
2827     * the length is stored in bits 0:7, versus 56:63 of r15.
2828     */
2829    int i;
2830    unsigned long l;
2831    int buffer_pattern;
2832 
2833    VERBOSE_FUNCTION_CALLOUT
2834 
2835    for (i = 0; i < nb_vargs; i += 2) {
2836       for (l = 0; l <= 16; l += 4) {
2837 
2838          for (buffer_pattern = 0; buffer_pattern < MAX_BUFFER_PATTERNS;
2839               buffer_pattern++) {
2840 
2841            /* set patterns on both ends */
2842             vec_xt = (vector unsigned long){vsxargs[i], vsxargs[i+1]};
2843             r14 = (unsigned long) & buffer;
2844 
2845             if (uses_bits_0to7(instruction_name)) {
2846                /* length is stored in bits 0:7 of gpr[r15]. */
2847                r15 = (unsigned long)((0xff & l) << 56);
2848 
2849             } else {
2850                /* length is stored in gpr[r15]. */
2851                r15 = l;
2852             }
2853 
2854             initialize_buffer(buffer_pattern);
2855 
2856             printf("%s ", instruction_name);
2857             printf("%016lx %016lx ", vec_xt[1], vec_xt[0] );
2858             if (uses_bits_0to7(instruction_name)) {
2859                printf(" 0x%2lx ", (long unsigned)r15>>56 );
2860 
2861             } else {
2862                printf(" l = 0x%2lx ", (long unsigned)r15 );
2863             }
2864 
2865             dump_small_buffer();
2866 
2867             (*test_function)();
2868 
2869             printf("=> %016lx %016lx & %16lx", vec_xt[1], vec_xt[0],
2870                    (long unsigned)r15 );
2871             printf("\n");
2872          }
2873       }
2874    }
2875 }
2876 
testfunction_vector_count_bytes(const char * instruction_name,test_func_t test_function,unsigned int ignore_flags)2877 static void testfunction_vector_count_bytes (const char* instruction_name,
2878                                              test_func_t test_function,
2879                                              unsigned int ignore_flags)
2880 {
2881    int i;
2882 
2883    VERBOSE_FUNCTION_CALLOUT
2884 
2885    for (i = 0; i < nb_vargs; i += 2) {
2886       vec_xb = (vector unsigned long){vsxargs[i], vsxargs[i+1]};
2887       r14 = 0;
2888 
2889       printf("%s ", instruction_name);
2890       printf("%016lx %016lx %2d ", vec_xb[1], vec_xb[0], (unsigned)r14);
2891 
2892       (*test_function)();
2893 
2894       printf("=> %2d\n", (unsigned)r14 );
2895    }
2896 }
2897 
testfunction_vector_extract(const char * instruction_name,test_func_t test_function,unsigned int ignore_flags)2898 static void testfunction_vector_extract (const char* instruction_name,
2899                                          test_func_t test_function,
2900                                          unsigned int ignore_flags)
2901 {
2902    int i;
2903 
2904    VERBOSE_FUNCTION_CALLOUT
2905 
2906    for (i = 0; i < nb_vargs; i += 2) {
2907       vec_xb = (vector unsigned long){vsxargs[i], vsxargs[i+1]};
2908       for (r15 = 0; r15 < 16; r15++) {
2909       r14 = 0;
2910 
2911       printf("%s ", instruction_name);
2912       printf("%016lx %016lx %2d ", vec_xb[1], vec_xb[0], (unsigned)r15);
2913 
2914       (*test_function)();
2915 
2916       printf("=> %16lx\n", (long unsigned)r14 );
2917       }
2918    }
2919 }
2920 
testfunction_vector_extend_sign(const char * instruction_name,test_func_t test_function,unsigned int ignore_flags)2921 static void testfunction_vector_extend_sign (const char* instruction_name,
2922                                              test_func_t test_function,
2923                                              unsigned int ignore_flags)
2924 {
2925    int i;
2926 
2927    VERBOSE_FUNCTION_CALLOUT
2928 
2929    for (i = 0; i < nb_vargs; i += 2) {
2930       vec_xb = (vector unsigned long){vsxargs[i], vsxargs[i+1]};
2931       vec_xt = (vector unsigned long){0, 0};
2932 
2933       printf("%s ", instruction_name);
2934       printf("%016lx %016lx ", vec_xb[1], vec_xb[0]);
2935 
2936       (*test_function)();
2937 
2938       printf("=> %016lx %016lx\n", vec_xt[1], vec_xt[0]);
2939    }
2940 }
2941 
2942 /* packed binary decimal misc */
2943 
2944 #define convert_from_zoned(instruction_name) (strncmp(instruction_name, "bcdcfz", 6) ==0 )
2945 
2946 #define convert_from_national(instruction_name) (strncmp(instruction_name, "bcdcfn", 6) == 0)
2947 
2948 #define convert_to_zoned(instruction_name) (strncmp(instruction_name, "bcdctz", 6) == 0)
2949 
2950 #define convert_to_national(instruction_name) (strncmp(instruction_name, "bcdctn", 6) == 0)
2951 
2952 #define shift_or_truncate(instruction_name)                \
2953          (strncmp(instruction_name, "bcds", 4)  == 0    || \
2954           strncmp(instruction_name, "bcdus", 5) == 0    || \
2955           strncmp(instruction_name, "bcdsr", 5) == 0    || \
2956           strncmp(instruction_name, "bcdtrunc", 8) == 0 || \
2957           strncmp(instruction_name, "bcdutrunc", 9) == 0)
2958 
2959 
2960 /* Helper function - returns 1 or 0 per whether the p1 or p0 string
2961  *  exists in the instruction name passed in.  The PS indicates preferred
2962  *  sign, and has meaning for some of the BCD instructions.
2963  */
p_value(const char * instruction_name)2964 static inline int p_value(const char * instruction_name) {
2965    char * found_p0;
2966    char * found_p1;
2967 
2968    found_p1 = strstr(instruction_name, "p1");
2969    found_p0 = strstr(instruction_name, "p0");
2970 
2971    if (found_p1) return 1;
2972 
2973    if (found_p0) return 0;
2974 
2975    if (verbose) printf("p* substring not found in (%s)\n", instruction_name);
2976 
2977    return 0;
2978 }
2979 
2980 /* bcd test has been split out a bit..  a few bcd specific global vars here
2981  * to help keep that clean.
2982  */
2983 long shift_or_truncate_instruction;
2984 int xa_sign, xb_sign, xt_sign;
2985 int short_circuit;
2986 
2987 /* testfunction_bcd_setup_inputs
2988  * This is a helper function that sets up the vec_xa, vec_xb values for
2989  * use in the bcd tests.
2990  */
testfunction_bcd_setup_inputs(const char * instruction_name,int i,int j)2991 static inline void testfunction_bcd_setup_inputs(const char * instruction_name,
2992                                                  int i, int j) {
2993    short_circuit=0;
2994 
2995    if (shift_or_truncate_instruction) {
2996       if (i >= nb_decimal_shift_entries - 2) {
2997          short_circuit = 1;
2998          return;
2999       }
3000       vec_xa = (vector unsigned long) {decimal_shift_table[i+1],
3001                                        decimal_shift_table[i]};
3002 
3003    } else {
3004       if (i >= nb_decimal_shift_entries - 2) {
3005          short_circuit = 1;
3006          return;
3007       }
3008 
3009       vec_xa = (vector unsigned long) {packed_decimal_table[i+1],
3010                                        packed_decimal_table[i]};
3011       xa_sign = extract_packed_decimal_sign(vec_xa[0], vec_xa[1]);
3012    }
3013 
3014    if (convert_from_zoned(instruction_name)) { /* convert from zoned */
3015       if (j >= nb_zoned_decimal_entries - 2) {
3016          short_circuit = 1;
3017          return;
3018       }
3019 
3020       vec_xb = (vector unsigned long) {zoned_decimal_table[j+1],
3021                                        zoned_decimal_table[j]};
3022       xb_sign = extract_zoned_decimal_sign(vec_xb[0], vec_xb[1]);
3023 
3024    } else if (convert_from_national(instruction_name)) {
3025       /* convert from national */
3026       if (j >= nb_national_decimal_entries - 2) {
3027          short_circuit = 1;
3028          return;
3029       }
3030       vec_xb = (vector unsigned long) {national_decimal_table[j+1],
3031                                        national_decimal_table[j]};
3032       xb_sign = extract_national_decimal_sign(vec_xb[0], vec_xb[1]);
3033 
3034    } else {
3035       /* packed decimal entries */
3036       if (j >= nb_packed_decimal_entries - 2) {
3037          short_circuit = 1;
3038          return;
3039       }
3040       vec_xb = (vector unsigned long) {packed_decimal_table[j+1],
3041                                        packed_decimal_table[j]};
3042       xb_sign = extract_packed_decimal_sign(vec_xb[0], vec_xb[1]);
3043    }
3044 }
3045 
testfunction_bcd_display_outputs(const char * instruction_name)3046 static inline void testfunction_bcd_display_outputs(const char * instruction_name) {
3047 
3048    printf(" xt:%016lx %016lx", vec_xt[0], vec_xt[1] );
3049 
3050    if (convert_to_zoned(instruction_name)) {
3051       /* convert to zoned */
3052       xt_sign = extract_zoned_decimal_sign(vec_xt[0], vec_xt[1]);
3053       dissect_zoned_decimal_sign(xt_sign, p_value(instruction_name));
3054 
3055    } else if (convert_to_national(instruction_name)) {
3056       /* convert to national */
3057       xt_sign = extract_national_decimal_sign(vec_xt[0], vec_xt[1]);
3058       dissect_national_decimal_sign(xt_sign);
3059 
3060    } else {
3061       /* packed decimal entries, or shift/truncate */
3062       if (!shift_or_truncate_instruction) {
3063          xt_sign = extract_packed_decimal_sign(vec_xt[0], vec_xt[1]);
3064          dissect_packed_decimal_sign(xt_sign);
3065       }
3066    }
3067    printf("\n");
3068 }
3069 
3070 #define uses_half_precision_input(instruction_name) (  \
3071    (strncmp(instruction_name, "xscvhpdp", 8) == 0) ||  \
3072    (strncmp(instruction_name, "xvcvhpsp", 8) == 0) )
3073 
3074 #define uses_single_precision_input(instruction_name) ( \
3075    (strncmp(instruction_name, "xvcvsphp", 8) == 0) )
3076 
3077 #define uses_double_precision_input(instruction_name) ( \
3078    (strncmp(instruction_name, "xscvdphp", 8) == 0) )
3079 
3080 #define uses_half_precision_output(instruction_name) (  \
3081    (strncmp(instruction_name, "xscvdphp", 8) == 0) ||   \
3082    (strncmp(instruction_name, "xvcvsphp", 8) == 0) )
3083 
3084 #define is_half_precision_instruction(instruction_name) ( \
3085     uses_half_precision_input(instruction_name) ||        \
3086     uses_half_precision_output(instruction_name) )
3087 
3088 /* Helper for those instructions with an unused second dword, indicating
3089  * the outer loop can be short-circuited after one pass.
3090  */
3091 #define unused_second_dword(instruction_name) (       \
3092    (strncmp(instruction_name, "xscvhpdp", 8) == 0) || \
3093    (strncmp(instruction_name, "xscvdphp", 8) == 0) )
3094 
testfunction_vector_scalar_two_quad(const char * instruction_name,test_func_t test_function,unsigned int ignore_flags)3095 static void testfunction_vector_scalar_two_quad (const char* instruction_name,
3096                                                  test_func_t test_function,
3097                                                  unsigned int ignore_flags)
3098 {
3099    int i;
3100 
3101    VERBOSE_FUNCTION_CALLOUT
3102 
3103    for (i = 0; i < nb_vargs; i += 2) {
3104       if (uses_half_precision_input(instruction_name)) {
3105          vec_xb = (vector unsigned long){binary16_float_vsxargs[i],
3106                                          binary16_float_vsxargs[i+1]};
3107       } else {
3108          vec_xb = (vector unsigned long){vsxargs[i], vsxargs[i+1]};
3109       }
3110 
3111       vec_xt = (vector unsigned long){0, 0};
3112 
3113       printf("%s ", instruction_name);
3114       printf("%016lx %016lx ", vec_xb[1], vec_xb[0]);
3115 
3116       SET_FPSCR_ZERO
3117 
3118       (*test_function)();
3119 
3120       GET_FPSCR(local_fpscr);
3121 
3122       printf("=> %016lx %016lx", vec_xt[1], vec_xt[0]);
3123       dissect_fpscr(local_fpscr);
3124       printf("\n");
3125    }
3126 }
3127 
3128 static void
testfunction_vector_scalar_compare_exp_double(const char * instruction_name,test_func_t test_function,unsigned int ignore_test_flags)3129 testfunction_vector_scalar_compare_exp_double (const char* instruction_name,
3130                                                test_func_t test_function,
3131                                                unsigned int ignore_test_flags){
3132    int i,j;
3133    /* Uses global variable x_index */
3134 
3135    VERBOSE_FUNCTION_CALLOUT
3136 
3137    for (i = 0; i < nb_float_vsxargs - 1; i++) {
3138       for (j = 0; j < nb_float_vsxargs - 1; j++) {
3139          for (x_index = 2; x_index < 3; x_index++) {
3140 
3141             /* TODO FIXME- there was a casting issue below.  This incantation
3142              * works, but I suspect can be simplified...
3143              */
3144             vec_xa = (vector unsigned long){(unsigned long)binary64_float_vsxargs[i+1], (unsigned long)binary64_float_vsxargs[i]};
3145 
3146             vec_xb = (vector unsigned long){(unsigned long)binary64_float_vsxargs[j], (unsigned long)binary64_float_vsxargs[j+1]};
3147 
3148             /* run each test against cleared CR and FPSCR */
3149             /* Note that the SET_*_ZERO calls are not actually sufficient here,
3150              * due to infrastructure between here and there that also set some
3151              * of the CR bits. The condition regs are cleared here, but are
3152              * also both cleared and read within the to-be-tested asm chunk to
3153              * get accurate results.
3154              */
3155             SET_CR_ZERO
3156             SET_FPSCR_ZERO
3157 
3158             printf("%s %016lx %016lx %016lx %016lx",
3159                    instruction_name,
3160                    vec_xa[0], vec_xa[1],
3161                    vec_xb[0], vec_xb[1]);
3162 
3163             if (verbose) printf(" cr#%d ", x_index);
3164 
3165             printf(" => ");
3166 
3167             (*test_function)();
3168 
3169             dissect_fpscr(local_fpscr);
3170             dissect_fpscr_result_value_class(local_fpscr);
3171             dissect_cr_rn(local_cr, x_index);
3172             printf("\n");
3173          }
3174       }
3175    }
3176 }
3177 
3178 /* These instructions set the floating point condition codes. */
3179 /* verify logic reversal */
3180 #define does_not_set_floating_point_cc(instruction_name) \
3181    (strncmp(instruction_name, "xvtstdcdp", 9) == 0) |    \
3182    (strncmp(instruction_name, "xvtstdcsp", 9) == 0)
3183 
3184 static void
testfunction_vector_scalar_data_class(const char * instruction_name,test_func_t test_function,unsigned int ignore_test_flags)3185 testfunction_vector_scalar_data_class (const char* instruction_name,
3186                                        test_func_t test_function,
3187                                        unsigned int ignore_test_flags) {
3188    int j;
3189    /* x_index is used as a key into the DCMX value.
3190     *
3191     *   BF, XB, DCMX
3192     * For instruction tests called through this function, note that we are only
3193     * utilizing bf (condition register) #3; where 3 was mostly randomly
3194     * chosen, and has no special meaning.
3195     */
3196 
3197    VERBOSE_FUNCTION_CALLOUT
3198 
3199    for (j = 0; j < nb_float_vsxargs - 1; j++) {
3200       /* for dcmx field, start with x_index=1 to skip the 'all' dcmx entry. */
3201       for (x_index = 1; x_index < 8; x_index++) {
3202          vec_xb[0] = float_vsxargs[j];
3203          vec_xb[1] = float_vsxargs[j+1];
3204          vec_xt[0] = 0x0a0a0a0a0a0a0a0a;
3205          vec_xt[1] = 0x0505050505050505;
3206          SET_CR_ZERO
3207          SET_FPSCR_ZERO
3208 
3209          dcmx_match = 0;
3210 
3211          (*test_function)();
3212 
3213          /* the local_fpscr value is gathered within the test_function call. */
3214          dcmx_match = (local_fpscr & FPCC_FE_BIT);
3215 
3216          if (dcmx_match || (verbose>2)) {
3217             printf("%s %016lx, %016lx ",
3218                    instruction_name, vec_xb[1], vec_xb[0]);
3219 
3220             print_dcmx_field(x_index);
3221 
3222             if (dcmx_match)
3223                printf(" => Match.  ");
3224 
3225             printf(" %016lx, %016lx ", vec_xt[1], vec_xt[0]);
3226 
3227             dissect_cr_rn(local_cr,3);
3228             dissect_fpscr_dcmx_indicator(local_fpscr);
3229             printf("\n");
3230          }
3231 
3232          printf("%s %016lx, %016lx => ",
3233                 instruction_name, vec_xb[1], vec_xb[0]);
3234 
3235          printf(" %016lx, %016lx\n", vec_xt[1], vec_xt[0]);
3236       }
3237    }
3238 }
3239 
testfunction_vector_scalar_compare_quads(const char * instruction_name,test_func_t test_function,unsigned int ignore_test_flags)3240 static void testfunction_vector_scalar_compare_quads (const char* instruction_name,
3241                                                       test_func_t test_function,
3242                                                       unsigned int ignore_test_flags) {
3243    /* Uses global variable x_index */
3244    int i,j;
3245 
3246    VERBOSE_FUNCTION_CALLOUT
3247 
3248    for (i = 0; i < nb_float_vsxargs - 1; i++) {
3249       for (j = 0; j < nb_float_vsxargs - 1; j++) {
3250          for (x_index = 0; x_index < 3 ; x_index++) {
3251             vec_xa[0] = float_vsxargs[i];
3252             vec_xa[1] = float_vsxargs[i+1];
3253             vec_xb[0] = float_vsxargs[j];
3254             vec_xb[1] = float_vsxargs[j+1];
3255 
3256             /* run each test against cleared CR and FPSCR */
3257             /* Note that the SET_*_ZERO calls are not actually sufficient here,
3258              * due to infrastructure between here and there that also set some
3259              * of the CR bits. The condition regs are cleared here, but are
3260              * also both cleared and read within the to-be-tested asm chunk
3261              * to get accurate results.
3262              */
3263             printf("%s %016lx%016lx %016lx%016lx (cr#%d) => ",
3264                    instruction_name,
3265                    vec_xa[1], vec_xa[0],
3266                    vec_xb[1], vec_xb[0],
3267                    x_index);
3268 
3269             SET_CR_ZERO
3270             SET_FPSCR_ZERO
3271 
3272             (*test_function)();
3273 
3274             GET_CR(local_cr);
3275             GET_FPSCR(local_fpscr);
3276 
3277             dissect_fpscr(local_fpscr);
3278             dissect_cr_rn(local_cr, x_index);
3279             printf("\n");
3280          }
3281       }
3282    }
3283 }
3284 
testfunction_vector_scalar_rounding_quads(const char * instruction_name,test_func_t test_function,unsigned int ignore_test_flags)3285 static void testfunction_vector_scalar_rounding_quads (const char* instruction_name,
3286                                                        test_func_t test_function,
3287                                                        unsigned int ignore_test_flags) {
3288    /* Uses global variable x_index */
3289    /* For this function, x_index is used as a key into R and RMC values.
3290     * Also note, the fpscr.rn value may be used to affect the rounding mode.
3291     * that variation is not evaluated here. */
3292    int j;
3293 
3294    VERBOSE_FUNCTION_CALLOUT
3295 
3296    for (j = 0; j < nb_float_vsxargs - 1; j++) {
3297       for (x_index = 0; x_index < 8; x_index++) {
3298          vec_xb[0] = float_vsxargs[j];
3299          vec_xb[1] = float_vsxargs[j+1];
3300 
3301          printf("%s %016lx%016lx (R=%x) (RMC=%x) => ",
3302                 instruction_name,
3303                 vec_xb[1], vec_xb[0],
3304                 (x_index & 0x4) >> 2, x_index & 0x3);
3305 
3306          SET_CR_ZERO
3307          SET_FPSCR_ZERO
3308 
3309          (*test_function)();
3310 
3311          GET_FPSCR(local_fpscr);
3312 
3313          printf("%016lx%016lx", vec_xt[1], vec_xt[0]);
3314          dissect_fpscr(local_fpscr);
3315          printf("\n");
3316       }
3317    }
3318 }
3319 
testfunction_vector_three_special(const char * instruction_name,test_func_t test_function,unsigned int ignore_test_flags)3320 static void testfunction_vector_three_special (const char* instruction_name,
3321                                                test_func_t test_function,
3322                                                unsigned int ignore_test_flags){
3323    /* Notes:
3324     *   vector instructions with two inputs, one output.
3325     *   vrt, vra, vrb
3326     */
3327    int i, j;
3328    int t;
3329 
3330    VERBOSE_FUNCTION_CALLOUT
3331 
3332    for (i = 0; i < nb_float_vsxargs - 1; i++) {
3333       for (j = 0; j < nb_float_vsxargs - 1; j++) {
3334          vec_xa[0] = float_vsxargs[i];
3335          vec_xa[1] = float_vsxargs[i+1];
3336          vec_xb[0] = float_vsxargs[j];
3337          vec_xb[1] = float_vsxargs[j+1];
3338 
3339          for (t = 0; t < 2; t++) {
3340             vec_xt[0] = (t == 0) ? 0 : 0xffffffffffffffff;
3341             vec_xt[1] = (t == 0) ? 0 : 0xffffffffffffffff;
3342 
3343             SET_FPSCR_ZERO;
3344             printf("%s %016lx%016lx %016lx%016lx %016lx%016lx => ",
3345                    instruction_name,
3346                    vec_xa[1], vec_xa[0],
3347                    vec_xb[1], vec_xb[0],
3348                    vec_xt[1], vec_xt[0]);
3349 
3350             (*test_function)();
3351 
3352             GET_FPSCR(local_fpscr);
3353 
3354             printf(" %016lx%016lx", vec_xt[1], vec_xt[0]);
3355             dissect_fpscr(local_fpscr);
3356             printf("\n");
3357          }
3358       }
3359    }
3360 }
3361 
3362 #define vector_instruction_is_xvcvhpsp(instruction_name) \
3363    (strncmp(instruction_name, "xvcvhpsp", 8) == 0)
3364 
testfunction_vector_scalar_two_double(const char * instruction_name,test_func_t test_function,unsigned int ignore_test_flags)3365 static void testfunction_vector_scalar_two_double(const char* instruction_name,
3366                                                   test_func_t test_function,
3367                                                   unsigned int ignore_test_flags) {
3368    /* Notes:
3369     *   iterate across double values stored in xa, xb.
3370     *   Or, on half-word values in vec_xb.
3371     *   Results are in vec_xt.
3372     */
3373    int i, j;
3374 
3375    VERBOSE_FUNCTION_CALLOUT
3376 
3377    for (i = 0; i < nb_float_vsxargs - 1; i += 2) {
3378       for (j = 0; j < nb_float_vsxargs - 1; j += 2) {
3379          /* vec_xb is only used by the convert instructions, the other callers
3380           * use the r14, r15 fields.
3381           * The 16-bit converts reference every other half-word in the vector.
3382           * For this reason, populate the input field with a cross-section of
3383           * values.
3384           */
3385          printf("%s ",instruction_name);
3386 
3387          if (uses_half_precision_input(instruction_name)) {
3388             vec_xb = (vector unsigned long) {
3389                binary16_float_vsxargs[i]         |
3390                binary16_float_vsxargs[j]   << 16 |
3391                binary16_float_vsxargs[i+1] << 32 |
3392                binary16_float_vsxargs[j+1] << 48,
3393                binary16_float_vsxargs[(nb_float_vsxargs - 1) - j - 1 ]       |
3394                binary16_float_vsxargs[(nb_float_vsxargs - 1) - i - 1] << 16  |
3395 
3396                binary16_float_vsxargs[(nb_float_vsxargs - 1) - j ] << 32  |
3397                binary16_float_vsxargs[(nb_float_vsxargs - 1) - i ] << 48
3398             };
3399             printf("   vec_xb[1] = 0x%lx, vec_xb[0] = 0x%lx ",
3400                    vec_xb[1], vec_xb[0]);
3401 
3402          } else if (uses_single_precision_input(instruction_name)) {
3403             vec_xb = (vector unsigned long) {
3404                binary32_float_vsxargs[i]         |
3405                binary32_float_vsxargs[i+1] << 32,
3406                binary32_float_vsxargs[nb_float_vsxargs - 1 - j ]         |
3407                binary32_float_vsxargs[nb_float_vsxargs - 1 - j ] << 32
3408             };
3409             printf("   vec_xb[1] = 0x%lx, vec_xb[0] = 0x%lx ",
3410                    vec_xb[1], vec_xb[0]);
3411 
3412          } else { /* uses double */
3413             r14 = binary64_float_vsxargs[i];
3414             r15 = binary64_float_vsxargs[j];
3415             printf("   r14 = 0x%lx, r15 = 0x%lx ", r14, r15);
3416          }
3417 
3418          vec_xt = (vector unsigned long){0, 0};
3419 
3420          printf("%016lx %016lx ", vec_xb[1], vec_xb[0] );
3421 
3422          if ((verbose > 2) && uses_double_precision_input(instruction_name)) {
3423             dissect_binary64_float(vec_xb[1]);
3424             dissect_binary64_float(vec_xb[0]);
3425          }
3426 
3427          printf(" => ");
3428          SET_FPSCR_ZERO
3429 
3430         (*test_function)();
3431 
3432          GET_FPSCR(local_fpscr);
3433          printf(" %016lx %016lx", vec_xt[1], vec_xt[0]);
3434 
3435          if ((verbose > 2) && uses_half_precision_output(instruction_name)) {
3436             dissect_double_as_16s(vec_xt[1]);
3437             dissect_double_as_16s(vec_xt[0]);
3438          }
3439 
3440          /* The xvcvhpsp instruction does not set the C and FPCC fields */
3441          if (!vector_instruction_is_xvcvhpsp(instruction_name))
3442             dissect_fpscr(local_fpscr);
3443 
3444          printf("\n");
3445       } // j
3446 
3447       /* If we are doing half precision conversions, the i-loop can be
3448        * short-circuited to avoid duplicate input values.  */
3449       if (unused_second_dword(instruction_name))
3450          i = nb_float_vsxargs+1;
3451    } // i
3452 }
3453 
testfunction_set_boolean(const char * instruction_name,test_func_t test_function,unsigned int ignore_test_flags)3454 static void testfunction_set_boolean (const char* instruction_name,
3455                                       test_func_t test_function,
3456                                       unsigned int ignore_test_flags)
3457 {
3458    int cr_base_value;
3459    /* Notes:
3460     * Set RT to values 0, -1, 1 depending on what bits are set in the specified
3461     * CR field.  x_index references here reflect the cr_field number.
3462     */
3463 
3464    VERBOSE_FUNCTION_CALLOUT
3465 
3466    for (x_index = 0; x_index <= 7; x_index++) {
3467       for (cr_base_value = 0; cr_base_value <= 8; cr_base_value++) {
3468          cr_value = (0x11111111 * cr_base_value)
3469             & (0xf << (4 * (7 - x_index))) ;
3470 
3471          r14 = 0xa5a5a5a5c7c7c7c7;
3472 
3473          printf("%s cr_field:%1x cr_value::%08x",
3474                 instruction_name, x_index,cr_value);
3475          printf(" => ");
3476 
3477          (*test_function)();
3478 
3479          printf(" %016lx\n", r14);
3480       }
3481    }
3482 }
3483 
3484 
testfunction_char_compare(const char * instruction_name,test_func_t test_function,unsigned int ignore_test_flags)3485 static void testfunction_char_compare (const char* instruction_name,
3486                                        test_func_t test_function,
3487                                        unsigned int ignore_test_flags)
3488 {
3489    /* Notes:
3490     *   iterate through char values stored in RA, RB.
3491     *   Results stored in cr field BF.
3492     */
3493    int i, j;
3494    int local_crf;
3495 
3496    VERBOSE_FUNCTION_CALLOUT
3497 
3498    for (x_index = 0; x_index <= 7; x_index++) {
3499       for (i = 0; i < nb_char_ranges; i += 4) {
3500          for (j = 0; j < nb_char_args; j++) {
3501             r14 = char_args[j];
3502 
3503             /* For cmprb*, only needs the lower characters. */
3504             r15 = char_ranges[i] | (char_ranges[i+1] << 8) |
3505                   char_ranges[i+2] << 16 | (char_ranges[i+3] << 24);
3506 
3507             /* For cmpeqb, also load the rest of the range field, shift allk
3508              * chars up by one.
3509              */
3510             r15 |= (r15 + 0x01010101) << 32;
3511             printf("%s 0x%02lx (%c) (cmpeq:0x%016lx) (cmprb:src22(%c-%c) src21(%c-%c))",
3512                    instruction_name,
3513                    r14, (int)r14,
3514                    r15, (int)(r15 & 0xff), (int)((r15 >> 8) & 0xff),
3515                    (int)((r15 >> 16) & 0xff), (int)((r15 >> 24) & 0xff)
3516                    );
3517 
3518             printf(" =>");
3519 
3520             (*test_function)();
3521 
3522             GET_CR(local_cr);
3523             local_crf = extract_cr_rn(local_cr, x_index);
3524 
3525             if (verbose)
3526                printf(" %s found or in range (%x)",
3527                       (cr_positive_set(local_crf))?"   " : " not", local_crf);
3528             else
3529                if (cr_positive_set(local_crf)) printf(" in range/found");
3530 
3531             printf("\n");
3532          }
3533       }
3534    }
3535 }
3536 
3537 #define instruction_uses_quads(instruction_name) (strncmp(instruction_name, "dtstsfiq", 8) == 0)
3538 
testfunction_dfp_significance(const char * instruction_name,test_func_t test_function,unsigned int ignore_test_flags)3539 static void testfunction_dfp_significance (const char* instruction_name,
3540                                            test_func_t test_function,
3541                                            unsigned int ignore_test_flags)
3542 {
3543    int local_crf;
3544    int i;
3545    int num_dfp_vals;
3546 
3547    VERBOSE_FUNCTION_CALLOUT
3548 
3549    if (instruction_uses_quads(instruction_name)) {
3550       num_dfp_vals = nb_dfp128_vals;
3551    } else {
3552       num_dfp_vals = nb_dfp64_vals;
3553    }
3554 
3555    for (i = 0; i < num_dfp_vals; i++) {
3556       if (instruction_uses_quads(instruction_name)) {
3557          dfp_value.u128.vall = dfp128_vals[i * 2];
3558          dfp_value.u128.valu = dfp128_vals[(i * 2) + 1];
3559 
3560       } else {
3561          // could rework this to use u64.val, but...
3562          dfp_value.u128.vall = dfp128_vals[i ];
3563          dfp_value.u128.valu = dfp128_vals[i ];
3564       }
3565 
3566       /* Keeping test simpler, always using cr3 within test_dtstsfi* */
3567       for (dfp_significance = 0; dfp_significance <= 63;) {
3568          /* Todo: tweak output here, or input values so the generated content
3569           * looks better.
3570           */
3571          printf("%s significance(0x%02x) ",
3572                 instruction_name, dfp_significance);
3573 
3574          if (instruction_uses_quads(instruction_name)) {
3575             dissect_dfp128_float(dfp_value.u128.vall, dfp_value.u128.valu);
3576 
3577             if (verbose > 6)
3578                printf("(RAW) value = %16lx,%016lx ",
3579                       dfp_value.u128.vall, dfp_value.u128.valu /*f14, f15 */);
3580 
3581          } else {
3582             dissect_dfp64_float(dfp_value.u128.vall);
3583 
3584             if (verbose > 6)
3585                printf("(RAW) value = %16lx ", dfp_value.u128.vall /*f14 */);
3586          }
3587 
3588          (*test_function)();
3589 
3590          GET_CR(local_cr);
3591 
3592          local_crf = extract_cr_rn(local_cr, /* hardcoded cr3 */ 3);
3593          dissect_cr_rn(local_cr, /* hardcoded cr3 */ 3);
3594 
3595          printf(" (%x)", local_crf);
3596          printf("\n");
3597 
3598          /* Special case for incrementation of the significance checking
3599           * value.
3600           */
3601          if (dfp_significance < 8)
3602             dfp_significance += 4;  /* 0, 4, 8 */
3603 
3604          else if (dfp_significance < 32)
3605             dfp_significance += 8; /* 16, 24, 32 */
3606 
3607          else if (dfp_significance < 48)
3608             dfp_significance += 16; /* 48 */
3609 
3610          else
3611             dfp_significance += 15; /* 63 */
3612       }
3613    }
3614 }
3615 
3616 /* packed binary decimal misc */
3617 
3618 #define convert_tofrom_instruction(instruction_name)      \
3619         ( (strncmp(instruction_name, "bcdcf", 5) == 0) || \
3620           (strncmp(instruction_name, "bcdct", 5) == 0) )
3621 
testfunction_bcd_misc(const char * instruction_name,test_func_t test_function,unsigned int ignore_test_flags)3622 static void testfunction_bcd_misc (const char* instruction_name,
3623                                    test_func_t test_function,
3624                                    unsigned int ignore_test_flags)
3625 {
3626    int i, j;
3627    int local_crf;
3628    long max_xa_entries = 0;
3629    long max_xb_entries = 0;
3630 
3631    VERBOSE_FUNCTION_CALLOUT
3632 
3633    shift_or_truncate_instruction = shift_or_truncate(instruction_name);
3634 
3635    max_xa_entries = MAX(max_xa_entries, nb_decimal_shift_entries);
3636    max_xa_entries = MAX(max_xa_entries, nb_packed_decimal_entries);
3637 
3638    max_xb_entries = MAX(max_xb_entries, nb_zoned_decimal_entries);
3639    max_xb_entries = MAX(max_xb_entries, nb_national_decimal_entries);
3640    max_xb_entries = MAX(max_xb_entries, nb_packed_decimal_entries);
3641 
3642    for (i = 0; i < (max_xa_entries - 1); i += 2) {
3643       for (j = 0; j < (max_xb_entries - 1); j += 2) {
3644          testfunction_bcd_setup_inputs(instruction_name, i, j);
3645 
3646          if (short_circuit) continue;
3647 
3648          printf("%s ",  instruction_name);
3649          printf("xa:%016lx %016lx ", vec_xa[0], vec_xa[1]);
3650 
3651          if (!shift_or_truncate_instruction)
3652             dissect_packed_decimal_sign(xa_sign);
3653 
3654          printf(" xb:%016lx %016lx ", vec_xb[0], vec_xb[1]);
3655 
3656          if (convert_from_zoned(instruction_name)) {
3657             /* convert from zoned */
3658             dissect_zoned_decimal_sign(xb_sign, p_value(instruction_name));
3659 
3660          } else if (convert_from_national(instruction_name)) {
3661             /* convert from national */
3662             dissect_national_decimal_sign(xb_sign);
3663 
3664          } else {
3665             /* packed decimal entries */
3666             if (!shift_or_truncate_instruction)
3667                dissect_packed_decimal_sign(xb_sign);
3668          }
3669 
3670          printf(" => ");
3671          SET_CR_ZERO
3672 
3673          (*test_function)();
3674 
3675          GET_CR(local_cr);
3676 
3677          /* note: the bcd instructions are hard wired to use cr6. */
3678          local_crf = extract_cr_rn(local_cr, 6);
3679          dissect_cr_rn(local_cr, 6);
3680          printf(" (%x)", local_crf);
3681 
3682          if (cr_overflow_set(local_crf)) {
3683             /* If overflow (S0)  is set the results are undefined.  Force the
3684              * output to print as zeros so we have consistent results for
3685              * comparison.
3686              */
3687             printf(" xt:%016lx %016lx", 0UL, 0UL);
3688 
3689          } else {
3690             testfunction_bcd_display_outputs(instruction_name);
3691          }
3692 
3693          printf("\n");
3694       } // j = xb loop.
3695 
3696    /* Since the bcdct* convert_tofrom instructions do not use the xa
3697     * field, we will short-circuit the xa (i=*) loop here.
3698     */
3699     if (convert_tofrom_instruction(instruction_name))
3700        i = nb_packed_decimal_entries;
3701    } //i = xa loop.
3702 }
3703 
3704 
testfunction_noop_misc(const char * instruction_name,test_func_t test_function,unsigned int ignore_test_flags)3705 static void testfunction_noop_misc (const char* instruction_name,
3706                                     test_func_t test_function,
3707                                     unsigned int ignore_test_flags)
3708 {
3709    VERBOSE_FUNCTION_CALLOUT
3710 
3711    printf("%s ",  instruction_name);
3712    printf(" =>");
3713 
3714    (*test_function)();
3715 
3716    printf("\n");
3717 }
3718 
testfunction_pc_immediate_misc(const char * instruction_name,test_func_t test_function,unsigned int ignore_test_flags)3719 static void testfunction_pc_immediate_misc (const char* instruction_name,
3720                                     test_func_t test_function,
3721                                     unsigned int ignore_test_flags)
3722 {
3723    VERBOSE_FUNCTION_CALLOUT
3724 
3725    for (x_index = 0; x_index < 16; x_index++) {
3726       printf("%s ",  instruction_name);
3727       printf(" %016x ", x_index);
3728       printf(" => ");
3729       (*test_function)();
3730       /*      printf(" %016lx\n", r14); */
3731       printf(" %016x\n", 0);  /* test is not portable just print zero */
3732    }
3733 }
3734 
3735 /* Identify those mffs* variants that take additional arguments.
3736  * This includes the immediate mffs*i variants. */
3737 #define is_not_simple_mffs_instruction(instruction_name) \
3738 	( (strncmp(instruction_name,"mffscdrn",8)==0) || \
3739 	  (strncmp(instruction_name,"mffscrn",7)==0) )
3740 
3741 /* Because some of the mffs* variants here are updating the fpscr as part
3742  * of the read, be sure to dissect both the retrieved (f14) and the updated
3743  * (local_fpscr) fpscr values. */
testfunction_mffs(const char * instruction_name,test_func_t test_function,unsigned int ignore_test_flags)3744 static void testfunction_mffs(const char* instruction_name,
3745                                     test_func_t test_function,
3746                                     unsigned int ignore_test_flags)
3747 {
3748    union reg_t {
3749       unsigned long int uli;
3750       double            dble;
3751    } f14_reg, f15_reg;
3752 
3753    /*This function uses global variable x_shift */
3754    VERBOSE_FUNCTION_CALLOUT
3755 
3756    if (is_not_simple_mffs_instruction(instruction_name)) {
3757       /* iterate x_shift across values used for RN,RM */
3758       for (x_shift = 0; x_shift < 3; x_shift++) {
3759          printf("%s ",  instruction_name);
3760          /* make sure bits in f14 get cleared so we can
3761             see correct resulg*/
3762          f14_reg.uli = 0x3FFFFFFFFUL;
3763 
3764          if (strcmp("mffscdrn", instruction_name) == 0) {
3765             /* instruction uses input reg f15 as input for DRN field */
3766             f15_reg.uli = (unsigned long int)x_shift << 32;
3767             printf(" f15 0X%lx  ", f15_reg.uli);
3768 
3769             /* Setup input register value */
3770             f15 = f15_reg.dble;
3771 
3772          } else if (strcmp("mffscrn", instruction_name) == 0) {
3773             /* instruction uses input reg f15 as input for RN field */
3774             f15_reg.uli = (unsigned long int)x_shift;
3775             printf(" f15 0X%lx  ", f15_reg.uli);
3776 
3777             /* Setup input register value */
3778             f15 = f15_reg.dble;
3779 
3780          } else {
3781             printf(" %x ", x_shift);
3782          }
3783 
3784 
3785          (*test_function)();
3786          printf(" => ");
3787          f14_reg.dble = f14;
3788          printf(" 0X%lx\n", f14_reg.uli);
3789          printf(" fpscr: f14 ");
3790          dissect_fpscr(f14);
3791          printf(" local_fpscr: ");
3792          dissect_fpscr(local_fpscr);
3793          printf("\n");
3794       }
3795    } else {
3796          printf("%s ",  instruction_name);
3797          printf(" => ");
3798          (*test_function)();
3799          printf(" %016f\n", f14);
3800          printf(" fpscr: f14 ");
3801          dissect_fpscr(f14);
3802          printf("\n");
3803          printf(" local_fpscr: ");
3804          dissect_fpscr(local_fpscr);
3805          printf("\n");
3806    }
3807 }
3808 
3809 /* ######## begin grand testing loops. */
3810 typedef struct insn_sel_flags_t_struct {
3811    unsigned int one_arg, two_args, three_args, four_args, cmp_args, ld_args, st_args,
3812       one_imed_args;
3813    unsigned int arith, logical, compare, popcnt, ldst, insert_extract, permute, round;
3814    unsigned int integer, altivec, altivec_quad, altivec_double, dfp, bcd, misc, mffs,
3815       no_op, pc_immediate;
3816    unsigned int cr;
3817 } insn_sel_flags_t;
3818 
do_tests(insn_sel_flags_t seln_flags)3819 static void do_tests ( insn_sel_flags_t seln_flags)
3820 {
3821    test_group_t group_function;
3822    test_list_t *tests;
3823    unsigned int nb_args, type, family;
3824    int i, j, n;
3825 
3826    n = 0;
3827    group_function = NULL;
3828 
3829    /* self-test of some utility functions. */
3830    if (verbose > 1) {
3831       printf("fpscr zero'd out:");
3832       dissect_fpscr(0);
3833       printf("\n");
3834       printf("fpscr all ones:");
3835       dissect_fpscr(0xffffffffffffffff);
3836       printf("\n");
3837       printf("fpscr RN bits:");
3838       dissect_fpscr_rounding_mode(0x0000000000000003);
3839       dissect_fpscr_rounding_mode(0x0000000000000002);
3840       dissect_fpscr_rounding_mode(0x0000000000000001);
3841       dissect_fpscr_rounding_mode(0x0000000000000000);
3842       printf("\n");
3843       printf("XER bits: (64)");
3844       dissect_xer(0xffffffffffffffff);
3845       printf("\n");
3846       printf("XER bits: (32)");
3847       dissect_xer(0xffffffff);
3848       printf("\n\n");
3849    }
3850 
3851    for (i=0; all_tests[i].name != NULL; i++) {
3852       nb_args = all_tests[i].flags & PPC_NB_ARGS_MASK;
3853       /* Check number of arguments */
3854       if ((nb_args == 1 && !seln_flags.one_arg)    ||
3855           (nb_args == 2 && !seln_flags.two_args)   ||
3856           (nb_args == 3 && !seln_flags.three_args) ||
3857           (nb_args == 4 && !seln_flags.four_args)  ||
3858           (nb_args == 5 && !seln_flags.cmp_args)   ||
3859           (nb_args == 6 && !seln_flags.ld_args)    ||
3860           (nb_args == 7 && !seln_flags.st_args)    ||
3861           (nb_args == 8 && !seln_flags.one_imed_args))
3862          continue;
3863 
3864       /* Check instruction type */
3865       type = all_tests[i].flags & PPC_TYPE_MASK;
3866       if ((type == PPC_ARITH   && !seln_flags.arith)   ||
3867           (type == PPC_LDST    && !seln_flags.ldst)    ||
3868           (type == PPC_LOGICAL && !seln_flags.logical) ||
3869           (type == PPC_COMPARE && !seln_flags.compare) ||
3870           (type == PPC_POPCNT  && !seln_flags.compare) ||
3871           (type == PPC_INSERTEXTRACT && !seln_flags.insert_extract))
3872          continue;
3873 
3874       /* Check instruction family */
3875       family = all_tests[i].flags & PPC_FAMILY_MASK;
3876 
3877       /* do each check each case individually to reduce computation */
3878       if (family == PPC_INTEGER  && seln_flags.integer == 0) continue;
3879       if (family == PPC_ALTIVEC  && seln_flags.altivec == 0) continue;
3880       if (family == PPC_DFP   && seln_flags.dfp == 0)        continue;
3881       if (family == PPC_BCD   && seln_flags.bcd == 0)        continue;
3882       if (family == PPC_NO_OP && seln_flags.no_op == 0)      continue;
3883       if (family == PPC_MISC  && seln_flags.misc == 0)       continue;
3884       if (family == PPC_MFFS  && seln_flags.mffs == 0)       continue;
3885       if (family == PPC_ALTIVEC_DOUBLE  && seln_flags.altivec_double == 0)
3886          continue;
3887 
3888       if (family == PPC_ALTIVEC_QUAD  && seln_flags.altivec_quad == 0)
3889          continue;
3890 
3891       if (family == PPC_PC_IMMEDIATE && seln_flags.pc_immediate == 0)
3892          continue;
3893 
3894       /* Check flags update */
3895       if (((all_tests[i].flags & PPC_CR)  && seln_flags.cr == 0) ||
3896           (!(all_tests[i].flags & PPC_CR) && seln_flags.cr == 1))
3897          continue;
3898 
3899       /* All criteria validation passed, do the tests */
3900       tests = all_tests[i].tests;
3901 
3902       /* Select the test group */
3903       switch (family) {
3904       case PPC_MFFS:
3905          group_function = &testfunction_mffs;
3906          break;
3907 
3908       case PPC_INTEGER:
3909          switch(type) {
3910          case PPC_ARITH:
3911             switch(nb_args) {
3912             case PPC_TWO_ARGS:
3913                group_function = &testfunction_int_two_args;
3914                break;
3915 
3916             case PPC_THREE_ARGS:
3917                group_function = &testfunction_three_args;
3918                break;
3919 
3920             default:
3921                printf("ERROR: PPC_INTEGER, unhandled number of arguments. 0x%08x\n",
3922                       nb_args);
3923             }
3924             break;
3925 
3926          case PPC_LOGICAL:
3927             switch(nb_args) {
3928             case PPC_ONE_IMM:
3929                group_function = &testfunction_set_boolean;
3930                break;
3931 
3932             case PPC_ONE_ARG:
3933                group_function = &testfunction_logical_one;
3934                break;
3935 
3936             default:
3937                printf("ERROR: PPC_LOGICAL, unhandled number of arguments. 0x%08x\n",
3938                       nb_args);
3939             }
3940             break;
3941 
3942          case PPC_COMPARE:
3943             group_function = &testfunction_char_compare;
3944             break;
3945 
3946          default:
3947             printf("ERROR: PPC_INTEGER, unhandled type  0x%08x\n", type);
3948             continue;
3949          } /* switch (type) */
3950          break;
3951 
3952       case PPC_ALTIVEC:
3953          switch(type) {
3954          case PPC_ARITH:
3955             switch(nb_args) {
3956             case PPC_TWO_ARGS:
3957                group_function = &testfunction_vector_absolute;
3958 
3959                break;
3960             default:
3961                printf("ERROR: PPC_ALTIVEC, PPC_ARITH, unhandled number of arguments. 0x%08x\n", nb_args);
3962                continue;
3963             } /* switch (PPC_ARITH, nb_args) */
3964             break;
3965 
3966          case PPC_LOGICAL:
3967             switch(nb_args) {
3968             case PPC_ONE_IMM:
3969                group_function = &testfunction_vector_immediate;
3970                break;
3971 
3972             case PPC_ONE_ARG:
3973                group_function = &testfunction_vector_logical_one;
3974                break;
3975 
3976             case PPC_TWO_ARGS:
3977                group_function = &testfunction_vector_extend_sign;
3978                break;
3979 
3980             case PPC_THREE_ARGS:
3981                group_function = &testfunction_vector_three_special;
3982                break;
3983 
3984             case PPC_FOUR_ARGS:
3985                group_function = &testfunction_vector_logical_four;
3986                break;
3987 
3988             default:
3989                printf("ERROR: PPC_ALTIVEC, PPC_LOGICAL, unhandled number of arguments. 0x%08x\n", nb_args);
3990                continue;
3991             }  /* switch(PPC_INSERTEXTRACT, nb_args) */
3992             break;
3993 
3994          case PPC_INSERTEXTRACT:
3995             switch(nb_args) {
3996             case PPC_ONE_IMM:
3997                group_function = &testfunction_vector_insert_or_extract_immediate;
3998                break;
3999 
4000             case PPC_TWO_ARGS:
4001                group_function = testfunction_vector_extract;
4002                break;
4003 
4004             default:
4005                printf("ERROR: PPC_ALTIVEC, PPC_INSERTEXTRACT, unhandled number of arguments. 0x%08x\n", nb_args);
4006                continue;
4007             }  /* switch(PPC_INSERTEXTRACT, nb_args) */
4008             break;
4009 
4010          case PPC_PERMUTE:
4011             group_function = &testfunction_vector_xxpermute;
4012             break;
4013 
4014          case PPC_LDST:
4015             switch(nb_args) {
4016             case PPC_ONE_IMM:
4017                /* Register holds immediate length value */
4018                group_function = &testfunction_vector_scalar_loadstore_length;
4019                break;
4020 
4021             case PPC_TWO_ARGS:
4022                /* Register holds address of buffer */
4023                group_function = &testfunction_vector_loadstore;
4024                break;
4025 
4026             default:
4027                printf("ERROR: PPC_ALTIVEC, PPC_LDST, unhandled number of arguments. 0x%08x\n", nb_args);
4028                continue;
4029             }  /* switch(PPC_LDST, nb_args) */
4030             break;
4031 
4032          case PPC_POPCNT:
4033             group_function = &testfunction_vector_count_bytes;
4034             break;
4035 
4036          default:
4037             printf("ERROR: PPC_ALTIVEC, unhandled type. %d\n", type);
4038             continue;
4039          } /* switch (PPC_ALTIVEC, type) */
4040          break;
4041 
4042       case PPC_MISC:
4043          switch(nb_args) {
4044             case PPC_TWO_ARGS:
4045                group_function = &testfunction_vectorscalar_move_tofrom;
4046                break;
4047             case PPC_THREE_ARGS:
4048                group_function = &testfunction_one_arg_with_shift;
4049                break;
4050             default:
4051                printf("ERROR: PPC_MISC, unhandled number of arguments. 0x%08x\n", nb_args);
4052                continue;
4053             }  /* switch(PPC_MISC, nb_args) */
4054          break;
4055 
4056       case PPC_ALTIVEC_QUAD:
4057          switch(type) {
4058          case PPC_LOGICAL:
4059             switch(nb_args) {
4060             case PPC_TWO_ARGS:
4061                group_function = &testfunction_vector_scalar_two_quad;
4062                break;
4063 
4064             default:
4065                printf("ERROR: PPC_ALTIVEC_QUAD, PPC_LOGICAL, unhandled number of arguments. 0x%08x\n", nb_args);
4066                continue;
4067             }  /* switch(PPC_LOGICAL, nb_args) */
4068             break;
4069 
4070          case PPC_COMPARE:
4071             group_function = &testfunction_vector_scalar_compare_quads;
4072             break;
4073 
4074          case PPC_ROUND:
4075             group_function = &testfunction_vector_scalar_rounding_quads;
4076             break;
4077 
4078          default:
4079             printf("ERROR: PPC_ALTIVEC_QUAD, unhandled type. %d\n", type);
4080             continue;
4081          } /* switch(type) */
4082          break;
4083 
4084       case PPC_ALTIVEC_DOUBLE:
4085          switch(type) {
4086          case PPC_COMPARE:
4087             switch(nb_args) {
4088             case PPC_ONE_ARG:
4089                group_function = &testfunction_vector_scalar_data_class;
4090                break;
4091 
4092             case PPC_TWO_ARGS:
4093                group_function = &testfunction_vector_scalar_two_double;
4094                break;
4095 
4096             case PPC_COMPARE_ARGS:
4097                group_function = &testfunction_vector_scalar_compare_exp_double;
4098                break;
4099 
4100             default:
4101                printf("ERROR: PPC_ALTIVEC_DOUBLE, PPC_COMPARE, unhandled number of arguments. 0x%08x\n", nb_args);
4102                continue;
4103             }  /* switch(PPC_COMPARE, nb_args) */
4104             break;
4105 
4106          default:
4107             printf("ERROR: PPC_ALTIVEC_DOUBLE, unhandled type. %d\n", type);
4108             continue;
4109 
4110          }   /* switch(type) */
4111          break;
4112 
4113       case PPC_DFP:
4114          group_function = &testfunction_dfp_significance;
4115          break;
4116 
4117       case PPC_BCD:
4118          group_function = &testfunction_bcd_misc;
4119          break;
4120 
4121       case PPC_NO_OP:
4122          group_function = &testfunction_noop_misc;
4123          break;
4124 
4125       case PPC_PC_IMMEDIATE:
4126          group_function = &testfunction_pc_immediate_misc;
4127          break;
4128 
4129       default:
4130          printf("ERROR: unknown instruction family %08x\n", family);
4131          continue;
4132       } /* switch(family) */
4133 
4134       printf("%s:\n", all_tests[i].name);
4135 
4136       printf("Test instruction group [%s]\n", all_tests[i].name);
4137       /* Now, spin through all entries in the group_function to
4138        * run the individual instruction tests.
4139        */
4140       for (j = 0; tests[j].name != NULL; j++) {
4141          if (verbose > 1)
4142             printf("Test instruction %s\n", tests[j].name);
4143          (*group_function)(tests[j].name, tests[j].func, all_tests[i].flags);
4144          printf("\n");
4145          n++;
4146       }
4147 
4148       if (verbose) printf("\n");
4149 
4150       printf("All done. Tested %d different instructions\n", n);
4151    }  /* for (i = 0; all_tests[i].name...) */
4152 }
4153 
usage(void)4154 static void usage (void)
4155 {
4156    fprintf(stderr,
4157            "Usage: test_isa_3_0 [OPTIONS]\n"
4158            "\t-i: test integer instructions (default)\n"
4159            "\t-a: test altivec instructions\n"
4160            "\t-d: test altivec double instructions\n"
4161            "\t-q: test altivec quad instructions\n"
4162            "\t-D: test DFP instructions\n"
4163            "\t-B: test BCD instructions\n"
4164            "\t-N: test No Op instructions\n"
4165            "\t-P: test PC Immediate Shifted instructions\n"
4166            "\t-m: test miscellaneous instructions\n"
4167            "\t-M: test MFFS instructions\n"
4168            "\t-v: be verbose\n"
4169            "\t-h: display this help and exit\n"
4170            );
4171 }
4172 
4173 #endif   // HAS_ISA_3_00
main(int argc,char ** argv)4174 int main (int argc, char **argv)
4175 {
4176 
4177 #ifndef HAS_ISA_3_00
4178    printf("NO ISA 3.00 SUPPORT\n");
4179    return 0;
4180 
4181 #else
4182    insn_sel_flags_t flags;
4183    int c;
4184 
4185 
4186    // Args
4187    flags.one_arg         = 1;
4188    flags.two_args        = 1;
4189    flags.three_args      = 1;
4190    flags.four_args       = 1;
4191    flags.cmp_args        = 1;
4192    flags.ld_args         = 1;
4193    flags.st_args         = 1;
4194    flags.one_imed_args   = 1;
4195 
4196    // Type
4197    flags.arith           = 1;
4198    flags.logical         = 1;
4199    flags.compare         = 1;
4200    flags.ldst            = 1;
4201    flags.popcnt          = 1;
4202    flags.insert_extract  = 1;
4203    flags.permute         = 1;
4204    flags.round           = 1;
4205 
4206    // Family
4207    flags.integer         = 0;
4208    flags.altivec         = 0;
4209    flags.altivec_double  = 0;
4210    flags.altivec_quad    = 0;
4211    flags.dfp             = 0;
4212    flags.bcd             = 0;
4213    flags.misc            = 0;
4214    flags.mffs            = 0;
4215    flags.no_op           = 0;
4216    flags.pc_immediate    = 0;
4217 
4218    // Flags
4219    flags.cr              = 2;
4220 
4221    while ((c = getopt(argc, argv, "ifmadqhvADBMNP")) != -1) {
4222       switch (c) {
4223       case 'i':
4224          flags.integer  = 1;
4225          break;
4226 
4227       case 'a':
4228          flags.altivec  = 1;
4229          break;
4230 
4231       case 'd':
4232          flags.altivec_double  = 1;
4233          break;
4234 
4235       case 'q':
4236          flags.altivec_quad  = 1;
4237          break;
4238 
4239       case 'D':
4240          flags.dfp      = 1;
4241          break;
4242 
4243       case 'B':
4244          flags.bcd      = 1;
4245          break;
4246 
4247       case 'm':
4248          flags.misc     = 1;
4249          break;
4250 
4251       case 'M':
4252          flags.mffs     = 1;
4253          break;
4254 
4255       case 'N':
4256          flags.no_op    = 1;
4257          break;
4258 
4259       case 'P':
4260          flags.pc_immediate = 1;
4261          break;
4262 
4263       case 'h':
4264          usage();
4265          return 0;
4266 
4267       case 'v':
4268          verbose++;
4269          break;
4270 
4271       default:
4272          usage();
4273          fprintf(stderr, "Unknown argument: '%c'\n", c);
4274          return 1;
4275       }
4276    }
4277 
4278    build_iargs_table();
4279    build_vsx_table();
4280    build_float_vsx_tables();
4281    build_vector_permute_table();
4282    build_char_table();
4283    build_char_range_table();
4284    build_packed_decimal_table();
4285    build_national_decimal_table();
4286    build_zoned_decimal_table();
4287    build_decimal_shift_table();
4288 
4289    if (verbose>2) {
4290       dump_char_table();
4291       dump_char_range_table();
4292       dump_float_vsx_table();
4293       dump_packed_decimal_table();
4294       dump_national_decimal_table();
4295       dump_zoned_decimal_table();
4296       dump_decimal_shift_table();
4297       dump_dfp64_table();
4298       dump_dfp128_table();
4299    }
4300 
4301    if (verbose > 1) {
4302       printf("\nInstruction Selection:\n");
4303       printf("  n_args: \n");
4304       printf("    one_arg        = %d\n", flags.one_arg);
4305       printf("    two_args       = %d\n", flags.two_args);
4306       printf("    three_args     = %d\n", flags.three_args);
4307       printf("    four_args      = %d\n", flags.four_args);
4308       printf("    cmp_args       = %d\n", flags.cmp_args);
4309       printf("    load_args      = %d\n", flags.ld_args);
4310       printf("    store_args     = %d\n", flags.st_args);
4311       printf("    one_im_args    = %d\n", flags.one_imed_args);
4312       printf("  type: \n");
4313       printf("    arith          = %d\n", flags.arith);
4314       printf("    logical        = %d\n", flags.logical);
4315       printf("    popcnt         = %d\n", flags.popcnt);
4316       printf("    compare        = %d\n", flags.compare);
4317       printf("    inset/extract  = %d\n", flags.insert_extract);
4318       printf("  family: \n");
4319       printf("    integer        = %d\n", flags.integer);
4320       printf("    altivec        = %d\n", flags.altivec);
4321       printf("    altivec double = %d\n", flags.altivec_double);
4322       printf("    altivec quad   = %d\n", flags.altivec_quad);
4323       printf("    DFP            = %d\n", flags.dfp);
4324       printf("    BCD            = %d\n", flags.bcd);
4325       printf("    PC immediate shifted = %d\n", flags.pc_immediate);
4326       printf("    misc           = %d\n", flags.misc);
4327       printf("  cr update: \n");
4328       printf("    cr             = %d\n", flags.cr);
4329       printf("\n");
4330       printf("  num args: \n");
4331       printf("    iargs      - %d\n", nb_iargs);
4332       printf("\n");
4333    }
4334 
4335    do_tests( flags );
4336 #endif
4337 
4338    return 0;
4339 }
4340