1
2/* HOW TO COMPILE:
3
4* 32bit build:
5   gcc -Winline -Wall -g -O -mregnames -maltivec
6* 64bit build:
7   gcc -Winline -Wall -g -O -mregnames -maltivec -m64
8
9This program is useful, but the register usage conventions in
10it are a complete dog.  In particular, _patch_op_imm has to
11be inlined, else you wind up with it segfaulting in
12completely different places due to corruption (of r20 in the
13case I chased).
14*/
15
16/*
17 * test-ppc.c:
18 * PPC tests for qemu-PPC CPU emulation checks
19 *
20 * Copyright (c) 2005 Jocelyn Mayer
21 *
22 *   This program is free software; you can redistribute it and/or
23 *   modify it under the terms of the GNU General Public License V2
24 *   as published by the Free Software Foundation
25 *
26 *   This program is distributed in the hope that it will be useful,
27 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
28 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29 *   GNU General Public License for more details.
30 *
31 *   You should have received a copy of the GNU General Public License
32 *   along with this program; if not, write to the Free Software
33 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
34 */
35
36/*
37 * Theory of operations:
38 * a few registers are reserved for the test program:
39 * r14 => r18
40 * f14 => f18
41 * I do preload test values in r14 thru r17 (or less, depending on the number
42 * of register operands needed), patch the test opcode if any immediate
43 * operands are required, execute the tested opcode.
44 * XER, CCR and FPSCR are cleared before every test.
45 * I always get the result in r17 and also save XER and CCR for fixed-point
46 * operations. I also check FPSCR for floating points operations.
47 *
48 * Improvments:
49 * a more clever FPSCR management is needed: for now, I always test
50 * the round-to-zero case. Other rounding modes also need to be tested.
51 */
52
53/*
54 * Operation details
55 * -----------------
56 * The 'test' functions (via all_tests[]) are wrappers of single asm instns
57 *
58 * The 'loops' (e.g. int_loops) do the actual work:
59 *  - loops over as many arguments as the instn needs (regs | imms)
60 *     - sets up the environment (reset cr,xer, assign src regs...)
61 *     - maybe modifies the asm instn to test different imm args
62 *     - calls the test function
63 *     - retrieves relevant register data (rD,cr,xer,...)
64 *     - prints argument and result data.
65 *
66 * More specifically...
67 *
68 * all_tests[i] holds insn tests
69 *  - of which each holds: {instn_test_arr[], description, flags}
70 *
71 * flags hold 3 instn classifiers: {family, type, arg_type}
72 *
73 * // The main test loop:
74 * do_tests( user_ctl_flags ) {
75 *    foreach(curr_test = all_test[i]) {
76 *
77 *       // flags are used to control what tests are run:
78 *       if (curr_test->flags && !user_ctl_flags)
79 *          continue;
80 *
81 *       // a 'loop_family_arr' is chosen based on the 'family' flag...
82 *       switch(curr_test->flags->family) {
83 *       case x: loop_family_arr = int_loops;
84 *      ...
85 *       }
86 *
87 *       // ...and the actual test_loop to run is found by indexing into
88 *       // the loop_family_arr with the 'arg_type' flag:
89 *       test_loop = loop_family[curr_test->flags->arg_type]
90 *
91 *       // finally, loop over all instn tests for this test:
92 *       foreach (instn_test = curr_test->instn_test_arr[i]) {
93 *
94 *          // and call the test_loop with the current instn_test function,name
95 *          test_loop( instn_test->func, instn_test->name )
96 *       }
97 *    }
98 * }
99 *
100 *
101 * Details of intruction patching for immediate operands
102 * -----------------------------------------------------
103 * All the immediate insn test functions are of the form {imm_insn, blr}
104 * In order to patch one of these functions, we simply copy both insns
105 * to a stack buffer, and rewrite the immediate part of imm_insn.
106 * We then execute our stack buffer.
107 * All ppc instructions are 32bits wide, which makes this fairly easy.
108 *
109 * Example:
110 * extern void test_addi (void);
111 * asm(".section \".text\"\n"
112 *     "    .align 2\n"
113 *     "    .type test_addi,@function\n"
114 *     "test_addi:\n"
115 *     "    addi\n"
116 *     "    blr\n"
117 *     "    .previous\n"
118 *     );
119 *
120 * We are interested only in:
121 *      "    addi         17, 14, 0\n"
122 *      "    blr\n"
123 *
124 * In a loop test, we may see:
125 * uint32_t func_buf[2];               // our new stack based 'function'
126 * for imm...                          // loop over imm
127 *   init_function( &func, func_buf );   // copy insns, set func ptr
128 *   patch_op_imm16(&func_buf[0], imm);  // patch 'addi' insn
129 *   ...
130 *   (*func)();                              // exec our rewritten code
131 *
132 * patch_op_imm16() itself simply takes the uint32_t insn and overwrites
133 * the immediate field with the new value (which, for 'addi', is the
134 * low 16 bits).
135 *
136 * So in the loop test, if 'imm' is currently 9, and p[0] is:
137 *   0x3A2E0000   => addi 17, 14, 0
138 *
139 * after patch_op_imm16(), func_buf[0] becomes:
140 *   0x3A2E0009   => addi 17, 14, 9
141 *
142 * Note: init_function() needs to be called on every iteration
143 *  - don't ask me why!
144*/
145
146
147/**********************************************************************/
148/* Uncomment to enable many arguments for altivec insns */
149#define USAGE_SIMPLE
150
151/* Uncomment to enable many arguments for altivec insns */
152//#define ALTIVEC_ARGS_LARGE
153
154/* Uncomment to enable output of CR flags for float tests */
155//#define TEST_FLOAT_FLAGS
156
157/* Uncomment to enable debug output */
158//#define DEBUG_ARGS_BUILD
159//#define DEBUG_FILTER
160
161/* These should be set at build time */
162//#define NO_FLOAT
163//#define HAS_ALTIVEC  // CFLAGS += -maltivec
164//#define IS_PPC405
165/**********************************************************************/
166
167
168#include <stdint.h>
169#include "tests/sys_mman.h"
170#include "tests/malloc.h"       // memalign16
171
172#define STATIC_ASSERT(e) sizeof(struct { int:-!(e); })
173
174/* Something of the same size as void*, so can be safely be coerced
175 * to/from a pointer type. Also same size as the host's gp registers.
176 * According to the AltiVec section of the GCC manual, the syntax does
177 * not allow the use of a typedef name as a type specifier in conjunction
178 * with the vector keyword, so typedefs uint[32|64]_t are #undef'ed here
179 * and redefined using #define.
180 */
181#undef uint32_t
182#undef uint64_t
183#define uint32_t unsigned int
184#define uint64_t unsigned long long int
185
186#ifndef __powerpc64__
187typedef uint32_t  HWord_t;
188#else
189typedef uint64_t  HWord_t;
190#endif /* __powerpc64__ */
191
192enum {
193    compile_time_test1 = STATIC_ASSERT(sizeof(uint32_t) == 4),
194    compile_time_test2 = STATIC_ASSERT(sizeof(uint64_t) == 8),
195};
196
197#define ALLCR "cr0","cr1","cr2","cr3","cr4","cr5","cr6","cr7"
198
199#define SET_CR(_arg) \
200      __asm__ __volatile__ ("mtcr  %0" : : "b"(_arg) : ALLCR );
201
202#define SET_XER(_arg) \
203      __asm__ __volatile__ ("mtxer %0" : : "b"(_arg) : "xer" );
204
205#define GET_CR(_lval) \
206      __asm__ __volatile__ ("mfcr %0"  : "=b"(_lval) )
207
208#define GET_XER(_lval) \
209      __asm__ __volatile__ ("mfxer %0" : "=b"(_lval) )
210
211#define GET_CR_XER(_lval_cr,_lval_xer) \
212   do { GET_CR(_lval_cr); GET_XER(_lval_xer); } while (0)
213
214#define SET_CR_ZERO \
215      SET_CR(0)
216
217#define SET_XER_ZERO \
218      SET_XER(0)
219
220#define SET_CR_XER_ZERO \
221   do { SET_CR_ZERO; SET_XER_ZERO; } while (0)
222
223#define SET_FPSCR_ZERO \
224   do { double _d = 0.0; \
225        __asm__ __volatile__ ("mtfsf 0xFF, %0" : : "f"(_d) ); \
226   } while (0)
227
228
229/* XXXX these must all be callee-save regs! */
230register double f14 __asm__ ("fr14");
231register double f15 __asm__ ("fr15");
232register double f16 __asm__ ("fr16");
233register double f17 __asm__ ("fr17");
234register HWord_t r14 __asm__ ("r14");
235register HWord_t r15 __asm__ ("r15");
236register HWord_t r16 __asm__ ("r16");
237register HWord_t r17 __asm__ ("r17");
238
239#include "config.h"         // HAS_ALTIVEC
240#if defined (HAS_ALTIVEC)
241#   include <altivec.h>
242#endif
243#include <assert.h>
244#include <ctype.h>     // isspace
245#include <stdio.h>
246#include <stdlib.h>
247#include <string.h>
248#include <unistd.h>    // getopt
249
250
251#ifndef __powerpc64__
252#define ASSEMBLY_FUNC(__fname, __insn)     \
253asm(".section \".text\"\n"                 \
254    "\t.align 2\n"                         \
255    "\t.type "__fname",@function\n"        \
256    __fname":\n"                           \
257    "\t"__insn"\n"                         \
258    "\tblr\n"                              \
259    "\t.previous\n"                        \
260    )
261#else
262#define ASSEMBLY_FUNC(__fname, __insn)     \
263asm(".section  \".text\"\n"                \
264    "\t.align 2\n"                         \
265    "\t.global "__fname"\n"                \
266    "\t.section \".opd\",\"aw\"\n"         \
267    "\t.align 3\n"                         \
268    ""__fname":\n"                         \
269    "\t.quad ."__fname",.TOC.@tocbase,0\n" \
270    "\t.previous\n"                        \
271    "\t.type ."__fname",@function\n"       \
272    "\t.global  ."__fname"\n"              \
273    "."__fname":\n"                        \
274    "\t"__insn"\n"                         \
275    "\tblr\n"                              \
276    )
277#endif // #ifndef __powerpc64__
278
279
280/* Return a pointer to a 1-page area where is is safe to both write
281   and execute instructions.  Area is filled with 'trap' insns. */
282static
283uint32_t* get_rwx_area ( void )
284{
285   int i;
286   static uint32_t* p = NULL;
287   if (p == NULL) {
288      p = mmap(NULL, 4096, PROT_READ|PROT_WRITE|PROT_EXEC,
289                           MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
290      assert(p != MAP_FAILED);
291   }
292
293   for (i = 0; i < 4096/sizeof(uint32_t); i++)
294      p[i] = 0x7fe00008; /* trap */
295
296   return p;
297}
298
299
300/* -------------- BEGIN #include "test-ppc.h" -------------- */
301/*
302 * test-ppc.h:
303 * PPC tests for qemu-PPC CPU emulation checks - definitions
304 *
305 * Copyright (c) 2005 Jocelyn Mayer
306 *
307 *   This program is free software; you can redistribute it and/or
308 *   modify it under the terms of the GNU General Public License V2
309 *   as published by the Free Software Foundation
310 *
311 *   This program is distributed in the hope that it will be useful,
312 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
313 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
314 *   GNU General Public License for more details.
315 *
316 *   You should have received a copy of the GNU General Public License
317 *   along with this program; if not, write to the Free Software
318 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
319 */
320
321#if !defined (__TEST_PPC_H__)
322#define __TEST_PPC_H__
323
324#include <stdint.h>
325
326typedef void (*test_func_t) (void);
327typedef struct test_t test_t;
328typedef struct test_table_t test_table_t;
329struct test_t {
330    test_func_t func;
331    const char *name;
332};
333
334struct test_table_t {
335    test_t *tests;
336    const char *name;
337    uint32_t flags;
338};
339
340typedef void (*test_loop_t) (const char *name, test_func_t func,
341                             uint32_t flags);
342
343enum test_flags {
344    /* Nb arguments */
345    PPC_ONE_ARG    = 0x00000001,
346    PPC_TWO_ARGS   = 0x00000002,
347    PPC_THREE_ARGS = 0x00000003,
348    PPC_CMP_ARGS   = 0x00000004,  // family: compare
349    PPC_CMPI_ARGS  = 0x00000005,  // family: compare
350    PPC_TWO_I16    = 0x00000006,  // family: arith/logical
351    PPC_SPECIAL    = 0x00000007,  // family: logical
352    PPC_LD_ARGS    = 0x00000008,  // family: ldst
353    PPC_LDX_ARGS   = 0x00000009,  // family: ldst
354    PPC_ST_ARGS    = 0x0000000A,  // family: ldst
355    PPC_STX_ARGS   = 0x0000000B,  // family: ldst
356    PPC_NB_ARGS    = 0x0000000F,
357    /* Type */
358    PPC_ARITH      = 0x00000100,
359    PPC_LOGICAL    = 0x00000200,
360    PPC_COMPARE    = 0x00000300,
361    PPC_CROP       = 0x00000400,
362    PPC_LDST       = 0x00000500,
363    PPC_POPCNT     = 0x00000600,
364    PPC_TYPE       = 0x00000F00,
365    /* Family */
366    PPC_INTEGER    = 0x00010000,
367    PPC_FLOAT      = 0x00020000,
368    PPC_405        = 0x00030000,
369    PPC_ALTIVEC    = 0x00040000,
370    PPC_FALTIVEC   = 0x00050000,
371    PPC_FAMILY     = 0x000F0000,
372    /* Flags: these may be combined, so use separate bitfields. */
373    PPC_CR         = 0x01000000,
374    PPC_XER_CA     = 0x02000000,
375};
376
377#endif /* !defined (__TEST_PPC_H__) */
378
379/* -------------- END #include "test-ppc.h" -------------- */
380
381
382
383
384#if defined (DEBUG_ARGS_BUILD)
385#define AB_DPRINTF(fmt, args...) do { fprintf(stderr, fmt , ##args); } while (0)
386#else
387#define AB_DPRINTF(fmt, args...) do { } while (0)
388#endif
389
390#if defined (DEBUG_FILTER)
391#define FDPRINTF(fmt, args...) do { fprintf(stderr, fmt , ##args); } while (0)
392#else
393#define FDPRINTF(fmt, args...) do { } while (0)
394#endif
395
396
397/* Produce the 64-bit pattern corresponding to the supplied double. */
398static uint64_t double_to_bits ( double d )
399{
400   union { uint64_t i; double d; } u;
401   assert(8 == sizeof(uint64_t));
402   assert(8 == sizeof(double));
403   assert(8 == sizeof(u));
404   u.d = d;
405   return u.i;
406}
407
408#if 0
409static float bits_to_float ( uint32_t i )
410{
411   union { uint32_t i; float f; } u;
412   assert(4 == sizeof(uint32_t));
413   assert(4 == sizeof(float));
414   assert(4 == sizeof(u));
415   u.i = i;
416   return u.f;
417}
418#endif
419
420
421#if defined (HAS_ALTIVEC)
422static void AB_DPRINTF_VEC32x4 ( vector unsigned int v )
423{
424#if defined (DEBUG_ARGS_BUILD)
425   int i;
426   unsigned int* p_int = (unsigned int*)&v;
427   AB_DPRINTF("val");
428   for (i=0; i<4; i++) {
429      AB_DPRINTF(" %08x", p_int[i]);
430   }
431   AB_DPRINTF("\n");
432#endif
433}
434#endif
435
436
437#define unused __attribute__ (( unused ))
438
439
440/* -------------- BEGIN #include "ops-ppc.c" -------------- */
441
442/* #include "test-ppc.h" */
443
444static void test_add (void)
445{
446    __asm__ __volatile__ ("add          17, 14, 15");
447}
448
449static void test_addo (void)
450{
451    __asm__ __volatile__ ("addo         17, 14, 15");
452}
453
454static void test_addc (void)
455{
456    __asm__ __volatile__ ("addc         17, 14, 15");
457}
458
459static void test_addco (void)
460{
461    __asm__ __volatile__ ("addco        17, 14, 15");
462}
463
464static void test_divw (void)
465{
466    __asm__ __volatile__ ("divw         17, 14, 15");
467}
468
469static void test_divwo (void)
470{
471    __asm__ __volatile__ ("divwo        17, 14, 15");
472}
473
474static void test_divwu (void)
475{
476    __asm__ __volatile__ ("divwu        17, 14, 15");
477}
478
479static void test_divwuo (void)
480{
481    __asm__ __volatile__ ("divwuo       17, 14, 15");
482}
483
484static void test_mulhw (void)
485{
486    __asm__ __volatile__ ("mulhw        17, 14, 15");
487}
488
489static void test_mulhwu (void)
490{
491    __asm__ __volatile__ ("mulhwu       17, 14, 15");
492}
493
494static void test_mullw (void)
495{
496    __asm__ __volatile__ ("mullw        17, 14, 15");
497}
498
499static void test_mullwo (void)
500{
501    __asm__ __volatile__ ("mullwo       17, 14, 15");
502}
503
504static void test_subf (void)
505{
506    __asm__ __volatile__ ("subf         17, 14, 15");
507}
508
509static void test_subfo (void)
510{
511    __asm__ __volatile__ ("subfo        17, 14, 15");
512}
513
514static void test_subfc (void)
515{
516    __asm__ __volatile__ ("subfc        17, 14, 15");
517}
518
519static void test_subfco (void)
520{
521    __asm__ __volatile__ ("subfco       17, 14, 15");
522}
523
524#ifdef __powerpc64__
525static void test_mulld (void)
526{
527    __asm__ __volatile__ ("mulld        17, 14, 15");
528}
529
530static void test_mulhd (void)
531{
532    __asm__ __volatile__ ("mulhd        17, 14, 15");
533}
534
535static void test_mulhdu (void)
536{
537    __asm__ __volatile__ ("mulhdu       17, 14, 15");
538}
539
540static void test_divd (void)
541{
542    __asm__ __volatile__ ("divd         17, 14, 15");
543}
544
545static void test_divdu (void)
546{
547    __asm__ __volatile__ ("divdu        17, 14, 15");
548}
549#endif // #ifdef __powerpc64__
550
551static test_t tests_ia_ops_two[] = {
552    { &test_add             , "         add", },
553    { &test_addo            , "        addo", },
554    { &test_addc            , "        addc", },
555    { &test_addco           , "       addco", },
556    { &test_divw            , "        divw", },
557    { &test_divwo           , "       divwo", },
558    { &test_divwu           , "       divwu", },
559    { &test_divwuo          , "      divwuo", },
560    { &test_mulhw           , "       mulhw", },
561    { &test_mulhwu          , "      mulhwu", },
562    { &test_mullw           , "       mullw", },
563    { &test_mullwo          , "      mullwo", },
564    { &test_subf            , "        subf", },
565    { &test_subfo           , "       subfo", },
566    { &test_subfc           , "       subfc", },
567    { &test_subfco          , "      subfco", },
568#ifdef __powerpc64__
569    { &test_mulhd           , "       mulhd", },
570    { &test_mulhdu          , "      mulhdu", },
571    { &test_mulld           , "       mulld", },
572    { &test_divd            , "        divd", },
573    { &test_divdu           , "       divdu", },
574#endif // #ifdef __powerpc64__
575    { NULL,                   NULL,           },
576};
577
578static void test_add_ (void)
579{
580    __asm__ __volatile__ ("add.         17, 14, 15");
581}
582
583static void test_addo_ (void)
584{
585    __asm__ __volatile__ ("addo.        17, 14, 15");
586}
587
588static void test_addc_ (void)
589{
590    __asm__ __volatile__ ("addc.        17, 14, 15");
591}
592
593static void test_addco_ (void)
594{
595    __asm__ __volatile__ ("addco.       17, 14, 15");
596}
597
598static void test_divw_ (void)
599{
600    __asm__ __volatile__ ("divw.        17, 14, 15");
601}
602
603static void test_divwo_ (void)
604{
605    __asm__ __volatile__ ("divwo.       17, 14, 15");
606}
607
608static void test_divwu_ (void)
609{
610    __asm__ __volatile__ ("divwu.       17, 14, 15");
611}
612
613static void test_divwuo_ (void)
614{
615    __asm__ __volatile__ ("divwuo.      17, 14, 15");
616}
617
618static void test_mulhw_ (void)
619{
620    __asm__ __volatile__ ("mulhw.       17, 14, 15");
621}
622
623static void test_mulhwu_ (void)
624{
625    __asm__ __volatile__ ("mulhwu.      17, 14, 15");
626}
627
628static void test_mullw_ (void)
629{
630    __asm__ __volatile__ ("mullw.       17, 14, 15");
631}
632
633static void test_mullwo_ (void)
634{
635    __asm__ __volatile__ ("mullwo.      17, 14, 15");
636}
637
638static void test_subf_ (void)
639{
640    __asm__ __volatile__ ("subf.        17, 14, 15");
641}
642
643static void test_subfo_ (void)
644{
645    __asm__ __volatile__ ("subfo.       17, 14, 15");
646}
647
648static void test_subfc_ (void)
649{
650    __asm__ __volatile__ ("subfc.       17, 14, 15");
651}
652
653static void test_subfco_ (void)
654{
655    __asm__ __volatile__ ("subfco.      17, 14, 15");
656}
657
658#ifdef __powerpc64__
659static void test_mulhd_ (void)
660{
661    __asm__ __volatile__ ("mulhd.       17, 14, 15");
662}
663
664static void test_mulhdu_ (void)
665{
666    __asm__ __volatile__ ("mulhdu.      17, 14, 15");
667}
668
669static void test_mulld_ (void)
670{
671    __asm__ __volatile__ ("mulld.       17, 14, 15");
672}
673
674static void test_divd_ (void)
675{
676    __asm__ __volatile__ ("divd.        17, 14, 15");
677}
678
679static void test_divdu_ (void)
680{
681    __asm__ __volatile__ ("divdu.       17, 14, 15");
682}
683#endif // #ifdef __powerpc64__
684
685static test_t tests_iar_ops_two[] = {
686    { &test_add_            , "        add.", },
687    { &test_addo_           , "       addo.", },
688    { &test_addc_           , "       addc.", },
689    { &test_addco_          , "      addco.", },
690    { &test_divw_           , "       divw.", },
691    { &test_divwo_          , "      divwo.", },
692    { &test_divwu_          , "      divwu.", },
693    { &test_divwuo_         , "     divwuo.", },
694    { &test_mulhw_          , "      mulhw.", },
695    { &test_mulhwu_         , "     mulhwu.", },
696    { &test_mullw_          , "      mullw.", },
697    { &test_mullwo_         , "     mullwo.", },
698    { &test_subf_           , "       subf.", },
699    { &test_subfo_          , "      subfo.", },
700    { &test_subfc_          , "      subfc.", },
701    { &test_subfco_         , "     subfco.", },
702#ifdef __powerpc64__
703    { &test_mulhd_          , "      mulhd.", },
704    { &test_mulhdu_         , "     mulhdu.", },
705    { &test_mulld_          , "      mulld.", },
706    { &test_divd_           , "       divd.", },
707    { &test_divdu_          , "      divdu.", },
708#endif // #ifdef __powerpc64__
709    { NULL,                   NULL,           },
710};
711
712static void test_adde (void)
713{
714    __asm__ __volatile__ ("adde         17, 14, 15");
715}
716
717static void test_addeo (void)
718{
719    __asm__ __volatile__ ("addeo        17, 14, 15");
720}
721
722static void test_subfe (void)
723{
724    __asm__ __volatile__ ("subfe        17, 14, 15");
725}
726
727static void test_subfeo (void)
728{
729    __asm__ __volatile__ ("subfeo       17, 14, 15");
730}
731
732static test_t tests_iac_ops_two[] = {
733    { &test_adde            , "        adde", },
734    { &test_addeo           , "       addeo", },
735    { &test_subfe           , "       subfe", },
736    { &test_subfeo          , "      subfeo", },
737    { NULL,                   NULL,           },
738};
739
740static void test_adde_ (void)
741{
742    __asm__ __volatile__ ("adde.        17, 14, 15");
743}
744
745static void test_addeo_ (void)
746{
747    __asm__ __volatile__ ("addeo.       17, 14, 15");
748}
749
750static void test_subfe_ (void)
751{
752    __asm__ __volatile__ ("subfe.       17, 14, 15");
753}
754
755static void test_subfeo_ (void)
756{
757    __asm__ __volatile__ ("subfeo.      17, 14, 15");
758}
759
760static test_t tests_iacr_ops_two[] = {
761    { &test_adde_           , "       adde.", },
762    { &test_addeo_          , "      addeo.", },
763    { &test_subfe_          , "      subfe.", },
764    { &test_subfeo_         , "     subfeo.", },
765    { NULL,                   NULL,           },
766};
767
768static void test_and (void)
769{
770    __asm__ __volatile__ ("and          17, 14, 15");
771}
772
773static void test_andc (void)
774{
775    __asm__ __volatile__ ("andc         17, 14, 15");
776}
777
778static void test_eqv (void)
779{
780    __asm__ __volatile__ ("eqv          17, 14, 15");
781}
782
783static void test_nand (void)
784{
785    __asm__ __volatile__ ("nand         17, 14, 15");
786}
787
788static void test_nor (void)
789{
790    __asm__ __volatile__ ("nor          17, 14, 15");
791}
792
793static void test_or (void)
794{
795    __asm__ __volatile__ ("or           17, 14, 15");
796}
797
798static void test_orc (void)
799{
800    __asm__ __volatile__ ("orc          17, 14, 15");
801}
802
803static void test_xor (void)
804{
805    __asm__ __volatile__ ("xor          17, 14, 15");
806}
807
808static void test_slw (void)
809{
810    __asm__ __volatile__ ("slw          17, 14, 15");
811}
812
813static void test_sraw (void)
814{
815    __asm__ __volatile__ ("sraw         17, 14, 15");
816}
817
818static void test_srw (void)
819{
820    __asm__ __volatile__ ("srw          17, 14, 15");
821}
822
823#ifdef __powerpc64__
824static void test_sld (void)
825{
826    __asm__ __volatile__ ("sld          17, 14, 15");
827}
828
829static void test_srad (void)
830{
831    __asm__ __volatile__ ("srad         17, 14, 15");
832}
833
834static void test_srd (void)
835{
836    __asm__ __volatile__ ("srd          17, 14, 15");
837}
838#endif // #ifdef __powerpc64__
839
840static test_t tests_il_ops_two[] = {
841    { &test_and             , "         and", },
842    { &test_andc            , "        andc", },
843    { &test_eqv             , "         eqv", },
844    { &test_nand            , "        nand", },
845    { &test_nor             , "         nor", },
846    { &test_or              , "          or", },
847    { &test_orc             , "         orc", },
848    { &test_xor             , "         xor", },
849    { &test_slw             , "         slw", },
850    { &test_sraw            , "        sraw", },
851    { &test_srw             , "         srw", },
852#ifdef __powerpc64__
853    { &test_sld             , "         sld", },
854    { &test_srad            , "        srad", },
855    { &test_srd             , "         srd", },
856#endif // #ifdef __powerpc64__
857    { NULL,                   NULL,           },
858};
859
860static void test_and_ (void)
861{
862    __asm__ __volatile__ ("and.         17, 14, 15");
863}
864
865static void test_andc_ (void)
866{
867    __asm__ __volatile__ ("andc.        17, 14, 15");
868}
869
870static void test_eqv_ (void)
871{
872    __asm__ __volatile__ ("eqv.         17, 14, 15");
873}
874
875static void test_nand_ (void)
876{
877    __asm__ __volatile__ ("nand.        17, 14, 15");
878}
879
880static void test_nor_ (void)
881{
882    __asm__ __volatile__ ("nor.         17, 14, 15");
883}
884
885static void test_or_ (void)
886{
887    __asm__ __volatile__ ("or.          17, 14, 15");
888}
889
890static void test_orc_ (void)
891{
892    __asm__ __volatile__ ("orc.         17, 14, 15");
893}
894
895static void test_xor_ (void)
896{
897    __asm__ __volatile__ ("xor.         17, 14, 15");
898}
899
900static void test_slw_ (void)
901{
902    __asm__ __volatile__ ("slw.         17, 14, 15");
903}
904
905static void test_sraw_ (void)
906{
907    __asm__ __volatile__ ("sraw.        17, 14, 15");
908}
909
910static void test_srw_ (void)
911{
912    __asm__ __volatile__ ("srw.         17, 14, 15");
913}
914
915#ifdef __powerpc64__
916static void test_sld_ (void)
917{
918    __asm__ __volatile__ ("sld.         17, 14, 15");
919}
920
921static void test_srad_ (void)
922{
923    __asm__ __volatile__ ("srad.        17, 14, 15");
924}
925
926static void test_srd_ (void)
927{
928    __asm__ __volatile__ ("srd.         17, 14, 15");
929}
930#endif // #ifdef __powerpc64__
931
932static test_t tests_ilr_ops_two[] = {
933    { &test_and_            , "        and.", },
934    { &test_andc_           , "       andc.", },
935    { &test_eqv_            , "        eqv.", },
936    { &test_nand_           , "       nand.", },
937    { &test_nor_            , "        nor.", },
938    { &test_or_             , "         or.", },
939    { &test_orc_            , "        orc.", },
940    { &test_xor_            , "        xor.", },
941    { &test_slw_            , "        slw.", },
942    { &test_sraw_           , "       sraw.", },
943    { &test_srw_            , "        srw.", },
944#ifdef __powerpc64__
945    { &test_sld_            , "        sld.", },
946    { &test_srad_           , "       srad.", },
947    { &test_srd_            , "        srd.", },
948#endif // #ifdef __powerpc64__
949    { NULL,                   NULL,           },
950};
951
952static void test_cmpw (void)
953{
954    __asm__ __volatile__ ("cmpw         2, 14, 15");
955}
956
957static void test_cmplw (void)
958{
959    __asm__ __volatile__ ("cmplw        2, 14, 15");
960}
961
962#ifdef __powerpc64__
963static void test_cmpd (void)
964{
965    __asm__ __volatile__ ("cmpd         2, 14, 15");
966}
967
968static void test_cmpld (void)
969{
970    __asm__ __volatile__ ("cmpld        2, 14, 15");
971}
972#endif // #ifdef __powerpc64__
973
974static test_t tests_icr_ops_two[] = {
975    { &test_cmpw            , "        cmpw", },
976    { &test_cmplw           , "       cmplw", },
977#ifdef __powerpc64__
978    { &test_cmpd            , "        cmpd", },
979    { &test_cmpld           , "       cmpld", },
980#endif // #ifdef __powerpc64__
981    { NULL,                   NULL,           },
982};
983
984extern void test_cmpwi (void);
985ASSEMBLY_FUNC("test_cmpwi", "cmpwi         2, 14, 0");
986
987extern void test_cmplwi (void);
988ASSEMBLY_FUNC("test_cmplwi", "cmplwi        2, 14, 0");
989
990#ifdef __powerpc64__
991extern void test_cmpdi (void);
992ASSEMBLY_FUNC("test_cmpdi", "cmpdi        2, 14, 0");
993
994extern void test_cmpldi (void);
995ASSEMBLY_FUNC("test_cmpldi", "cmpldi       2, 14, 0");
996#endif // #ifdef __powerpc64__
997
998static test_t tests_icr_ops_two_i16[] = {
999    { &test_cmpwi           , "       cmpwi", },
1000    { &test_cmplwi          , "      cmplwi", },
1001#ifdef __powerpc64__
1002    { &test_cmpdi           , "       cmpdi", },
1003    { &test_cmpldi          , "      cmpldi", },
1004#endif // #ifdef __powerpc64__
1005    { NULL,                   NULL,           },
1006};
1007
1008extern void test_addi (void);
1009ASSEMBLY_FUNC("test_addi", "addi         17, 14, 0");
1010
1011extern void test_addic (void);
1012ASSEMBLY_FUNC("test_addic", "addic        17, 14, 0");
1013
1014extern void test_addis (void);
1015ASSEMBLY_FUNC("test_addis", "addis        17, 14, 0");
1016
1017extern void test_mulli (void);
1018ASSEMBLY_FUNC("test_mulli", "mulli        17, 14, 0");
1019
1020extern void test_subfic (void);
1021ASSEMBLY_FUNC("test_subfic", "subfic       17, 14, 0");
1022
1023static test_t tests_ia_ops_two_i16[] = {
1024    { &test_addi            , "        addi", },
1025    { &test_addic           , "       addic", },
1026    { &test_addis           , "       addis", },
1027    { &test_mulli           , "       mulli", },
1028    { &test_subfic          , "      subfic", },
1029    { NULL,                   NULL,           },
1030};
1031
1032extern void test_addic_ (void);
1033ASSEMBLY_FUNC("test_addic_", "addic.       17, 14, 0");
1034
1035static test_t tests_iar_ops_two_i16[] = {
1036    { &test_addic_          , "      addic.", },
1037    { NULL,                   NULL,           },
1038};
1039
1040extern void test_ori (void);
1041ASSEMBLY_FUNC("test_ori", "ori       17, 14, 0");
1042
1043extern void test_oris (void);
1044ASSEMBLY_FUNC("test_oris", "oris       17, 14, 0");
1045
1046extern void test_xori (void);
1047ASSEMBLY_FUNC("test_xori", "xori       17, 14, 0");
1048
1049extern void test_xoris (void);
1050ASSEMBLY_FUNC("test_xoris", "xoris       17, 14, 0");
1051
1052static test_t tests_il_ops_two_i16[] = {
1053    { &test_ori             , "         ori", },
1054    { &test_oris            , "        oris", },
1055    { &test_xori            , "        xori", },
1056    { &test_xoris           , "       xoris", },
1057    { NULL,                   NULL,           },
1058};
1059
1060extern void test_andi_ (void);
1061ASSEMBLY_FUNC("test_andi_", "andi.       17, 14, 0");
1062
1063extern void test_andis_ (void);
1064ASSEMBLY_FUNC("test_andis_", "andis.      17, 14, 0");
1065
1066static test_t tests_ilr_ops_two_i16[] = {
1067    { &test_andi_           , "       andi.", },
1068    { &test_andis_          , "      andis.", },
1069    { NULL,                   NULL,           },
1070};
1071
1072static void test_crand (void)
1073{
1074    __asm__ __volatile__ ("crand        17, 14, 15");
1075}
1076
1077static void test_crandc (void)
1078{
1079    __asm__ __volatile__ ("crandc       17, 14, 15");
1080}
1081
1082static void test_creqv (void)
1083{
1084    __asm__ __volatile__ ("creqv        17, 14, 15");
1085}
1086
1087static void test_crnand (void)
1088{
1089    __asm__ __volatile__ ("crnand       17, 14, 15");
1090}
1091
1092static void test_crnor (void)
1093{
1094    __asm__ __volatile__ ("crnor        17, 14, 15");
1095}
1096
1097static void test_cror (void)
1098{
1099    __asm__ __volatile__ ("cror         17, 14, 15");
1100}
1101
1102static void test_crorc (void)
1103{
1104    __asm__ __volatile__ ("crorc        17, 14, 15");
1105}
1106
1107static void test_crxor (void)
1108{
1109    __asm__ __volatile__ ("crxor        17, 14, 15");
1110}
1111
1112static test_t tests_crl_ops_two[] = {
1113    { &test_crand           , "       crand", },
1114    { &test_crandc          , "      crandc", },
1115    { &test_creqv           , "       creqv", },
1116    { &test_crnand          , "      crnand", },
1117    { &test_crnor           , "       crnor", },
1118    { &test_cror            , "        cror", },
1119    { &test_crorc           , "       crorc", },
1120    { &test_crxor           , "       crxor", },
1121    { NULL,                   NULL,           },
1122};
1123
1124static void test_addme (void)
1125{
1126    __asm__ __volatile__ ("addme        17, 14");
1127}
1128
1129static void test_addmeo (void)
1130{
1131    __asm__ __volatile__ ("addmeo       17, 14");
1132}
1133
1134static void test_addze (void)
1135{
1136    __asm__ __volatile__ ("addze        17, 14");
1137}
1138
1139static void test_addzeo (void)
1140{
1141    __asm__ __volatile__ ("addzeo       17, 14");
1142}
1143
1144static void test_subfme (void)
1145{
1146    __asm__ __volatile__ ("subfme       17, 14");
1147}
1148
1149static void test_subfmeo (void)
1150{
1151    __asm__ __volatile__ ("subfmeo      17, 14");
1152}
1153
1154static void test_subfze (void)
1155{
1156    __asm__ __volatile__ ("subfze       17, 14");
1157}
1158
1159static void test_subfzeo (void)
1160{
1161    __asm__ __volatile__ ("subfzeo      17, 14");
1162}
1163
1164static test_t tests_iac_ops_one[] = {
1165    { &test_addme           , "       addme", },
1166    { &test_addmeo          , "      addmeo", },
1167    { &test_addze           , "       addze", },
1168    { &test_addzeo          , "      addzeo", },
1169    { &test_subfme          , "      subfme", },
1170    { &test_subfmeo         , "     subfmeo", },
1171    { &test_subfze          , "      subfze", },
1172    { &test_subfzeo         , "     subfzeo", },
1173    { NULL,                   NULL,           },
1174};
1175
1176static void test_addme_ (void)
1177{
1178    __asm__ __volatile__ ("addme.       17, 14");
1179}
1180
1181static void test_addmeo_ (void)
1182{
1183    __asm__ __volatile__ ("addmeo.      17, 14");
1184}
1185
1186static void test_addze_ (void)
1187{
1188    __asm__ __volatile__ ("addze.       17, 14");
1189}
1190
1191static void test_addzeo_ (void)
1192{
1193    __asm__ __volatile__ ("addzeo.      17, 14");
1194}
1195
1196static void test_subfme_ (void)
1197{
1198    __asm__ __volatile__ ("subfme.      17, 14");
1199}
1200
1201static void test_subfmeo_ (void)
1202{
1203    __asm__ __volatile__ ("subfmeo.     17, 14");
1204}
1205
1206static void test_subfze_ (void)
1207{
1208    __asm__ __volatile__ ("subfze.      17, 14");
1209}
1210
1211static void test_subfzeo_ (void)
1212{
1213    __asm__ __volatile__ ("subfzeo.     17, 14");
1214}
1215
1216static test_t tests_iacr_ops_one[] = {
1217    { &test_addme_          , "      addme.", },
1218    { &test_addmeo_         , "     addmeo.", },
1219    { &test_addze_          , "      addze.", },
1220    { &test_addzeo_         , "     addzeo.", },
1221    { &test_subfme_         , "     subfme.", },
1222    { &test_subfmeo_        , "    subfmeo.", },
1223    { &test_subfze_         , "     subfze.", },
1224    { &test_subfzeo_        , "    subfzeo.", },
1225    { NULL,                   NULL,           },
1226};
1227
1228static void test_cntlzw (void)
1229{
1230    __asm__ __volatile__ ("cntlzw       17, 14");
1231}
1232
1233static void test_extsb (void)
1234{
1235    __asm__ __volatile__ ("extsb        17, 14");
1236}
1237
1238static void test_extsh (void)
1239{
1240    __asm__ __volatile__ ("extsh        17, 14");
1241}
1242
1243static void test_neg (void)
1244{
1245    __asm__ __volatile__ ("neg          17, 14");
1246}
1247
1248static void test_nego (void)
1249{
1250    __asm__ __volatile__ ("nego         17, 14");
1251}
1252
1253#ifdef __powerpc64__
1254static void test_cntlzd (void)
1255{
1256    __asm__ __volatile__ ("cntlzd       17, 14");
1257}
1258
1259static void test_extsw (void)
1260{
1261    __asm__ __volatile__ ("extsw        17, 14");
1262}
1263#endif // #ifdef __powerpc64__
1264
1265static test_t tests_il_ops_one[] = {
1266    { &test_cntlzw          , "      cntlzw", },
1267    { &test_extsb           , "       extsb", },
1268    { &test_extsh           , "       extsh", },
1269    { &test_neg             , "         neg", },
1270    { &test_nego            , "        nego", },
1271#ifdef __powerpc64__
1272    { &test_cntlzd          , "      cntlzd", },
1273    { &test_extsw           , "       extsw", },
1274#endif // #ifdef __powerpc64__
1275    { NULL,                   NULL,           },
1276};
1277
1278static void test_cntlzw_ (void)
1279{
1280    __asm__ __volatile__ ("cntlzw.      17, 14");
1281}
1282
1283static void test_extsb_ (void)
1284{
1285    __asm__ __volatile__ ("extsb.       17, 14");
1286}
1287
1288static void test_extsh_ (void)
1289{
1290    __asm__ __volatile__ ("extsh.       17, 14");
1291}
1292
1293static void test_neg_ (void)
1294{
1295    __asm__ __volatile__ ("neg.         17, 14");
1296}
1297
1298static void test_nego_ (void)
1299{
1300    __asm__ __volatile__ ("nego.        17, 14");
1301}
1302
1303#ifdef __powerpc64__
1304static void test_cntlzd_ (void)
1305{
1306    __asm__ __volatile__ ("cntlzd.      17, 14");
1307}
1308
1309static void test_extsw_ (void)
1310{
1311    __asm__ __volatile__ ("extsw.       17, 14");
1312}
1313#endif // #ifdef __powerpc64__
1314
1315static test_t tests_ilr_ops_one[] = {
1316    { &test_cntlzw_         , "     cntlzw.", },
1317    { &test_extsb_          , "      extsb.", },
1318    { &test_extsh_          , "      extsh.", },
1319    { &test_neg_            , "        neg.", },
1320    { &test_nego_           , "       nego.", },
1321#ifdef __powerpc64__
1322    { &test_cntlzd_         , "     cntlzd.", },
1323    { &test_extsw_          , "      extsw.", },
1324#endif // #ifdef __powerpc64__
1325    { NULL,                   NULL,           },
1326};
1327
1328extern void test_rlwimi (void);
1329ASSEMBLY_FUNC("test_rlwimi", "rlwimi      17, 14, 0, 0, 0");
1330
1331extern void test_rlwinm (void);
1332ASSEMBLY_FUNC("test_rlwinm", "rlwinm      17, 14, 0, 0, 0");
1333
1334extern void test_rlwnm (void);
1335ASSEMBLY_FUNC("test_rlwnm", "rlwnm      17, 14, 15, 0, 0");
1336
1337extern void test_srawi (void);
1338ASSEMBLY_FUNC("test_srawi", "srawi      17, 14, 0");
1339
1340static void test_mfcr (void)
1341{
1342    __asm__ __volatile__ ("mfcr         17");
1343}
1344
1345static void test_mfspr (void)
1346{
1347    __asm__ __volatile__ ("mfspr        17, 1");
1348}
1349
1350static void test_mtspr (void)
1351{
1352    __asm__ __volatile__ ("mtspr        1, 14");
1353}
1354
1355#ifdef __powerpc64__
1356extern void test_rldcl (void);
1357ASSEMBLY_FUNC("test_rldcl", "rldcl       17, 14, 15, 0");
1358
1359extern void test_rldcr (void);
1360ASSEMBLY_FUNC("test_rldcr", "rldcr       17, 14, 15, 0");
1361
1362extern void test_rldic (void);
1363ASSEMBLY_FUNC("test_rldic", "rldic       17, 14, 0, 0");
1364
1365extern void test_rldicl (void);
1366ASSEMBLY_FUNC("test_rldicl", "rldicl      17, 14, 0, 0");
1367
1368extern void test_rldicr (void);
1369ASSEMBLY_FUNC("test_rldicr", "rldicr      17, 14, 0, 0");
1370
1371extern void test_rldimi (void);
1372ASSEMBLY_FUNC("test_rldimi", "rldimi      17, 14, 0, 0");
1373
1374extern void test_sradi (void);
1375ASSEMBLY_FUNC("test_sradi", "sradi      17, 14, 0");
1376#endif // #ifdef __powerpc64__
1377
1378static test_t tests_il_ops_spe[] = {
1379    { &test_rlwimi          , "      rlwimi", },
1380    { &test_rlwinm          , "      rlwinm", },
1381    { &test_rlwnm           , "       rlwnm", },
1382    { &test_srawi           , "       srawi", },
1383    { &test_mfcr            , "        mfcr", },
1384    { &test_mfspr           , "       mfspr", },
1385    { &test_mtspr           , "       mtspr", },
1386#ifdef __powerpc64__
1387    { &test_rldcl           , "       rldcl", },
1388    { &test_rldcr           , "       rldcr", },
1389    { &test_rldic           , "       rldic", },
1390    { &test_rldicl          , "      rldicl", },
1391    { &test_rldicr          , "      rldicr", },
1392    { &test_rldimi          , "      rldimi", },
1393    { &test_sradi           , "       sradi", },
1394#endif // #ifdef __powerpc64__
1395    { NULL,                   NULL,           },
1396};
1397
1398extern void test_rlwimi_ (void);
1399ASSEMBLY_FUNC("test_rlwimi_", "rlwimi.      17, 14, 0, 0, 0");
1400
1401extern void test_rlwinm_ (void);
1402ASSEMBLY_FUNC("test_rlwinm_", "rlwinm.      17, 14, 0, 0, 0");
1403
1404extern void test_rlwnm_ (void);
1405ASSEMBLY_FUNC("test_rlwnm_", "rlwnm.      17, 14, 15, 0, 0");
1406
1407extern void test_srawi_ (void);
1408ASSEMBLY_FUNC("test_srawi_", "srawi.      17, 14, 0");
1409
1410extern void test_mcrf (void);
1411ASSEMBLY_FUNC("test_mcrf", "mcrf      0, 0");
1412
1413extern void test_mcrxr (void);
1414ASSEMBLY_FUNC("test_mcrxr", "mcrxr      0");
1415
1416extern void test_mtcrf (void);
1417ASSEMBLY_FUNC("test_mtcrf", "mtcrf      0, 14");
1418
1419#ifdef __powerpc64__
1420extern void test_rldcl_ (void);
1421ASSEMBLY_FUNC("test_rldcl_", "rldcl.      17, 14, 15, 0");
1422
1423extern void test_rldcr_ (void);
1424ASSEMBLY_FUNC("test_rldcr_", "rldcr.      17, 14, 15, 0");
1425
1426extern void test_rldic_ (void);
1427ASSEMBLY_FUNC("test_rldic_", "rldic.      17, 14, 0, 0");
1428
1429extern void test_rldicl_ (void);
1430ASSEMBLY_FUNC("test_rldicl_", "rldicl.     17, 14, 0, 0");
1431
1432extern void test_rldicr_ (void);
1433ASSEMBLY_FUNC("test_rldicr_", "rldicr.     17, 14, 0, 0");
1434
1435extern void test_rldimi_ (void);
1436ASSEMBLY_FUNC("test_rldimi_", "rldimi.     17, 14, 0, 0");
1437
1438extern void test_sradi_ (void);
1439ASSEMBLY_FUNC("test_sradi_", "sradi.      17, 14, 0");
1440#endif // #ifdef __powerpc64__
1441
1442static test_t tests_ilr_ops_spe[] = {
1443    { &test_rlwimi_         , "     rlwimi.", },
1444    { &test_rlwinm_         , "     rlwinm.", },
1445    { &test_rlwnm_          , "      rlwnm.", },
1446    { &test_srawi_          , "      srawi.", },
1447    { &test_mcrf            , "        mcrf", },
1448    { &test_mcrxr           , "       mcrxr", },
1449    { &test_mtcrf           , "       mtcrf", },
1450#ifdef __powerpc64__
1451    { &test_rldcl_          , "      rldcl.", },
1452    { &test_rldcr_          , "      rldcr.", },
1453    { &test_rldic_          , "      rldic.", },
1454    { &test_rldicl_         , "     rldicl.", },
1455    { &test_rldicr_         , "     rldicr.", },
1456    { &test_rldimi_         , "     rldimi.", },
1457    { &test_sradi_          , "      sradi.", },
1458#endif // #ifdef __powerpc64__
1459    { NULL,                   NULL,           },
1460};
1461
1462extern void test_lbz (void);
1463ASSEMBLY_FUNC("test_lbz", "lbz          17,0(14)");
1464
1465extern void test_lbzu (void);
1466ASSEMBLY_FUNC("test_lbzu", "lbzu          17,0(14)");
1467
1468extern void test_lha (void);
1469ASSEMBLY_FUNC("test_lha", "lha          17,0(14)");
1470
1471extern void test_lhau (void);
1472ASSEMBLY_FUNC("test_lhau", "lhau          17,0(14)");
1473
1474extern void test_lhz (void);
1475ASSEMBLY_FUNC("test_lhz", "lhz          17,0(14)");
1476
1477extern void test_lhzu (void);
1478ASSEMBLY_FUNC("test_lhzu", "lhzu         17,0(14)");
1479
1480extern void test_lwz (void);
1481ASSEMBLY_FUNC("test_lwz", "lwz          17,0(14)");
1482
1483extern void test_lwzu (void);
1484ASSEMBLY_FUNC("test_lwzu", "lwzu          17,0(14)");
1485
1486#ifdef __powerpc64__
1487extern void test_ld (void);
1488ASSEMBLY_FUNC("test_ld", "ld            17,0(14)");
1489
1490extern void test_ldu (void);
1491ASSEMBLY_FUNC("test_ldu", "ldu           17,0(14)");
1492
1493extern void test_lwa (void);
1494ASSEMBLY_FUNC("test_lwa", "lwa           17,0(14)");
1495#endif // #ifdef __powerpc64__
1496
1497static test_t tests_ild_ops_two_i16[] = {
1498    { &test_lbz             , "         lbz", },
1499    { &test_lbzu            , "        lbzu", },
1500    { &test_lha             , "         lha", },
1501    { &test_lhau            , "        lhau", },
1502    { &test_lhz             , "         lhz", },
1503    { &test_lhzu            , "        lhzu", },
1504    { &test_lwz             , "         lwz", },
1505    { &test_lwzu            , "        lwzu", },
1506#ifdef __powerpc64__
1507    { &test_ld              , "          ld", },
1508    { &test_ldu             , "         ldu", },
1509    { &test_lwa             , "         lwa", },
1510#endif // #ifdef __powerpc64__
1511    { NULL,                   NULL,           },
1512};
1513
1514static void test_lbzx (void)
1515{
1516    __asm__ __volatile__ ("lbzx         17,14,15");
1517}
1518
1519static void test_lbzux (void)
1520{
1521    __asm__ __volatile__ ("lbzux        17,14,15");
1522}
1523
1524static void test_lhax (void)
1525{
1526    __asm__ __volatile__ ("lhax         17,14,15");
1527}
1528
1529static void test_lhaux (void)
1530{
1531    __asm__ __volatile__ ("lhaux        17,14,15");
1532}
1533
1534static void test_lhzx (void)
1535{
1536    __asm__ __volatile__ ("lhzx         17,14,15");
1537}
1538
1539static void test_lhzux (void)
1540{
1541    __asm__ __volatile__ ("lhzux        17,14,15");
1542}
1543
1544static void test_lwzx (void)
1545{
1546    __asm__ __volatile__ ("lwzx         17,14,15");
1547}
1548
1549static void test_lwzux (void)
1550{
1551    __asm__ __volatile__ ("lwzux        17,14,15");
1552}
1553
1554#ifdef __powerpc64__
1555static void test_ldx (void)
1556{
1557    __asm__ __volatile__ ("ldx         17,14,15");
1558}
1559
1560static void test_ldux (void)
1561{
1562    __asm__ __volatile__ ("ldux        17,14,15");
1563}
1564
1565static void test_lwax (void)
1566{
1567    __asm__ __volatile__ ("lwax        17,14,15");
1568}
1569
1570static void test_lwaux (void)
1571{
1572    __asm__ __volatile__ ("lwaux        17,14,15");
1573}
1574#endif // #ifdef __powerpc64__
1575
1576static test_t tests_ild_ops_two[] = {
1577    { &test_lbzx            , "        lbzx", },
1578    { &test_lbzux           , "       lbzux", },
1579    { &test_lhax            , "        lhax", },
1580    { &test_lhaux           , "       lhaux", },
1581    { &test_lhzx            , "        lhzx", },
1582    { &test_lhzux           , "       lhzux", },
1583    { &test_lwzx            , "        lwzx", },
1584    { &test_lwzux           , "       lwzux", },
1585#ifdef __powerpc64__
1586    { &test_ldx             , "         ldx", },
1587    { &test_ldux            , "        ldux", },
1588    { &test_lwax            , "        lwax", },
1589    { &test_lwaux           , "       lwaux", },
1590#endif // #ifdef __powerpc64__
1591    { NULL,                   NULL,           },
1592};
1593
1594extern void test_stb (void);
1595ASSEMBLY_FUNC("test_stb", "stb          14,0(15)");
1596
1597extern void test_stbu (void);
1598ASSEMBLY_FUNC("test_stbu", "stbu          14,0(15)");
1599
1600extern void test_sth (void);
1601ASSEMBLY_FUNC("test_sth", "sth          14,0(15)");
1602
1603extern void test_sthu (void);
1604ASSEMBLY_FUNC("test_sthu", "sthu         14,0(15)");
1605
1606extern void test_stw (void);
1607ASSEMBLY_FUNC("test_stw", "stw          14,0(15)");
1608
1609extern void test_stwu (void);
1610ASSEMBLY_FUNC("test_stwu", "stwu          14,0(15)");
1611
1612#ifdef __powerpc64__
1613extern void test_std (void);
1614ASSEMBLY_FUNC("test_std", "std          14,0(15)");
1615
1616extern void test_stdu (void);
1617ASSEMBLY_FUNC("test_stdu", "stdu          14,0(15)");
1618#endif // #ifdef __powerpc64__
1619
1620static test_t tests_ist_ops_three_i16[] = {
1621    { &test_stb             , "         stb", },
1622    { &test_stbu            , "        stbu", },
1623    { &test_sth             , "         sth", },
1624    { &test_sthu            , "        sthu", },
1625    { &test_stw             , "         stw", },
1626    { &test_stwu            , "        stwu", },
1627#ifdef __powerpc64__
1628    { &test_std             , "         std", },
1629    { &test_stdu            , "        stdu", },
1630#endif // #ifdef __powerpc64__
1631    { NULL,                   NULL,           },
1632};
1633
1634static void test_stbx (void)
1635{
1636    __asm__ __volatile__ ("stbx         14,15,16");
1637}
1638
1639static void test_stbux (void)
1640{
1641    __asm__ __volatile__ ("stbux        14,15,16");
1642}
1643
1644static void test_sthx (void)
1645{
1646    __asm__ __volatile__ ("sthx         14,15,16");
1647}
1648
1649static void test_sthux (void)
1650{
1651    __asm__ __volatile__ ("sthux        14,15,16");
1652}
1653
1654static void test_stwx (void)
1655{
1656    __asm__ __volatile__ ("stwx         14,15,16");
1657}
1658
1659static void test_stwux (void)
1660{
1661    __asm__ __volatile__ ("stwux        14,15,16");
1662}
1663
1664#ifdef __powerpc64__
1665static void test_stdx (void)
1666{
1667    __asm__ __volatile__ ("stdx         14,15,16");
1668}
1669
1670static void test_stdux (void)
1671{
1672    __asm__ __volatile__ ("stdux        14,15,16");
1673}
1674#endif // #ifdef __powerpc64__
1675
1676static test_t tests_ist_ops_three[] = {
1677    { &test_stbx            , "        stbx", },
1678    { &test_stbux           , "       stbux", },
1679    { &test_sthx            , "        sthx", },
1680    { &test_sthux           , "       sthux", },
1681    { &test_stwx            , "        stwx", },
1682    { &test_stwux           , "       stwux", },
1683#ifdef __powerpc64__
1684    { &test_stdx            , "        stdx", },
1685    { &test_stdux           , "       stdux", },
1686#endif // #ifdef __powerpc64__
1687    { NULL,                   NULL,           },
1688};
1689
1690static void
1691tests_popcnt_one(void)
1692{
1693   __asm__ __volatile__ ("popcntb      17, 14");
1694}
1695
1696static test_t tests_popcnt_ops_one[] = {
1697    { &tests_popcnt_one            , "        popcntb", },
1698    { NULL,                   NULL,           },
1699};
1700
1701#if !defined (NO_FLOAT)
1702static void test_fsel (void)
1703{
1704    __asm__ __volatile__ ("fsel         17, 14, 15, 16");
1705}
1706
1707static void test_fmadd (void)
1708{
1709    __asm__ __volatile__ ("fmadd        17, 14, 15, 16");
1710}
1711
1712static void test_fmadds (void)
1713{
1714    __asm__ __volatile__ ("fmadds       17, 14, 15, 16");
1715}
1716
1717static void test_fmsub (void)
1718{
1719    __asm__ __volatile__ ("fmsub        17, 14, 15, 16");
1720}
1721
1722static void test_fmsubs (void)
1723{
1724    __asm__ __volatile__ ("fmsubs       17, 14, 15, 16");
1725}
1726
1727static void test_fnmadd (void)
1728{
1729    __asm__ __volatile__ ("fnmadd       17, 14, 15, 16");
1730}
1731
1732static void test_fnmadds (void)
1733{
1734    __asm__ __volatile__ ("fnmadds      17, 14, 15, 16");
1735}
1736
1737static void test_fnmsub (void)
1738{
1739    __asm__ __volatile__ ("fnmsub       17, 14, 15, 16");
1740}
1741
1742static void test_fnmsubs (void)
1743{
1744    __asm__ __volatile__ ("fnmsubs      17, 14, 15, 16");
1745}
1746
1747static test_t tests_fa_ops_three[] = {
1748    { &test_fsel            , "        fsel", },
1749    { &test_fmadd           , "       fmadd", },
1750    { &test_fmadds          , "      fmadds", },
1751    { &test_fmsub           , "       fmsub", },
1752    { &test_fmsubs          , "      fmsubs", },
1753    { &test_fnmadd          , "      fnmadd", },
1754    { &test_fnmadds         , "     fnmadds", },
1755    { &test_fnmsub          , "      fnmsub", },
1756    { &test_fnmsubs         , "     fnmsubs", },
1757    { NULL,                   NULL,           },
1758};
1759#endif /* !defined (NO_FLOAT) */
1760
1761#if !defined (NO_FLOAT)
1762static void test_fsel_ (void)
1763{
1764    __asm__ __volatile__ ("fsel.        17, 14, 15, 16");
1765}
1766
1767static void test_fmadd_ (void)
1768{
1769    __asm__ __volatile__ ("fmadd.       17, 14, 15, 16");
1770}
1771
1772static void test_fmadds_ (void)
1773{
1774    __asm__ __volatile__ ("fmadds.      17, 14, 15, 16");
1775}
1776
1777static void test_fmsub_ (void)
1778{
1779    __asm__ __volatile__ ("fmsub.       17, 14, 15, 16");
1780}
1781
1782static void test_fmsubs_ (void)
1783{
1784    __asm__ __volatile__ ("fmsubs.      17, 14, 15, 16");
1785}
1786
1787static void test_fnmadd_ (void)
1788{
1789    __asm__ __volatile__ ("fnmadd.      17, 14, 15, 16");
1790}
1791
1792static void test_fnmadds_ (void)
1793{
1794    __asm__ __volatile__ ("fnmadds.     17, 14, 15, 16");
1795}
1796
1797static void test_fnmsub_ (void)
1798{
1799    __asm__ __volatile__ ("fnmsub.      17, 14, 15, 16");
1800}
1801
1802static void test_fnmsubs_ (void)
1803{
1804    __asm__ __volatile__ ("fnmsubs.     17, 14, 15, 16");
1805}
1806
1807static test_t tests_far_ops_three[] = {
1808    { &test_fsel_           , "       fsel.", },
1809    { &test_fmadd_          , "      fmadd.", },
1810    { &test_fmadds_         , "     fmadds.", },
1811    { &test_fmsub_          , "      fmsub.", },
1812    { &test_fmsubs_         , "     fmsubs.", },
1813    { &test_fnmadd_         , "     fnmadd.", },
1814    { &test_fnmadds_        , "    fnmadds.", },
1815    { &test_fnmsub_         , "     fnmsub.", },
1816    { &test_fnmsubs_        , "    fnmsubs.", },
1817    { NULL,                   NULL,           },
1818};
1819#endif /* !defined (NO_FLOAT) */
1820
1821#if !defined (NO_FLOAT)
1822static void test_fadd (void)
1823{
1824    __asm__ __volatile__ ("fadd         17, 14, 15");
1825}
1826
1827static void test_fadds (void)
1828{
1829    __asm__ __volatile__ ("fadds        17, 14, 15");
1830}
1831
1832static void test_fsub (void)
1833{
1834    __asm__ __volatile__ ("fsub         17, 14, 15");
1835}
1836
1837static void test_fsubs (void)
1838{
1839    __asm__ __volatile__ ("fsubs        17, 14, 15");
1840}
1841
1842static void test_fmul (void)
1843{
1844    __asm__ __volatile__ ("fmul         17, 14, 15");
1845}
1846
1847static void test_fmuls (void)
1848{
1849    __asm__ __volatile__ ("fmuls        17, 14, 15");
1850}
1851
1852static void test_fdiv (void)
1853{
1854    __asm__ __volatile__ ("fdiv         17, 14, 15");
1855}
1856
1857static void test_fdivs (void)
1858{
1859    __asm__ __volatile__ ("fdivs        17, 14, 15");
1860}
1861
1862static test_t tests_fa_ops_two[] = {
1863    { &test_fadd            , "        fadd", },
1864    { &test_fadds           , "       fadds", },
1865    { &test_fsub            , "        fsub", },
1866    { &test_fsubs           , "       fsubs", },
1867    { &test_fmul            , "        fmul", },
1868    { &test_fmuls           , "       fmuls", },
1869    { &test_fdiv            , "        fdiv", },
1870    { &test_fdivs           , "       fdivs", },
1871    { NULL,                   NULL,           },
1872};
1873#endif /* !defined (NO_FLOAT) */
1874
1875#if !defined (NO_FLOAT)
1876static void test_fadd_ (void)
1877{
1878    __asm__ __volatile__ ("fadd.        17, 14, 15");
1879}
1880
1881static void test_fadds_ (void)
1882{
1883    __asm__ __volatile__ ("fadds.       17, 14, 15");
1884}
1885
1886static void test_fsub_ (void)
1887{
1888    __asm__ __volatile__ ("fsub.        17, 14, 15");
1889}
1890
1891static void test_fsubs_ (void)
1892{
1893    __asm__ __volatile__ ("fsubs.       17, 14, 15");
1894}
1895
1896static void test_fmul_ (void)
1897{
1898    __asm__ __volatile__ ("fmul.        17, 14, 15");
1899}
1900
1901static void test_fmuls_ (void)
1902{
1903    __asm__ __volatile__ ("fmuls.       17, 14, 15");
1904}
1905
1906static void test_fdiv_ (void)
1907{
1908    __asm__ __volatile__ ("fdiv.        17, 14, 15");
1909}
1910
1911static void test_fdivs_ (void)
1912{
1913    __asm__ __volatile__ ("fdivs.       17, 14, 15");
1914}
1915
1916static test_t tests_far_ops_two[] = {
1917    { &test_fadd_           , "       fadd.", },
1918    { &test_fadds_          , "      fadds.", },
1919    { &test_fsub_           , "       fsub.", },
1920    { &test_fsubs_          , "      fsubs.", },
1921    { &test_fmul_           , "       fmul.", },
1922    { &test_fmuls_          , "      fmuls.", },
1923    { &test_fdiv_           , "       fdiv.", },
1924    { &test_fdivs_          , "      fdivs.", },
1925    { NULL,                   NULL,           },
1926};
1927#endif /* !defined (NO_FLOAT) */
1928
1929#if !defined (NO_FLOAT)
1930static void test_fcmpo (void)
1931{
1932    __asm__ __volatile__ ("fcmpo        2, 14, 15");
1933}
1934
1935static void test_fcmpu (void)
1936{
1937    __asm__ __volatile__ ("fcmpu        2, 14, 15");
1938}
1939
1940static test_t tests_fcr_ops_two[] = {
1941    { &test_fcmpo           , "       fcmpo", },
1942    { &test_fcmpu           , "       fcmpu", },
1943    { NULL,                   NULL,           },
1944};
1945#endif /* !defined (NO_FLOAT) */
1946
1947#if !defined (NO_FLOAT)
1948
1949static void test_fres (void)
1950{
1951    __asm__ __volatile__ ("fres         17, 14");
1952}
1953
1954static void test_frsqrte (void)
1955{
1956    __asm__ __volatile__ ("frsqrte      17, 14");
1957}
1958
1959static void test_frsp (void)
1960{
1961    __asm__ __volatile__ ("frsp         17, 14");
1962}
1963
1964static void test_fctiw (void)
1965{
1966    __asm__ __volatile__ ("fctiw        17, 14");
1967}
1968
1969static void test_fctiwz (void)
1970{
1971    __asm__ __volatile__ ("fctiwz       17, 14");
1972}
1973
1974static void test_fmr (void)
1975{
1976    __asm__ __volatile__ ("fmr          17, 14");
1977}
1978
1979static void test_fneg (void)
1980{
1981    __asm__ __volatile__ ("fneg         17, 14");
1982}
1983
1984static void test_fabs (void)
1985{
1986    __asm__ __volatile__ ("fabs         17, 14");
1987}
1988
1989static void test_fnabs (void)
1990{
1991    __asm__ __volatile__ ("fnabs        17, 14");
1992}
1993
1994static void test_fsqrt (void)
1995{
1996    __asm__ __volatile__ ("fsqrt        17, 14");
1997}
1998
1999#ifdef __powerpc64__
2000static void test_fcfid (void)
2001{
2002    __asm__ __volatile__ ("fcfid        17, 14");
2003}
2004
2005static void test_fctid (void)
2006{
2007    __asm__ __volatile__ ("fctid        17, 14");
2008}
2009
2010static void test_fctidz (void)
2011{
2012    __asm__ __volatile__ ("fctidz       17, 14");
2013}
2014#endif // #ifdef __powerpc64__
2015
2016static test_t tests_fa_ops_one[] = {
2017    { &test_fres            , "        fres", },
2018    { &test_frsqrte         , "     frsqrte", },
2019    { &test_frsp            , "        frsp", },
2020    { &test_fctiw           , "       fctiw", },
2021    { &test_fctiwz          , "      fctiwz", },
2022    { &test_fmr             , "         fmr", },
2023    { &test_fneg            , "        fneg", },
2024    { &test_fabs            , "        fabs", },
2025    { &test_fnabs           , "       fnabs", },
2026    { &test_fsqrt           , "       fsqrt", },
2027#ifdef __powerpc64__
2028    { &test_fcfid           , "       fcfid", },
2029    { &test_fctid           , "       fctid", },
2030    { &test_fctidz          , "      fctidz", },
2031#endif // #ifdef __powerpc64__
2032    { NULL,                   NULL,           },
2033};
2034#endif /* !defined (NO_FLOAT) */
2035
2036#if !defined (NO_FLOAT)
2037
2038static void test_fres_ (void)
2039{
2040    __asm__ __volatile__ ("fres.        17, 14");
2041}
2042
2043static void test_frsqrte_ (void)
2044{
2045     __asm__ __volatile__ ("frsqrte.     17, 14");
2046}
2047
2048static void test_frsp_ (void)
2049{
2050    __asm__ __volatile__ ("frsp.        17, 14");
2051}
2052
2053static void test_fctiw_ (void)
2054{
2055    __asm__ __volatile__ ("fctiw.       17, 14");
2056}
2057
2058static void test_fctiwz_ (void)
2059{
2060    __asm__ __volatile__ ("fctiwz.      17, 14");
2061}
2062
2063static void test_fmr_ (void)
2064{
2065    __asm__ __volatile__ ("fmr.         17, 14");
2066}
2067
2068static void test_fneg_ (void)
2069{
2070    __asm__ __volatile__ ("fneg.        17, 14");
2071}
2072
2073static void test_fabs_ (void)
2074{
2075    __asm__ __volatile__ ("fabs.        17, 14");
2076}
2077
2078static void test_fnabs_ (void)
2079{
2080    __asm__ __volatile__ ("fnabs.       17, 14");
2081}
2082
2083#ifdef __powerpc64__
2084static void test_fcfid_ (void)
2085{
2086    __asm__ __volatile__ ("fcfid.       17, 14");
2087}
2088
2089static void test_fctid_ (void)
2090{
2091    __asm__ __volatile__ ("fctid.       17, 14");
2092}
2093
2094static void test_fctidz_ (void)
2095{
2096    __asm__ __volatile__ ("fctidz.      17, 14");
2097}
2098#endif // #ifdef __powerpc64__
2099
2100static test_t tests_far_ops_one[] = {
2101    { &test_fres_           , "       fres.", },
2102    { &test_frsqrte_        , "    frsqrte.", },
2103    { &test_frsp_           , "       frsp.", },
2104    { &test_fctiw_          , "      fctiw.", },
2105    { &test_fctiwz_         , "     fctiwz.", },
2106    { &test_fmr_            , "        fmr.", },
2107    { &test_fneg_           , "       fneg.", },
2108    { &test_fabs_           , "       fabs.", },
2109    { &test_fnabs_          , "      fnabs.", },
2110#ifdef __powerpc64__
2111    { &test_fcfid_          , "      fcfid.", },
2112    { &test_fctid_          , "      fctid.", },
2113    { &test_fctidz_         , "     fctidz.", },
2114#endif // #ifdef __powerpc64__
2115    { NULL,                   NULL,           },
2116};
2117#endif /* !defined (NO_FLOAT) */
2118
2119#if !defined (NO_FLOAT)
2120static test_t tests_fl_ops_spe[] = {
2121    { NULL,                   NULL,           },
2122};
2123#endif /* !defined (NO_FLOAT) */
2124
2125#if !defined (NO_FLOAT)
2126static test_t tests_flr_ops_spe[] = {
2127    { NULL,                   NULL,           },
2128};
2129#endif /* !defined (NO_FLOAT) */
2130
2131
2132#if !defined (NO_FLOAT)
2133extern void test_lfs (void);
2134ASSEMBLY_FUNC("test_lfs", "lfs          17,0(14)");
2135
2136extern void test_lfsu (void);
2137ASSEMBLY_FUNC("test_lfsu", "lfsu          17,0(14)");
2138
2139extern void test_lfd (void);
2140ASSEMBLY_FUNC("test_lfd", "lfd          17,0(14)");
2141
2142extern void test_lfdu (void);
2143ASSEMBLY_FUNC("test_lfdu", "lfdu          17,0(14)");
2144
2145static test_t tests_fld_ops_two_i16[] = {
2146    { &test_lfs             , "         lfs", },
2147    { &test_lfsu            , "        lfsu", },
2148    { &test_lfd             , "         lfd", },
2149    { &test_lfdu            , "        lfdu", },
2150    { NULL,                   NULL,           },
2151};
2152#endif /* !defined (NO_FLOAT) */
2153
2154#if !defined (NO_FLOAT)
2155static void test_lfsx (void)
2156{
2157    __asm__ __volatile__ ("lfsx         17,14,15");
2158}
2159
2160static void test_lfsux (void)
2161{
2162    __asm__ __volatile__ ("lfsux        17,14,15");
2163}
2164
2165static void test_lfdx (void)
2166{
2167    __asm__ __volatile__ ("lfdx         17,14,15");
2168}
2169
2170static void test_lfdux (void)
2171{
2172    __asm__ __volatile__ ("lfdux        17,14,15");
2173}
2174
2175static test_t tests_fld_ops_two[] = {
2176    { &test_lfsx            , "        lfsx", },
2177    { &test_lfsux           , "       lfsux", },
2178    { &test_lfdx            , "        lfdx", },
2179    { &test_lfdux           , "       lfdux", },
2180    { NULL,                   NULL,           },
2181};
2182#endif /* !defined (NO_FLOAT) */
2183
2184#if !defined (NO_FLOAT)
2185extern void test_stfs (void);
2186ASSEMBLY_FUNC("test_stfs", "stfs          14,0(15)");
2187
2188extern void test_stfsu (void);
2189ASSEMBLY_FUNC("test_stfsu", "stfsu          14,0(15)");
2190
2191extern void test_stfd (void);
2192ASSEMBLY_FUNC("test_stfd", "stfd          14,0(15)");
2193
2194extern void test_stfdu (void);
2195ASSEMBLY_FUNC("test_stfdu", "stfdu         14,0(15)");
2196
2197static test_t tests_fst_ops_three_i16[] = {
2198    { &test_stfs             , "         stfs", },
2199    { &test_stfsu            , "        stfsu", },
2200    { &test_stfd             , "         stfd", },
2201    { &test_stfdu            , "        stfdu", },
2202    { NULL,                   NULL,           },
2203};
2204#endif /* !defined (NO_FLOAT) */
2205
2206#if !defined (NO_FLOAT)
2207static void test_stfsx (void)
2208{
2209    __asm__ __volatile__ ("stfsx         14,15,16");
2210}
2211
2212static void test_stfsux (void)
2213{
2214    __asm__ __volatile__ ("stfsux        14,15,16");
2215}
2216
2217static void test_stfdx (void)
2218{
2219    __asm__ __volatile__ ("stfdx         14,15,16");
2220}
2221
2222static void test_stfdux (void)
2223{
2224    __asm__ __volatile__ ("stfdux        14,15,16");
2225}
2226
2227static test_t tests_fst_ops_three[] = {
2228    { &test_stfsx            , "        stfsx", },
2229    { &test_stfsux           , "       stfsux", },
2230    { &test_stfdx            , "        stfdx", },
2231    { &test_stfdux           , "       stfdux", },
2232    { NULL,                   NULL,           },
2233};
2234#endif /* !defined (NO_FLOAT) */
2235
2236
2237#if defined (HAS_ALTIVEC)
2238static void test_vmhaddshs (void)
2239{
2240    __asm__ __volatile__ ("vmhaddshs    17, 14, 15, 16");
2241}
2242
2243static void test_vmhraddshs (void)
2244{
2245    __asm__ __volatile__ ("vmhraddshs   17, 14, 15, 16");
2246}
2247
2248static void test_vmladduhm (void)
2249{
2250    __asm__ __volatile__ ("vmladduhm    17, 14, 15, 16");
2251}
2252
2253static void test_vmsumubm (void)
2254{
2255    __asm__ __volatile__ ("vmsumubm     17, 14, 15, 16");
2256}
2257
2258static void test_vmsumuhm (void)
2259{
2260    __asm__ __volatile__ ("vmsumuhm     17, 14, 15, 16");
2261}
2262
2263static void test_vmsumshs (void)
2264{
2265    __asm__ __volatile__ ("vmsumshs     17, 14, 15, 16");
2266}
2267
2268static void test_vmsumuhs (void)
2269{
2270    __asm__ __volatile__ ("vmsumuhs     17, 14, 15, 16");
2271}
2272
2273static void test_vmsummbm (void)
2274{
2275    __asm__ __volatile__ ("vmsummbm     17, 14, 15, 16");
2276}
2277
2278static void test_vmsumshm (void)
2279{
2280    __asm__ __volatile__ ("vmsumshm     17, 14, 15, 16");
2281}
2282
2283static test_t tests_aa_ops_three[] = {
2284    { &test_vmhaddshs       , "   vmhaddshs", },
2285    { &test_vmhraddshs      , "  vmhraddshs", },
2286    { &test_vmladduhm       , "   vmladduhm", },
2287    { &test_vmsumubm        , "    vmsumubm", },
2288    { &test_vmsumuhm        , "    vmsumuhm", },
2289    { &test_vmsumshs        , "    vmsumshs", },
2290    { &test_vmsumuhs        , "    vmsumuhs", },
2291    { &test_vmsummbm        , "    vmsummbm", },
2292    { &test_vmsumshm        , "    vmsumshm", },
2293    { NULL,                   NULL,           },
2294};
2295#endif /* defined (HAS_ALTIVEC) */
2296
2297#if defined (HAS_ALTIVEC)
2298static void test_vperm (void)
2299{
2300    __asm__ __volatile__ ("vperm        17, 14, 15, 16");
2301}
2302
2303static void test_vsel (void)
2304{
2305    __asm__ __volatile__ ("vsel         17, 14, 15, 16");
2306}
2307
2308static test_t tests_al_ops_three[] = {
2309    { &test_vperm           , "       vperm", },
2310    { &test_vsel            , "        vsel", },
2311    { NULL,                   NULL,           },
2312};
2313#endif /* defined (HAS_ALTIVEC) */
2314
2315#if defined (HAS_ALTIVEC)
2316static void test_vaddubm (void)
2317{
2318    __asm__ __volatile__ ("vaddubm      17, 14, 15");
2319}
2320
2321static void test_vadduhm (void)
2322{
2323    __asm__ __volatile__ ("vadduhm      17, 14, 15");
2324}
2325
2326static void test_vadduwm (void)
2327{
2328    __asm__ __volatile__ ("vadduwm      17, 14, 15");
2329}
2330
2331static void test_vaddubs (void)
2332{
2333    __asm__ __volatile__ ("vaddubs      17, 14, 15");
2334}
2335
2336static void test_vadduhs (void)
2337{
2338    __asm__ __volatile__ ("vadduhs      17, 14, 15");
2339}
2340
2341static void test_vadduws (void)
2342{
2343    __asm__ __volatile__ ("vadduws      17, 14, 15");
2344}
2345
2346static void test_vaddsbs (void)
2347{
2348    __asm__ __volatile__ ("vaddsbs      17, 14, 15");
2349}
2350
2351static void test_vaddshs (void)
2352{
2353    __asm__ __volatile__ ("vaddshs      17, 14, 15");
2354}
2355
2356static void test_vaddsws (void)
2357{
2358    __asm__ __volatile__ ("vaddsws      17, 14, 15");
2359}
2360
2361static void test_vaddcuw (void)
2362{
2363    __asm__ __volatile__ ("vaddcuw      17, 14, 15");
2364}
2365
2366static void test_vsububm (void)
2367{
2368    __asm__ __volatile__ ("vsububm      17, 14, 15");
2369}
2370
2371static void test_vsubuhm (void)
2372{
2373    __asm__ __volatile__ ("vsubuhm      17, 14, 15");
2374}
2375
2376static void test_vsubuwm (void)
2377{
2378    __asm__ __volatile__ ("vsubuwm      17, 14, 15");
2379}
2380
2381static void test_vsububs (void)
2382{
2383    __asm__ __volatile__ ("vsububs      17, 14, 15");
2384}
2385
2386static void test_vsubuhs (void)
2387{
2388    __asm__ __volatile__ ("vsubuhs      17, 14, 15");
2389}
2390
2391static void test_vsubuws (void)
2392{
2393    __asm__ __volatile__ ("vsubuws      17, 14, 15");
2394}
2395
2396static void test_vsubsbs (void)
2397{
2398    __asm__ __volatile__ ("vsubsbs      17, 14, 15");
2399}
2400
2401static void test_vsubshs (void)
2402{
2403    __asm__ __volatile__ ("vsubshs      17, 14, 15");
2404}
2405
2406static void test_vsubsws (void)
2407{
2408    __asm__ __volatile__ ("vsubsws      17, 14, 15");
2409}
2410
2411static void test_vsubcuw (void)
2412{
2413    __asm__ __volatile__ ("vsubcuw      17, 14, 15");
2414}
2415
2416static void test_vmuloub (void)
2417{
2418    __asm__ __volatile__ ("vmuloub      17, 14, 15");
2419}
2420
2421static void test_vmulouh (void)
2422{
2423    __asm__ __volatile__ ("vmulouh      17, 14, 15");
2424}
2425
2426static void test_vmulosb (void)
2427{
2428    __asm__ __volatile__ ("vmulosb      17, 14, 15");
2429}
2430
2431static void test_vmulosh (void)
2432{
2433    __asm__ __volatile__ ("vmulosh      17, 14, 15");
2434}
2435
2436static void test_vmuleub (void)
2437{
2438    __asm__ __volatile__ ("vmuleub      17, 14, 15");
2439}
2440
2441static void test_vmuleuh (void)
2442{
2443    __asm__ __volatile__ ("vmuleuh      17, 14, 15");
2444}
2445
2446static void test_vmulesb (void)
2447{
2448    __asm__ __volatile__ ("vmulesb      17, 14, 15");
2449}
2450
2451static void test_vmulesh (void)
2452{
2453    __asm__ __volatile__ ("vmulesh      17, 14, 15");
2454}
2455
2456static void test_vsumsws (void)
2457{
2458    __asm__ __volatile__ ("vsumsws      17, 14, 15");
2459}
2460
2461static void test_vsum2sws (void)
2462{
2463    __asm__ __volatile__ ("vsum2sws     17, 14, 15");
2464}
2465
2466static void test_vsum4ubs (void)
2467{
2468    __asm__ __volatile__ ("vsum4ubs     17, 14, 15");
2469}
2470
2471static void test_vsum4sbs (void)
2472{
2473    __asm__ __volatile__ ("vsum4sbs     17, 14, 15");
2474}
2475
2476static void test_vsum4shs (void)
2477{
2478    __asm__ __volatile__ ("vsum4shs     17, 14, 15");
2479}
2480
2481static void test_vavgub (void)
2482{
2483    __asm__ __volatile__ ("vavgub       17, 14, 15");
2484}
2485
2486static void test_vavguh (void)
2487{
2488    __asm__ __volatile__ ("vavguh       17, 14, 15");
2489}
2490
2491static void test_vavguw (void)
2492{
2493    __asm__ __volatile__ ("vavguw       17, 14, 15");
2494}
2495
2496static void test_vavgsb (void)
2497{
2498    __asm__ __volatile__ ("vavgsb       17, 14, 15");
2499}
2500
2501static void test_vavgsh (void)
2502{
2503    __asm__ __volatile__ ("vavgsh       17, 14, 15");
2504}
2505
2506static void test_vavgsw (void)
2507{
2508    __asm__ __volatile__ ("vavgsw       17, 14, 15");
2509}
2510
2511static void test_vmaxub (void)
2512{
2513    __asm__ __volatile__ ("vmaxub       17, 14, 15");
2514}
2515
2516static void test_vmaxuh (void)
2517{
2518    __asm__ __volatile__ ("vmaxuh       17, 14, 15");
2519}
2520
2521static void test_vmaxuw (void)
2522{
2523    __asm__ __volatile__ ("vmaxuw       17, 14, 15");
2524}
2525
2526static void test_vmaxsb (void)
2527{
2528    __asm__ __volatile__ ("vmaxsb       17, 14, 15");
2529}
2530
2531static void test_vmaxsh (void)
2532{
2533    __asm__ __volatile__ ("vmaxsh       17, 14, 15");
2534}
2535
2536static void test_vmaxsw (void)
2537{
2538    __asm__ __volatile__ ("vmaxsw       17, 14, 15");
2539}
2540
2541static void test_vminub (void)
2542{
2543    __asm__ __volatile__ ("vminub       17, 14, 15");
2544}
2545
2546static void test_vminuh (void)
2547{
2548    __asm__ __volatile__ ("vminuh       17, 14, 15");
2549}
2550
2551static void test_vminuw (void)
2552{
2553    __asm__ __volatile__ ("vminuw       17, 14, 15");
2554}
2555
2556static void test_vminsb (void)
2557{
2558    __asm__ __volatile__ ("vminsb       17, 14, 15");
2559}
2560
2561static void test_vminsh (void)
2562{
2563    __asm__ __volatile__ ("vminsh       17, 14, 15");
2564}
2565
2566static void test_vminsw (void)
2567{
2568    __asm__ __volatile__ ("vminsw       17, 14, 15");
2569}
2570
2571static test_t tests_aa_ops_two[] = {
2572    { &test_vaddubm         , "     vaddubm", },
2573    { &test_vadduhm         , "     vadduhm", },
2574    { &test_vadduwm         , "     vadduwm", },
2575    { &test_vaddubs         , "     vaddubs", },
2576    { &test_vadduhs         , "     vadduhs", },
2577    { &test_vadduws         , "     vadduws", },
2578    { &test_vaddsbs         , "     vaddsbs", },
2579    { &test_vaddshs         , "     vaddshs", },
2580    { &test_vaddsws         , "     vaddsws", },
2581    { &test_vaddcuw         , "     vaddcuw", },
2582    { &test_vsububm         , "     vsububm", },
2583    { &test_vsubuhm         , "     vsubuhm", },
2584    { &test_vsubuwm         , "     vsubuwm", },
2585    { &test_vsububs         , "     vsububs", },
2586    { &test_vsubuhs         , "     vsubuhs", },
2587    { &test_vsubuws         , "     vsubuws", },
2588    { &test_vsubsbs         , "     vsubsbs", },
2589    { &test_vsubshs         , "     vsubshs", },
2590    { &test_vsubsws         , "     vsubsws", },
2591    { &test_vsubcuw         , "     vsubcuw", },
2592    { &test_vmuloub         , "     vmuloub", },
2593    { &test_vmulouh         , "     vmulouh", },
2594    { &test_vmulosb         , "     vmulosb", },
2595    { &test_vmulosh         , "     vmulosh", },
2596    { &test_vmuleub         , "     vmuleub", },
2597    { &test_vmuleuh         , "     vmuleuh", },
2598    { &test_vmulesb         , "     vmulesb", },
2599    { &test_vmulesh         , "     vmulesh", },
2600    { &test_vsumsws         , "     vsumsws", },
2601    { &test_vsum2sws        , "    vsum2sws", },
2602    { &test_vsum4ubs        , "    vsum4ubs", },
2603    { &test_vsum4sbs        , "    vsum4sbs", },
2604    { &test_vsum4shs        , "    vsum4shs", },
2605    { &test_vavgub          , "      vavgub", },
2606    { &test_vavguh          , "      vavguh", },
2607    { &test_vavguw          , "      vavguw", },
2608    { &test_vavgsb          , "      vavgsb", },
2609    { &test_vavgsh          , "      vavgsh", },
2610    { &test_vavgsw          , "      vavgsw", },
2611    { &test_vmaxub          , "      vmaxub", },
2612    { &test_vmaxuh          , "      vmaxuh", },
2613    { &test_vmaxuw          , "      vmaxuw", },
2614    { &test_vmaxsb          , "      vmaxsb", },
2615    { &test_vmaxsh          , "      vmaxsh", },
2616    { &test_vmaxsw          , "      vmaxsw", },
2617    { &test_vminub          , "      vminub", },
2618    { &test_vminuh          , "      vminuh", },
2619    { &test_vminuw          , "      vminuw", },
2620    { &test_vminsb          , "      vminsb", },
2621    { &test_vminsh          , "      vminsh", },
2622    { &test_vminsw          , "      vminsw", },
2623    { NULL,                   NULL,           },
2624};
2625#endif /* defined (HAS_ALTIVEC) */
2626
2627#if defined (HAS_ALTIVEC)
2628static void test_vand (void)
2629{
2630    __asm__ __volatile__ ("vand         17, 14, 15");
2631}
2632
2633static void test_vor (void)
2634{
2635    __asm__ __volatile__ ("vor          17, 14, 15");
2636}
2637
2638static void test_vxor (void)
2639{
2640    __asm__ __volatile__ ("vxor         17, 14, 15");
2641}
2642
2643static void test_vandc (void)
2644{
2645    __asm__ __volatile__ ("vandc        17, 14, 15");
2646}
2647
2648static void test_vnor (void)
2649{
2650    __asm__ __volatile__ ("vnor         17, 14, 15");
2651}
2652
2653static void test_vrlb (void)
2654{
2655    __asm__ __volatile__ ("vrlb         17, 14, 15");
2656}
2657
2658static void test_vrlh (void)
2659{
2660    __asm__ __volatile__ ("vrlh         17, 14, 15");
2661}
2662
2663static void test_vrlw (void)
2664{
2665    __asm__ __volatile__ ("vrlw         17, 14, 15");
2666}
2667
2668static void test_vslb (void)
2669{
2670    __asm__ __volatile__ ("vslb         17, 14, 15");
2671}
2672
2673static void test_vslh (void)
2674{
2675    __asm__ __volatile__ ("vslh         17, 14, 15");
2676}
2677
2678static void test_vslw (void)
2679{
2680    __asm__ __volatile__ ("vslw         17, 14, 15");
2681}
2682
2683static void test_vsrb (void)
2684{
2685    __asm__ __volatile__ ("vsrb         17, 14, 15");
2686}
2687
2688static void test_vsrh (void)
2689{
2690    __asm__ __volatile__ ("vsrh         17, 14, 15");
2691}
2692
2693static void test_vsrw (void)
2694{
2695    __asm__ __volatile__ ("vsrw         17, 14, 15");
2696}
2697
2698static void test_vsrab (void)
2699{
2700    __asm__ __volatile__ ("vsrab        17, 14, 15");
2701}
2702
2703static void test_vsrah (void)
2704{
2705    __asm__ __volatile__ ("vsrah        17, 14, 15");
2706}
2707
2708static void test_vsraw (void)
2709{
2710    __asm__ __volatile__ ("vsraw        17, 14, 15");
2711}
2712
2713static void test_vpkuhum (void)
2714{
2715    __asm__ __volatile__ ("vpkuhum      17, 14, 15");
2716}
2717
2718static void test_vpkuwum (void)
2719{
2720    __asm__ __volatile__ ("vpkuwum      17, 14, 15");
2721}
2722
2723static void test_vpkuhus (void)
2724{
2725    __asm__ __volatile__ ("vpkuhus      17, 14, 15");
2726}
2727
2728static void test_vpkuwus (void)
2729{
2730    __asm__ __volatile__ ("vpkuwus      17, 14, 15");
2731}
2732
2733static void test_vpkshus (void)
2734{
2735    __asm__ __volatile__ ("vpkshus      17, 14, 15");
2736}
2737
2738static void test_vpkswus (void)
2739{
2740    __asm__ __volatile__ ("vpkswus      17, 14, 15");
2741}
2742
2743static void test_vpkshss (void)
2744{
2745    __asm__ __volatile__ ("vpkshss      17, 14, 15");
2746}
2747
2748static void test_vpkswss (void)
2749{
2750    __asm__ __volatile__ ("vpkswss      17, 14, 15");
2751}
2752
2753static void test_vpkpx (void)
2754{
2755    __asm__ __volatile__ ("vpkpx        17, 14, 15");
2756}
2757
2758static void test_vmrghb (void)
2759{
2760    __asm__ __volatile__ ("vmrghb       17, 14, 15");
2761}
2762
2763static void test_vmrghh (void)
2764{
2765    __asm__ __volatile__ ("vmrghh       17, 14, 15");
2766}
2767
2768static void test_vmrghw (void)
2769{
2770    __asm__ __volatile__ ("vmrghw       17, 14, 15");
2771}
2772
2773static void test_vmrglb (void)
2774{
2775    __asm__ __volatile__ ("vmrglb       17, 14, 15");
2776}
2777
2778static void test_vmrglh (void)
2779{
2780    __asm__ __volatile__ ("vmrglh       17, 14, 15");
2781}
2782
2783static void test_vmrglw (void)
2784{
2785    __asm__ __volatile__ ("vmrglw       17, 14, 15");
2786}
2787
2788static void test_vslo (void)
2789{
2790    __asm__ __volatile__ ("vslo         17, 14, 15");
2791}
2792
2793static void test_vsro (void)
2794{
2795    __asm__ __volatile__ ("vsro         17, 14, 15");
2796}
2797
2798static test_t tests_al_ops_two[] = {
2799    { &test_vand            , "        vand", },
2800    { &test_vor             , "         vor", },
2801    { &test_vxor            , "        vxor", },
2802    { &test_vandc           , "       vandc", },
2803    { &test_vnor            , "        vnor", },
2804    { &test_vrlb            , "        vrlb", },
2805    { &test_vrlh            , "        vrlh", },
2806    { &test_vrlw            , "        vrlw", },
2807    { &test_vslb            , "        vslb", },
2808    { &test_vslh            , "        vslh", },
2809    { &test_vslw            , "        vslw", },
2810    { &test_vsrb            , "        vsrb", },
2811    { &test_vsrh            , "        vsrh", },
2812    { &test_vsrw            , "        vsrw", },
2813    { &test_vsrab           , "       vsrab", },
2814    { &test_vsrah           , "       vsrah", },
2815    { &test_vsraw           , "       vsraw", },
2816    { &test_vpkuhum         , "     vpkuhum", },
2817    { &test_vpkuwum         , "     vpkuwum", },
2818    { &test_vpkuhus         , "     vpkuhus", },
2819    { &test_vpkuwus         , "     vpkuwus", },
2820    { &test_vpkshus         , "     vpkshus", },
2821    { &test_vpkswus         , "     vpkswus", },
2822    { &test_vpkshss         , "     vpkshss", },
2823    { &test_vpkswss         , "     vpkswss", },
2824    { &test_vpkpx           , "       vpkpx", },
2825    { &test_vmrghb          , "      vmrghb", },
2826    { &test_vmrghh          , "      vmrghh", },
2827    { &test_vmrghw          , "      vmrghw", },
2828    { &test_vmrglb          , "      vmrglb", },
2829    { &test_vmrglh          , "      vmrglh", },
2830    { &test_vmrglw          , "      vmrglw", },
2831    { &test_vslo            , "        vslo", },
2832    { &test_vsro            , "        vsro", },
2833    { NULL,                   NULL,           },
2834};
2835#endif /* defined (HAS_ALTIVEC) */
2836
2837#if defined (HAS_ALTIVEC)
2838static void test_vupkhsb (void)
2839{
2840    __asm__ __volatile__ ("vupkhsb      17, 14");
2841}
2842
2843static void test_vupkhsh (void)
2844{
2845    __asm__ __volatile__ ("vupkhsh      17, 14");
2846}
2847
2848static void test_vupkhpx (void)
2849{
2850    __asm__ __volatile__ ("vupkhpx      17, 14");
2851}
2852
2853static void test_vupklsb (void)
2854{
2855    __asm__ __volatile__ ("vupklsb      17, 14");
2856}
2857
2858static void test_vupklsh (void)
2859{
2860    __asm__ __volatile__ ("vupklsh      17, 14");
2861}
2862
2863static void test_vupklpx (void)
2864{
2865    __asm__ __volatile__ ("vupklpx      17, 14");
2866}
2867
2868static test_t tests_al_ops_one[] = {
2869    { &test_vupkhsb         , "     vupkhsb", },
2870    { &test_vupkhsh         , "     vupkhsh", },
2871    { &test_vupkhpx         , "     vupkhpx", },
2872    { &test_vupklsb         , "     vupklsb", },
2873    { &test_vupklsh         , "     vupklsh", },
2874    { &test_vupklpx         , "     vupklpx", },
2875    { NULL,                   NULL,           },
2876};
2877#endif /* defined (HAS_ALTIVEC) */
2878
2879#if defined (HAS_ALTIVEC)
2880static void test_vcmpgtub (void)
2881{
2882    __asm__ __volatile__ ("vcmpgtub     17, 14, 15");
2883}
2884
2885static void test_vcmpgtuh (void)
2886{
2887    __asm__ __volatile__ ("vcmpgtuh     17, 14, 15");
2888}
2889
2890static void test_vcmpgtuw (void)
2891{
2892    __asm__ __volatile__ ("vcmpgtuw     17, 14, 15");
2893}
2894
2895static void test_vcmpgtsb (void)
2896{
2897    __asm__ __volatile__ ("vcmpgtsb     17, 14, 15");
2898}
2899
2900static void test_vcmpgtsh (void)
2901{
2902    __asm__ __volatile__ ("vcmpgtsh     17, 14, 15");
2903}
2904
2905static void test_vcmpgtsw (void)
2906{
2907    __asm__ __volatile__ ("vcmpgtsw     17, 14, 15");
2908}
2909
2910static void test_vcmpequb (void)
2911{
2912    __asm__ __volatile__ ("vcmpequb     17, 14, 15");
2913}
2914
2915static void test_vcmpequh (void)
2916{
2917    __asm__ __volatile__ ("vcmpequh     17, 14, 15");
2918}
2919
2920static void test_vcmpequw (void)
2921{
2922    __asm__ __volatile__ ("vcmpequw     17, 14, 15");
2923}
2924
2925static test_t tests_ac_ops_two[] = {
2926    { &test_vcmpgtub        , "    vcmpgtub", },
2927    { &test_vcmpgtuh        , "    vcmpgtuh", },
2928    { &test_vcmpgtuw        , "    vcmpgtuw", },
2929    { &test_vcmpgtsb        , "    vcmpgtsb", },
2930    { &test_vcmpgtsh        , "    vcmpgtsh", },
2931    { &test_vcmpgtsw        , "    vcmpgtsw", },
2932    { &test_vcmpequb        , "    vcmpequb", },
2933    { &test_vcmpequh        , "    vcmpequh", },
2934    { &test_vcmpequw        , "    vcmpequw", },
2935    { NULL,                   NULL,           },
2936};
2937#endif /* defined (HAS_ALTIVEC) */
2938
2939#if defined (HAS_ALTIVEC)
2940static void test_vcmpgtub_ (void)
2941{
2942    __asm__ __volatile__ ("vcmpgtub.    17, 14, 15");
2943}
2944
2945static void test_vcmpgtuh_ (void)
2946{
2947    __asm__ __volatile__ ("vcmpgtuh.    17, 14, 15");
2948}
2949
2950static void test_vcmpgtuw_ (void)
2951{
2952    __asm__ __volatile__ ("vcmpgtuw.    17, 14, 15");
2953}
2954
2955static void test_vcmpgtsb_ (void)
2956{
2957    __asm__ __volatile__ ("vcmpgtsb.    17, 14, 15");
2958}
2959
2960static void test_vcmpgtsh_ (void)
2961{
2962    __asm__ __volatile__ ("vcmpgtsh.    17, 14, 15");
2963}
2964
2965static void test_vcmpgtsw_ (void)
2966{
2967    __asm__ __volatile__ ("vcmpgtsw.    17, 14, 15");
2968}
2969
2970static void test_vcmpequb_ (void)
2971{
2972    __asm__ __volatile__ ("vcmpequb.    17, 14, 15");
2973}
2974
2975static void test_vcmpequh_ (void)
2976{
2977    __asm__ __volatile__ ("vcmpequh.    17, 14, 15");
2978}
2979
2980static void test_vcmpequw_ (void)
2981{
2982    __asm__ __volatile__ ("vcmpequw.    17, 14, 15");
2983}
2984
2985static test_t tests_acr_ops_two[] = {
2986    { &test_vcmpgtub_       , "   vcmpgtub.", },
2987    { &test_vcmpgtuh_       , "   vcmpgtuh.", },
2988    { &test_vcmpgtuw_       , "   vcmpgtuw.", },
2989    { &test_vcmpgtsb_       , "   vcmpgtsb.", },
2990    { &test_vcmpgtsh_       , "   vcmpgtsh.", },
2991    { &test_vcmpgtsw_       , "   vcmpgtsw.", },
2992    { &test_vcmpequb_       , "   vcmpequb.", },
2993    { &test_vcmpequh_       , "   vcmpequh.", },
2994    { &test_vcmpequw_       , "   vcmpequw.", },
2995    { NULL,                   NULL,           },
2996};
2997#endif /* defined (HAS_ALTIVEC) */
2998
2999#if defined (HAS_ALTIVEC)
3000static void test_vsl (void)
3001{
3002    __asm__ __volatile__ ("vsl          17, 14, 15");
3003}
3004
3005static void test_vsr (void)
3006{
3007    __asm__ __volatile__ ("vsr          17, 14, 15");
3008}
3009
3010extern void test_vspltb (void);
3011ASSEMBLY_FUNC("test_vspltb", "vspltb       17, 14, 0");
3012
3013extern void test_vsplth (void);
3014ASSEMBLY_FUNC("test_vsplth", "vsplth       17, 14, 0");
3015
3016extern void test_vspltw (void);
3017ASSEMBLY_FUNC("test_vspltw", "vspltw       17, 14, 0");
3018
3019extern void test_vspltisb (void);
3020ASSEMBLY_FUNC("test_vspltisb", "vspltisb       17, 0");
3021
3022extern void test_vspltish (void);
3023ASSEMBLY_FUNC("test_vspltish", "vspltish       17, 0");
3024
3025extern void test_vspltisw (void);
3026ASSEMBLY_FUNC("test_vspltisw", "vspltisw       17, 0");
3027
3028extern void test_vsldoi (void);
3029ASSEMBLY_FUNC("test_vsldoi", "vsldoi       17, 14, 15, 0");
3030
3031static void test_lvsl (void)
3032{
3033    __asm__ __volatile__ ("lvsl         17, 14, 15");
3034}
3035
3036static void test_lvsr (void)
3037{
3038    __asm__ __volatile__ ("lvsr         17, 14, 15");
3039}
3040
3041static test_t tests_av_int_ops_spe[] = {
3042    { &test_vsl             , "         vsl", },
3043    { &test_vsr             , "         vsr", },
3044    { &test_vspltb          , "      vspltb", },
3045    { &test_vsplth          , "      vsplth", },
3046    { &test_vspltw          , "      vspltw", },
3047    { &test_vspltisb        , "    vspltisb", },
3048    { &test_vspltish        , "    vspltish", },
3049    { &test_vspltisw        , "    vspltisw", },
3050    { &test_vsldoi          , "      vsldoi", },
3051    { &test_lvsl            , "        lvsl", },
3052    { &test_lvsr            , "        lvsr", },
3053    { NULL,                   NULL,           },
3054};
3055#endif /* defined (HAS_ALTIVEC) */
3056
3057#if defined (HAS_ALTIVEC)
3058static void test_lvebx (void)
3059{
3060    __asm__ __volatile__ ("lvebx        17,14,15");
3061}
3062
3063static void test_lvehx (void)
3064{
3065    __asm__ __volatile__ ("lvehx        17,14,15");
3066}
3067
3068static void test_lvewx (void)
3069{
3070    __asm__ __volatile__ ("lvewx        17,14,15");
3071}
3072
3073static void test_lvx (void)
3074{
3075    __asm__ __volatile__ ("lvx          17,14,15");
3076}
3077
3078static void test_lvxl (void)
3079{
3080    __asm__ __volatile__ ("lvxl         17,14,15");
3081}
3082
3083static test_t tests_ald_ops_two[] = {
3084    { &test_lvebx           , "       lvebx", },
3085    { &test_lvehx           , "       lvehx", },
3086    { &test_lvewx           , "       lvewx", },
3087    { &test_lvx             , "         lvx", },
3088    { &test_lvxl            , "        lvxl", },
3089    { NULL,                   NULL,           },
3090};
3091#endif /* defined (HAS_ALTIVEC) */
3092
3093#if defined (HAS_ALTIVEC)
3094static void test_stvebx (void)
3095{
3096    __asm__ __volatile__ ("stvebx       14,15,16");
3097}
3098
3099static void test_stvehx (void)
3100{
3101    __asm__ __volatile__ ("stvehx       14,15,16");
3102}
3103
3104static void test_stvewx (void)
3105{
3106    __asm__ __volatile__ ("stvewx       14,15,16");
3107}
3108
3109static void test_stvx (void)
3110{
3111    __asm__ __volatile__ ("stvx         14,15,16");
3112}
3113
3114static void test_stvxl (void)
3115{
3116    __asm__ __volatile__ ("stvxl        14,15,16");
3117}
3118
3119static test_t tests_ast_ops_three[] = {
3120    { &test_stvebx          , "      stvebx", },
3121    { &test_stvehx          , "      stvehx", },
3122    { &test_stvewx          , "      stvewx", },
3123    { &test_stvx            , "        stvx", },
3124    { &test_stvxl           , "       stvxl", },
3125    { NULL,                   NULL,           },
3126};
3127#endif /* defined (HAS_ALTIVEC) */
3128
3129#if defined (HAS_ALTIVEC)
3130#if 1
3131static void test_vmaddfp (void)
3132{
3133    __asm__ __volatile__ ("vmaddfp      17, 14, 15, 16");
3134}
3135
3136static void test_vnmsubfp (void)
3137{
3138    __asm__ __volatile__ ("vnmsubfp     17, 14, 15, 16");
3139}
3140#endif
3141
3142static test_t tests_afa_ops_three[] = {
3143    { &test_vmaddfp         , "     vmaddfp", },
3144    { &test_vnmsubfp        , "    vnmsubfp", },
3145    { NULL,                   NULL,           },
3146};
3147#endif /* defined (HAS_ALTIVEC) */
3148
3149#if defined (HAS_ALTIVEC)
3150static void test_vaddfp (void)
3151{
3152    __asm__ __volatile__ ("vaddfp       17, 14, 15");
3153}
3154
3155static void test_vsubfp (void)
3156{
3157    __asm__ __volatile__ ("vsubfp       17, 14, 15");
3158}
3159
3160static void test_vmaxfp (void)
3161{
3162    __asm__ __volatile__ ("vmaxfp       17, 14, 15");
3163}
3164
3165static void test_vminfp (void)
3166{
3167    __asm__ __volatile__ ("vminfp       17, 14, 15");
3168}
3169
3170static test_t tests_afa_ops_two[] = {
3171    { &test_vaddfp          , "      vaddfp", },
3172    { &test_vsubfp          , "      vsubfp", },
3173    { &test_vmaxfp          , "      vmaxfp", },
3174    { &test_vminfp          , "      vminfp", },
3175    { NULL,                   NULL,           },
3176};
3177#endif /* defined (HAS_ALTIVEC) */
3178
3179#if defined (HAS_ALTIVEC)
3180static void test_vrfin (void)
3181{
3182    __asm__ __volatile__ ("vrfin        17, 14");
3183}
3184
3185static void test_vrfiz (void)
3186{
3187    __asm__ __volatile__ ("vrfiz        17, 14");
3188}
3189
3190static void test_vrfip (void)
3191{
3192    __asm__ __volatile__ ("vrfip        17, 14");
3193}
3194
3195static void test_vrfim (void)
3196{
3197    __asm__ __volatile__ ("vrfim        17, 14");
3198}
3199
3200static void test_vrefp (void)
3201{
3202    __asm__ __volatile__ ("vrefp        17, 14");
3203}
3204
3205static void test_vrsqrtefp (void)
3206{
3207    __asm__ __volatile__ ("vrsqrtefp    17, 14");
3208}
3209
3210#if 0   // TODO: Not yet supported
3211static void test_vlogefp (void)
3212{
3213    __asm__ __volatile__ ("vlogefp      17, 14");
3214}
3215
3216static void test_vexptefp (void)
3217{
3218    __asm__ __volatile__ ("vexptefp     17, 14");
3219}
3220#endif
3221
3222static test_t tests_afa_ops_one[] = {
3223    { &test_vrfin           , "       vrfin", },
3224    { &test_vrfiz           , "       vrfiz", },
3225    { &test_vrfip           , "       vrfip", },
3226    { &test_vrfim           , "       vrfim", },
3227    { &test_vrefp           , "       vrefp", },
3228    { &test_vrsqrtefp       , "   vrsqrtefp", },
3229    //    { &test_vlogefp         , "     vlogefp", },   // TODO: Not yet supported
3230    //    { &test_vexptefp        , "    vexptefp", },   // TODO: Not yet supported
3231    { NULL,                   NULL,           },
3232};
3233#endif /* defined (HAS_ALTIVEC) */
3234
3235#if defined (HAS_ALTIVEC)
3236static void test_vcmpgtfp (void)
3237{
3238    __asm__ __volatile__ ("vcmpgtfp     17, 14, 15");
3239}
3240
3241static void test_vcmpeqfp (void)
3242{
3243    __asm__ __volatile__ ("vcmpeqfp     17, 14, 15");
3244}
3245
3246static void test_vcmpgefp (void)
3247{
3248    __asm__ __volatile__ ("vcmpgefp     17, 14, 15");
3249}
3250
3251static void test_vcmpbfp (void)
3252{
3253    __asm__ __volatile__ ("vcmpbfp      17, 14, 15");
3254}
3255
3256static test_t tests_afc_ops_two[] = {
3257    { &test_vcmpgtfp        , "    vcmpgtfp", },
3258    { &test_vcmpeqfp        , "    vcmpeqfp", },
3259    { &test_vcmpgefp        , "    vcmpgefp", },
3260    { &test_vcmpbfp         , "     vcmpbfp", },
3261    { NULL,                   NULL,           },
3262};
3263#endif /* defined (HAS_ALTIVEC) */
3264
3265#if defined (HAS_ALTIVEC)
3266static void test_vcmpgtfp_ (void)
3267{
3268    __asm__ __volatile__ ("vcmpgtfp.    17, 14, 15");
3269}
3270
3271static void test_vcmpeqfp_ (void)
3272{
3273    __asm__ __volatile__ ("vcmpeqfp.    17, 14, 15");
3274}
3275
3276static void test_vcmpgefp_ (void)
3277{
3278    __asm__ __volatile__ ("vcmpgefp.    17, 14, 15");
3279}
3280
3281static void test_vcmpbfp_ (void)
3282{
3283    __asm__ __volatile__ ("vcmpbfp.     17, 14, 15");
3284}
3285
3286static test_t tests_afcr_ops_two[] = {
3287    { &test_vcmpgtfp_       , "   vcmpgtfp.", },
3288    { &test_vcmpeqfp_       , "   vcmpeqfp.", },
3289    { &test_vcmpgefp_       , "   vcmpgefp.", },
3290    { &test_vcmpbfp_        , "    vcmpbfp.", },
3291    { NULL,                   NULL,           },
3292};
3293#endif /* defined (HAS_ALTIVEC) */
3294
3295#if defined (HAS_ALTIVEC)
3296extern void test_vcfux (void);
3297ASSEMBLY_FUNC("test_vcfux", "vcfux        17, 14, 0");
3298
3299extern void test_vcfsx (void);
3300ASSEMBLY_FUNC("test_vcfsx", "vcfsx        17, 14, 0");
3301
3302extern void test_vctuxs (void);
3303ASSEMBLY_FUNC("test_vctuxs", "vctuxs        17, 14, 0");
3304
3305extern void test_vctsxs (void);
3306ASSEMBLY_FUNC("test_vctsxs", "vctsxs        17, 14, 0");
3307
3308static test_t tests_av_float_ops_spe[] = {
3309    { &test_vcfux           , "       vcfux", },
3310    { &test_vcfsx           , "       vcfsx", },
3311    { &test_vctuxs          , "      vctuxs", },
3312    { &test_vctsxs          , "      vctsxs", },
3313    { NULL,                   NULL,           },
3314};
3315#endif /* defined (HAS_ALTIVEC) */
3316
3317#if defined (IS_PPC405)
3318static void test_macchw (void)
3319{
3320    __asm__ __volatile__ ("macchw       17, 14, 15");
3321}
3322
3323static void test_macchwo (void)
3324{
3325    __asm__ __volatile__ ("macchwo      17, 14, 15");
3326}
3327
3328static void test_macchws (void)
3329{
3330    __asm__ __volatile__ ("macchws      17, 14, 15");
3331}
3332
3333static void test_macchwso (void)
3334{
3335    __asm__ __volatile__ ("macchwso     17, 14, 15");
3336}
3337
3338static void test_macchwsu (void)
3339{
3340    __asm__ __volatile__ ("macchwsu     17, 14, 15");
3341}
3342
3343static void test_macchwsuo (void)
3344{
3345    __asm__ __volatile__ ("macchwsuo    17, 14, 15");
3346}
3347
3348static void test_macchwu (void)
3349{
3350    __asm__ __volatile__ ("macchwu      17, 14, 15");
3351}
3352
3353static void test_macchwuo (void)
3354{
3355    __asm__ __volatile__ ("macchwuo     17, 14, 15");
3356}
3357
3358static void test_machhw (void)
3359{
3360    __asm__ __volatile__ ("machhw       17, 14, 15");
3361}
3362
3363static void test_machhwo (void)
3364{
3365    __asm__ __volatile__ ("machhwo      17, 14, 15");
3366}
3367
3368static void test_machhws (void)
3369{
3370    __asm__ __volatile__ ("machhws      17, 14, 15");
3371}
3372
3373static void test_machhwso (void)
3374{
3375    __asm__ __volatile__ ("machhwso     17, 14, 15");
3376}
3377
3378static void test_machhwsu (void)
3379{
3380    __asm__ __volatile__ ("machhwsu     17, 14, 15");
3381}
3382
3383static void test_machhwsuo (void)
3384{
3385    __asm__ __volatile__ ("machhwsuo    17, 14, 15");
3386}
3387
3388static void test_machhwu (void)
3389{
3390    __asm__ __volatile__ ("machhwu      17, 14, 15");
3391}
3392
3393static void test_machhwuo (void)
3394{
3395    __asm__ __volatile__ ("machhwuo     17, 14, 15");
3396}
3397
3398static void test_maclhw (void)
3399{
3400    __asm__ __volatile__ ("maclhw       17, 14, 15");
3401}
3402
3403static void test_maclhwo (void)
3404{
3405    __asm__ __volatile__ ("maclhwo      17, 14, 15");
3406}
3407
3408static void test_maclhws (void)
3409{
3410    __asm__ __volatile__ ("maclhws      17, 14, 15");
3411}
3412
3413static void test_maclhwso (void)
3414{
3415    __asm__ __volatile__ ("maclhwso     17, 14, 15");
3416}
3417
3418static void test_maclhwsu (void)
3419{
3420    __asm__ __volatile__ ("maclhwsu     17, 14, 15");
3421}
3422
3423static void test_maclhwsuo (void)
3424{
3425    __asm__ __volatile__ ("maclhwsuo    17, 14, 15");
3426}
3427
3428static void test_maclhwu (void)
3429{
3430    __asm__ __volatile__ ("maclhwu      17, 14, 15");
3431}
3432
3433static void test_maclhwuo (void)
3434{
3435    __asm__ __volatile__ ("maclhwuo     17, 14, 15");
3436}
3437
3438static void test_mulchw (void)
3439{
3440    __asm__ __volatile__ ("mulchw       17, 14, 15");
3441}
3442
3443static void test_mulchwu (void)
3444{
3445    __asm__ __volatile__ ("mulchwu      17, 14, 15");
3446}
3447
3448static void test_mulhhw (void)
3449{
3450    __asm__ __volatile__ ("mulhhw       17, 14, 15");
3451}
3452
3453static void test_mulhhwu (void)
3454{
3455    __asm__ __volatile__ ("mulhhwu      17, 14, 15");
3456}
3457
3458static void test_mullhw (void)
3459{
3460    __asm__ __volatile__ ("mullhw       17, 14, 15");
3461}
3462
3463static void test_mullhwu (void)
3464{
3465    __asm__ __volatile__ ("mullhwu      17, 14, 15");
3466}
3467
3468static void test_nmacchw (void)
3469{
3470    __asm__ __volatile__ ("nmacchw      17, 14, 15");
3471}
3472
3473static void test_nmacchwo (void)
3474{
3475    __asm__ __volatile__ ("nmacchwo     17, 14, 15");
3476}
3477
3478static void test_nmacchws (void)
3479{
3480    __asm__ __volatile__ ("nmacchws     17, 14, 15");
3481}
3482
3483static void test_nmacchwso (void)
3484{
3485    __asm__ __volatile__ ("nmacchwso    17, 14, 15");
3486}
3487
3488static void test_nmachhw (void)
3489{
3490    __asm__ __volatile__ ("nmachhw      17, 14, 15");
3491}
3492
3493static void test_nmachhwo (void)
3494{
3495    __asm__ __volatile__ ("nmachhwo     17, 14, 15");
3496}
3497
3498static void test_nmachhws (void)
3499{
3500    __asm__ __volatile__ ("nmachhws     17, 14, 15");
3501}
3502
3503static void test_nmachhwso (void)
3504{
3505    __asm__ __volatile__ ("nmachhwso    17, 14, 15");
3506}
3507
3508static void test_nmaclhw (void)
3509{
3510    __asm__ __volatile__ ("nmaclhw      17, 14, 15");
3511}
3512
3513static void test_nmaclhwo (void)
3514{
3515    __asm__ __volatile__ ("nmaclhwo     17, 14, 15");
3516}
3517
3518static void test_nmaclhws (void)
3519{
3520    __asm__ __volatile__ ("nmaclhws     17, 14, 15");
3521}
3522
3523static void test_nmaclhwso (void)
3524{
3525    __asm__ __volatile__ ("nmaclhwso    17, 14, 15");
3526}
3527
3528static test_t tests_p4m_ops_two[] = {
3529    { &test_macchw          , "      macchw", },
3530    { &test_macchwo         , "     macchwo", },
3531    { &test_macchws         , "     macchws", },
3532    { &test_macchwso        , "    macchwso", },
3533    { &test_macchwsu        , "    macchwsu", },
3534    { &test_macchwsuo       , "   macchwsuo", },
3535    { &test_macchwu         , "     macchwu", },
3536    { &test_macchwuo        , "    macchwuo", },
3537    { &test_machhw          , "      machhw", },
3538    { &test_machhwo         , "     machhwo", },
3539    { &test_machhws         , "     machhws", },
3540    { &test_machhwso        , "    machhwso", },
3541    { &test_machhwsu        , "    machhwsu", },
3542    { &test_machhwsuo       , "   machhwsuo", },
3543    { &test_machhwu         , "     machhwu", },
3544    { &test_machhwuo        , "    machhwuo", },
3545    { &test_maclhw          , "      maclhw", },
3546    { &test_maclhwo         , "     maclhwo", },
3547    { &test_maclhws         , "     maclhws", },
3548    { &test_maclhwso        , "    maclhwso", },
3549    { &test_maclhwsu        , "    maclhwsu", },
3550    { &test_maclhwsuo       , "   maclhwsuo", },
3551    { &test_maclhwu         , "     maclhwu", },
3552    { &test_maclhwuo        , "    maclhwuo", },
3553    { &test_mulchw          , "      mulchw", },
3554    { &test_mulchwu         , "     mulchwu", },
3555    { &test_mulhhw          , "      mulhhw", },
3556    { &test_mulhhwu         , "     mulhhwu", },
3557    { &test_mullhw          , "      mullhw", },
3558    { &test_mullhwu         , "     mullhwu", },
3559    { &test_nmacchw         , "     nmacchw", },
3560    { &test_nmacchwo        , "    nmacchwo", },
3561    { &test_nmacchws        , "    nmacchws", },
3562    { &test_nmacchwso       , "   nmacchwso", },
3563    { &test_nmachhw         , "     nmachhw", },
3564    { &test_nmachhwo        , "    nmachhwo", },
3565    { &test_nmachhws        , "    nmachhws", },
3566    { &test_nmachhwso       , "   nmachhwso", },
3567    { &test_nmaclhw         , "     nmaclhw", },
3568    { &test_nmaclhwo        , "    nmaclhwo", },
3569    { &test_nmaclhws        , "    nmaclhws", },
3570    { &test_nmaclhwso       , "   nmaclhwso", },
3571    { NULL,                   NULL,           },
3572};
3573#endif /* defined (IS_PPC405) */
3574
3575#if defined (IS_PPC405)
3576static void test_macchw_ (void)
3577{
3578    __asm__ __volatile__ ("macchw.      17, 14, 15");
3579}
3580
3581static void test_macchwo_ (void)
3582{
3583    __asm__ __volatile__ ("macchwo.     17, 14, 15");
3584}
3585
3586static void test_macchws_ (void)
3587{
3588    __asm__ __volatile__ ("macchws.     17, 14, 15");
3589}
3590
3591static void test_macchwso_ (void)
3592{
3593    __asm__ __volatile__ ("macchwso.    17, 14, 15");
3594}
3595
3596static void test_macchwsu_ (void)
3597{
3598    __asm__ __volatile__ ("macchwsu.    17, 14, 15");
3599}
3600
3601static void test_macchwsuo_ (void)
3602{
3603    __asm__ __volatile__ ("macchwsuo.   17, 14, 15");
3604}
3605
3606static void test_macchwu_ (void)
3607{
3608    __asm__ __volatile__ ("macchwu.     17, 14, 15");
3609}
3610
3611static void test_macchwuo_ (void)
3612{
3613    __asm__ __volatile__ ("macchwuo.    17, 14, 15");
3614}
3615
3616static void test_machhw_ (void)
3617{
3618    __asm__ __volatile__ ("machhw.      17, 14, 15");
3619}
3620
3621static void test_machhwo_ (void)
3622{
3623    __asm__ __volatile__ ("machhwo.     17, 14, 15");
3624}
3625
3626static void test_machhws_ (void)
3627{
3628    __asm__ __volatile__ ("machhws.     17, 14, 15");
3629}
3630
3631static void test_machhwso_ (void)
3632{
3633    __asm__ __volatile__ ("machhwso.    17, 14, 15");
3634}
3635
3636static void test_machhwsu_ (void)
3637{
3638    __asm__ __volatile__ ("machhwsu.    17, 14, 15");
3639}
3640
3641static void test_machhwsuo_ (void)
3642{
3643    __asm__ __volatile__ ("machhwsuo.   17, 14, 15");
3644}
3645
3646static void test_machhwu_ (void)
3647{
3648    __asm__ __volatile__ ("machhwu.     17, 14, 15");
3649}
3650
3651static void test_machhwuo_ (void)
3652{
3653    __asm__ __volatile__ ("machhwuo.    17, 14, 15");
3654}
3655
3656static void test_maclhw_ (void)
3657{
3658    __asm__ __volatile__ ("maclhw.      17, 14, 15");
3659}
3660
3661static void test_maclhwo_ (void)
3662{
3663    __asm__ __volatile__ ("maclhwo.     17, 14, 15");
3664}
3665
3666static void test_maclhws_ (void)
3667{
3668    __asm__ __volatile__ ("maclhws.     17, 14, 15");
3669}
3670
3671static void test_maclhwso_ (void)
3672{
3673    __asm__ __volatile__ ("maclhwso.    17, 14, 15");
3674}
3675
3676static void test_maclhwsu_ (void)
3677{
3678    __asm__ __volatile__ ("maclhwsu.    17, 14, 15");
3679}
3680
3681static void test_maclhwsuo_ (void)
3682{
3683    __asm__ __volatile__ ("maclhwsuo.   17, 14, 15");
3684}
3685
3686static void test_maclhwu_ (void)
3687{
3688    __asm__ __volatile__ ("maclhwu.     17, 14, 15");
3689}
3690
3691static void test_maclhwuo_ (void)
3692{
3693    __asm__ __volatile__ ("maclhwuo.    17, 14, 15");
3694}
3695
3696static void test_mulchw_ (void)
3697{
3698    __asm__ __volatile__ ("mulchw.      17, 14, 15");
3699}
3700
3701static void test_mulchwu_ (void)
3702{
3703    __asm__ __volatile__ ("mulchwu.     17, 14, 15");
3704}
3705
3706static void test_mulhhw_ (void)
3707{
3708    __asm__ __volatile__ ("mulhhw.      17, 14, 15");
3709}
3710
3711static void test_mulhhwu_ (void)
3712{
3713    __asm__ __volatile__ ("mulhhwu.     17, 14, 15");
3714}
3715
3716static void test_mullhw_ (void)
3717{
3718    __asm__ __volatile__ ("mullhw.      17, 14, 15");
3719}
3720
3721static void test_mullhwu_ (void)
3722{
3723    __asm__ __volatile__ ("mullhwu.     17, 14, 15");
3724}
3725
3726static void test_nmacchw_ (void)
3727{
3728    __asm__ __volatile__ ("nmacchw.     17, 14, 15");
3729}
3730
3731static void test_nmacchwo_ (void)
3732{
3733    __asm__ __volatile__ ("nmacchwo.    17, 14, 15");
3734}
3735
3736static void test_nmacchws_ (void)
3737{
3738    __asm__ __volatile__ ("nmacchws.    17, 14, 15");
3739}
3740
3741static void test_nmacchwso_ (void)
3742{
3743    __asm__ __volatile__ ("nmacchwso.   17, 14, 15");
3744}
3745
3746static void test_nmachhw_ (void)
3747{
3748    __asm__ __volatile__ ("nmachhw.     17, 14, 15");
3749}
3750
3751static void test_nmachhwo_ (void)
3752{
3753    __asm__ __volatile__ ("nmachhwo.    17, 14, 15");
3754}
3755
3756static void test_nmachhws_ (void)
3757{
3758    __asm__ __volatile__ ("nmachhws.    17, 14, 15");
3759}
3760
3761static void test_nmachhwso_ (void)
3762{
3763    __asm__ __volatile__ ("nmachhwso.   17, 14, 15");
3764}
3765
3766static void test_nmaclhw_ (void)
3767{
3768    __asm__ __volatile__ ("nmaclhw.     17, 14, 15");
3769}
3770
3771static void test_nmaclhwo_ (void)
3772{
3773    __asm__ __volatile__ ("nmaclhwo.    17, 14, 15");
3774}
3775
3776static void test_nmaclhws_ (void)
3777{
3778    __asm__ __volatile__ ("nmaclhws.    17, 14, 15");
3779}
3780
3781static void test_nmaclhwso_ (void)
3782{
3783    __asm__ __volatile__ ("nmaclhwso.   17, 14, 15");
3784}
3785
3786static test_t tests_p4mc_ops_two[] = {
3787    { &test_macchw_         , "     macchw.", },
3788    { &test_macchwo_        , "    macchwo.", },
3789    { &test_macchws_        , "    macchws.", },
3790    { &test_macchwso_       , "   macchwso.", },
3791    { &test_macchwsu_       , "   macchwsu.", },
3792    { &test_macchwsuo_      , "  macchwsuo.", },
3793    { &test_macchwu_        , "    macchwu.", },
3794    { &test_macchwuo_       , "   macchwuo.", },
3795    { &test_machhw_         , "     machhw.", },
3796    { &test_machhwo_        , "    machhwo.", },
3797    { &test_machhws_        , "    machhws.", },
3798    { &test_machhwso_       , "   machhwso.", },
3799    { &test_machhwsu_       , "   machhwsu.", },
3800    { &test_machhwsuo_      , "  machhwsuo.", },
3801    { &test_machhwu_        , "    machhwu.", },
3802    { &test_machhwuo_       , "   machhwuo.", },
3803    { &test_maclhw_         , "     maclhw.", },
3804    { &test_maclhwo_        , "    maclhwo.", },
3805    { &test_maclhws_        , "    maclhws.", },
3806    { &test_maclhwso_       , "   maclhwso.", },
3807    { &test_maclhwsu_       , "   maclhwsu.", },
3808    { &test_maclhwsuo_      , "  maclhwsuo.", },
3809    { &test_maclhwu_        , "    maclhwu.", },
3810    { &test_maclhwuo_       , "   maclhwuo.", },
3811    { &test_mulchw_         , "     mulchw.", },
3812    { &test_mulchwu_        , "    mulchwu.", },
3813    { &test_mulhhw_         , "     mulhhw.", },
3814    { &test_mulhhwu_        , "    mulhhwu.", },
3815    { &test_mullhw_         , "     mullhw.", },
3816    { &test_mullhwu_        , "    mullhwu.", },
3817    { &test_nmacchw_        , "    nmacchw.", },
3818    { &test_nmacchwo_       , "   nmacchwo.", },
3819    { &test_nmacchws_       , "   nmacchws.", },
3820    { &test_nmacchwso_      , "  nmacchwso.", },
3821    { &test_nmachhw_        , "    nmachhw.", },
3822    { &test_nmachhwo_       , "   nmachhwo.", },
3823    { &test_nmachhws_       , "   nmachhws.", },
3824    { &test_nmachhwso_      , "  nmachhwso.", },
3825    { &test_nmaclhw_        , "    nmaclhw.", },
3826    { &test_nmaclhwo_       , "   nmaclhwo.", },
3827    { &test_nmaclhws_       , "   nmaclhws.", },
3828    { &test_nmaclhwso_      , "  nmaclhwso.", },
3829    { NULL,                   NULL,           },
3830};
3831#endif /* defined (IS_PPC405) */
3832
3833static test_table_t all_tests[] = {
3834    {
3835        tests_ia_ops_two      ,
3836        "PPC integer arith insns with two args",
3837        0x00010102,
3838    },
3839    {
3840        tests_iar_ops_two     ,
3841        "PPC integer arith insns with two args with flags update",
3842        0x01010102,
3843    },
3844    {
3845        tests_iac_ops_two     ,
3846        "PPC integer arith insns with two args and carry",
3847        0x02010102,
3848    },
3849    {
3850        tests_iacr_ops_two    ,
3851        "PPC integer arith insns with two args and carry with flags update",
3852        0x03010102,
3853    },
3854    {
3855        tests_il_ops_two      ,
3856        "PPC integer logical insns with two args",
3857        0x00010202,
3858    },
3859    {
3860        tests_ilr_ops_two     ,
3861        "PPC integer logical insns with two args with flags update",
3862        0x01010202,
3863    },
3864    {
3865        tests_icr_ops_two     ,
3866        "PPC integer compare insns (two args)",
3867        0x01010304,
3868    },
3869    {
3870        tests_icr_ops_two_i16 ,
3871        "PPC integer compare with immediate insns (two args)",
3872        0x01010305,
3873    },
3874    {
3875        tests_ia_ops_two_i16  ,
3876        "PPC integer arith insns\n    with one register + one 16 bits immediate args",
3877        0x00010106,
3878    },
3879    {
3880        tests_iar_ops_two_i16 ,
3881        "PPC integer arith insns\n    with one register + one 16 bits immediate args with flags update",
3882        0x01010106,
3883    },
3884    {
3885        tests_il_ops_two_i16  ,
3886        "PPC integer logical insns\n    with one register + one 16 bits immediate args",
3887        0x00010206,
3888    },
3889    {
3890        tests_ilr_ops_two_i16 ,
3891        "PPC integer logical insns\n    with one register + one 16 bits immediate args with flags update",
3892        0x01010206,
3893    },
3894    {
3895        tests_crl_ops_two     ,
3896        "PPC condition register logical insns - two operands",
3897        0x01010202,
3898    },
3899    {
3900        tests_iac_ops_one     ,
3901        "PPC integer arith insns with one arg and carry",
3902        0x02010101,
3903    },
3904    {
3905        tests_iacr_ops_one    ,
3906        "PPC integer arith insns with one arg and carry with flags update",
3907        0x03010101,
3908    },
3909    {
3910        tests_il_ops_one      ,
3911        "PPC integer logical insns with one arg",
3912        0x00010201,
3913    },
3914    {
3915        tests_ilr_ops_one     ,
3916        "PPC integer logical insns with one arg with flags update",
3917        0x01010201,
3918    },
3919    {
3920        tests_il_ops_spe      ,
3921        "PPC logical insns with special forms",
3922        0x00010207,
3923    },
3924    {
3925        tests_ilr_ops_spe     ,
3926        "PPC logical insns with special forms with flags update",
3927        0x01010207,
3928    },
3929    {
3930        tests_ild_ops_two_i16 ,
3931        "PPC integer load insns\n    with one register + one 16 bits immediate args with flags update",
3932        0x00010508,
3933    },
3934    {
3935        tests_ild_ops_two     ,
3936        "PPC integer load insns with two register args",
3937        0x00010509,
3938    },
3939    {
3940        tests_ist_ops_three_i16,
3941        "PPC integer store insns\n    with one register + one 16 bits immediate args with flags update",
3942        0x0001050a,
3943    },
3944    {
3945        tests_ist_ops_three   ,
3946        "PPC integer store insns with three register args",
3947        0x0001050b,
3948    },
3949    {
3950        tests_popcnt_ops_one   ,
3951        "PPC integer population count with one register args, no flags",
3952        0x00010601,
3953    },
3954#if !defined (NO_FLOAT)
3955    {
3956        tests_fa_ops_three    ,
3957        "PPC floating point arith insns with three args",
3958        0x00020103,
3959    },
3960#endif /* !defined (NO_FLOAT) */
3961#if !defined (NO_FLOAT)
3962    {
3963        tests_far_ops_three    ,
3964        "PPC floating point arith insns\n    with three args with flags update",
3965        0x01020103,
3966    },
3967#endif /* !defined (NO_FLOAT) */
3968#if !defined (NO_FLOAT)
3969    {
3970        tests_fa_ops_two      ,
3971        "PPC floating point arith insns with two args",
3972        0x00020102,
3973    },
3974#endif /* !defined (NO_FLOAT) */
3975#if !defined (NO_FLOAT)
3976    {
3977        tests_far_ops_two     ,
3978        "PPC floating point arith insns\n    with two args with flags update",
3979        0x01020102,
3980    },
3981#endif /* !defined (NO_FLOAT) */
3982#if !defined (NO_FLOAT)
3983    {
3984        tests_fcr_ops_two     ,
3985        "PPC floating point compare insns (two args)",
3986        0x01020304,
3987    },
3988#endif /* !defined (NO_FLOAT) */
3989#if !defined (NO_FLOAT)
3990    {
3991        tests_fa_ops_one      ,
3992        "PPC floating point arith insns with one arg",
3993        0x00020101,
3994    },
3995#endif /* !defined (NO_FLOAT) */
3996#if !defined (NO_FLOAT)
3997    {
3998        tests_far_ops_one     ,
3999        "PPC floating point arith insns\n    with one arg with flags update",
4000        0x01020101,
4001    },
4002#endif /* !defined (NO_FLOAT) */
4003#if !defined (NO_FLOAT)
4004    {
4005        tests_fl_ops_spe      ,
4006        "PPC floating point status register manipulation insns",
4007        0x00020207,
4008    },
4009#endif /* !defined (NO_FLOAT) */
4010#if !defined (NO_FLOAT)
4011    {
4012        tests_flr_ops_spe     ,
4013        "PPC floating point status register manipulation insns\n  with flags update",
4014        0x01020207,
4015    },
4016#endif /* !defined (NO_FLOAT) */
4017#if !defined (NO_FLOAT)
4018    {
4019        tests_fld_ops_two_i16 ,
4020        "PPC float load insns\n    with one register + one 16 bits immediate args with flags update",
4021        0x00020508,
4022    },
4023#endif /* !defined (NO_FLOAT) */
4024#if !defined (NO_FLOAT)
4025    {
4026        tests_fld_ops_two     ,
4027        "PPC float load insns with two register args",
4028        0x00020509,
4029    },
4030#endif /* !defined (NO_FLOAT) */
4031#if !defined (NO_FLOAT)
4032    {
4033        tests_fst_ops_three_i16,
4034        "PPC float store insns\n    with one register + one 16 bits immediate args with flags update",
4035        0x0002050a,
4036    },
4037#endif /* !defined (NO_FLOAT) */
4038#if !defined (NO_FLOAT)
4039    {
4040        tests_fst_ops_three   ,
4041        "PPC float store insns with three register args",
4042        0x0002050b,
4043    },
4044#endif /* !defined (NO_FLOAT) */
4045#if defined (HAS_ALTIVEC)
4046    {
4047        tests_aa_ops_three    ,
4048        "PPC altivec integer arith insns with three args",
4049        0x00040103,
4050    },
4051#endif /* defined (HAS_ALTIVEC) */
4052#if defined (HAS_ALTIVEC)
4053    {
4054        tests_al_ops_three    ,
4055        "PPC altivec integer logical insns with three args",
4056        0x00040203,
4057    },
4058#endif /* defined (HAS_ALTIVEC) */
4059#if defined (HAS_ALTIVEC)
4060    {
4061        tests_aa_ops_two      ,
4062        "PPC altivec integer arith insns with two args",
4063        0x00040102,
4064    },
4065#endif /* defined (HAS_ALTIVEC) */
4066#if defined (HAS_ALTIVEC)
4067    {
4068        tests_al_ops_two      ,
4069        "PPC altivec integer logical insns with two args",
4070        0x00040202,
4071    },
4072#endif /* defined (HAS_ALTIVEC) */
4073#if defined (HAS_ALTIVEC)
4074    {
4075        tests_al_ops_one      ,
4076        "PPC altivec integer logical insns with one arg",
4077        0x00040201,
4078    },
4079#endif /* defined (HAS_ALTIVEC) */
4080#if defined (HAS_ALTIVEC)
4081    {
4082        tests_ac_ops_two      ,
4083        "Altivec integer compare insns",
4084        0x00040302,
4085    },
4086#endif /* defined (HAS_ALTIVEC) */
4087#if defined (HAS_ALTIVEC)
4088    {
4089        tests_acr_ops_two     ,
4090        "Altivec integer compare insns with flags update",
4091        0x01040302,
4092    },
4093#endif /* defined (HAS_ALTIVEC) */
4094#if defined (HAS_ALTIVEC)
4095    {
4096        tests_av_int_ops_spe  ,
4097        "Altivec integer special insns",
4098        0x00040207,
4099    },
4100#endif /* defined (HAS_ALTIVEC) */
4101#if defined (HAS_ALTIVEC)
4102    {
4103        tests_ald_ops_two     ,
4104        "Altivec load insns with two register args",
4105        0x00040509,
4106    },
4107#endif /* defined (HAS_ALTIVEC) */
4108#if defined (HAS_ALTIVEC)
4109    {
4110        tests_ast_ops_three   ,
4111        "Altivec store insns with three register args",
4112        0x0004050b,
4113    },
4114#endif /* defined (HAS_ALTIVEC) */
4115#if defined (HAS_ALTIVEC)
4116    {
4117        tests_afa_ops_two     ,
4118        "Altivec floating point arith insns with two args",
4119        0x00050102,
4120    },
4121#endif /* defined (HAS_ALTIVEC) */
4122#if defined (HAS_ALTIVEC)
4123    {
4124        tests_afa_ops_three   ,
4125        "Altivec floating point arith insns with three args",
4126        0x00050103,
4127    },
4128#endif /* defined (HAS_ALTIVEC) */
4129#if defined (HAS_ALTIVEC)
4130    {
4131        tests_afa_ops_one     ,
4132        "Altivec floating point arith insns with one arg",
4133        0x00050101,
4134    },
4135#endif /* defined (HAS_ALTIVEC) */
4136#if defined (HAS_ALTIVEC)
4137    {
4138        tests_afc_ops_two     ,
4139        "Altivec floating point compare insns",
4140        0x00050302,
4141    },
4142#endif /* defined (HAS_ALTIVEC) */
4143#if defined (HAS_ALTIVEC)
4144    {
4145        tests_afcr_ops_two    ,
4146        "Altivec floating point compare insns with flags update",
4147        0x01050302,
4148    },
4149#endif /* defined (HAS_ALTIVEC) */
4150#if defined (HAS_ALTIVEC)
4151    {
4152        tests_av_float_ops_spe,
4153        "Altivec float special insns",
4154        0x00050207,
4155    },
4156#endif /* defined (HAS_ALTIVEC) */
4157#if defined (IS_PPC405)
4158    {
4159        tests_p4m_ops_two     ,
4160        "PPC 405 mac insns with three args",
4161        0x00030102,
4162    },
4163#endif /* defined (IS_PPC405) */
4164#if defined (IS_PPC405)
4165    {
4166        tests_p4mc_ops_two    ,
4167        "PPC 405 mac insns with three args with flags update",
4168        0x01030102,
4169    },
4170#endif /* defined (IS_PPC405) */
4171    { NULL,                   NULL,               0x00000000, },
4172};
4173
4174/* -------------- END #include "ops-ppc.c" -------------- */
4175
4176static int verbose = 0;
4177static int arg_list_size = 0;
4178
4179static double *fargs = NULL;
4180static int nb_fargs = 0;
4181static int nb_normal_fargs = 0;
4182static HWord_t *iargs = NULL;
4183static int nb_iargs = 0;
4184static uint16_t *ii16 = NULL;
4185static int nb_ii16 = 0;
4186
4187#if defined (HAS_ALTIVEC)
4188static vector unsigned int* viargs = NULL;
4189static int nb_viargs = 0;
4190static vector float* vfargs = NULL;
4191static int nb_vfargs = 0;
4192
4193//#define TEST_VSCR_SAT
4194#endif
4195
4196static inline void register_farg (void *farg,
4197                                  int s, uint16_t _exp, uint64_t mant)
4198{
4199   uint64_t tmp;
4200
4201   tmp = ((uint64_t)s << 63) | ((uint64_t)_exp << 52) | mant;
4202   *(uint64_t *)farg = tmp;
4203#ifndef __powerpc64__
4204   AB_DPRINTF("%d %03x %013llx => %016llx %0e\n",
4205#else
4206   AB_DPRINTF("%d %03x %013lx => %016lx %0e\n",
4207#endif
4208              s, _exp, mant, *(uint64_t *)farg, *(double *)farg);
4209}
4210
4211static void build_fargs_table (void)
4212{
4213   /* Double precision:
4214    * Sign goes from zero to one               (1 bit)
4215    * Exponent goes from 0 to ((1 << 12) - 1)  (11 bits)
4216    * Mantissa goes from 1 to ((1 << 52) - 1)  (52 bits)
4217    * + special values:
4218    * +0.0      : 0 0x000 0x0000000000000 => 0x0000000000000000
4219    * -0.0      : 1 0x000 0x0000000000000 => 0x8000000000000000
4220    * +infinity : 0 0x7FF 0x0000000000000 => 0x7FF0000000000000
4221    * -infinity : 1 0x7FF 0x0000000000000 => 0xFFF0000000000000
4222    * +QNaN     : 0 0x7FF 0x7FFFFFFFFFFFF => 0x7FF7FFFFFFFFFFFF
4223    * -QNaN     : 1 0x7FF 0x7FFFFFFFFFFFF => 0xFFF7FFFFFFFFFFFF
4224    * +SNaN     : 0 0x7FF 0x8000000000000 => 0x7FF8000000000000
4225    * -SNaN     : 1 0x7FF 0x8000000000000 => 0xFFF8000000000000
4226    * (8 values)
4227
4228    * Ref only:
4229    * Single precision
4230    * Sign:     1 bit
4231    * Exponent: 8 bits
4232    * Mantissa: 23 bits
4233    * +0.0      : 0 0x00 0x000000 => 0x00000000
4234    * -0.0      : 1 0x00 0x000000 => 0x80000000
4235    * +infinity : 0 0xFF 0x000000 => 0x7F800000
4236    * -infinity : 1 0xFF 0x000000 => 0xFF800000
4237    * +QNaN     : 0 0xFF 0x3FFFFF => 0x7FBFFFFF
4238    * -QNaN     : 1 0xFF 0x3FFFFF => 0xFFBFFFFF
4239    * +SNaN     : 0 0xFF 0x400000 => 0x7FC00000
4240    * -SNaN     : 1 0xFF 0x400000 => 0xFFC00000
4241    */
4242   uint64_t mant;
4243   uint16_t _exp, e0, e1;
4244   int s;
4245   int i=0;
4246
4247   /* Note: VEX isn't so hot with denormals, so don't bother
4248      testing them: set _exp > 0
4249   */
4250
4251   if ( arg_list_size == 1 ) {   // Large
4252      fargs = malloc(200 * sizeof(double));
4253      for (s=0; s<2; s++) {
4254         for (e0=0; e0<2; e0++) {
4255            for (e1=0x001; ; e1 = ((e1 + 1) << 2) + 6) {
4256               if (e1 >= 0x400)
4257                  e1 = 0x3fe;
4258               _exp = (e0 << 10) | e1;
4259               for (mant = 0x0000000000001ULL; mant < (1ULL << 52);
4260                    /* Add 'random' bits */
4261                    mant = ((mant + 0x4A6) << 13) + 0x359) {
4262                  register_farg(&fargs[i++], s, _exp, mant);
4263               }
4264               if (e1 == 0x3fe)
4265                  break;
4266            }
4267         }
4268      }
4269   } else {                      // Default
4270      fargs = malloc(16 * sizeof(double));
4271      for (s=0; s<2; s++) {                                // x2
4272//       for (e0=0; e0<2; e0++) {
4273            for (e1=0x001; ; e1 = ((e1 + 1) << 13) + 7) {  // x2
4274//          for (e1=0x001; ; e1 = ((e1 + 1) << 5) + 7) {   // x3
4275               if (e1 >= 0x400)
4276                  e1 = 0x3fe;
4277//             _exp = (e0 << 10) | e1;
4278               _exp = e1;
4279               for (mant = 0x0000000000001ULL; mant < (1ULL << 52);
4280                    /* Add 'random' bits */
4281                    mant = ((mant + 0x4A6) << 29) + 0x359) {  // x2
4282                  register_farg(&fargs[i++], s, _exp, mant);
4283               }
4284               if (e1 == 0x3fe)
4285                  break;
4286            }
4287//       }
4288      }
4289   }
4290
4291   /* To iterate over non-special values only */
4292   nb_normal_fargs = i;
4293
4294
4295   /* Special values */
4296   /* +0.0      : 0 0x000 0x0000000000000 */
4297   s = 0;
4298   _exp = 0x000;
4299   mant = 0x0000000000000ULL;
4300   register_farg(&fargs[i++], s, _exp, mant);
4301   /* -0.0      : 1 0x000 0x0000000000000 */
4302   s = 1;
4303   _exp = 0x000;
4304   mant = 0x0000000000000ULL;
4305   register_farg(&fargs[i++], s, _exp, mant);
4306   /* +infinity : 0 0x7FF 0x0000000000000  */
4307   s = 0;
4308   _exp = 0x7FF;
4309   mant = 0x0000000000000ULL;
4310   register_farg(&fargs[i++], s, _exp, mant);
4311   /* -infinity : 1 0x7FF 0x0000000000000 */
4312   s = 1;
4313   _exp = 0x7FF;
4314   mant = 0x0000000000000ULL;
4315   register_farg(&fargs[i++], s, _exp, mant);
4316   /* +QNaN     : 0 0x7FF 0x7FFFFFFFFFFFF */
4317   s = 0;
4318   _exp = 0x7FF;
4319   mant = 0x7FFFFFFFFFFFFULL;
4320   register_farg(&fargs[i++], s, _exp, mant);
4321   /* -QNaN     : 1 0x7FF 0x7FFFFFFFFFFFF */
4322   s = 1;
4323   _exp = 0x7FF;
4324   mant = 0x7FFFFFFFFFFFFULL;
4325   register_farg(&fargs[i++], s, _exp, mant);
4326   /* +SNaN     : 0 0x7FF 0x8000000000000 */
4327   s = 0;
4328   _exp = 0x7FF;
4329   mant = 0x8000000000000ULL;
4330   register_farg(&fargs[i++], s, _exp, mant);
4331   /* -SNaN     : 1 0x7FF 0x8000000000000 */
4332   s = 1;
4333   _exp = 0x7FF;
4334   mant = 0x8000000000000ULL;
4335   register_farg(&fargs[i++], s, _exp, mant);
4336   AB_DPRINTF("Registered %d fargs values\n", i);
4337
4338   nb_fargs = i;
4339}
4340
4341static void build_iargs_table (void)
4342{
4343   uint64_t tmp;
4344   int i=0;
4345
4346#ifndef __powerpc64__
4347   if (arg_list_size == 1) {                   // Large
4348      iargs = malloc(400 * sizeof(HWord_t));
4349      for (tmp=0; ; tmp = tmp + 1 + (tmp >> 1)) {
4350         if (tmp >= 0x100000000ULL)
4351            tmp = 0xFFFFFFFF;
4352         iargs[i++] = (HWord_t)tmp;
4353         AB_DPRINTF("val %08x\n", (HWord_t)tmp);
4354         if (tmp == 0xFFFFFFFF)
4355            break;
4356      }
4357   } else {                                    // Default
4358      iargs = malloc(10 * sizeof(HWord_t));
4359      // for (tmp = 0; ; tmp = 71*tmp + 1 + (tmp>>1)) {  // gives 8
4360      // for (tmp = 0; ; tmp = 100000*tmp + 1 + (tmp>>1)) {  // gives 4
4361      for (tmp=0; ; tmp = 999999*tmp + 999999) {  // gives 3
4362         if (tmp >= 0x100000000ULL)
4363            tmp = 0xFFFFFFFF;
4364         iargs[i++] = (HWord_t)tmp;
4365         AB_DPRINTF("val %08x\n", (HWord_t)tmp);
4366         if (tmp == 0xFFFFFFFF)
4367            break;
4368      }
4369   }
4370#else
4371   if (arg_list_size == 1) {                   // Large
4372      iargs = malloc(800 * sizeof(HWord_t));
4373      for (tmp=0; ; tmp = 2*tmp + 1 + (tmp >> 2)) {
4374         if ((long)tmp < 0 )
4375            tmp = 0xFFFFFFFFFFFFFFFFULL;
4376         iargs[i++] = tmp;
4377         AB_DPRINTF("val %016lx\n", tmp);
4378         if (tmp == 0xFFFFFFFFFFFFFFFFULL)
4379            break;
4380      }
4381   } else {                                    // Default
4382      iargs = malloc(20 * sizeof(HWord_t));
4383      // for (tmp=0; ; tmp = 9999*tmp + 999999) {  // gives 6
4384      for (tmp = 0; ; tmp = 123456789*tmp + 123456789999) {  // gives 3
4385         if ((long)tmp < 0 )
4386            tmp = 0xFFFFFFFFFFFFFFFFULL;
4387         iargs[i++] = tmp;
4388         AB_DPRINTF("val %016lx\n", tmp);
4389         if (tmp == 0xFFFFFFFFFFFFFFFFULL)
4390            break;
4391      }
4392   }
4393#endif // #ifndef __powerpc64__
4394
4395   AB_DPRINTF("Registered %d iargs values\n", i);
4396   nb_iargs = i;
4397}
4398
4399static void build_ii16_table (void)
4400{
4401   uint32_t tmp;
4402   int i=0;
4403
4404   if (arg_list_size == 1) {                   // Large
4405      ii16 = malloc(200 * sizeof(uint32_t));
4406      for (tmp=0; ; tmp = tmp + 1 + (tmp >> 2)) {
4407         if (tmp >= 0x10000)
4408            tmp = 0xFFFF;
4409         ii16[i++] = tmp;
4410         AB_DPRINTF("val %04x\n", tmp);
4411         if (tmp == 0xFFFF)
4412            break;
4413      }
4414   } else {                                    // Default
4415      ii16 = malloc(10 * sizeof(uint32_t));
4416      for (tmp=0; ; tmp = 999*tmp + 999) {  // gives 3
4417         if (tmp >= 0x10000)
4418            tmp = 0xFFFF;
4419         ii16[i++] = tmp;
4420         AB_DPRINTF("val %04x\n", tmp);
4421         if (tmp == 0xFFFF)
4422            break;
4423      }
4424   }
4425   AB_DPRINTF("Registered %d ii16 values\n", i);
4426   nb_ii16 = i;
4427}
4428
4429#if defined (HAS_ALTIVEC)
4430static void build_viargs_table (void)
4431{
4432#if !defined (ALTIVEC_ARGS_LARGE)
4433   unsigned int i=2;
4434   viargs = memalign16(i * sizeof(vector unsigned int));
4435   viargs[0] = (vector unsigned int) { 0x01020304,0x05060708,0x090A0B0C,0x0E0D0E0F };
4436   AB_DPRINTF_VEC32x4( viargs[0] );
4437   viargs[1] = (vector unsigned int) { 0xF1F2F3F4,0xF5F6F7F8,0xF9FAFBFC,0xFEFDFEFF };
4438   AB_DPRINTF_VEC32x4( viargs[1] );
4439#else
4440   unsigned int i,j;
4441   // build from iargs table (large/default already set)
4442   viargs = malloc(nb_iargs * sizeof(vector unsigned int));
4443   for (i=0; i<nb_iargs; i++) {
4444      j = iargs[i];
4445      viargs[i] = (vector unsigned int){ j, j*2, j*3, j*4 };
4446      AB_DPRINTF_VEC32x4( viargs[i] );
4447   }
4448#endif
4449
4450   AB_DPRINTF("Registered %d viargs values\n", i);
4451   nb_viargs = i;
4452}
4453
4454static inline void register_vfarg (vector float* vfarg,
4455                                  int s, uint8_t _exp, uint32_t mant)
4456{
4457   uint32_t tmp;
4458   vector uint32_t* vfargI = (vector uint32_t*)vfarg;
4459
4460   tmp = ((uint64_t)s << 31) | ((uint64_t)_exp << 23) | mant;
4461   *vfargI = (vector uint32_t){ tmp,tmp,tmp,tmp };
4462   AB_DPRINTF("%d %02x %06x => %08x %0e\n",
4463              s, _exp, mant, *((uint32_t*)&tmp), *(float*)&tmp);
4464}
4465
4466static void build_vfargs_table (void)
4467{
4468   /* Sign goes from zero to one
4469    * Exponent goes from 0 to ((1 << 9) - 1)
4470    * Mantissa goes from 1 to ((1 << 24) - 1)
4471    * + special values:
4472    * +0.0      : 0 0x00 0x000000            => 0x00000000
4473    * -0.0      : 1 0x00 0x000000            => 0x80000000
4474    * +infinity : 0 0xFF 0x000000            => 0x7F800000
4475    * -infinity : 1 0xFF 0x000000            => 0xFF800000
4476    * +SNaN     : 0 0xFF 0x7FFFFF (non-zero) => 0x7FFFFFFF
4477    * -SNaN     : 1 0xFF 0x7FFFFF (non-zero) => 0xFFFFFFFF
4478    * +QNaN     : 0 0xFF 0x3FFFFF (non-zero) => 0x7FBFFFFF
4479    * -QNaN     : 1 0xFF 0x3FFFFF (non-zero) => 0xFFBFFFFF
4480    * (8 values)
4481    */
4482   uint32_t mant;
4483   uint16_t _exp;
4484   int s;
4485   int i=0;
4486
4487
4488#if !defined (ALTIVEC_ARGS_LARGE)
4489   nb_vfargs = 12;
4490   vfargs = memalign16(nb_vfargs * sizeof(vector float));
4491
4492   // 4 values:
4493   for (s=0; s<2; s++) {
4494      for (_exp=0x5; ; _exp += 0x9D ) {
4495         if (_exp > 0xDF)
4496            break;
4497         for (mant = 0x3FFFFF; mant < 0x7FFFFF;
4498              mant = /* random */ ((mant + 0x1A6) << 31) + 0x159) {
4499            register_vfarg(&vfargs[i++], s, (uint8_t)_exp, mant);
4500         }
4501      }
4502   }
4503#else
4504   nb_vfargs = 50;
4505   vfargs = memalign16(nb_vfargs * sizeof(vector float));
4506
4507   for (s=0; s<2; s++) {
4508      for (_exp=0x0; ; _exp += 0x3F ) {
4509         //      for (_exp=0; ; _exp = ((_exp + 1) << 1) + 3) {
4510         if (_exp >= 0xFE)
4511            _exp = 0xFE;
4512         for (mant = 0x0; mant < 0x7FFFFF;
4513              mant = /* random */ ((mant + 0x4A6) << 5) + 0x359) {
4514            register_vfarg(&vfargs[i++], s, (uint8_t)_exp, mant);
4515         }
4516         if (_exp >= 0xFE)
4517            break;
4518      }
4519   }
4520#endif
4521
4522   /* Special values */
4523   /* +0.0      : 0 0x00 0x000000 */
4524   s = 0;
4525   _exp = 0x00;
4526   mant = 0x000000;
4527   register_vfarg(&vfargs[i++], s, _exp, mant);
4528   /* -0.0      : 1 0x00 0x000000 */
4529   s = 1;
4530   _exp = 0x00;
4531   mant = 0x000000;
4532   register_vfarg(&vfargs[i++], s, _exp, mant);
4533
4534   /* +infinity : 0 0xFF 0x000000  */
4535   s = 0;
4536   _exp = 0xFF;
4537   mant = 0x000000;
4538   register_vfarg(&vfargs[i++], s, _exp, mant);
4539   /* -infinity : 1 0xFF 0x000000 */
4540   s = 1;
4541   _exp = 0xFF;
4542   mant = 0x000000;
4543   register_vfarg(&vfargs[i++], s, _exp, mant);
4544
4545   /* NaN: _exponent all 1s, non-zero fraction */
4546   /* SNaN is a NaN with the most significant fraction bit clear.*/
4547   /* +SNaN     : 0 0xFF 0x7FFFFF */
4548   s = 0;
4549   _exp = 0xFF;
4550   mant = 0x7FFFFF;
4551   register_vfarg(&vfargs[i++], s, _exp, mant);
4552   /* -SNaN     : 1 0xFF 0x7FFFFF */
4553   s = 1;
4554   _exp = 0xFF;
4555   mant = 0x7FFFFF;
4556   register_vfarg(&vfargs[i++], s, _exp, mant);
4557
4558   /* QNaN is a NaN with the most significant fraction bit set */
4559   /* +QNaN     : 0 0xFF 0x3F0000 */
4560   s = 0;
4561   _exp = 0xFF;
4562   mant = 0x3FFFFF;
4563   register_vfarg(&vfargs[i++], s, _exp, mant);
4564   /* -QNaN     : 1 0xFF 0x3F0000 */
4565   s = 1;
4566   _exp = 0xFF;
4567   mant = 0x3FFFFF;
4568   register_vfarg(&vfargs[i++], s, _exp, mant);
4569   AB_DPRINTF("Registered %d vfargs values\n", i);
4570
4571   assert(i <= nb_vfargs);
4572   nb_vfargs = i;
4573}
4574#endif
4575
4576#if 0
4577static void dump_iargs (void)
4578{
4579   int i;
4580   for (i = 0; i < nb_iargs; i++) {
4581      printf("iarg %d: %08x %08x %08x\n", i, iargs[i],
4582             (unsigned int)&iargs[i], (unsigned int)iargs);
4583   }
4584}
4585
4586static void dump_iargs16 (void)
4587{
4588   int i;
4589   for (i = 0; i < nb_ii16; i++) {
4590      printf("iarg16 %d: %08x %08x %08x\n", i, ii16[i],
4591             (unsigned int)&ii16[i], (unsigned int)ii16);
4592   }
4593}
4594
4595static void dump_vfargs (void)
4596{
4597   vector float vf;
4598   float f;
4599   int i=0;
4600   for (i=0; i<nb_vfargs; i++) {
4601      vf = (vector float)vfargs[i];
4602      f  = ((float*)&vf)[0];
4603      printf("vfarg %3d: %24f : %08x\n", i, f, ((unsigned int*)&f)[0]);
4604   }
4605}
4606#endif
4607
4608static void test_int_three_args (const char* name, test_func_t func,
4609                                 unused uint32_t test_flags)
4610{
4611   volatile HWord_t res;
4612   volatile uint32_t flags, xer;
4613   int i, j, k;
4614
4615   for (i=0; i<nb_iargs; i++) {
4616      for (j=0; j<nb_iargs; j++) {
4617         for (k=0; k<nb_iargs; k++) {
4618            r14 = iargs[i];
4619            r15 = iargs[j];
4620            r16 = iargs[k];
4621
4622	    SET_CR_XER_ZERO;
4623            (*func)();
4624	    GET_CR_XER(flags,xer);
4625            res = r17;
4626
4627#ifndef __powerpc64__
4628            printf("%s %08x, %08x, %08x => %08x (%08x %08x)\n",
4629#else
4630            printf("%s %016llx, %016llx, %016llx => %016llx (%08x %08x)\n",
4631#endif
4632                   name, iargs[i], iargs[j], iargs[k], res, flags, xer);
4633         }
4634         if (verbose) printf("\n");
4635      }
4636   }
4637}
4638
4639static void test_int_two_args (const char* name, test_func_t func,
4640                               uint32_t test_flags)
4641{
4642   volatile HWord_t res;
4643   volatile uint32_t flags, xer, xer_orig;
4644   int i, j, is_div;
4645#ifdef __powerpc64__
4646   int zap_hi32;
4647#endif
4648
4649   // catches div, divwu, divo, divwu, divwuo, and . variants
4650   is_div = strstr(name, "divw") != NULL;
4651
4652#ifdef __powerpc64__
4653   zap_hi32 = strstr(name, "mulhw") != NULL;
4654#endif
4655
4656   xer_orig = 0x00000000;
4657 redo:
4658   for (i=0; i<nb_iargs; i++) {
4659      for (j=0; j<nb_iargs; j++) {
4660
4661         /* result of division by zero is implementation dependent.
4662            don't test it. */
4663         if (is_div && iargs[j] == 0)
4664            continue;
4665
4666         r14 = iargs[i];
4667         r15 = iargs[j];
4668
4669         SET_XER(xer_orig);
4670         SET_CR_ZERO;
4671         (*func)();
4672         GET_CR_XER(flags,xer);
4673         res = r17;
4674
4675#ifndef __powerpc64__
4676         printf("%s %08x, %08x => %08x (%08x %08x)\n",
4677#else
4678         if (zap_hi32) res &= 0xFFFFFFFFULL;
4679         printf("%s %016llx, %016llx => %016llx (%08x %08x)\n",
4680#endif
4681                name, iargs[i], iargs[j], res, flags, xer);
4682      }
4683      if (verbose) printf("\n");
4684   }
4685   if ((test_flags & PPC_XER_CA) && xer_orig == 0x00000000) {
4686      xer_orig = 0x20000000;
4687      goto redo;
4688   }
4689}
4690
4691static void test_int_one_arg (const char* name, test_func_t func,
4692                               uint32_t test_flags)
4693{
4694   volatile HWord_t res;
4695   volatile uint32_t flags, xer, xer_orig;
4696   int i;
4697
4698   xer_orig = 0x00000000;
4699 redo:
4700   for (i=0; i<nb_iargs; i++) {
4701      r14 = iargs[i];
4702      SET_XER(xer_orig);
4703      SET_CR_ZERO;
4704      (*func)();
4705      res = r17;
4706      GET_CR_XER(flags,xer);
4707
4708#ifndef __powerpc64__
4709      printf("%s %08x => %08x (%08x %08x)\n",
4710#else
4711      printf("%s %016llx => %016llx (%08x %08x)\n",
4712#endif
4713             name, iargs[i], res, flags, xer);
4714   }
4715   if ((test_flags & PPC_XER_CA) && xer_orig == 0x00000000) {
4716      xer_orig = 0x20000000;
4717      goto redo;
4718   }
4719}
4720
4721static inline void invalidate_icache ( void *ptr, int nbytes )
4722{
4723   HWord_t startaddr = (HWord_t) ptr;
4724   HWord_t endaddr   = startaddr + nbytes;
4725   HWord_t cls       = 32; /*VG_(cache_line_size_ppc32);*/
4726   HWord_t addr;
4727
4728   startaddr &= ~(cls - 1);
4729   for (addr = startaddr; addr < endaddr; addr += cls)
4730      asm volatile("dcbst 0,%0" : : "r" (addr));
4731   asm volatile("sync");
4732   for (addr = startaddr; addr < endaddr; addr += cls)
4733      asm volatile("icbi 0,%0" : : "r" (addr));
4734   asm volatile("sync; isync");
4735}
4736
4737/* for god knows what reason, if this isn't inlined, the
4738   program segfaults. */
4739static inline
4740void _patch_op_imm (uint32_t *p_insn, uint16_t imm, int sh, int len)
4741{
4742   uint32_t mask = ((1 << len) - 1) << sh;
4743   *p_insn = (*p_insn & ~mask) | ((imm<<sh) & mask);
4744}
4745
4746static inline
4747void patch_op_imm (uint32_t* p_insn, uint16_t imm, int sh, int len)
4748{
4749   _patch_op_imm(p_insn, imm, sh, len);
4750   invalidate_icache(p_insn, 4);
4751}
4752
4753static inline
4754void patch_op_imm16 (uint32_t *p_insn, uint16_t imm)
4755{
4756   patch_op_imm(p_insn, imm, 0, 16);
4757}
4758
4759
4760/* Copy the 2 insn function starting at p_func_F to func_buf[], and
4761   return a possibly different pointer, which, when called, runs the
4762   copy in func_buf[]. */
4763static inline
4764test_func_t init_function( test_func_t p_func_F, uint32_t func_buf[] )
4765{
4766   uint32_t* p_func = (uint32_t*)p_func_F;
4767#ifndef __powerpc64__
4768   func_buf[0] = p_func[0];
4769   func_buf[1] = p_func[1];
4770   return (test_func_t)&func_buf[0];
4771#else
4772   /* p_func points to a function descriptor, the first word of which
4773      points to the real code.  Copy the code itself but not the
4774      descriptor, and just swizzle the descriptor's entry pointer. */
4775   uint64_t* descr = (uint64_t*)p_func;
4776   uint32_t* entry = (uint32_t*)(descr[0]);
4777   func_buf[0] = entry[0];
4778   func_buf[1] = entry[1];
4779   descr[0] = (uint64_t)&func_buf[0];
4780   return (test_func_t)descr;
4781#endif // #ifndef __powerpc64__
4782}
4783
4784
4785static void test_int_one_reg_imm16 (const char* name,
4786                                    test_func_t func_IN,
4787                                    unused uint32_t test_flags)
4788{
4789   volatile test_func_t func;
4790   uint32_t* func_buf = get_rwx_area();
4791   volatile HWord_t res;
4792   volatile uint32_t flags, xer;
4793   int i, j;
4794
4795   for (i=0; i<nb_iargs; i++) {
4796      for (j=0; j<nb_ii16; j++) {
4797         /* Patch up the instruction */
4798         func = init_function( func_IN, func_buf );
4799         patch_op_imm16(&func_buf[0], ii16[j]);
4800
4801         r14 = iargs[i];
4802
4803         SET_CR_XER_ZERO;
4804         (*func)();
4805         GET_CR_XER(flags,xer);
4806         res = r17;
4807
4808#ifndef __powerpc64__
4809         printf("%s %08x, %08x => %08x (%08x %08x)\n",
4810#else
4811         printf("%s %016llx, %08x => %016llx (%08x %08x)\n",
4812#endif
4813                name, iargs[i], ii16[j], res, flags, xer);
4814      }
4815      if (verbose) printf("\n");
4816   }
4817}
4818
4819/* Special test cases for:
4820 * rlwimi
4821 * rlwinm
4822 * rlwnm
4823 * srawi
4824 * mcrf
4825 * mcrfs
4826 * mcrxr_cb
4827 * mfcr_cb
4828 * mfspr_cb
4829 * mftb_cb
4830 * mtcrf_cb
4831 * mtspr_cb
4832
4833 __powerpc64__ only:
4834 * rldcl       rA,rS,SH,MB
4835 * rldcr       rA,rS,SH,ME
4836 * rldic       rA,rS,SH,MB
4837 * rldicl      rA,rS,SH,MB
4838 * rldicr      rA,rS,SH,ME
4839 * rldimi      rA,rS,SH,MB
4840 * sradi       rA,rS,SH
4841 */
4842
4843static void rlwi_cb (const char* name, test_func_t func_IN,
4844                     unused uint32_t test_flags)
4845{
4846   volatile test_func_t func;
4847   uint32_t* func_buf = get_rwx_area();
4848   volatile HWord_t res;
4849   volatile uint32_t flags, xer;
4850   int i, j, k, l, arg_step;
4851
4852   arg_step = (arg_list_size == 0) ? 31 : 3;
4853
4854   r17 = 0;  // rlwimi takes r17 as input: start with a clean slate.
4855
4856   for (i=0; i<nb_iargs; i++) {
4857      for (j=0; j<32; j+=arg_step) {
4858         for (k=0; k<32; k+=arg_step) {
4859            for (l=0; l<32; l+=arg_step) {
4860               /* Patch up the instruction */
4861               func = init_function( func_IN, func_buf );
4862               _patch_op_imm(&func_buf[0], j, 11, 5);
4863               _patch_op_imm(&func_buf[0], k, 6, 5);
4864               patch_op_imm(&func_buf[0], l, 1, 5);
4865
4866               r14 = iargs[i];
4867
4868               SET_CR_XER_ZERO;
4869               (*func)();
4870               GET_CR_XER(flags,xer);
4871               res = r17;
4872
4873#ifndef __powerpc64__
4874               printf("%s %08x, %2d, %2d, %2d => %08x (%08x %08x)\n",
4875#else
4876               printf("%s %016llx, %2d, %2d, %2d => %016llx (%08x %08x)\n",
4877#endif
4878                      name, iargs[i], j, k, l, res, flags, xer);
4879            }
4880            if (verbose) printf("\n");
4881         }
4882      }
4883   }
4884}
4885
4886static void rlwnm_cb (const char* name, test_func_t func_IN,
4887                      unused uint32_t test_flags)
4888{
4889   volatile test_func_t func;
4890   uint32_t* func_buf = get_rwx_area();
4891   volatile HWord_t res;
4892   volatile uint32_t flags, xer;
4893   int i, j, k, l, arg_step;
4894
4895   arg_step = (arg_list_size == 0) ? 31 : 3;
4896
4897   for (i=0; i<nb_iargs; i++) {
4898      for (j=0; j<nb_iargs; j++) {
4899         for (k=0; k<32; k+=arg_step) {
4900            for (l=0; l<32; l+=arg_step) {
4901               /* Patch up the instruction */
4902               func = init_function( func_IN, func_buf );
4903               _patch_op_imm(&func_buf[0], k, 6, 5);
4904               patch_op_imm(&func_buf[0], l, 1, 5);
4905
4906               r14 = iargs[i];
4907               r15 = iargs[j];
4908
4909               SET_CR_XER_ZERO;
4910               (*func)();
4911               GET_CR_XER(flags,xer);
4912               res = r17;
4913
4914#ifndef __powerpc64__
4915               printf("%s %08x, %08x, %2d, %2d => %08x (%08x %08x)\n",
4916#else
4917               printf("%s %016llx, %016llx, %2d, %2d => %016llx (%08x %08x)\n",
4918#endif
4919                      name, iargs[i], iargs[j], k, l, res, flags, xer);
4920            }
4921            if (verbose) printf("\n");
4922         }
4923      }
4924   }
4925}
4926
4927static void srawi_cb (const char* name, test_func_t func_IN,
4928                      unused uint32_t test_flags)
4929{
4930   volatile test_func_t func;
4931   uint32_t* func_buf = get_rwx_area();
4932   volatile HWord_t res;
4933   volatile uint32_t flags, xer;
4934   int i, j, arg_step;
4935
4936   arg_step = (arg_list_size == 0) ? 31 : 1;
4937
4938   for (i=0; i<nb_iargs; i++) {
4939      for (j=0; j<32; j+=arg_step) {
4940         /* Patch up the instruction */
4941         func = init_function( func_IN, func_buf );
4942         patch_op_imm(&func_buf[0], j, 11, 5);
4943
4944         r14 = iargs[i];
4945
4946         SET_CR_XER_ZERO;
4947         (*func)();
4948         GET_CR_XER(flags,xer);
4949         res = r17;
4950
4951#ifndef __powerpc64__
4952         printf("%s %08x, %2d => %08x (%08x %08x)\n",
4953#else
4954         printf("%s %016llx, %2d => %016llx (%08x %08x)\n",
4955#endif
4956                name, iargs[i], j, res, flags, xer);
4957      }
4958      if (verbose) printf("\n");
4959   }
4960}
4961
4962static void mcrf_cb (const char* name, test_func_t func_IN,
4963                      unused uint32_t test_flags)
4964{
4965   volatile test_func_t func;
4966   uint32_t* func_buf = get_rwx_area();
4967   volatile uint32_t flags, xer;
4968   int i, j, k, arg_step;
4969
4970   arg_step = (arg_list_size == 0) ? 7 : 1;
4971
4972   for (i=0; i<nb_iargs; i++) {
4973      for (j=0; j<8; j+=arg_step) {
4974         for (k=0; k<8; k+=arg_step) {
4975            /* Patch up the instruction */
4976            func = init_function( func_IN, func_buf );
4977            _patch_op_imm(&func_buf[0], j, 23, 3);
4978            patch_op_imm(&func_buf[0], k, 18, 3);
4979
4980            r14 = iargs[i];
4981
4982            SET_CR(r14);
4983            SET_XER_ZERO;
4984            (*func)();
4985            GET_CR_XER(flags,xer);
4986
4987#ifndef __powerpc64__
4988            printf("%s %d, %d (%08x) => (%08x %08x)\n",
4989#else
4990            printf("%s %d, %d (%016llx) => (%08x %08x)\n",
4991#endif
4992                   name, j, k, iargs[i], flags, xer);
4993         }
4994         if (verbose) printf("\n");
4995      }
4996   }
4997}
4998
4999static void mcrxr_cb (const char* name, test_func_t func_IN,
5000                      unused uint32_t test_flags)
5001{
5002   volatile test_func_t func;
5003   uint32_t* func_buf = get_rwx_area();
5004   volatile uint32_t flags, xer;
5005   int i, j, k, arg_step;
5006
5007   arg_step = 1; //(arg_list_size == 0) ? 7 : 1;
5008
5009   for (i=0; i<16; i+=arg_step) {
5010      j = i << 28;
5011      for (k=0; k<8; k+=arg_step) {
5012         /* Patch up the instruction */
5013         func = init_function( func_IN, func_buf );
5014         patch_op_imm(&func_buf[0], k, 23, 3);
5015
5016         r14 = j;
5017
5018	 SET_CR_ZERO;
5019	 SET_XER(r14);
5020         (*func)();
5021         GET_CR_XER(flags,xer);
5022
5023         printf("%s %d (%08x) => (%08x %08x)\n",
5024                name, k, j, flags, xer);
5025      }
5026      if (verbose) printf("\n");
5027   }
5028}
5029
5030static void mfcr_cb (const char* name, test_func_t func,
5031                     unused uint32_t test_flags)
5032{
5033   volatile HWord_t res;
5034   volatile uint32_t flags, xer;
5035   int i;
5036
5037   for (i=0; i<nb_iargs; i++) {
5038      r14 = iargs[i];
5039
5040      /* Set up flags for test */
5041      SET_CR(r14);
5042      SET_XER_ZERO;
5043      (*func)();
5044      GET_CR_XER(flags,xer);
5045      res = r17;
5046
5047#ifndef __powerpc64__
5048      printf("%s (%08x) => %08x (%08x %08x)\n",
5049#else
5050      printf("%s (%016llx) => %016llx (%08x %08x)\n",
5051#endif
5052             name, iargs[i], res, flags, xer);
5053   }
5054}
5055
5056// NOTE: Not using func: calling function kills lr
5057static void mfspr_cb (const char* name, test_func_t func,
5058                      unused uint32_t test_flags)
5059{
5060   //volatile uint32_t res, flags, xer, ctr, lr, tmpcr, tmpxer;
5061   volatile HWord_t res;
5062   int j, k;
5063   func = func; // just to stop compiler complaining
5064
5065   // mtxer followed by mfxer
5066   for (k=0; k<nb_iargs; k++) {
5067      j = iargs[k];
5068      __asm__ __volatile__(
5069         "mtxer %1\n"
5070         "\tmfxer %0"
5071         : /*out*/"=b"(res) : /*in*/"b"(j) : /*trashed*/"xer"
5072      );
5073      res &= 0xE000007F; /* rest of the bits are undefined */
5074
5075#ifndef __powerpc64__
5076      printf("%s 1 (%08x) -> mtxer -> mfxer => %08x\n",
5077#else
5078      printf("%s 1 (%08x) -> mtxer -> mfxer => %016llx\n",
5079#endif
5080             name, j, res);
5081   }
5082
5083   // mtlr followed by mflr
5084   for (k=0; k<nb_iargs; k++) {
5085      j = iargs[k];
5086      __asm__ __volatile__(
5087         "mtlr %1\n"
5088         "\tmflr %0"
5089         : /*out*/"=b"(res) : /*in*/"b"(j) : /*trashed*/"lr"
5090      );
5091
5092#ifndef __powerpc64__
5093      printf("%s 8 (%08x) ->  mtlr ->  mflr => %08x\n",
5094#else
5095      printf("%s 8 (%08x) ->  mtlr ->  mflr => %016llx\n",
5096#endif
5097             name, j, res);
5098   }
5099
5100   // mtctr followed by mfctr
5101   for (k=0; k<nb_iargs; k++) {
5102      j = iargs[k];
5103      __asm__ __volatile__(
5104         "mtctr %1\n"
5105         "\tmfctr %0"
5106         : /*out*/"=b"(res) : /*in*/"b"(j) : /*trashed*/"ctr"
5107      );
5108
5109#ifndef __powerpc64__
5110      printf("%s 9 (%08x) -> mtctr -> mfctr => %08x\n",
5111#else
5112      printf("%s 9 (%08x) -> mtctr -> mfctr => %016llx\n",
5113#endif
5114             name, j, res);
5115   }
5116}
5117
5118static void mtcrf_cb (const char* name, test_func_t func_IN,
5119                      unused uint32_t test_flags)
5120{
5121   volatile test_func_t func;
5122   uint32_t* func_buf = get_rwx_area();
5123   volatile uint32_t flags, xer;
5124   int i, j, arg_step;
5125
5126   arg_step = (arg_list_size == 0) ? 99 : 1;
5127
5128   for (i=0; i<nb_iargs; i++) {
5129      for (j=0; j<256; j+=arg_step) {
5130         /* Patch up the instruction */
5131         func = init_function( func_IN, func_buf );
5132         patch_op_imm(&func_buf[0], j, 12, 8);
5133
5134         r14 = iargs[i];
5135
5136         SET_CR_XER_ZERO;
5137         (*func)();
5138         GET_CR_XER(flags,xer);
5139
5140#ifndef __powerpc64__
5141         printf("%s %3d, %08x => (%08x %08x)\n",
5142#else
5143         printf("%s %3d, %016llx => (%08x %08x)\n",
5144#endif
5145                name, j, iargs[i], flags, xer);
5146      }
5147      if (verbose) printf("\n");
5148   }
5149}
5150
5151// NOTE: Not using func: calling function kills lr
5152static void mtspr_cb (const char* name, test_func_t func,
5153                      unused uint32_t test_flags)
5154{
5155}
5156
5157#ifdef __powerpc64__
5158static void rldc_cb (const char* name, test_func_t func_IN,
5159                     unused uint32_t test_flags)
5160{
5161   volatile test_func_t func;
5162   uint32_t* func_buf = get_rwx_area();
5163   volatile HWord_t res;
5164   volatile uint32_t flags, xer;
5165   int i, j, k, arg_step;
5166
5167   arg_step = (arg_list_size == 0) ? 7 : 3;
5168
5169   for (i=0; i<nb_iargs; i++) {
5170      for (j=0; j<nb_iargs; j++) {
5171         for (k=0; k<64; k+=arg_step) {
5172            /* Patch up the instruction */
5173            func = init_function( func_IN, func_buf );
5174            patch_op_imm(&func_buf[0], (((k & 0x1F)<<1) | ((k>>5)&1)), 5, 6);
5175
5176            r14 = iargs[i];
5177            r15 = iargs[j];
5178
5179            SET_CR_XER_ZERO;
5180            (*func)();
5181            GET_CR_XER(flags,xer);
5182            res = r17;
5183
5184            printf("%s %016llx, %016llx, %2d => %016llx (%08x %08x)\n",
5185                   name, iargs[i], iargs[j], k, res, flags, xer);
5186         }
5187         if (verbose) printf("\n");
5188      }
5189   }
5190}
5191
5192static void rldi_cb (const char* name, test_func_t func_IN,
5193                     unused uint32_t test_flags)
5194{
5195   volatile test_func_t func;
5196   uint32_t* func_buf = get_rwx_area();
5197   volatile HWord_t res;
5198   volatile uint32_t flags, xer;
5199   int i, j, k, arg_step;
5200
5201   arg_step = (arg_list_size == 0) ? 7 : 3;
5202
5203   for (i=0; i<nb_iargs; i++) {
5204      for (j=0; j<64; j+=arg_step) {     // SH
5205         for (k=0; k<64; k+=arg_step) {  // MB|ME
5206            /* Patch up the instruction */
5207            func = init_function( func_IN, func_buf );
5208            _patch_op_imm(&func_buf[0], (j & 0x1F), 11, 5);
5209            _patch_op_imm(&func_buf[0], ((j>>5)&1), 1, 1);
5210            patch_op_imm(&func_buf[0], (((k & 0x1F)<<1) | ((k>>5)&1)), 5, 6);
5211
5212            r14 = iargs[i];
5213
5214            SET_CR_XER_ZERO;
5215            (*func)();
5216            GET_CR_XER(flags,xer);
5217            res = r17;
5218
5219            printf("%s %016llx, %2d, %2d => %016llx (%08x %08x)\n",
5220                   name, iargs[i], j, k, res, flags, xer);
5221         }
5222         if (verbose) printf("\n");
5223      }
5224   }
5225}
5226
5227static void sradi_cb (const char* name, test_func_t func_IN,
5228                      unused uint32_t test_flags)
5229{
5230   volatile test_func_t func;
5231   uint32_t* func_buf = get_rwx_area();
5232   volatile HWord_t res;
5233   volatile uint32_t flags, xer;
5234   int i, j, arg_step;
5235
5236   arg_step = (arg_list_size == 0) ? 7 : 3;
5237
5238   for (i=0; i<nb_iargs; i++) {
5239      for (j=0; j<64; j+=arg_step) {     // SH
5240         /* Patch up the instruction */
5241         func = init_function( func_IN, func_buf );
5242         _patch_op_imm(&func_buf[0], (j & 0x1F), 11, 5);
5243         patch_op_imm(&func_buf[0], ((j>>5)&1), 1, 1);
5244
5245         r14 = iargs[i];
5246
5247         SET_CR_XER_ZERO;
5248         (*func)();
5249         GET_CR_XER(flags,xer);
5250         res = r17;
5251
5252         printf("%s %016llx, %2d => %016llx (%08x %08x)\n",
5253                name, iargs[i], j, res, flags, xer);
5254      }
5255      if (verbose) printf("\n");
5256   }
5257}
5258#endif // #ifdef __powerpc64__
5259
5260
5261typedef struct special_t special_t;
5262
5263struct special_t {
5264   const char *name;
5265   void (*test_cb)(const char* name, test_func_t func,
5266                   unused uint32_t test_flags);
5267};
5268
5269static void test_special (special_t *table,
5270                          const char* name, test_func_t func,
5271                          unused uint32_t test_flags)
5272{
5273   const char *tmp;
5274   int i;
5275
5276   for (tmp = name; isspace(*tmp); tmp++)
5277      continue;
5278   for (i=0; table[i].name != NULL; i++) {
5279#if 0
5280      fprintf(stderr, "look for handler for '%s' (%s)\n", name,
5281              table[i].name);
5282#endif
5283      if (strcmp(table[i].name, tmp) == 0) {
5284         (*table[i].test_cb)(name, func, test_flags);
5285         return;
5286      }
5287   }
5288   fprintf(stderr, "ERROR: no test found for op '%s'\n", name);
5289}
5290
5291static special_t special_int_ops[] = {
5292   {
5293      "rlwimi", /* One register + 3 5 bits immediate arguments */
5294      &rlwi_cb,
5295   },
5296   {
5297      "rlwimi.", /* One register + 3 5 bits immediate arguments */
5298      &rlwi_cb,
5299   },
5300   {
5301      "rlwinm", /* One register + 3 5 bits immediate arguments */
5302      &rlwi_cb,
5303   },
5304   {
5305      "rlwinm.", /* One register + 3 5 bits immediate arguments */
5306      &rlwi_cb,
5307   },
5308   {
5309      "rlwnm",  /* Two registers + 2 5 bits immediate arguments */
5310      &rlwnm_cb,
5311   },
5312   {
5313      "rlwnm.",  /* Two registers + 2 5 bits immediate arguments */
5314      &rlwnm_cb,
5315   },
5316   {
5317      "srawi",  /* One register + 1 5 bits immediate arguments */
5318      &srawi_cb,
5319   },
5320   {
5321      "srawi.",  /* One register + 1 5 bits immediate arguments */
5322      &srawi_cb,
5323   },
5324   {
5325      "mcrf",  /* 2 3 bits immediate arguments */
5326      &mcrf_cb,
5327   },
5328#if 0
5329   {
5330      "mcrfs",  /* 2 3 bits immediate arguments */
5331      &mcrfs_cb,
5332   },
5333#endif
5334   {
5335      "mcrxr",  /* 1 3 bits immediate argument */
5336      &mcrxr_cb,
5337   },
5338   {
5339      "mfcr",  /* No arguments */
5340      &mfcr_cb,
5341   },
5342   {
5343      "mfspr",  /* 1 10 bits immediate argument */
5344      &mfspr_cb,
5345   },
5346#if 0
5347   {   // Move from time base
5348      "mftb",  /* 1 10 bits immediate arguments */
5349      &mftb_cb,
5350   },
5351#endif
5352   {
5353      "mtcrf",  /* One register + 1 8 bits immediate arguments */
5354      &mtcrf_cb,
5355   },
5356   {
5357      "mtspr",  /* One register + 1 10 bits immediate arguments */
5358      &mtspr_cb,
5359   },
5360#ifdef __powerpc64__
5361   {
5362      "rldcl",   /* Two registers + 1 6 bit immediate argument */
5363      &rldc_cb,
5364   },
5365   {
5366      "rldcl.",  /* Two registers + 1 6 bit immediate argument */
5367      &rldc_cb,
5368   },
5369   {
5370      "rldcr",   /* Two registers + 1 6 bit immediate argument */
5371      &rldc_cb,
5372   },
5373   {
5374      "rldcr.",  /* Two registers + 1 6 bit immediate argument */
5375      &rldc_cb,
5376   },
5377   {
5378      "rldic",   /* One register + 2 6 bit immediate arguments */
5379      &rldi_cb,
5380   },
5381   {
5382      "rldic.",  /* One register + 2 6 bit immediate arguments */
5383      &rldi_cb,
5384   },
5385   {
5386      "rldicl",  /* One register + 2 6 bit immediate arguments */
5387      &rldi_cb,
5388   },
5389   {
5390      "rldicl.", /* One register + 2 6 bit immediate arguments */
5391      &rldi_cb,
5392   },
5393   {
5394      "rldicr",  /* One register + 2 6 bit immediate arguments */
5395      &rldi_cb,
5396   },
5397   {
5398      "rldicr.", /* One register + 2 6 bit immediate arguments */
5399      &rldi_cb,
5400   },
5401   {
5402      "rldimi",  /* One register + 2 6 bit immediate arguments */
5403      &rldi_cb,
5404   },
5405   {
5406      "rldimi.", /* One register + 2 6 bit immediate arguments */
5407      &rldi_cb,
5408   },
5409   {
5410      "sradi",  /* One register + 1 6 bit immediate argument */
5411      &sradi_cb,
5412   },
5413   {
5414      "sradi.", /* One register + 1 6 bit immediate argument */
5415      &sradi_cb,
5416   },
5417#endif // #ifdef __powerpc64__
5418   {
5419      NULL,
5420      NULL,
5421   },
5422};
5423
5424static void test_int_special (const char* name, test_func_t func,
5425                              uint32_t test_flags)
5426{
5427   test_special(special_int_ops, name, func, test_flags);
5428}
5429
5430
5431static void test_int_ld_one_reg_imm16 (const char* name,
5432                                       test_func_t func_IN,
5433                                       unused uint32_t test_flags)
5434{
5435   volatile test_func_t func;
5436   uint32_t* func_buf = get_rwx_area();
5437   volatile HWord_t res, base;
5438   volatile uint32_t flags, xer;
5439   int i, offs, is_lwa=0;
5440
5441#ifdef __powerpc64__
5442   is_lwa = strstr(name, "lwa") != NULL;
5443#endif
5444
5445   // +ve d
5446   base = (HWord_t)&iargs[0];
5447   for (i=0; i<nb_iargs; i++) {
5448      offs = i * sizeof(HWord_t);
5449
5450      /* Patch up the instruction */
5451      func = init_function( func_IN, func_buf );
5452      if (is_lwa)
5453         patch_op_imm(&func_buf[0], offs>>2, 2, 14);
5454      else
5455         patch_op_imm16(&func_buf[0], offs);
5456
5457      r14 = base;
5458
5459      SET_CR_XER_ZERO;
5460      (*func)();
5461      GET_CR_XER(flags,xer);
5462      res = r17;
5463
5464#ifndef __powerpc64__
5465      printf("%s %2d, (%08x) => %08x, %2d (%08x %08x)\n",
5466#else
5467      printf("%s %3d, (%016llx) => %016llx, %3lld (%08x %08x)\n",
5468#endif
5469             name, offs, iargs[i], res, r14-base, flags, xer);
5470   }
5471   if (verbose) printf("\n");
5472
5473   // -ve d
5474   base = (HWord_t)&iargs[nb_iargs-1];
5475   for (i = -nb_iargs+1; i<=0; i++) {
5476      offs = i * sizeof(HWord_t);
5477
5478      /* Patch up the instruction */
5479      func = init_function( func, func_buf );
5480      patch_op_imm16(&func_buf[0], offs);
5481
5482      r14 = base;
5483
5484      SET_CR_XER_ZERO;
5485      (*func)();
5486      GET_CR_XER(flags,xer);
5487      res = r17;
5488
5489#ifndef __powerpc64__
5490      printf("%s %2d, (%08x) => %08x, %2d (%08x %08x)\n",
5491#else
5492      printf("%s %3d, (%016llx) => %016llx, %3lld (%08x %08x)\n",
5493#endif
5494             name, offs, iargs[nb_iargs-1+i], res, r14-base, flags, xer);
5495   }
5496}
5497
5498static void test_int_ld_two_regs (const char* name,
5499                                  test_func_t func,
5500                                  unused uint32_t test_flags)
5501{
5502   volatile HWord_t res, base;
5503   volatile uint32_t flags, xer;
5504   int i, offs;
5505
5506   // +ve d
5507   base = (HWord_t)&iargs[0];
5508   for (i=0; i<nb_iargs; i++) {
5509      offs = i * sizeof(HWord_t);
5510      r14 = base;
5511      r15 = offs;
5512
5513      SET_CR_XER_ZERO;
5514      (*func)();
5515      GET_CR_XER(flags,xer);
5516      res = r17;
5517
5518#ifndef __powerpc64__
5519      printf("%s %d (%08x) => %08x, %d (%08x %08x)\n",
5520#else
5521      printf("%s %3d, (%016llx) => %016llx, %2lld (%08x %08x)\n",
5522#endif
5523             name, offs, iargs[i], res, r14-base, flags, xer);
5524   }
5525}
5526
5527static void test_int_st_two_regs_imm16 (const char* name,
5528                                        test_func_t func_IN,
5529                                        unused uint32_t test_flags)
5530{
5531   volatile test_func_t func;
5532   uint32_t* func_buf = get_rwx_area();
5533   volatile uint32_t flags, xer;
5534   int i, offs, k;
5535   HWord_t *iargs_priv, base;
5536
5537   // private iargs table to store to
5538   iargs_priv = malloc(nb_iargs * sizeof(HWord_t));
5539
5540   // +ve d
5541   base = (HWord_t)&iargs_priv[0];
5542   for (i=0; i<nb_iargs; i++) {
5543      for (k=0; k<nb_iargs; k++)  // clear array
5544         iargs_priv[k] = 0;
5545
5546      offs = i * sizeof(HWord_t);
5547
5548      /* Patch up the instruction */
5549      func = init_function( func_IN, func_buf );
5550      patch_op_imm16(&func_buf[0], offs);
5551
5552      r14 = iargs[i];             // read from iargs
5553      r15 = base;                 // store to r15 + offs
5554
5555      SET_CR_XER_ZERO;
5556      (*func)();
5557      GET_CR_XER(flags,xer);
5558
5559#ifndef __powerpc64__
5560      printf("%s %08x, %2d => %08x, %2d (%08x %08x)\n",
5561#else
5562      printf("%s %016llx, %3d => %016llx, %3lld (%08x %08x)\n",
5563#endif
5564             name, iargs[i], offs, iargs_priv[i], r15-base, flags, xer);
5565   }
5566   if (verbose) printf("\n");
5567
5568   // -ve d
5569   base = (HWord_t)&iargs_priv[nb_iargs-1];
5570   for (i = -nb_iargs+1; i<=0; i++) {
5571      for (k=0; k<nb_iargs; k++)  // clear array
5572         iargs_priv[k] = 0;
5573
5574      offs = i * sizeof(HWord_t);
5575
5576      /* Patch up the instruction */
5577      func = init_function( func, func_buf );
5578      patch_op_imm16(&func_buf[0], offs);
5579
5580      r14 = iargs[nb_iargs-1+i];  // read from iargs
5581      r15 = base;                 // store to r15 + offs
5582
5583      SET_CR_XER_ZERO;
5584      (*func)();
5585      GET_CR_XER(flags,xer);
5586
5587#ifndef __powerpc64__
5588      printf("%s %08x, %2d => %08x, %2d (%08x %08x)\n",
5589#else
5590      printf("%s %016llx, %3d => %016llx, %3lld (%08x %08x)\n",
5591#endif
5592             name, iargs[nb_iargs-1+i], offs, iargs_priv[nb_iargs-1+i],
5593             r15-base, flags, xer);
5594   }
5595   free(iargs_priv);
5596}
5597
5598static void test_int_st_three_regs (const char* name,
5599                                    test_func_t func,
5600                                    unused uint32_t test_flags)
5601{
5602   volatile uint32_t flags, xer;
5603   int i, offs, k;
5604   HWord_t *iargs_priv, base;
5605
5606   // private iargs table to store to
5607   iargs_priv = malloc(nb_iargs * sizeof(HWord_t));
5608
5609   base = (HWord_t)&iargs_priv[0];
5610   for (i=0; i<nb_iargs; i++) {
5611      for (k=0; k<nb_iargs; k++)  // clear array
5612         iargs_priv[k] = 0;
5613
5614      offs = i * sizeof(HWord_t);
5615      r14 = iargs[i];             // read from iargs
5616      r15 = base;                 // store to r15 + offs
5617      r16 = offs;
5618
5619      SET_CR_XER_ZERO;
5620      (*func)();
5621      GET_CR_XER(flags,xer);
5622
5623#ifndef __powerpc64__
5624      printf("%s %08x, %d => %08x, %d (%08x %08x)\n",
5625#else
5626      printf("%s %016llx, %3d => %016llx, %2lld (%08x %08x)\n",
5627#endif
5628             name, iargs[i], offs, iargs_priv[i], r15-base, flags, xer);
5629   }
5630   free(iargs_priv);
5631}
5632
5633
5634/* Used in do_tests, indexed by flags->nb_args
5635   Elements correspond to enum test_flags::num args
5636*/
5637static test_loop_t int_loops[] = {
5638   &test_int_one_arg,
5639   &test_int_two_args,
5640   &test_int_three_args,
5641   &test_int_two_args,
5642   &test_int_one_reg_imm16,
5643   &test_int_one_reg_imm16,
5644   &test_int_special,
5645   &test_int_ld_one_reg_imm16,
5646   &test_int_ld_two_regs,
5647   &test_int_st_two_regs_imm16,
5648   &test_int_st_three_regs,
5649};
5650
5651#if !defined (NO_FLOAT)
5652static void test_float_three_args (const char* name, test_func_t func,
5653                                   unused uint32_t test_flags)
5654{
5655   double res;
5656   uint64_t u0, u1, u2, ur;
5657   volatile uint32_t flags;
5658   int i, j, k;
5659
5660   /* Note: using nb_normal_fargs:
5661      - not testing special values for these insns
5662   */
5663
5664   for (i=0; i<nb_normal_fargs; i+=3) {
5665      for (j=0; j<nb_normal_fargs; j+=5) {
5666         for (k=0; k<nb_normal_fargs; k+=7) {
5667            u0 = *(uint64_t *)(&fargs[i]);
5668            u1 = *(uint64_t *)(&fargs[j]);
5669            u2 = *(uint64_t *)(&fargs[k]);
5670            f14 = fargs[i];
5671            f15 = fargs[j];
5672            f16 = fargs[k];
5673
5674            SET_FPSCR_ZERO;
5675            SET_CR_XER_ZERO;
5676            (*func)();
5677            GET_CR(flags);
5678            res = f17;
5679            ur = *(uint64_t *)(&res);
5680
5681            /* Note: zapping the bottom byte of the result,
5682               as vex's accuracy isn't perfect */
5683            ur &= 0xFFFFFFFFFFFFFF00ULL;
5684
5685#ifndef __powerpc64__
5686            printf("%s %016llx, %016llx, %016llx => %016llx",
5687#else
5688            printf("%s %016llx, %016llx, %016llx => %016llx",
5689#endif
5690                   name, u0, u1, u2, ur);
5691#if defined TEST_FLOAT_FLAGS
5692            printf(" (%08x)", flags);
5693#endif
5694            printf("\n");
5695         }
5696         if (verbose) printf("\n");
5697      }
5698   }
5699}
5700
5701static void test_float_two_args (const char* name, test_func_t func,
5702                                 unused uint32_t test_flags)
5703{
5704   double res;
5705   uint64_t u0, u1, ur;
5706   volatile uint32_t flags;
5707   int i, j;
5708
5709   for (i=0; i<nb_fargs; i+=3) {
5710      for (j=0; j<nb_fargs; j+=5) {
5711         u0 = *(uint64_t *)(&fargs[i]);
5712         u1 = *(uint64_t *)(&fargs[j]);
5713         f14 = fargs[i];
5714         f15 = fargs[j];
5715
5716         SET_FPSCR_ZERO;
5717         SET_CR_XER_ZERO;
5718         (*func)();
5719         GET_CR(flags);
5720         res = f17;
5721         ur = *(uint64_t *)(&res);
5722
5723#ifndef __powerpc64__
5724         printf("%s %016llx, %016llx => %016llx",
5725#else
5726         printf("%s %016llx, %016llx => %016llx",
5727#endif
5728                name, u0, u1, ur);
5729#if defined TEST_FLOAT_FLAGS
5730         printf(" (%08x)", flags);
5731#endif
5732         printf("\n");
5733      }
5734      if (verbose) printf("\n");
5735   }
5736}
5737
5738static void test_float_one_arg (const char* name, test_func_t func,
5739                                unused uint32_t test_flags)
5740{
5741   double res;
5742   uint64_t u0, ur;
5743   volatile uint32_t flags;
5744   int i;
5745   unsigned zap_hi_32bits, zap_lo_44bits, zap_lo_47bits;
5746
5747   /* if we're testing fctiw or fctiwz, zap the hi 32bits,
5748      as they're undefined */
5749   zap_hi_32bits = strstr(name, " fctiw")    != NULL  ? 1 : 0;
5750   zap_lo_44bits = strstr(name, " fres")     != NULL  ? 1 : 0;
5751   zap_lo_47bits = strstr(name, " frsqrte")  != NULL  ? 1 : 0;
5752
5753   assert(zap_hi_32bits + zap_lo_44bits + zap_lo_47bits <= 1);
5754
5755   for (i=0; i<nb_fargs; i++) {
5756      u0 = *(uint64_t *)(&fargs[i]);
5757      f14 = fargs[i];
5758
5759       SET_FPSCR_ZERO;
5760       SET_CR_XER_ZERO;
5761       (*func)();
5762       GET_CR(flags);
5763       res = f17;
5764       ur = *(uint64_t *)(&res);
5765
5766       if (strstr(name, " frsqrte") !=  NULL)
5767          /* The 32-bit frsqrte instruction is the Floatig Reciprical Square
5768           * Root Estimate instruction.  The precision of the estimate will
5769           * vary from Proceesor implementation.  The approximation varies in
5770           * bottom two bytes of the 32-bit result.
5771           */
5772           ur &= 0xFFFF000000000000ULL;
5773
5774      if (zap_hi_32bits)
5775         ur &= 0x00000000FFFFFFFFULL;
5776      if (zap_lo_44bits)
5777         ur &= 0xFFFFF00000000000ULL;
5778      if (zap_lo_47bits)
5779         ur &= 0xFFFF800000000000ULL;
5780
5781#ifndef __powerpc64__
5782      printf("%s %016llx => %016llx",
5783#else
5784      printf("%s %016llx => %016llx",
5785#endif
5786             name, u0, ur);
5787#if defined TEST_FLOAT_FLAGS
5788      printf(" (%08x)", flags);
5789#endif
5790      printf("\n");
5791    }
5792}
5793
5794/* Special test cases for:
5795 * mffs
5796 * mtfsb0
5797 * mtfsb1
5798 */
5799static special_t special_float_ops[] = {
5800#if 0
5801   {
5802      "mffs",   /* One 5 bits immediate argument */
5803      &mffs_cb,
5804   },
5805   {
5806      "mffs.",   /* One 5 bits immediate argument */
5807      &mffs_cb,
5808   },
5809   {
5810      "mtfsb0", /* One 5 bits immediate argument */
5811      &mffs_cb,
5812   },
5813   {
5814      "mtfsb0.", /* One 5 bits immediate argument */
5815      &mffs_cb,
5816   },
5817   {
5818      "mtfsb1", /* One 5 bits immediate argument */
5819      &mffs_cb,
5820   },
5821   {
5822      "mtfsb1.", /* One 5 bits immediate argument */
5823      &mffs_cb,
5824   },
5825   {
5826      "mtfsf",  /* One register + 1 8 bits immediate argument */
5827      &mtfsf_cb,
5828   },
5829   {
5830      "mtfsf.",  /* One register + 1 8 bits immediate argument */
5831      &mtfsf_cb,
5832   },
5833   {
5834      "mtfsfi", /* One 5 bits argument + 1 5 bits argument */
5835      &mtfsfi_cb,
5836   },
5837   {
5838      "mtfsfi.", /* One 5 bits argument + 1 5 bits argument */
5839      &mtfsfi_cb,
5840   },
5841#endif
5842   {
5843      NULL,
5844      NULL,
5845   },
5846};
5847
5848static void test_float_special (const char* name, test_func_t func,
5849                                uint32_t test_flags)
5850{
5851   test_special(special_float_ops, name, func, test_flags);
5852}
5853
5854
5855static void test_float_ld_one_reg_imm16 (const char* name,
5856                                         test_func_t func_IN,
5857                                         unused uint32_t test_flags)
5858{
5859   volatile test_func_t func;
5860   uint32_t* func_buf = get_rwx_area();
5861   uint32_t base;
5862   volatile uint32_t flags, xer;
5863   volatile double src, res;
5864   int i, offs;
5865
5866   /* offset within [1-nb_fargs:nb_fargs] */
5867   for (i=1-nb_fargs; i<nb_fargs; i++) {
5868      offs = i * 8;      // offset = i * sizeof(double)
5869      if (i < 0) {
5870         src  = fargs[nb_fargs-1 + i];
5871         base = (HWord_t)&fargs[nb_fargs-1];
5872      } else {
5873         src = fargs[i];
5874         base = (HWord_t)&fargs[0];
5875      }
5876
5877      /* Patch up the instruction */
5878      func = init_function( func_IN, func_buf );
5879      patch_op_imm16(&func_buf[0], offs);
5880
5881      // load from fargs[idx] => r14 + offs
5882      r14 = base;
5883
5884      SET_CR_XER_ZERO;
5885      (*func)();
5886      GET_CR_XER(flags,xer);
5887      res = f17;
5888
5889#ifndef __powerpc64__
5890      printf("%s %016llx, %4d => %016llx, %4d",
5891#else
5892      printf("%s %016llx, %4d => %016llx, %4lld",
5893#endif
5894             name, double_to_bits(src), offs,
5895             double_to_bits(res), r14-base);
5896#if defined TEST_FLOAT_FLAGS
5897      printf(" (%08x %08x)", flags, xer);
5898#endif
5899      printf("\n");
5900   }
5901   if (verbose) printf("\n");
5902}
5903
5904static void test_float_ld_two_regs (const char* name,
5905                                    test_func_t func,
5906                                    unused uint32_t test_flags)
5907{
5908   volatile HWord_t base;
5909   volatile uint32_t flags, xer;
5910   volatile double src, res;
5911   int i, offs;
5912
5913   /* offset within [1-nb_fargs:nb_fargs] */
5914   for (i=1-nb_fargs; i<nb_fargs; i++) {
5915      offs = i * 8;                // offset = i * sizeof(double)
5916      if (i < 0) {                 // base reg = start of array
5917         src  = fargs[nb_fargs-1 + i];
5918         base = (HWord_t)&fargs[nb_fargs-1];
5919      } else {
5920         src  = fargs[i];
5921         base = (HWord_t)&fargs[0];
5922      }
5923
5924      r14 = base;
5925      r15 = offs;
5926
5927      SET_CR_XER_ZERO;
5928      (*func)();
5929      GET_CR_XER(flags,xer);
5930      res = f17;
5931
5932#ifndef __powerpc64__
5933      printf("%s %016llx, %4d => %016llx, %4d",
5934#else
5935      printf("%s %016llx, %4lld => %016llx, %4lld",
5936#endif
5937             name, double_to_bits(src), r15/*offs*/,
5938             double_to_bits(res), r14-base);
5939#if defined TEST_FLOAT_FLAGS
5940      printf(" (%08x %08x)", flags, xer);
5941#endif
5942      printf("\n");
5943   }
5944}
5945
5946static void test_float_st_two_regs_imm16 (const char* name,
5947                                          test_func_t func_IN,
5948                                          unused uint32_t test_flags)
5949{
5950   volatile test_func_t func;
5951   uint32_t* func_buf = get_rwx_area();
5952   HWord_t base;
5953   volatile uint32_t flags, xer;
5954   double src, *p_dst;
5955   int i, offs;
5956   double *fargs_priv;
5957   int nb_tmp_fargs = nb_fargs;
5958
5959
5960   /* if we're storing an fp single-precision, don't want nans
5961      - the vex implementation doesn't like them (yet)
5962      Note: This is actually a bigger problem: the vex implementation
5963      rounds these insns twice.  This leads to many rounding errors.
5964      For the small fargs set, however, this doesn't show up.
5965   */
5966   if (strstr(name, "stfs") != NULL)
5967      nb_tmp_fargs = nb_normal_fargs;
5968
5969
5970   // private fargs table to store to
5971   fargs_priv = malloc(nb_tmp_fargs * sizeof(double));
5972
5973   /* offset within [1-nb_tmp_fargs:nb_tmp_fargs] */
5974   for (i=1-nb_tmp_fargs; i<nb_tmp_fargs; i++) {
5975      offs = i * 8;    // offset = i * sizeof(double)
5976      if (i < 0) {
5977         src   =  fargs     [nb_tmp_fargs-1 + i];
5978         p_dst = &fargs_priv[nb_tmp_fargs-1 + i];
5979         base  = (HWord_t)&fargs_priv[nb_tmp_fargs-1];
5980      } else {
5981         src   =  fargs     [i];
5982         p_dst = &fargs_priv[i];
5983         base  = (HWord_t)&fargs_priv[0];
5984      }
5985      *p_dst = 0;  // clear dst
5986
5987      /* Patch up the instruction */
5988      func = init_function( func_IN, func_buf );
5989      patch_op_imm16(&func_buf[0], offs);
5990
5991      // read from fargs[idx] => f14
5992      // store to fargs_priv[idx] => r15 + offs
5993      f14 = src;
5994      r15 = base;
5995
5996      SET_CR_XER_ZERO;
5997      (*func)();
5998      GET_CR_XER(flags,xer);
5999
6000#ifndef __powerpc64__
6001      printf("%s %016llx, %4d => %016llx, %4d",
6002#else
6003      printf("%s %016llx, %4d => %016llx, %4lld",
6004#endif
6005             name, double_to_bits(src), offs,
6006             double_to_bits(*p_dst), r15-base);
6007#if defined TEST_FLOAT_FLAGS
6008      printf(" (%08x %08x)", flags, xer);
6009#endif
6010      printf("\n");
6011   }
6012   free(fargs_priv);
6013}
6014
6015static void test_float_st_three_regs (const char* name,
6016                                      test_func_t func,
6017                                      unused uint32_t test_flags)
6018{
6019   volatile HWord_t base;
6020   volatile uint32_t flags, xer;
6021   double src, *p_dst;
6022   int i, offs;
6023   double *fargs_priv;
6024   int nb_tmp_fargs = nb_fargs;
6025
6026
6027   /* if we're storing an fp single-precision, don't want nans
6028      - the vex implementation doesn't like them (yet)
6029      Note: This is actually a bigger problem: the vex implementation
6030      rounds these insns twice.  This leads to many rounding errors.
6031      For the small fargs set, however, this doesn't show up.
6032   */
6033   if (strstr(name, "stfs") != NULL)  // stfs(u)(x)
6034      nb_tmp_fargs = nb_normal_fargs;
6035
6036
6037   // private fargs table to store to
6038   fargs_priv = malloc(nb_tmp_fargs * sizeof(double));
6039
6040   //   /* offset within [1-nb_tmp_fargs:nb_tmp_fargs] */
6041   //   for (i=1-nb_tmp_fargs; i<nb_tmp_fargs; i++) {
6042   for (i=0; i<nb_tmp_fargs; i++) {
6043      offs = i * 8;    // offset = i * sizeof(double)
6044      if (i < 0) {
6045         src   =  fargs     [nb_tmp_fargs-1 + i];
6046         p_dst = &fargs_priv[nb_tmp_fargs-1 + i];
6047         base  = (HWord_t)&fargs_priv[nb_tmp_fargs-1];
6048      } else {
6049         src   =  fargs     [i];
6050         p_dst = &fargs_priv[i];
6051         base  = (HWord_t)&fargs_priv[0];
6052      }
6053      *p_dst = 0;  // clear dst
6054
6055      f14  = src;    // read from fargs
6056      r15  = base;   // store to r15 + offs
6057      r16  = offs;
6058
6059      SET_CR_XER_ZERO;
6060      (*func)();
6061      GET_CR_XER(flags,xer);
6062
6063#ifndef __powerpc64__
6064      printf("%s %016llx, %4d => %016llx, %4d",
6065#else
6066      printf("%s %016llx, %4lld => %016llx, %4lld",
6067#endif
6068             name, double_to_bits(src), r16/*offs*/,
6069             double_to_bits(*p_dst), r15-base);
6070#if defined TEST_FLOAT_FLAGS
6071      printf(" (%08x %08x)", flags, xer);
6072#endif
6073      printf("\n");
6074
6075
6076#if 0
6077      // print double precision result
6078#ifndef __powerpc64__
6079      printf("%s %016llx (%014e), %4d => %016llx (%014e), %08x (%08x %08x)\n",
6080#else
6081      printf("%s %016llx (%014e), %4d => %016llx (%014e), %08x (%08x %08x)\n",
6082#endif
6083             name, double_to_bits(src), src, offs,
6084             double_to_bits(*p_dst), *p_dst, r15, flags, xer);
6085
6086      // print single precision result
6087#ifndef __powerpc64__
6088      printf("%s %016llx (%014e), %4d => %08x (%f), %08x (%08x %08x)\n",
6089#else
6090      printf("%s %016llx (%014e), %4d => %08x (%f), %08x (%08x %08x)\n",
6091#endif
6092             name, double_to_bits(src), src, offs,
6093             (uint32_t)(double_to_bits(*p_dst) >> 32),
6094             bits_to_float( (uint32_t)(double_to_bits(*p_dst) >> 32) ),
6095             r15, flags, xer);
6096#endif
6097   }
6098   free(fargs_priv);
6099}
6100
6101
6102/* Used in do_tests, indexed by flags->nb_args
6103   Elements correspond to enum test_flags::num args
6104*/
6105static test_loop_t float_loops[] = {
6106   &test_float_one_arg,
6107   &test_float_two_args,
6108   &test_float_three_args,
6109   &test_float_two_args,
6110   NULL,
6111   NULL,
6112   &test_float_special,
6113   &test_float_ld_one_reg_imm16,
6114   &test_float_ld_two_regs,
6115   &test_float_st_two_regs_imm16,
6116   &test_float_st_three_regs,
6117};
6118#endif /* !defined (NO_FLOAT) */
6119
6120
6121#if defined (HAS_ALTIVEC)
6122
6123/* Ref: vector insns to test setting CR, VSCR:
6124         volatile vector unsigned int v1 =
6125            //            (vector unsigned int){ 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF };
6126            (vector unsigned int){ 0x80808080,0x80808080,0x80808080,0x80808080 };
6127         volatile vector unsigned int v2 =
6128            //            (vector unsigned int){ 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF };
6129            (vector unsigned int){ 0x01010101,0x01010101,0x01010101,0x01010101 };
6130         //__asm__ __volatile__ ("vcmpequw. 31,%0,%1" : : "v" (v1), "v" (v2));   // sets CR[6]
6131         //__asm__ __volatile__ ("vpkswss 31,%0,%1" : : "v" (v1), "v" (v2));     // sets VSCR[SAT]
6132         __asm__ __volatile__ ("vsubsbs 31,%0,%1" : : "v" (v1), "v" (v2));       // sets VSCR[SAT]
6133*/
6134
6135//#define DEFAULT_VSCR 0x00010000
6136#define DEFAULT_VSCR 0x0
6137
6138static void test_av_int_one_arg (const char* name, test_func_t func,
6139                                 unused uint32_t test_flags)
6140{
6141   volatile uint32_t flags, tmpcr;
6142   volatile vector unsigned int tmpvscr;
6143   volatile vector unsigned int vec_in, vec_out, vscr;
6144   unsigned int *src, *dst;
6145   int i;
6146#if defined TEST_VSCR_SAT
6147   unsigned int* p_vscr;
6148#endif
6149
6150   for (i=0; i<nb_viargs; i++) {
6151      /* Save flags */
6152      __asm__ __volatile__ ("mfcr   %0" : "=r"  (tmpcr));
6153      __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr));
6154
6155      vec_in  = (vector unsigned int)viargs[i];
6156      vec_out = (vector unsigned int){ 0,0,0,0 };
6157
6158      // reset VSCR and CR
6159      vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR };
6160      flags = 0;
6161      __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) );
6162      __asm__ __volatile__ ("mtcr   %0" : : "r" (flags));
6163
6164      // load input -> r14
6165      __asm__ __volatile__ ("vor 14,%0,%0" : : "v" (vec_in));
6166
6167      // do stuff
6168      (*func)();
6169
6170      // retrieve output <- r17
6171      __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out));
6172
6173      // get CR,VSCR flags
6174      __asm__ __volatile__ ("mfcr   %0" : "=r" (flags));
6175      __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr));
6176
6177      /* Restore flags */
6178      __asm__ __volatile__ ("mtcr   %0" : : "r"  (tmpcr));
6179      __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr));
6180
6181      src = (unsigned int*)&vec_in;
6182      dst = (unsigned int*)&vec_out;
6183
6184      printf("%s: %08x %08x %08x %08x\n", name,
6185             src[0], src[1], src[2], src[3]);
6186      printf("%s:  => %08x %08x %08x %08x ", name,
6187             dst[0], dst[1], dst[2], dst[3]);
6188#if defined TEST_VSCR_SAT
6189      p_vscr = (unsigned int*)&vscr;
6190      printf("(%08x, %08x)\n", flags, p_vscr[3]);
6191#else
6192      printf("(%08x)\n", flags);
6193#endif
6194   }
6195}
6196
6197static void test_av_int_two_args (const char* name, test_func_t func,
6198                                  unused uint32_t test_flags)
6199{
6200   volatile uint32_t flags, tmpcr;
6201   volatile vector unsigned int tmpvscr;
6202   volatile vector unsigned int vec_in1, vec_in2, vec_out, vscr;
6203   unsigned int *src1, *src2, *dst;
6204   int i,j;
6205#if defined TEST_VSCR_SAT
6206   unsigned int* p_vscr;
6207#endif
6208
6209   for (i=0; i<nb_viargs; i++) {
6210      vec_in1 = (vector unsigned int)viargs[i];
6211      for (j=0; j<nb_viargs; j++) {
6212         vec_in2 = (vector unsigned int)viargs[j];
6213         vec_out = (vector unsigned int){ 0,0,0,0 };
6214
6215         /* Save flags */
6216         __asm__ __volatile__ ("mfcr   %0" : "=r"  (tmpcr));
6217         __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr));
6218
6219         // reset VSCR and CR
6220         vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR };
6221         flags = 0;
6222         __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) );
6223         __asm__ __volatile__ ("mtcr   %0" : : "r" (flags));
6224
6225         // load inputs -> r14,r15
6226         __asm__ __volatile__ ("vor 14,%0,%0" : : "v" (vec_in1));
6227         __asm__ __volatile__ ("vor 15,%0,%0" : : "v" (vec_in2));
6228
6229         // do stuff
6230         (*func)();
6231
6232         // retrieve output <- r17
6233         __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out));
6234
6235         // get CR,VSCR flags
6236         __asm__ __volatile__ ("mfcr   %0" : "=r" (flags));
6237         __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr));
6238
6239         /* Restore flags */
6240         __asm__ __volatile__ ("mtcr   %0" : : "r"  (tmpcr));
6241         __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr));
6242
6243         src1 = (unsigned int*)&vec_in1;
6244         src2 = (unsigned int*)&vec_in2;
6245         dst  = (unsigned int*)&vec_out;
6246
6247         printf("%s: ", name);
6248         printf("%08x%08x%08x%08x, ", src1[0], src1[1], src1[2], src1[3]);
6249         printf("%08x%08x%08x%08x\n", src2[0], src2[1], src2[2], src2[3]);
6250         printf("%s:  => %08x %08x %08x %08x ", name,
6251                dst[0], dst[1], dst[2], dst[3]);
6252#if defined TEST_VSCR_SAT
6253         p_vscr = (unsigned int*)&vscr;
6254         printf("(%08x, %08x)\n", flags, p_vscr[3]);
6255#else
6256         printf("(%08x)\n", flags);
6257#endif
6258      }
6259      if (verbose) printf("\n");
6260   }
6261}
6262
6263static void test_av_int_three_args (const char* name, test_func_t func,
6264                                    unused uint32_t test_flags)
6265{
6266   volatile uint32_t flags, tmpcr;
6267   volatile vector unsigned int tmpvscr;
6268   volatile vector unsigned int vec_in1, vec_in2, vec_in3, vec_out, vscr;
6269   unsigned int *src1, *src2, *src3, *dst;
6270   int i,j,k;
6271#if defined TEST_VSCR_SAT
6272   unsigned int* p_vscr;
6273#endif
6274
6275   for (i=0; i<nb_viargs; i++) {
6276      vec_in1 = (vector unsigned int)viargs[i];
6277      for (j=0; j<nb_viargs; j++) {
6278         vec_in2 = (vector unsigned int)viargs[j];
6279         for (k=0; k<nb_viargs; k++) {
6280            vec_in3 = (vector unsigned int)viargs[k];
6281            vec_out = (vector unsigned int){ 0,0,0,0 };
6282
6283            /* Save flags */
6284            __asm__ __volatile__ ("mfcr   %0" : "=r"  (tmpcr));
6285            __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr));
6286
6287            // reset VSCR and CR
6288            vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR };
6289            flags = 0;
6290            __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) );
6291            __asm__ __volatile__ ("mtcr   %0" : : "r" (flags));
6292
6293            // load inputs -> r14,r15,r16
6294            __asm__ __volatile__ ("vor 14,%0,%0" : : "v" (vec_in1));
6295            __asm__ __volatile__ ("vor 15,%0,%0" : : "v" (vec_in2));
6296            __asm__ __volatile__ ("vor 16,%0,%0" : : "v" (vec_in3));
6297
6298            // do stuff
6299            (*func)();
6300
6301            // retrieve output <- r17
6302            __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out));
6303
6304            // get CR,VSCR flags
6305            __asm__ __volatile__ ("mfcr   %0" : "=r" (flags));
6306            __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr));
6307
6308            /* Restore flags */
6309            __asm__ __volatile__ ("mtcr   %0" : : "r"  (tmpcr));
6310            __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr));
6311
6312            src1 = (unsigned int*)&vec_in1;
6313            src2 = (unsigned int*)&vec_in2;
6314            src3 = (unsigned int*)&vec_in3;
6315            dst  = (unsigned int*)&vec_out;
6316
6317            printf("%s: %08x%08x%08x%08x, %08x%08x%08x%08x, %08x%08x%08x%08x\n", name,
6318                   src1[0], src1[1], src1[2], src1[3],
6319                   src2[0], src2[1], src2[2], src2[3],
6320                   src3[0], src3[1], src3[2], src3[3]);
6321
6322            printf("%s:  => %08x%08x%08x%08x ", name,
6323                   dst[0], dst[1], dst[2], dst[3]);
6324#if defined TEST_VSCR_SAT
6325            p_vscr = (unsigned int*)&vscr;
6326            printf("(%08x, %08x)\n", flags, p_vscr[3]);
6327#else
6328            printf("(%08x)\n", flags);
6329#endif
6330         }
6331         if (verbose) printf("\n");
6332      }
6333   }
6334}
6335
6336
6337static void vs128_cb (const char* name, test_func_t func,
6338                      unused uint32_t test_flags)
6339{
6340   volatile uint32_t flags, tmpcr;
6341   volatile vector unsigned int tmpvscr;
6342   volatile vector unsigned char vec_shft;
6343   volatile vector unsigned int vec_in1, vec_out, vscr;
6344   unsigned int *src1, *src2, *dst;
6345   int i,j;
6346#if defined TEST_VSCR_SAT
6347   unsigned int* p_vscr;
6348#endif
6349
6350   for (i=0; i<nb_viargs; i++) {
6351      vec_in1 = (vector unsigned int)viargs[i];
6352      for (j=0; j<8; j++) {
6353         /* low-order 3bits of every byte must be the same for the shift vector */
6354         vec_shft = (vector unsigned char) { j,j,j,j, j,j,j,j, j,j,j,j, j,j,j,j };
6355         vec_out  = (vector unsigned int){ 0,0,0,0 };
6356
6357         /* Save flags */
6358         __asm__ __volatile__ ("mfcr   %0" : "=r"  (tmpcr));
6359         __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr));
6360
6361         // reset VSCR and CR
6362         vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR };
6363         flags = 0;
6364         __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) );
6365         __asm__ __volatile__ ("mtcr   %0" : : "r" (flags));
6366
6367         // load inputs -> r14,r15
6368         __asm__ __volatile__ ("vor 14,%0,%0" : : "v" (vec_in1));
6369         __asm__ __volatile__ ("vor 15,%0,%0" : : "v" (vec_shft));
6370
6371         // do stuff
6372         (*func)();
6373
6374         // retrieve output <- r17
6375         __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out));
6376
6377         // get CR,VSCR flags
6378         __asm__ __volatile__ ("mfcr   %0" : "=r" (flags));
6379         __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr));
6380
6381         /* Restore flags */
6382         __asm__ __volatile__ ("mtcr   %0" : : "r"  (tmpcr));
6383         __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr));
6384
6385         src1 = (unsigned int*)&vec_in1;
6386         src2 = (unsigned int*)&vec_shft;
6387         dst  = (unsigned int*)&vec_out;
6388
6389         printf("%s: ", name);
6390         printf("%08x%08x%08x%08x, ", src1[0], src1[1], src1[2], src1[3]);
6391         printf("%08x%08x%08x%08x\n", src2[0], src2[1], src2[2], src2[3]);
6392
6393         printf("%s:  => %08x %08x %08x %08x ", name,
6394                dst[0], dst[1], dst[2], dst[3]);
6395#if defined TEST_VSCR_SAT
6396         p_vscr = (unsigned int*)&vscr;
6397         printf("(%08x, %08x)\n", flags, p_vscr[3]);
6398#else
6399         printf("(%08x)\n", flags);
6400#endif
6401      }
6402      if (verbose) printf("\n");
6403   }
6404}
6405
6406static void vsplt_cb (const char* name, test_func_t func_IN,
6407                      unused uint32_t test_flags)
6408{
6409   volatile test_func_t func;
6410   uint32_t* func_buf = get_rwx_area();
6411   volatile uint32_t flags, tmpcr;
6412   volatile vector unsigned int tmpvscr;
6413   volatile vector unsigned int vec_in1, vec_out, vscr;
6414   unsigned int *src1, *dst;
6415   int i,j;
6416#if defined TEST_VSCR_SAT
6417   unsigned int* p_vscr;
6418#endif
6419
6420   for (i=0; i<nb_viargs; i++) {
6421      vec_in1 = (vector unsigned int)viargs[i];
6422
6423      for (j=0; j<16; j+=3) {
6424         vec_out = (vector unsigned int){ 0,0,0,0 };
6425
6426         /* Patch up the instruction */
6427         func = init_function( func_IN, func_buf );
6428         patch_op_imm(&func_buf[0], j, 16, 5);
6429
6430         /* Save flags */
6431         __asm__ __volatile__ ("mfcr   %0" : "=r"  (tmpcr));
6432         __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr));
6433
6434         // reset VSCR and CR
6435         vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR };
6436         flags = 0;
6437         __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) );
6438         __asm__ __volatile__ ("mtcr   %0" : : "r" (flags));
6439
6440         // load input -> r14
6441         __asm__ __volatile__ ("vor 14,%0,%0" : : "v" (vec_in1));
6442
6443         // do stuff
6444         (*func)();
6445
6446         // retrieve output <- r17
6447         __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out));
6448
6449         // get CR,VSCR flags
6450         __asm__ __volatile__ ("mfcr   %0" : "=r" (flags));
6451         __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr));
6452
6453         /* Restore flags */
6454         __asm__ __volatile__ ("mtcr   %0" : : "r"  (tmpcr));
6455         __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr));
6456
6457         src1 = (unsigned int*)&vec_in1;
6458         dst  = (unsigned int*)&vec_out;
6459
6460         printf("%s: ", name);
6461         printf("%08x %08x %08x %08x, %u\n", src1[0], src1[1], src1[2], src1[3], j);
6462
6463         printf("%s:  => %08x %08x %08x %08x ", name,
6464                dst[0], dst[1], dst[2], dst[3]);
6465#if defined TEST_VSCR_SAT
6466         p_vscr = (unsigned int*)&vscr;
6467         printf("(%08x, %08x)\n", flags, p_vscr[3]);
6468#else
6469         printf("(%08x)\n", flags);
6470#endif
6471      }
6472      if (verbose) printf("\n");
6473   }
6474}
6475
6476static void vspltis_cb (const char* name, test_func_t func_IN,
6477                      unused uint32_t test_flags)
6478{
6479   volatile test_func_t func;
6480   uint32_t* func_buf = get_rwx_area();
6481   volatile uint32_t flags, tmpcr;
6482   volatile vector unsigned int tmpvscr;
6483   volatile vector unsigned int vec_out, vscr;
6484   unsigned int *dst;
6485   int i;
6486#if defined TEST_VSCR_SAT
6487   unsigned int* p_vscr;
6488#endif
6489
6490   for (i=0; i<32; i++) {
6491      vec_out = (vector unsigned int){ 0,0,0,0 };
6492
6493      /* Patch up the instruction */
6494      func = init_function( func_IN, func_buf );
6495      patch_op_imm(&func_buf[0], i, 16, 5);
6496
6497      /* Save flags */
6498      __asm__ __volatile__ ("mfcr   %0" : "=r"  (tmpcr));
6499      __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr));
6500
6501      // reset VSCR and CR
6502      vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR };
6503      flags = 0;
6504      __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) );
6505      __asm__ __volatile__ ("mtcr   %0" : : "r" (flags));
6506
6507      // do stuff
6508      (*func)();
6509
6510      // retrieve output <- r17
6511      __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out));
6512
6513      // get CR,VSCR flags
6514      __asm__ __volatile__ ("mfcr   %0" : "=r" (flags));
6515      __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr));
6516
6517      /* Restore flags */
6518      __asm__ __volatile__ ("mtcr   %0" : : "r"  (tmpcr));
6519      __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr));
6520
6521      dst = (unsigned int*)&vec_out;
6522
6523      printf("%s: %2d => ", name, i);
6524      printf("%08x %08x %08x %08x ", dst[0], dst[1], dst[2], dst[3]);
6525#if defined TEST_VSCR_SAT
6526      p_vscr = (unsigned int*)&vscr;
6527      printf("(%08x, %08x)\n", flags, p_vscr[3]);
6528#else
6529      printf("(%08x)\n", flags);
6530#endif
6531   }
6532}
6533
6534static void vsldoi_cb (const char* name, test_func_t func_IN,
6535                       unused uint32_t test_flags)
6536{
6537   volatile test_func_t func;
6538   uint32_t* func_buf = get_rwx_area();
6539   volatile uint32_t flags, tmpcr;
6540   volatile vector unsigned int tmpvscr;
6541   volatile vector unsigned int vec_in1, vec_in2, vec_out, vscr;
6542   unsigned int *src1, *src2, *dst;
6543   int i,j,k;
6544#if defined TEST_VSCR_SAT
6545   unsigned int* p_vscr;
6546#endif
6547
6548   for (i=0; i<nb_viargs; i++) {
6549      vec_in1 = (vector unsigned int)viargs[i];
6550      for (j=0; j<nb_viargs; j++) {
6551         vec_in2 = (vector unsigned int)viargs[j];
6552         for (k=0; k<16; k+=14) {
6553            vec_out = (vector unsigned int){ 0,0,0,0 };
6554
6555            /* Patch up the instruction */
6556            func = init_function( func_IN, func_buf );
6557            patch_op_imm(&func_buf[0], k, 6, 4);
6558
6559            /* Save flags */
6560            __asm__ __volatile__ ("mfcr   %0" : "=r"  (tmpcr));
6561            __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr));
6562
6563            // reset VSCR and CR
6564            vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR };
6565            flags = 0;
6566            __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) );
6567            __asm__ __volatile__ ("mtcr   %0" : : "r" (flags));
6568
6569            // load inputs -> r14,r15
6570            __asm__ __volatile__ ("vor 14,%0,%0" : : "v" (vec_in1));
6571            __asm__ __volatile__ ("vor 15,%0,%0" : : "v" (vec_in2));
6572
6573            // do stuff
6574            (*func)();
6575
6576            // retrieve output <- r17
6577            __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out));
6578
6579            // get CR,VSCR flags
6580            __asm__ __volatile__ ("mfcr   %0" : "=r" (flags));
6581            __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr));
6582
6583            /* Restore flags */
6584            __asm__ __volatile__ ("mtcr   %0" : : "r"  (tmpcr));
6585            __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr));
6586
6587            src1   = (unsigned int*)&vec_in1;
6588            src2   = (unsigned int*)&vec_in2;
6589            dst    = (unsigned int*)&vec_out;
6590
6591            printf("%s: ", name);
6592            printf("%08x%08x%08x%08x, %08x%08x%08x%08x, %u\n",
6593                   src1[0], src1[1], src1[2], src1[3],
6594                   src2[0], src2[1], src2[2], src2[3], k);
6595
6596            printf("%s:  => %08x %08x %08x %08x] ", name,
6597                   dst[0], dst[1], dst[2], dst[3]);
6598#if defined TEST_VSCR_SAT
6599            p_vscr = (unsigned int*)&vscr;
6600            printf("(%08x, %08x)\n", flags, p_vscr[3]);
6601#else
6602            printf("(%08x)\n", flags);
6603#endif
6604         }
6605         if (verbose) printf("\n");
6606      }
6607   }
6608}
6609
6610/* lvsl, lvsr */
6611static void lvs_cb (const char *name, test_func_t func,
6612                    unused uint32_t test_flags)
6613{
6614   volatile uint32_t flags, tmpcr;
6615   volatile vector unsigned int tmpvscr;
6616   volatile vector unsigned int vec_out, vscr;
6617   unsigned int *dst;
6618   int i;
6619#if defined TEST_VSCR_SAT
6620   unsigned int* p_vscr;
6621#endif
6622
6623   for (i=-1; i<17; i++) {
6624      vec_out = (vector unsigned int){ 0,0,0,0 };
6625
6626      // make sure start address is 16 aligned - use viargs[0]
6627      r15 = (HWord_t)&viargs[0];
6628      r14 = i;
6629
6630      /* Save flags */
6631      __asm__ __volatile__ ("mfcr   %0" : "=r"  (tmpcr));
6632      __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr));
6633
6634      // reset VSCR and CR
6635      vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR };
6636      flags = 0;
6637      __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) );
6638      __asm__ __volatile__ ("mtcr   %0" : : "r" (flags));
6639
6640      // do stuff
6641      (*func)();
6642
6643      // retrieve output <- r17
6644      __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out));
6645
6646      // get CR,VSCR flags
6647      __asm__ __volatile__ ("mfcr   %0" : "=r" (flags));
6648      __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr));
6649
6650      /* Restore flags */
6651      __asm__ __volatile__ ("mtcr   %0" : : "r"  (tmpcr));
6652      __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr));
6653
6654      dst = (unsigned int*)&vec_out;
6655
6656      printf("%s %3d, %3d", name, i, 0);
6657      printf(" => %08x %08x %08x %08x ", dst[0], dst[1], dst[2], dst[3]);
6658      printf("(%08x)\n", flags);
6659   }
6660   if (verbose) printf("\n");
6661}
6662
6663static special_t special_av_int_ops[] = {
6664   {
6665      "vsr", /* Two registers arguments */
6666      &vs128_cb,
6667   },
6668   {
6669      "vsl", /* Two registers arguments */
6670      &vs128_cb,
6671   },
6672   {
6673      "vspltb", /* One reg, one 5-bit uimm arguments */
6674      &vsplt_cb,
6675   },
6676   {
6677      "vsplth", /* One reg, one 5-bit uimm arguments */
6678      &vsplt_cb,
6679   },
6680   {
6681      "vspltw", /* One reg, one 5-bit uimm arguments */
6682      &vsplt_cb,
6683   },
6684   {
6685      "vspltisb", /* One reg, one 5-bit uimm arguments */
6686      &vspltis_cb,
6687   },
6688   {
6689      "vspltish", /* One reg, one 5-bit uimm arguments */
6690      &vspltis_cb,
6691   },
6692   {
6693      "vspltisw", /* One reg, one 5-bit uimm arguments */
6694      &vspltis_cb,
6695   },
6696   {
6697      "vsldoi", /* Two regs, one 4-bit uimm arguments */
6698      &vsldoi_cb,
6699   },
6700   {
6701      "lvsl", /* Two regs */
6702      &lvs_cb,
6703   },
6704   {
6705      "lvsr", /* Two regs */
6706      &lvs_cb,
6707   },
6708   {
6709      NULL,
6710      NULL,
6711   },
6712};
6713
6714static void test_av_int_special (const char* name, test_func_t func,
6715                                 uint32_t test_flags)
6716{
6717   test_special(special_av_int_ops, name, func, test_flags);
6718}
6719
6720static void test_av_int_ld_two_regs (const char *name,
6721                                  test_func_t func,
6722                                  unused uint32_t test_flags)
6723{
6724   volatile uint32_t flags, tmpcr;
6725   volatile vector unsigned int tmpvscr;
6726   volatile vector unsigned int vec_in, vec_out, vscr;
6727   unsigned int *src, *dst;
6728   int i,j, k, do_mask;
6729
6730   do_mask = 0;
6731   if (strstr(name, "lvebx") != NULL) do_mask = 1;
6732   if (strstr(name, "lvehx") != NULL) do_mask = 2;
6733   if (strstr(name, "lvewx") != NULL) do_mask = 4;
6734
6735   for (i=0; i<nb_viargs; i++) {
6736      for (j=0; j<16; j+=7) {
6737         vec_out = (vector unsigned int){ 0,0,0,0 };
6738
6739         // load from viargs array + some dis-alignment
6740         r15 = (HWord_t)&viargs[0];
6741         r14 = i*16 + j;
6742
6743         /* Save flags */
6744         __asm__ __volatile__ ("mfcr   %0" : "=r"  (tmpcr));
6745         __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr));
6746
6747         // reset VSCR and CR
6748         vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR };
6749         flags = 0;
6750         __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) );
6751         __asm__ __volatile__ ("mtcr   %0" : : "r" (flags));
6752
6753         // do stuff
6754         (*func)();
6755
6756         // retrieve output <- r17
6757         __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out));
6758
6759         // get CR,VSCR flags
6760         __asm__ __volatile__ ("mfcr   %0" : "=r" (flags));
6761         __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr));
6762
6763         /* Restore flags */
6764         __asm__ __volatile__ ("mtcr   %0" : : "r"  (tmpcr));
6765         __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr));
6766
6767         vec_in = (vector unsigned int)viargs[i];
6768         src = (unsigned int*)&vec_in;
6769         dst = (unsigned int*)&vec_out;
6770
6771         /* For lvebx/lvehx/lvewx, as per the documentation, all of
6772            the dest reg except the loaded bits are undefined
6773            afterwards.  And different CPUs really do produce
6774            different results.  So mask out bits of the result that
6775            are undefined so as to make the test work reliably. */
6776         if (do_mask == 1) {
6777            char* p = (char*)dst;
6778            for (k = 0; k < 16; k++)
6779               if (k != j)
6780                  p[k] = (char)0;
6781         }
6782         if (do_mask == 2) {
6783            short* p = (short*)dst;
6784            for (k = 0; k < 8; k++)
6785               if (k != (j>>1))
6786                  p[k] = (short)0;
6787         }
6788         if (do_mask == 4) {
6789            int* p = (int*)dst;
6790            for (k = 0; k < 4; k++)
6791               if (k != (j>>2))
6792                  p[k] = (int)0;
6793         }
6794
6795         printf("%s %3d, %08x %08x %08x %08x", name, j, src[0], src[1], src[2], src[3]);
6796         printf(" => %08x %08x %08x %08x ", dst[0], dst[1], dst[2], dst[3]);
6797         printf("(%08x)\n", flags);
6798      }
6799      if (verbose) printf("\n");
6800   }
6801}
6802
6803
6804static void test_av_int_st_three_regs (const char *name,
6805                                       test_func_t func,
6806                                       unused uint32_t test_flags)
6807{
6808   volatile uint32_t flags, tmpcr;
6809   volatile vector unsigned int tmpvscr;
6810   volatile vector unsigned int vec_in, vec_out, vscr;
6811   unsigned int *src, *dst;
6812   int i,j;
6813   vector unsigned int* viargs_priv;
6814
6815   // private viargs table to store to
6816   viargs_priv = memalign16(nb_viargs * sizeof(vector unsigned int));
6817   for (i=0; i<nb_viargs; i++)
6818      viargs_priv[i] = (vector unsigned int) { 0,0,0,0 };
6819
6820   for (i=0; i<nb_viargs; i++) {
6821      for (j=0; j<16; j+=7) {
6822         // read from viargs
6823         vec_in = (vector unsigned int)viargs[i];
6824
6825         // store to viargs_priv[0] + some dis-alignment
6826         r16 = (HWord_t)&viargs_priv[0];
6827         r15 = i*16 + j;
6828
6829         /* Save flags */
6830         __asm__ __volatile__ ("mfcr   %0" : "=r"  (tmpcr));
6831         __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr));
6832
6833         // reset VSCR and CR
6834         vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR };
6835         flags = 0;
6836         __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) );
6837         __asm__ __volatile__ ("mtcr   %0" : : "r" (flags));
6838
6839         // load inputs -> r14
6840         __asm__ __volatile__ ("vor 14,%0,%0" : : "v" (vec_in));
6841
6842         // do stuff
6843         (*func)();
6844
6845         // Output stored in viargs_priv
6846
6847         // get CR,VSCR flags
6848         __asm__ __volatile__ ("mfcr   %0" : "=r" (flags));
6849         __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr));
6850
6851         /* Restore flags */
6852         __asm__ __volatile__ ("mtcr   %0" : : "r"  (tmpcr));
6853         __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr));
6854
6855         vec_out = (vector unsigned int)viargs_priv[i];
6856         src = (unsigned int*)&vec_in;
6857         dst = (unsigned int*)&vec_out;
6858
6859         printf("%s %3d, %08x %08x %08x %08x", name, j, src[0], src[1], src[2], src[3]);
6860         printf(" => %08x %08x %08x %08x ", dst[0], dst[1], dst[2], dst[3]);
6861         printf("(%08x)\n", flags);
6862      }
6863      if (verbose) printf("\n");
6864   }
6865}
6866
6867/* Used in do_tests, indexed by flags->nb_args
6868   Elements correspond to enum test_flags::num args
6869*/
6870static test_loop_t altivec_int_loops[] = {
6871   &test_av_int_one_arg,
6872   &test_av_int_two_args,
6873   &test_av_int_three_args,
6874   &test_av_int_two_args,
6875   NULL,
6876   NULL,
6877   &test_av_int_special,
6878   NULL,
6879   &test_av_int_ld_two_regs,
6880   NULL,
6881   test_av_int_st_three_regs,
6882};
6883
6884
6885static void test_av_float_one_arg (const char* name, test_func_t func,
6886                                   unused uint32_t test_flags)
6887{
6888   volatile uint32_t flags, tmpcr;
6889   volatile vector unsigned int tmpvscr;
6890   volatile vector float vec_in, vec_out;
6891   volatile vector unsigned int vscr;
6892   unsigned int *src, *dst;
6893   int i;
6894#if defined TEST_VSCR_SAT
6895   unsigned int* p_vscr;
6896#endif
6897
6898   /* if we're doing an estimation operation, arrange to zap the
6899      bottom 10-bits of the result as it's basically garbage, and differs
6900      between cpus */
6901   unsigned int mask
6902      = (strstr(name,"vrsqrtefp") != NULL ||
6903         strstr(name,    "vrefp") != NULL)
6904           ? 0xFFFFC000 : 0xFFFFFFFF;
6905
6906   for (i=0; i<nb_vfargs; i++) {
6907      vec_in  = (vector float)vfargs[i];
6908      vec_out = (vector float){ 0.0, 0.0, 0.0, 0.0 };
6909
6910      /* Save flags */
6911      __asm__ __volatile__ ("mfcr   %0" : "=r"  (tmpcr));
6912      __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr));
6913
6914      // reset VSCR and CR
6915      vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR };
6916      flags = 0;
6917      __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) );
6918      __asm__ __volatile__ ("mtcr   %0" : : "r" (flags));
6919
6920      // load input -> r14
6921      __asm__ __volatile__ ("vor 14,%0,%0" : : "v" (vec_in));
6922
6923      // do stuff
6924      (*func)();
6925
6926      // retrieve output <- r17
6927      __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out));
6928
6929      // get CR,VSCR flags
6930      __asm__ __volatile__ ("mfcr   %0" : "=r" (flags));
6931      __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr));
6932
6933      /* Restore flags */
6934      __asm__ __volatile__ ("mtcr   %0" : : "r"  (tmpcr));
6935      __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr));
6936
6937      src = (unsigned int*)&vec_in;
6938      dst = (unsigned int*)&vec_out;
6939
6940      printf("%s: %08x %08x %08x %08x\n", name,
6941             src[0], src[1], src[2], src[3]);
6942      printf("%s:  => %08x %08x %08x %08x ", name,
6943             dst[0] & mask, dst[1] & mask, dst[2] & mask, dst[3] & mask);
6944#if defined TEST_VSCR_SAT
6945      p_vscr = (unsigned int*)&vscr;
6946      printf("(%08x, %08x)\n", flags, p_vscr[3]);
6947#else
6948      printf("(%08x)\n", flags);
6949#endif
6950   }
6951}
6952
6953static void test_av_float_two_args (const char* name, test_func_t func,
6954                                    unused uint32_t test_flags)
6955{
6956   volatile uint32_t flags, tmpcr;
6957   volatile vector unsigned int tmpvscr;
6958   volatile vector float vec_in1, vec_in2, vec_out;
6959   volatile vector unsigned int vscr;
6960   unsigned int *src1, *src2, *dst;
6961   int i,j;
6962#if defined TEST_VSCR_SAT
6963   unsigned int* p_vscr;
6964#endif
6965
6966   for (i=0; i<nb_vfargs; i++) {
6967      for (j=0; j<nb_vfargs; j+=3) {
6968         vec_in1 = (vector float)vfargs[i];
6969         vec_in2 = (vector float)vfargs[j];
6970         vec_out = (vector float){ 0.0, 0.0, 0.0, 0.0 };
6971
6972         /* Save flags */
6973         __asm__ __volatile__ ("mfcr   %0" : "=r"  (tmpcr));
6974         __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr));
6975
6976         // reset VSCR and CR
6977         vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR };
6978         flags = 0;
6979         __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) );
6980         __asm__ __volatile__ ("mtcr   %0" : : "r" (flags));
6981
6982         // load inputs -> r14,r15
6983         __asm__ __volatile__ ("vor 14,%0,%0" : : "v" (vec_in1));
6984         __asm__ __volatile__ ("vor 15,%0,%0" : : "v" (vec_in2));
6985
6986         // do stuff
6987         (*func)();
6988
6989         // retrieve output <- r17
6990         __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out));
6991
6992         // get CR,VSCR flags
6993         __asm__ __volatile__ ("mfcr   %0" : "=r" (flags));
6994         __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr));
6995
6996         /* Restore flags */
6997         __asm__ __volatile__ ("mtcr   %0" : : "r"  (tmpcr));
6998         __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr));
6999
7000         src1 = (unsigned int*)&vec_in1;
7001         src2 = (unsigned int*)&vec_in2;
7002         dst  = (unsigned int*)&vec_out;
7003
7004         printf("%s: %08x%08x%08x%08x, %08x%08x%08x%08x\n", name,
7005                src1[0], src1[1], src1[2], src1[3],
7006                src2[0], src2[1], src2[2], src2[3]);
7007         printf("%s:  => %08x %08x %08x %08x ", name,
7008                dst[0], dst[1], dst[2], dst[3]);
7009#if defined TEST_VSCR_SAT
7010         p_vscr = (unsigned int*)&vscr;
7011         printf("(%08x, %08x)\n", flags, p_vscr[3]);
7012#else
7013         printf("(%08x)\n", flags);
7014#endif
7015      }
7016      if (verbose) printf("\n");
7017   }
7018}
7019
7020static void test_av_float_three_args (const char* name, test_func_t func,
7021                                      unused uint32_t test_flags)
7022{
7023   volatile uint32_t flags, tmpcr;
7024   volatile vector unsigned int tmpvscr;
7025   volatile vector float vec_in1, vec_in2, vec_in3, vec_out;
7026   volatile vector unsigned int vscr;
7027   unsigned int *src1, *src2, *src3, *dst;
7028   int i,j,k,n;
7029#if defined TEST_VSCR_SAT
7030   unsigned int* p_vscr;
7031#endif
7032
7033   for (i=0; i<nb_vfargs; i++) {
7034      for (j=0; j<nb_vfargs; j+=3) {
7035         for (k=0; k<nb_vfargs; k+=5) {
7036            vec_in1 = (vector float)vfargs[i];
7037            vec_in2 = (vector float)vfargs[j];
7038            vec_in3 = (vector float)vfargs[k];
7039            vec_out = (vector float){ 0.0, 0.0, 0.0, 0.0 };
7040
7041            /* Save flags */
7042            __asm__ __volatile__ ("mfcr   %0" : "=r"  (tmpcr));
7043            __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr));
7044
7045            // reset VSCR and CR
7046            vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR };
7047            flags = 0;
7048            __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) );
7049            __asm__ __volatile__ ("mtcr   %0" : : "r" (flags));
7050
7051            // load inputs -> r14,r15,r16
7052            __asm__ __volatile__ ("vor 14,%0,%0" : : "v" (vec_in1));
7053            __asm__ __volatile__ ("vor 15,%0,%0" : : "v" (vec_in2));
7054            __asm__ __volatile__ ("vor 16,%0,%0" : : "v" (vec_in3));
7055
7056            // do stuff
7057            (*func)();
7058
7059            // retrieve output <- r17
7060            __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out));
7061
7062            // get CR,VSCR flags
7063            __asm__ __volatile__ ("mfcr   %0" : "=r" (flags));
7064            __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr));
7065
7066            /* Restore flags */
7067            __asm__ __volatile__ ("mtcr   %0" : : "r"  (tmpcr));
7068            __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr));
7069
7070            src1 = (unsigned int*)&vec_in1;
7071            src2 = (unsigned int*)&vec_in2;
7072            src3 = (unsigned int*)&vec_in3;
7073            dst  = (unsigned int*)&vec_out;
7074
7075            /* Valgrind emulation for vmaddfp and vnmsubfp generates negative
7076             * NAN.  Technically, NAN is not positive or negative so mask off
7077             * the sign bit to eliminate false errors.
7078             *
7079             * Valgrind emulation is creating negative zero.  Mask off negative
7080             * from zero result.
7081             *
7082             * These are only an issue as we are printing the result in hex.
7083             *
7084             * The VEX emulation accuracy for the vmaddfp and vnmsubfp
7085             * instructions is off by a single bit in the least significant
7086             * bit position of the result.  Mask off the LSB.
7087             */
7088
7089             for (n=0; n<4; n++) {
7090                /* NAN result*/
7091                if (((dst[n] & 0x7F800000) == 0x7F800000) &&
7092                   ((dst[n] & 0x7FFFFF) != 0))
7093                   dst[n] &= 0x7FFFFFFF;
7094
7095                /* Negative zero result */
7096                else if (dst[n] == 0x80000000)
7097                    dst[n] = 0x0;
7098
7099                else
7100                    /* The actual result and the emulated result for the
7101                     * vmaddfp and vnmsubfp instructions sometimes differ
7102                     * in the least significant bit.  Mask off the bit.
7103                     */
7104                    dst[n] &= 0xFFFFFFFE;
7105                }
7106
7107            printf("%s: %08x%08x%08x%08x, %08x%08x%08x%08x, %08x%08x%08x%08x\n", name,
7108                   src1[0], src1[1], src1[2], src1[3],
7109                   src2[0], src2[1], src2[2], src2[3],
7110                   src3[0], src3[1], src3[2], src3[3]);
7111            printf("%s:  => %08x %08x %08x %08x ", name,
7112                   dst[0], dst[1], dst[2], dst[3]);
7113#if defined TEST_VSCR_SAT
7114            p_vscr = (unsigned int*)&vscr;
7115            printf("(%08x, %08x)\n", flags, p_vscr[3]);
7116#else
7117            printf("(%08x)\n", flags);
7118#endif
7119         }
7120         if (verbose) printf("\n");
7121      }
7122   }
7123}
7124
7125static void vcvt_cb (const char* name, test_func_t func_IN,
7126                     unused uint32_t test_flags)
7127{
7128   volatile test_func_t func;
7129   uint32_t* func_buf = get_rwx_area();
7130   volatile uint32_t flags, tmpcr;
7131   volatile vector unsigned int tmpvscr;
7132   volatile vector unsigned int vec_in, vec_out, vscr;
7133   unsigned int *src, *dst;
7134   int i,j;
7135#if defined TEST_VSCR_SAT
7136   unsigned int* p_vscr;
7137#endif
7138
7139   for (i=0; i<nb_vfargs; i++) {
7140      vec_in = (vector unsigned int)vfargs[i];
7141
7142      for (j=0; j<32; j+=9) {
7143         vec_out = (vector unsigned int){ 0,0,0,0 };
7144
7145         /* Patch up the instruction */
7146         func = init_function( func_IN, func_buf );
7147         patch_op_imm(&func_buf[0], j, 16, 5);
7148
7149         /* Save flags */
7150         __asm__ __volatile__ ("mfcr   %0" : "=r"  (tmpcr));
7151         __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr));
7152
7153         // reset VSCR and CR
7154         vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR };
7155         flags = 0;
7156         __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) );
7157         __asm__ __volatile__ ("mtcr   %0" : : "r" (flags));
7158
7159         // load input -> r14
7160         __asm__ __volatile__ ("vor 14,%0,%0" : : "v" (vec_in));
7161
7162         // do stuff
7163         (*func)();
7164
7165         // retrieve output <- r17
7166         __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out));
7167
7168         // get CR,VSCR flags
7169         __asm__ __volatile__ ("mfcr   %0" : "=r" (flags));
7170         __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr));
7171
7172         /* Restore flags */
7173         __asm__ __volatile__ ("mtcr   %0" : : "r"  (tmpcr));
7174         __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr));
7175
7176         src = (unsigned int*)&vec_in;
7177         dst = (unsigned int*)&vec_out;
7178
7179         printf("%s: %08x (%13e), %2u", name, src[0], *(float*)(&src[0]), j);
7180         printf(" => %08x (%13e) ", dst[0], *(float*)(&dst[0]));
7181//         printf(" => %08x ", dst[0]);
7182#if defined TEST_VSCR_SAT
7183            p_vscr = (unsigned int*)&vscr;
7184            printf("(%08x, %08x)\n", flags, p_vscr[3]);
7185#else
7186            printf("(%08x)\n", flags);
7187#endif
7188      }
7189      if (verbose) printf("\n");
7190   }
7191}
7192
7193static special_t special_av_float_ops[] = {
7194   {
7195      "vcfux", /* One reg, one 5-bit uimm argument */
7196      &vcvt_cb,
7197   },
7198   {
7199      "vcfsx", /* One reg, one 5-bit uimm argument */
7200      &vcvt_cb,
7201   },
7202   {
7203      "vctuxs", /* One reg, one 5-bit uimm argument */
7204      &vcvt_cb,
7205   },
7206   {
7207      "vcfux", /* One reg, one 5-bit uimm argument */
7208      &vcvt_cb,
7209   },
7210   {
7211      "vctsxs", /* One reg, one 5-bit uimm argument */
7212      &vcvt_cb,
7213   },
7214   {
7215      NULL,
7216      NULL,
7217   },
7218};
7219
7220static void test_av_float_special (const char* name, test_func_t func,
7221                                   uint32_t test_flags)
7222{
7223   test_special(special_av_float_ops, name, func, test_flags);
7224}
7225
7226/* Used in do_tests, indexed by flags->nb_args
7227   Elements correspond to enum test_flags::num args
7228*/
7229static test_loop_t altivec_float_loops[] = {
7230   &test_av_float_one_arg,
7231   &test_av_float_two_args,
7232   &test_av_float_three_args,
7233   &test_av_float_two_args,
7234   NULL,
7235   NULL,
7236   &test_av_float_special,
7237   NULL,
7238   NULL,
7239   NULL,
7240   NULL,
7241};
7242
7243#endif /* defined (HAS_ALTIVEC) */
7244
7245
7246#if defined (IS_PPC405)
7247static void test_ppc405 (const char* name, test_func_t func,
7248                         unused uint32_t test_flags)
7249{
7250   volatile uint32_t res, flags, xer, tmpcr, tmpxer;
7251   int i, j, k;
7252
7253   for (i=0; i<nb_iargs; i++) {
7254      for (j=0; j<nb_iargs; j++) {
7255         for (k=0; k<nb_iargs; k++) {
7256            r14 = iargs[i];
7257            r15 = iargs[j];
7258            /* Beware: the third argument and the result
7259             * are in the same register
7260             */
7261            r17 = iargs[k];
7262
7263            /* Save flags */
7264            __asm__ __volatile__ ("mfcr 18");
7265            tmpcr = r18;
7266            __asm__ __volatile__ ("mfxer 18");
7267            tmpxer = r18;
7268
7269            /* Set up flags for test */
7270            r18 = 0;
7271            __asm__ __volatile__ ("mtcr 18");
7272            __asm__ __volatile__ ("mtxer 18");
7273            (*func)();
7274            __asm__ __volatile__ ("mfcr 18");
7275            flags = r18;
7276            __asm__ __volatile__ ("mfxer 18");
7277            xer = r18;
7278            res = r17;
7279
7280            /* Restore flags */
7281            r18 = tmpcr;
7282            __asm__ __volatile__ ("mtcr 18");
7283            r18 = tmpxer;
7284            __asm__ __volatile__ ("mtxer 18");
7285
7286            printf("%s %08x, %08x, %08x => %08x (%08x %08x)\n",
7287                   name, iargs[i], iargs[j], iargs[k], res, flags, xer);
7288         }
7289         if (verbose) printf("\n");
7290      }
7291   }
7292}
7293#endif /* defined (IS_PPC405) */
7294
7295static int check_filter (char *filter)
7296{
7297   char *c;
7298   int ret = 1;
7299
7300   if (filter != NULL) {
7301      c = strchr(filter, '*');
7302      if (c != NULL) {
7303         *c = '\0';
7304         ret = 0;
7305      }
7306   }
7307
7308   return ret;
7309}
7310
7311static int check_name (const char* name, const char *filter,
7312                       int exact)
7313{
7314   int nlen, flen;
7315   int ret = 0;
7316
7317   if (filter != NULL) {
7318      for (; isspace(*name); name++)
7319         continue;
7320      FDPRINTF("Check '%s' againt '%s' (%s match)\n",
7321               name, filter, exact ? "exact" : "starting");
7322      nlen = strlen(name);
7323      flen = strlen(filter);
7324      if (exact) {
7325         if (nlen == flen && memcmp(name, filter, flen) == 0)
7326            ret = 1;
7327      } else {
7328         if (flen <= nlen && memcmp(name, filter, flen) == 0)
7329            ret = 1;
7330      }
7331   } else {
7332      ret = 1;
7333   }
7334   return ret;
7335}
7336
7337
7338
7339typedef struct insn_sel_flags_t_struct {
7340   int one_arg, two_args, three_args;
7341   int arith, logical, compare, ldst;
7342   int integer, floats, p405, altivec, faltivec;
7343   int cr;
7344} insn_sel_flags_t;
7345
7346static void do_tests ( insn_sel_flags_t seln_flags,
7347                       char *filter)
7348{
7349#if defined (IS_PPC405)
7350   test_loop_t tmpl;
7351#endif
7352   test_loop_t *loop;
7353   test_t *tests;
7354   int nb_args, type, family;
7355   int i, j, n;
7356   int exact;
7357
7358   exact = check_filter(filter);
7359   n = 0;
7360   for (i=0; all_tests[i].name != NULL; i++) {
7361      nb_args = all_tests[i].flags & PPC_NB_ARGS;
7362      /* Check number of arguments */
7363      if ((nb_args == 1 && !seln_flags.one_arg) ||
7364          (nb_args == 2 && !seln_flags.two_args) ||
7365          (nb_args == 3 && !seln_flags.three_args))
7366         continue;
7367      /* Check instruction type */
7368      type = all_tests[i].flags & PPC_TYPE;
7369      if ((type == PPC_ARITH   && !seln_flags.arith) ||
7370          (type == PPC_LOGICAL && !seln_flags.logical) ||
7371          (type == PPC_COMPARE && !seln_flags.compare) ||
7372          (type == PPC_LDST && !seln_flags.ldst) ||
7373          (type == PPC_POPCNT && !seln_flags.arith))
7374         continue;
7375      /* Check instruction family */
7376      family = all_tests[i].flags & PPC_FAMILY;
7377      if ((family == PPC_INTEGER  && !seln_flags.integer) ||
7378          (family == PPC_FLOAT    && !seln_flags.floats) ||
7379          (family == PPC_405      && !seln_flags.p405) ||
7380          (family == PPC_ALTIVEC  && !seln_flags.altivec) ||
7381          (family == PPC_FALTIVEC && !seln_flags.faltivec))
7382         continue;
7383      /* Check flags update */
7384      if (((all_tests[i].flags & PPC_CR)  && seln_flags.cr == 0) ||
7385          (!(all_tests[i].flags & PPC_CR) && seln_flags.cr == 1))
7386         continue;
7387      /* All passed, do the tests */
7388      tests = all_tests[i].tests;
7389      /* Select the test loop */
7390      switch (family) {
7391      case PPC_INTEGER:
7392         loop = &int_loops[nb_args - 1];
7393         break;
7394      case PPC_FLOAT:
7395#if !defined (NO_FLOAT)
7396         loop = &float_loops[nb_args - 1];
7397         break;
7398#else
7399         fprintf(stderr, "Sorry. "
7400                 "PPC floating point instructions tests "
7401                 "are disabled on your host\n");
7402#endif /* !defined (NO_FLOAT) */
7403
7404      case PPC_405:
7405#if defined (IS_PPC405)
7406         tmpl = &test_ppc405;
7407         loop = &tmpl;
7408         break;
7409#else
7410         fprintf(stderr, "Sorry. "
7411                 "PPC405 instructions tests are disabled on your host\n");
7412         continue;
7413#endif /* defined (IS_PPC405) */
7414      case PPC_ALTIVEC:
7415#if defined (HAS_ALTIVEC)
7416         loop = &altivec_int_loops[nb_args - 1];
7417         break;
7418#else
7419         fprintf(stderr, "Sorry. "
7420                 "Altivec instructions tests are disabled on your host\n");
7421         continue;
7422#endif
7423      case PPC_FALTIVEC:
7424#if defined (HAS_ALTIVEC)
7425         loop = &altivec_float_loops[nb_args - 1];
7426         break;
7427#else
7428         fprintf(stderr, "Sorry. "
7429                 "Altivec float instructions tests "
7430                 "are disabled on your host\n");
7431#endif
7432         continue;
7433      default:
7434         printf("ERROR: unknown insn family %08x\n", family);
7435         continue;
7436      }
7437      if (1 || verbose > 0)
7438         printf("%s:\n", all_tests[i].name);
7439      for (j=0; tests[j].name != NULL; j++) {
7440         if (check_name(tests[j].name, filter, exact)) {
7441            if (verbose > 1)
7442               printf("Test instruction %s\n", tests[j].name);
7443            (*loop)(tests[j].name, tests[j].func, all_tests[i].flags);
7444            printf("\n");
7445            n++;
7446         }
7447        }
7448      if (verbose) printf("\n");
7449   }
7450   printf("All done. Tested %d different instructions\n", n);
7451}
7452
7453
7454static void usage (void)
7455{
7456#if !defined (USAGE_SIMPLE)
7457   fprintf(stderr,
7458           "jm-insns [-1] [-2] [-3] [-*] [-t <type>] [-f <family>] [-u] "
7459           "[-n <filter>] [-r <test_rigour>] [-h]\n"
7460           "\t-1: test opcodes with one argument\n"
7461           "\t-2: test opcodes with two arguments\n"
7462           "\t-3: test opcodes with three arguments\n"
7463           "\t-*: launch test without checking the number of arguments\n"
7464           "\t-t: launch test for instructions of type <type>\n"
7465           "\t    recognized types:\n"
7466           "\t\tarith (or a)\n"
7467           "\t\tlogical (or l)\n"
7468           "\t\tcompare (or c)\n"
7469           "\t\tstoreload (or s)\n"
7470           "\t-f: launch test for instructions of family <family>\n"
7471           "\t    recognized families:\n"
7472           "\t\tinteger (or i)\n"
7473           "\t\tfloat (or f)\n"
7474           "\t\tppc405 (or mac)\n"
7475           "\t\taltivec (or a)\n"
7476           "\t-u: test instructions that update flags\n"
7477           "\t-n: filter instructions with <filter>\n"
7478           "\t    <filter> can be in two forms:\n"
7479           "\t\tname  : filter functions that exactly match <name>\n"
7480           "\t\tname* : filter functions that start with <name>\n"
7481           "\t-r: set size of arg tables to use to define <test_rigour>\n"
7482           "\t    recognized types:\n"
7483           "\t\tlarge (or l)\n"
7484           "\t\tsmall (or s) - default\n"
7485           "\t-v: verbose (-v -v for more)\n"
7486           "\t-h: print this help\n"
7487           );
7488#else // #if !defined (USAGE_SIMPLE)
7489   fprintf(stderr,
7490           "Usage: jm-insns [OPTION]\n"
7491           "\t-i: test integer instructions (default)\n"
7492           "\t-f: test floating point instructions\n"
7493           "\t-a: test altivec instructions\n"
7494           "\t-A: test all (int, fp, altivec) instructions\n"
7495           "\t-v: be verbose\n"
7496           "\t-h: display this help and exit\n"
7497           );
7498#endif // #if !defined (USAGE_SIMPLE)
7499}
7500
7501
7502
7503int main (int argc, char **argv)
7504{
7505#if !defined (USAGE_SIMPLE)
7506////////////////////////////////////////////////////////////////////////
7507   unsigned char *tmp, *filter = NULL;
7508   insn_sel_flags_t flags;
7509   int c;
7510
7511   // check HWord_t really is a host word
7512   assert(sizeof(void*) == sizeof(HWord_t));
7513
7514   flags.one_arg    = 0;
7515   flags.two_args   = 0;
7516   flags.three_args = 0;
7517   flags.arith      = 0;
7518   flags.logical    = 0;
7519   flags.compare    = 0;
7520   flags.ldst       = 0;
7521   flags.integer    = 0;
7522   flags.floats     = 0;
7523   flags.p405       = 0;
7524   flags.altivec    = 0;
7525   flags.faltivec   = 0;
7526   flags.cr         = -1;
7527
7528   while ((c = getopt(argc, argv, "123t:f:n:r:uvh")) != -1) {
7529      switch (c) {
7530      case '1':
7531         flags.one_arg = 1;
7532         break;
7533      case '2':
7534         flags.two_args = 1;
7535         break;
7536      case '3':
7537         flags.three_args = 1;
7538         break;
7539      case 't':
7540         tmp = optarg;
7541         if (strcmp(tmp, "arith") == 0 || strcmp(tmp, "a") == 0) {
7542            flags.arith = 1;
7543         } else if (strcmp(tmp, "logical") == 0 || strcmp(tmp, "l") == 0) {
7544            flags.logical = 1;
7545         } else if (strcmp(tmp, "compare") == 0 || strcmp(tmp, "c") == 0) {
7546            flags.compare = 1;
7547         } else if (strcmp(tmp, "storeload") == 0 || strcmp(tmp, "s") == 0) {
7548            flags.ldst = 1;
7549         } else {
7550            goto bad_arg;
7551         }
7552         break;
7553      case 'f':
7554         tmp = optarg;
7555         if (strcmp(tmp, "integer") == 0 || strcmp(tmp, "i") == 0) {
7556            flags.integer = 1;
7557         } else if (strcmp(tmp, "float") == 0 || strcmp(tmp, "f") == 0) {
7558            flags.floats = 1;
7559         } else if (strcmp(tmp, "ppc405") == 0 || strcmp(tmp, "mac") == 0) {
7560            flags.p405 = 1;
7561         } else if (strcmp(tmp, "altivec") == 0 || strcmp(tmp, "a") == 0) {
7562            flags.altivec = 1;
7563            flags.faltivec = 1;
7564         } else {
7565            goto bad_arg;
7566         }
7567         break;
7568      case 'n':
7569         filter = optarg;
7570         break;
7571      case 'r':
7572         tmp = optarg;
7573         if (strcmp(tmp, "large") == 0 || strcmp(tmp, "l") == 0) {
7574            arg_list_size = 1;
7575         } else if (strcmp(tmp, "small") == 0 || strcmp(tmp, "s") == 0) {
7576            arg_list_size = 0;
7577         } else {
7578            goto bad_arg;
7579         }
7580         break;
7581
7582      case 'u':
7583         flags.cr = 1;
7584         break;
7585      case 'h':
7586         usage();
7587         return 0;
7588      case 'v':
7589         verbose++;
7590         break;
7591      default:
7592         usage();
7593         fprintf(stderr, "Unknown argument: '%c'\n", c);
7594         return 1;
7595      bad_arg:
7596         usage();
7597         fprintf(stderr, "Bad argument for '%c': '%s'\n", c, tmp);
7598         return 1;
7599      }
7600   }
7601   if (argc != optind) {
7602      usage();
7603      fprintf(stderr, "Bad number of arguments\n");
7604      return 1;
7605   }
7606
7607   // Default n_args
7608   if (flags.one_arg == 0 && flags.two_args == 0 && flags.three_args == 0) {
7609      flags.one_arg = 1;
7610      flags.two_args = 1;
7611      flags.three_args = 1;
7612   }
7613   // Default type
7614   if (flags.arith == 0 && flags.logical == 0 &&
7615       flags.compare == 0 && flags.ldst == 0) {
7616      flags.arith   = 1;
7617      flags.logical = 1;
7618      flags.compare = 1;
7619      flags.ldst    = 1;
7620   }
7621   // Default family
7622   if (flags.integer == 0 && flags.floats == 0 &&
7623       flags.p405 == 0 && flags.altivec == 0 && flags.faltivec == 0) {
7624      flags.integer  = 1;
7625      flags.floats   = 1;
7626      flags.p405     = 1;
7627      flags.altivec  = 1;
7628      flags.faltivec = 1;
7629   }
7630   // Default cr update
7631   if (flags.cr == -1)
7632      flags.cr = 2;       // both
7633
7634#else // #if !defined (USAGE_SIMPLE)
7635////////////////////////////////////////////////////////////////////////
7636   /* Simple usage:
7637      ./jm-insns -i   => int insns
7638      ./jm-insns -f   => fp  insns
7639      ./jm-insns -a   => av  insns
7640      ./jm-insns -A   => int, fp and avinsns
7641   */
7642   char *filter = NULL;
7643   insn_sel_flags_t flags;
7644   int c;
7645
7646   // Args
7647   flags.one_arg    = 1;
7648   flags.two_args   = 1;
7649   flags.three_args = 1;
7650   // Type
7651   flags.arith      = 1;
7652   flags.logical    = 1;
7653   flags.compare    = 1;
7654   flags.ldst       = 1;
7655   // Family
7656   flags.integer    = 0;
7657   flags.floats     = 0;
7658   flags.p405       = 0;
7659   flags.altivec    = 0;
7660   flags.faltivec   = 0;
7661   // Flags
7662   flags.cr         = 2;
7663
7664   while ((c = getopt(argc, argv, "ifahvA")) != -1) {
7665      switch (c) {
7666      case 'i':
7667         flags.integer  = 1;
7668         break;
7669      case 'f':
7670         flags.floats   = 1;
7671         break;
7672      case 'a':
7673         flags.altivec  = 1;
7674         flags.faltivec = 1;
7675         break;
7676      case 'A':
7677         flags.integer  = 1;
7678         flags.floats   = 1;
7679         flags.altivec  = 1;
7680         flags.faltivec = 1;
7681         break;
7682      case 'h':
7683         usage();
7684         return 0;
7685      case 'v':
7686         verbose++;
7687         break;
7688      default:
7689         usage();
7690         fprintf(stderr, "Unknown argument: '%c'\n", c);
7691         return 1;
7692      }
7693   }
7694
7695   arg_list_size = 0;
7696#endif // #if !defined (USAGE_SIMPLE)
7697
7698
7699   build_iargs_table();
7700   build_fargs_table();
7701   build_ii16_table();
7702#if defined (HAS_ALTIVEC)
7703   if (flags.altivec || flags.faltivec) {
7704      build_viargs_table();
7705      build_vfargs_table();
7706   }
7707#endif
7708   // dump_iargs();
7709   // dump_iargs16();
7710   // dump_vfargs();
7711
7712   if (verbose > 1) {
7713      printf("\nInstruction Selection:\n");
7714      printf("  n_args: \n");
7715      printf("    one_arg    = %d\n", flags.one_arg);
7716      printf("    two_args   = %d\n", flags.two_args);
7717      printf("    three_args = %d\n", flags.three_args);
7718      printf("  type: \n");
7719      printf("    arith      = %d\n", flags.arith);
7720      printf("    logical    = %d\n", flags.logical);
7721      printf("    compare    = %d\n", flags.compare);
7722      printf("    ldst       = %d\n", flags.ldst);
7723      printf("  family: \n");
7724      printf("    integer    = %d\n", flags.integer);
7725      printf("    floats     = %d\n", flags.floats);
7726      printf("    p405       = %d\n", flags.p405);
7727      printf("    altivec    = %d\n", flags.altivec);
7728      printf("    faltivec   = %d\n", flags.faltivec);
7729      printf("  cr update: \n");
7730      printf("    cr         = %d\n", flags.cr);
7731      printf("\n");
7732      printf("  num args: \n");
7733      printf("    iargs      - %d\n", nb_iargs);
7734      printf("    fargs      - %d\n", nb_fargs);
7735#if defined (HAS_ALTIVEC)
7736      printf("    viargs     - %d\n", nb_viargs);
7737      printf("    vfargs     - %d\n", nb_vfargs);
7738#endif
7739      printf("\n");
7740   }
7741
7742   do_tests( flags, filter );
7743
7744   return 0;
7745}
7746