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