jm-insns.c revision 8f943afc22a6a683b78271836c8ddc462b4824a9
1
2/* HOW TO COMPILE:
3
4* 32bit build:
5   gcc -Winline -Wall -g -O -mregnames -maltivec
6* 64bit build:
7   gcc -Winline -Wall -g -O -mregnames -maltivec -m64
8
9This program is useful, but the register usage conventions in
10it are a complete dog.  In particular, _patch_op_imm has to
11be inlined, else you wind up with it segfaulting in
12completely different places due to corruption (of r20 in the
13case I chased).
14*/
15
16/*
17 * test-ppc.c:
18 * PPC tests for qemu-PPC CPU emulation checks
19 *
20 * Copyright (c) 2005 Jocelyn Mayer
21 *
22 *   This program is free software; you can redistribute it and/or
23 *   modify it under the terms of the GNU General Public License V2
24 *   as published by the Free Software Foundation
25 *
26 *   This program is distributed in the hope that it will be useful,
27 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
28 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29 *   GNU General Public License for more details.
30 *
31 *   You should have received a copy of the GNU General Public License
32 *   along with this program; if not, write to the Free Software
33 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
34 */
35
36/*
37 * Theory of operations:
38 * a few registers are reserved for the test program:
39 * r14 => r18
40 * f14 => f18
41 * I do preload test values in r14 thru r17 (or less, depending on the number
42 * of register operands needed), patch the test opcode if any immediate
43 * operands are required, execute the tested opcode.
44 * XER, CCR and FPSCR are cleared before every test.
45 * I always get the result in r17 and also save XER and CCR for fixed-point
46 * operations. I also check FPSCR for floating points operations.
47 *
48 * Improvments:
49 * a more clever FPSCR management is needed: for now, I always test
50 * the round-to-zero case. Other rounding modes also need to be tested.
51 */
52
53/*
54 * Operation details
55 * -----------------
56 * The 'test' functions (via all_tests[]) are wrappers of single asm instns
57 *
58 * The 'loops' (e.g. int_loops) do the actual work:
59 *  - loops over as many arguments as the instn needs (regs | imms)
60 *     - sets up the environment (reset cr,xer, assign src regs...)
61 *     - maybe modifies the asm instn to test different imm args
62 *     - calls the test function
63 *     - retrieves relevant register data (rD,cr,xer,...)
64 *     - prints argument and result data.
65 *
66 * More specifically...
67 *
68 * all_tests[i] holds insn tests
69 *  - of which each holds: {instn_test_arr[], description, flags}
70 *
71 * flags hold 3 instn classifiers: {family, type, arg_type}
72 *
73 * // The main test loop:
74 * do_tests( user_ctl_flags ) {
75 *    foreach(curr_test = all_test[i]) {
76 *
77 *       // flags are used to control what tests are run:
78 *       if (curr_test->flags && !user_ctl_flags)
79 *          continue;
80 *
81 *       // a 'loop_family_arr' is chosen based on the 'family' flag...
82 *       switch(curr_test->flags->family) {
83 *       case x: loop_family_arr = int_loops;
84 *      ...
85 *       }
86 *
87 *       // ...and the actual test_loop to run is found by indexing into
88 *       // the loop_family_arr with the 'arg_type' flag:
89 *       test_loop = loop_family[curr_test->flags->arg_type]
90 *
91 *       // finally, loop over all instn tests for this test:
92 *       foreach (instn_test = curr_test->instn_test_arr[i]) {
93 *
94 *          // and call the test_loop with the current instn_test function,name
95 *          test_loop( instn_test->func, instn_test->name )
96 *       }
97 *    }
98 * }
99 *
100 *
101 * Details of intruction patching for immediate operands
102 * -----------------------------------------------------
103 * All the immediate insn test functions are of the form {imm_insn, blr}
104 * In order to patch one of these functions, we simply copy both insns
105 * to a stack buffer, and rewrite the immediate part of imm_insn.
106 * We then execute our stack buffer.
107 * All ppc instructions are 32bits wide, which makes this fairly easy.
108 *
109 * Example:
110 * extern void test_addi (void);
111 * asm(".section \".text\"\n"
112 *     "    .align 2\n"
113 *     "    .type test_addi,@function\n"
114 *     "test_addi:\n"
115 *     "    addi\n"
116 *     "    blr\n"
117 *     "    .previous\n"
118 *     );
119 *
120 * We are interested only in:
121 *      "    addi         17, 14, 0\n"
122 *      "    blr\n"
123 *
124 * In a loop test, we may see:
125 * uint32_t func_buf[2];               // our new stack based 'function'
126 * for imm...                          // loop over imm
127 *   init_function( &func, func_buf );   // copy insns, set func ptr
128 *   patch_op_imm16(&func_buf[0], imm);  // patch 'addi' insn
129 *   ...
130 *   (*func)();                              // exec our rewritten code
131 *
132 * patch_op_imm16() itself simply takes the uint32_t insn and overwrites
133 * the immediate field with the new value (which, for 'addi', is the
134 * low 16 bits).
135 *
136 * So in the loop test, if 'imm' is currently 9, and p[0] is:
137 *   0x3A2E0000   => addi 17, 14, 0
138 *
139 * after patch_op_imm16(), func_buf[0] becomes:
140 *   0x3A2E0009   => addi 17, 14, 9
141 *
142 * Note: init_function() needs to be called on every iteration
143 *  - don't ask me why!
144*/
145
146
147/**********************************************************************/
148/* Uncomment to enable many arguments for altivec insns */
149#define USAGE_SIMPLE
150
151/* Uncomment to enable many arguments for altivec insns */
152//#define ALTIVEC_ARGS_LARGE
153
154/* Uncomment to enable output of CR flags for float tests */
155//#define TEST_FLOAT_FLAGS
156
157/* Uncomment to enable debug output */
158//#define DEBUG_ARGS_BUILD
159//#define DEBUG_FILTER
160
161/* These should be set at build time */
162//#define NO_FLOAT
163//#define HAS_ALTIVEC  // CFLAGS += -maltivec
164//#define IS_PPC405
165/**********************************************************************/
166
167
168#include <stdint.h>
169#include "tests/sys_mman.h"
170#include "tests/malloc.h"       // memalign16
171
172#define STATIC_ASSERT(e) sizeof(struct { int:-!(e); })
173
174/* Something of the same size as void*, so can be safely be coerced
175 * to/from a pointer type. Also same size as the host's gp registers.
176 * According to the AltiVec section of the GCC manual, the syntax does
177 * not allow the use of a typedef name as a type specifier in conjunction
178 * with the vector keyword, so typedefs uint[32|64]_t are #undef'ed here
179 * and redefined using #define.
180 */
181#undef uint32_t
182#undef uint64_t
183#define uint32_t unsigned int
184#define uint64_t unsigned long long int
185
186#ifndef __powerpc64__
187typedef uint32_t  HWord_t;
188#else
189typedef uint64_t  HWord_t;
190#endif /* __powerpc64__ */
191
192enum {
193    compile_time_test1 = STATIC_ASSERT(sizeof(uint32_t) == 4),
194    compile_time_test2 = STATIC_ASSERT(sizeof(uint64_t) == 8),
195};
196
197#define ALLCR "cr0","cr1","cr2","cr3","cr4","cr5","cr6","cr7"
198
199#define SET_CR(_arg) \
200      __asm__ __volatile__ ("mtcr  %0" : : "b"(_arg) : ALLCR );
201
202#define SET_XER(_arg) \
203      __asm__ __volatile__ ("mtxer %0" : : "b"(_arg) : "xer" );
204
205#define GET_CR(_lval) \
206      __asm__ __volatile__ ("mfcr %0"  : "=b"(_lval) )
207
208#define GET_XER(_lval) \
209      __asm__ __volatile__ ("mfxer %0" : "=b"(_lval) )
210
211#define GET_CR_XER(_lval_cr,_lval_xer) \
212   do { GET_CR(_lval_cr); GET_XER(_lval_xer); } while (0)
213
214#define SET_CR_ZERO \
215      SET_CR(0)
216
217#define SET_XER_ZERO \
218      SET_XER(0)
219
220#define SET_CR_XER_ZERO \
221   do { SET_CR_ZERO; SET_XER_ZERO; } while (0)
222
223#define SET_FPSCR_ZERO \
224   do { double _d = 0.0; \
225        __asm__ __volatile__ ("mtfsf 0xFF, %0" : : "f"(_d) ); \
226   } while (0)
227
228
229/* XXXX these must all be callee-save regs! */
230register double f14 __asm__ ("fr14");
231register double f15 __asm__ ("fr15");
232register double f16 __asm__ ("fr16");
233register double f17 __asm__ ("fr17");
234register HWord_t r14 __asm__ ("r14");
235register HWord_t r15 __asm__ ("r15");
236register HWord_t r16 __asm__ ("r16");
237register HWord_t r17 __asm__ ("r17");
238
239#include "config.h"         // HAS_ALTIVEC
240#if defined (HAS_ALTIVEC)
241#   include <altivec.h>
242#endif
243#include <assert.h>
244#include <ctype.h>     // isspace
245#include <stdio.h>
246#include <stdlib.h>
247#include <string.h>
248#include <unistd.h>    // getopt
249
250
251#ifndef __powerpc64__
252#define ASSEMBLY_FUNC(__fname, __insn)     \
253asm(".section \".text\"\n"                 \
254    "\t.align 2\n"                         \
255    "\t.type "__fname",@function\n"        \
256    __fname":\n"                           \
257    "\t"__insn"\n"                         \
258    "\tblr\n"                              \
259    "\t.previous\n"                        \
260    )
261#else
262#define ASSEMBLY_FUNC(__fname, __insn)     \
263asm(".section  \".text\"\n"                \
264    "\t.align 2\n"                         \
265    "\t.global "__fname"\n"                \
266    "\t.section \".opd\",\"aw\"\n"         \
267    "\t.align 3\n"                         \
268    ""__fname":\n"                         \
269    "\t.quad ."__fname",.TOC.@tocbase,0\n" \
270    "\t.previous\n"                        \
271    "\t.type ."__fname",@function\n"       \
272    "\t.global  ."__fname"\n"              \
273    "."__fname":\n"                        \
274    "\t"__insn"\n"                         \
275    "\tblr\n"                              \
276    )
277#endif // #ifndef __powerpc64__
278
279
280/* Return a pointer to a 1-page area where is is safe to both write
281   and execute instructions.  Area is filled with 'trap' insns. */
282static
283uint32_t* get_rwx_area ( void )
284{
285   int i;
286   static uint32_t* p = NULL;
287   if (p == NULL) {
288      p = mmap(NULL, 4096, PROT_READ|PROT_WRITE|PROT_EXEC,
289                           MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
290      assert(p != MAP_FAILED);
291   }
292
293   for (i = 0; i < 4096/sizeof(uint32_t); i++)
294      p[i] = 0x7fe00008; /* trap */
295
296   return p;
297}
298
299
300/* -------------- BEGIN #include "test-ppc.h" -------------- */
301/*
302 * test-ppc.h:
303 * PPC tests for qemu-PPC CPU emulation checks - definitions
304 *
305 * Copyright (c) 2005 Jocelyn Mayer
306 *
307 *   This program is free software; you can redistribute it and/or
308 *   modify it under the terms of the GNU General Public License V2
309 *   as published by the Free Software Foundation
310 *
311 *   This program is distributed in the hope that it will be useful,
312 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
313 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
314 *   GNU General Public License for more details.
315 *
316 *   You should have received a copy of the GNU General Public License
317 *   along with this program; if not, write to the Free Software
318 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
319 */
320
321#if !defined (__TEST_PPC_H__)
322#define __TEST_PPC_H__
323
324#include <stdint.h>
325
326typedef void (*test_func_t) (void);
327typedef struct test_t test_t;
328typedef struct test_table_t test_table_t;
329struct test_t {
330    test_func_t func;
331    const char *name;
332};
333
334struct test_table_t {
335    test_t *tests;
336    const char *name;
337    uint32_t flags;
338};
339
340typedef void (*test_loop_t) (const char *name, test_func_t func,
341                             uint32_t flags);
342
343enum test_flags {
344    /* Nb arguments */
345    PPC_ONE_ARG    = 0x00000001,
346    PPC_TWO_ARGS   = 0x00000002,
347    PPC_THREE_ARGS = 0x00000003,
348    PPC_CMP_ARGS   = 0x00000004,  // family: compare
349    PPC_CMPI_ARGS  = 0x00000005,  // family: compare
350    PPC_TWO_I16    = 0x00000006,  // family: arith/logical
351    PPC_SPECIAL    = 0x00000007,  // family: logical
352    PPC_LD_ARGS    = 0x00000008,  // family: ldst
353    PPC_LDX_ARGS   = 0x00000009,  // family: ldst
354    PPC_ST_ARGS    = 0x0000000A,  // family: ldst
355    PPC_STX_ARGS   = 0x0000000B,  // family: ldst
356    PPC_NB_ARGS    = 0x0000000F,
357    /* Type */
358    PPC_ARITH      = 0x00000100,
359    PPC_LOGICAL    = 0x00000200,
360    PPC_COMPARE    = 0x00000300,
361    PPC_CROP       = 0x00000400,
362    PPC_LDST       = 0x00000500,
363    PPC_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
1937static void test_fres (void)
1938{
1939    __asm__ __volatile__ ("fres         17, 14");
1940}
1941
1942static void test_frsqrte (void)
1943{
1944    __asm__ __volatile__ ("frsqrte      17, 14");
1945}
1946
1947static void test_frsp (void)
1948{
1949    __asm__ __volatile__ ("frsp         17, 14");
1950}
1951
1952static void test_fctiw (void)
1953{
1954    __asm__ __volatile__ ("fctiw        17, 14");
1955}
1956
1957static void test_fctiwz (void)
1958{
1959    __asm__ __volatile__ ("fctiwz       17, 14");
1960}
1961
1962static void test_fmr (void)
1963{
1964    __asm__ __volatile__ ("fmr          17, 14");
1965}
1966
1967static void test_fneg (void)
1968{
1969    __asm__ __volatile__ ("fneg         17, 14");
1970}
1971
1972static void test_fabs (void)
1973{
1974    __asm__ __volatile__ ("fabs         17, 14");
1975}
1976
1977static void test_fnabs (void)
1978{
1979    __asm__ __volatile__ ("fnabs        17, 14");
1980}
1981
1982static void test_fsqrt (void)
1983{
1984    __asm__ __volatile__ ("fsqrt        17, 14");
1985}
1986
1987#ifdef __powerpc64__
1988static void test_fcfid (void)
1989{
1990    __asm__ __volatile__ ("fcfid        17, 14");
1991}
1992
1993static void test_fctid (void)
1994{
1995    __asm__ __volatile__ ("fctid        17, 14");
1996}
1997
1998static void test_fctidz (void)
1999{
2000    __asm__ __volatile__ ("fctidz       17, 14");
2001}
2002#endif // #ifdef __powerpc64__
2003
2004static test_t tests_fa_ops_one[] = {
2005    { &test_fres            , "        fres", },
2006    { &test_frsqrte         , "     frsqrte", },
2007    { &test_frsp            , "        frsp", },
2008    { &test_fctiw           , "       fctiw", },
2009    { &test_fctiwz          , "      fctiwz", },
2010    { &test_fmr             , "         fmr", },
2011    { &test_fneg            , "        fneg", },
2012    { &test_fabs            , "        fabs", },
2013    { &test_fnabs           , "       fnabs", },
2014    { &test_fsqrt           , "       fsqrt", },
2015#ifdef __powerpc64__
2016    { &test_fcfid           , "       fcfid", },
2017    { &test_fctid           , "       fctid", },
2018    { &test_fctidz          , "      fctidz", },
2019#endif // #ifdef __powerpc64__
2020    { NULL,                   NULL,           },
2021};
2022#endif /* !defined (NO_FLOAT) */
2023
2024#if !defined (NO_FLOAT)
2025
2026static void test_fres_ (void)
2027{
2028    __asm__ __volatile__ ("fres.        17, 14");
2029}
2030
2031static void test_frsqrte_ (void)
2032{
2033    __asm__ __volatile__ ("frsqrte.     17, 14");
2034}
2035
2036static void test_frsp_ (void)
2037{
2038    __asm__ __volatile__ ("frsp.        17, 14");
2039}
2040
2041static void test_fctiw_ (void)
2042{
2043    __asm__ __volatile__ ("fctiw.       17, 14");
2044}
2045
2046static void test_fctiwz_ (void)
2047{
2048    __asm__ __volatile__ ("fctiwz.      17, 14");
2049}
2050
2051static void test_fmr_ (void)
2052{
2053    __asm__ __volatile__ ("fmr.         17, 14");
2054}
2055
2056static void test_fneg_ (void)
2057{
2058    __asm__ __volatile__ ("fneg.        17, 14");
2059}
2060
2061static void test_fabs_ (void)
2062{
2063    __asm__ __volatile__ ("fabs.        17, 14");
2064}
2065
2066static void test_fnabs_ (void)
2067{
2068    __asm__ __volatile__ ("fnabs.       17, 14");
2069}
2070
2071#ifdef __powerpc64__
2072static void test_fcfid_ (void)
2073{
2074    __asm__ __volatile__ ("fcfid.       17, 14");
2075}
2076
2077static void test_fctid_ (void)
2078{
2079    __asm__ __volatile__ ("fctid.       17, 14");
2080}
2081
2082static void test_fctidz_ (void)
2083{
2084    __asm__ __volatile__ ("fctidz.      17, 14");
2085}
2086#endif // #ifdef __powerpc64__
2087
2088static test_t tests_far_ops_one[] = {
2089    { &test_fres_           , "       fres.", },
2090    { &test_frsqrte_        , "    frsqrte.", },
2091    { &test_frsp_           , "       frsp.", },
2092    { &test_fctiw_          , "      fctiw.", },
2093    { &test_fctiwz_         , "     fctiwz.", },
2094    { &test_fmr_            , "        fmr.", },
2095    { &test_fneg_           , "       fneg.", },
2096    { &test_fabs_           , "       fabs.", },
2097    { &test_fnabs_          , "      fnabs.", },
2098#ifdef __powerpc64__
2099    { &test_fcfid_          , "      fcfid.", },
2100    { &test_fctid_          , "      fctid.", },
2101    { &test_fctidz_         , "     fctidz.", },
2102#endif // #ifdef __powerpc64__
2103    { NULL,                   NULL,           },
2104};
2105#endif /* !defined (NO_FLOAT) */
2106
2107#if !defined (NO_FLOAT)
2108static test_t tests_fl_ops_spe[] = {
2109    { NULL,                   NULL,           },
2110};
2111#endif /* !defined (NO_FLOAT) */
2112
2113#if !defined (NO_FLOAT)
2114static test_t tests_flr_ops_spe[] = {
2115    { NULL,                   NULL,           },
2116};
2117#endif /* !defined (NO_FLOAT) */
2118
2119
2120#if !defined (NO_FLOAT)
2121extern void test_lfs (void);
2122ASSEMBLY_FUNC("test_lfs", "lfs          17,0(14)");
2123
2124extern void test_lfsu (void);
2125ASSEMBLY_FUNC("test_lfsu", "lfsu          17,0(14)");
2126
2127extern void test_lfd (void);
2128ASSEMBLY_FUNC("test_lfd", "lfd          17,0(14)");
2129
2130extern void test_lfdu (void);
2131ASSEMBLY_FUNC("test_lfdu", "lfdu          17,0(14)");
2132
2133static test_t tests_fld_ops_two_i16[] = {
2134    { &test_lfs             , "         lfs", },
2135    { &test_lfsu            , "        lfsu", },
2136    { &test_lfd             , "         lfd", },
2137    { &test_lfdu            , "        lfdu", },
2138    { NULL,                   NULL,           },
2139};
2140#endif /* !defined (NO_FLOAT) */
2141
2142#if !defined (NO_FLOAT)
2143static void test_lfsx (void)
2144{
2145    __asm__ __volatile__ ("lfsx         17,14,15");
2146}
2147
2148static void test_lfsux (void)
2149{
2150    __asm__ __volatile__ ("lfsux        17,14,15");
2151}
2152
2153static void test_lfdx (void)
2154{
2155    __asm__ __volatile__ ("lfdx         17,14,15");
2156}
2157
2158static void test_lfdux (void)
2159{
2160    __asm__ __volatile__ ("lfdux        17,14,15");
2161}
2162
2163static test_t tests_fld_ops_two[] = {
2164    { &test_lfsx            , "        lfsx", },
2165    { &test_lfsux           , "       lfsux", },
2166    { &test_lfdx            , "        lfdx", },
2167    { &test_lfdux           , "       lfdux", },
2168    { NULL,                   NULL,           },
2169};
2170#endif /* !defined (NO_FLOAT) */
2171
2172#if !defined (NO_FLOAT)
2173extern void test_stfs (void);
2174ASSEMBLY_FUNC("test_stfs", "stfs          14,0(15)");
2175
2176extern void test_stfsu (void);
2177ASSEMBLY_FUNC("test_stfsu", "stfsu          14,0(15)");
2178
2179extern void test_stfd (void);
2180ASSEMBLY_FUNC("test_stfd", "stfd          14,0(15)");
2181
2182extern void test_stfdu (void);
2183ASSEMBLY_FUNC("test_stfdu", "stfdu         14,0(15)");
2184
2185static test_t tests_fst_ops_three_i16[] = {
2186    { &test_stfs             , "         stfs", },
2187    { &test_stfsu            , "        stfsu", },
2188    { &test_stfd             , "         stfd", },
2189    { &test_stfdu            , "        stfdu", },
2190    { NULL,                   NULL,           },
2191};
2192#endif /* !defined (NO_FLOAT) */
2193
2194#if !defined (NO_FLOAT)
2195static void test_stfsx (void)
2196{
2197    __asm__ __volatile__ ("stfsx         14,15,16");
2198}
2199
2200static void test_stfsux (void)
2201{
2202    __asm__ __volatile__ ("stfsux        14,15,16");
2203}
2204
2205static void test_stfdx (void)
2206{
2207    __asm__ __volatile__ ("stfdx         14,15,16");
2208}
2209
2210static void test_stfdux (void)
2211{
2212    __asm__ __volatile__ ("stfdux        14,15,16");
2213}
2214
2215static test_t tests_fst_ops_three[] = {
2216    { &test_stfsx            , "        stfsx", },
2217    { &test_stfsux           , "       stfsux", },
2218    { &test_stfdx            , "        stfdx", },
2219    { &test_stfdux           , "       stfdux", },
2220    { NULL,                   NULL,           },
2221};
2222#endif /* !defined (NO_FLOAT) */
2223
2224
2225#if defined (HAS_ALTIVEC)
2226static void test_vmhaddshs (void)
2227{
2228    __asm__ __volatile__ ("vmhaddshs    17, 14, 15, 16");
2229}
2230
2231static void test_vmhraddshs (void)
2232{
2233    __asm__ __volatile__ ("vmhraddshs   17, 14, 15, 16");
2234}
2235
2236static void test_vmladduhm (void)
2237{
2238    __asm__ __volatile__ ("vmladduhm    17, 14, 15, 16");
2239}
2240
2241static void test_vmsumubm (void)
2242{
2243    __asm__ __volatile__ ("vmsumubm     17, 14, 15, 16");
2244}
2245
2246static void test_vmsumuhm (void)
2247{
2248    __asm__ __volatile__ ("vmsumuhm     17, 14, 15, 16");
2249}
2250
2251static void test_vmsumshs (void)
2252{
2253    __asm__ __volatile__ ("vmsumshs     17, 14, 15, 16");
2254}
2255
2256static void test_vmsumuhs (void)
2257{
2258    __asm__ __volatile__ ("vmsumuhs     17, 14, 15, 16");
2259}
2260
2261static void test_vmsummbm (void)
2262{
2263    __asm__ __volatile__ ("vmsummbm     17, 14, 15, 16");
2264}
2265
2266static void test_vmsumshm (void)
2267{
2268    __asm__ __volatile__ ("vmsumshm     17, 14, 15, 16");
2269}
2270
2271static test_t tests_aa_ops_three[] = {
2272    { &test_vmhaddshs       , "   vmhaddshs", },
2273    { &test_vmhraddshs      , "  vmhraddshs", },
2274    { &test_vmladduhm       , "   vmladduhm", },
2275    { &test_vmsumubm        , "    vmsumubm", },
2276    { &test_vmsumuhm        , "    vmsumuhm", },
2277    { &test_vmsumshs        , "    vmsumshs", },
2278    { &test_vmsumuhs        , "    vmsumuhs", },
2279    { &test_vmsummbm        , "    vmsummbm", },
2280    { &test_vmsumshm        , "    vmsumshm", },
2281    { NULL,                   NULL,           },
2282};
2283#endif /* defined (HAS_ALTIVEC) */
2284
2285#if defined (HAS_ALTIVEC)
2286static void test_vperm (void)
2287{
2288    __asm__ __volatile__ ("vperm        17, 14, 15, 16");
2289}
2290
2291static void test_vsel (void)
2292{
2293    __asm__ __volatile__ ("vsel         17, 14, 15, 16");
2294}
2295
2296static test_t tests_al_ops_three[] = {
2297    { &test_vperm           , "       vperm", },
2298    { &test_vsel            , "        vsel", },
2299    { NULL,                   NULL,           },
2300};
2301#endif /* defined (HAS_ALTIVEC) */
2302
2303#if defined (HAS_ALTIVEC)
2304static void test_vaddubm (void)
2305{
2306    __asm__ __volatile__ ("vaddubm      17, 14, 15");
2307}
2308
2309static void test_vadduhm (void)
2310{
2311    __asm__ __volatile__ ("vadduhm      17, 14, 15");
2312}
2313
2314static void test_vadduwm (void)
2315{
2316    __asm__ __volatile__ ("vadduwm      17, 14, 15");
2317}
2318
2319static void test_vaddubs (void)
2320{
2321    __asm__ __volatile__ ("vaddubs      17, 14, 15");
2322}
2323
2324static void test_vadduhs (void)
2325{
2326    __asm__ __volatile__ ("vadduhs      17, 14, 15");
2327}
2328
2329static void test_vadduws (void)
2330{
2331    __asm__ __volatile__ ("vadduws      17, 14, 15");
2332}
2333
2334static void test_vaddsbs (void)
2335{
2336    __asm__ __volatile__ ("vaddsbs      17, 14, 15");
2337}
2338
2339static void test_vaddshs (void)
2340{
2341    __asm__ __volatile__ ("vaddshs      17, 14, 15");
2342}
2343
2344static void test_vaddsws (void)
2345{
2346    __asm__ __volatile__ ("vaddsws      17, 14, 15");
2347}
2348
2349static void test_vaddcuw (void)
2350{
2351    __asm__ __volatile__ ("vaddcuw      17, 14, 15");
2352}
2353
2354static void test_vsububm (void)
2355{
2356    __asm__ __volatile__ ("vsububm      17, 14, 15");
2357}
2358
2359static void test_vsubuhm (void)
2360{
2361    __asm__ __volatile__ ("vsubuhm      17, 14, 15");
2362}
2363
2364static void test_vsubuwm (void)
2365{
2366    __asm__ __volatile__ ("vsubuwm      17, 14, 15");
2367}
2368
2369static void test_vsububs (void)
2370{
2371    __asm__ __volatile__ ("vsububs      17, 14, 15");
2372}
2373
2374static void test_vsubuhs (void)
2375{
2376    __asm__ __volatile__ ("vsubuhs      17, 14, 15");
2377}
2378
2379static void test_vsubuws (void)
2380{
2381    __asm__ __volatile__ ("vsubuws      17, 14, 15");
2382}
2383
2384static void test_vsubsbs (void)
2385{
2386    __asm__ __volatile__ ("vsubsbs      17, 14, 15");
2387}
2388
2389static void test_vsubshs (void)
2390{
2391    __asm__ __volatile__ ("vsubshs      17, 14, 15");
2392}
2393
2394static void test_vsubsws (void)
2395{
2396    __asm__ __volatile__ ("vsubsws      17, 14, 15");
2397}
2398
2399static void test_vsubcuw (void)
2400{
2401    __asm__ __volatile__ ("vsubcuw      17, 14, 15");
2402}
2403
2404static void test_vmuloub (void)
2405{
2406    __asm__ __volatile__ ("vmuloub      17, 14, 15");
2407}
2408
2409static void test_vmulouh (void)
2410{
2411    __asm__ __volatile__ ("vmulouh      17, 14, 15");
2412}
2413
2414static void test_vmulosb (void)
2415{
2416    __asm__ __volatile__ ("vmulosb      17, 14, 15");
2417}
2418
2419static void test_vmulosh (void)
2420{
2421    __asm__ __volatile__ ("vmulosh      17, 14, 15");
2422}
2423
2424static void test_vmuleub (void)
2425{
2426    __asm__ __volatile__ ("vmuleub      17, 14, 15");
2427}
2428
2429static void test_vmuleuh (void)
2430{
2431    __asm__ __volatile__ ("vmuleuh      17, 14, 15");
2432}
2433
2434static void test_vmulesb (void)
2435{
2436    __asm__ __volatile__ ("vmulesb      17, 14, 15");
2437}
2438
2439static void test_vmulesh (void)
2440{
2441    __asm__ __volatile__ ("vmulesh      17, 14, 15");
2442}
2443
2444static void test_vsumsws (void)
2445{
2446    __asm__ __volatile__ ("vsumsws      17, 14, 15");
2447}
2448
2449static void test_vsum2sws (void)
2450{
2451    __asm__ __volatile__ ("vsum2sws     17, 14, 15");
2452}
2453
2454static void test_vsum4ubs (void)
2455{
2456    __asm__ __volatile__ ("vsum4ubs     17, 14, 15");
2457}
2458
2459static void test_vsum4sbs (void)
2460{
2461    __asm__ __volatile__ ("vsum4sbs     17, 14, 15");
2462}
2463
2464static void test_vsum4shs (void)
2465{
2466    __asm__ __volatile__ ("vsum4shs     17, 14, 15");
2467}
2468
2469static void test_vavgub (void)
2470{
2471    __asm__ __volatile__ ("vavgub       17, 14, 15");
2472}
2473
2474static void test_vavguh (void)
2475{
2476    __asm__ __volatile__ ("vavguh       17, 14, 15");
2477}
2478
2479static void test_vavguw (void)
2480{
2481    __asm__ __volatile__ ("vavguw       17, 14, 15");
2482}
2483
2484static void test_vavgsb (void)
2485{
2486    __asm__ __volatile__ ("vavgsb       17, 14, 15");
2487}
2488
2489static void test_vavgsh (void)
2490{
2491    __asm__ __volatile__ ("vavgsh       17, 14, 15");
2492}
2493
2494static void test_vavgsw (void)
2495{
2496    __asm__ __volatile__ ("vavgsw       17, 14, 15");
2497}
2498
2499static void test_vmaxub (void)
2500{
2501    __asm__ __volatile__ ("vmaxub       17, 14, 15");
2502}
2503
2504static void test_vmaxuh (void)
2505{
2506    __asm__ __volatile__ ("vmaxuh       17, 14, 15");
2507}
2508
2509static void test_vmaxuw (void)
2510{
2511    __asm__ __volatile__ ("vmaxuw       17, 14, 15");
2512}
2513
2514static void test_vmaxsb (void)
2515{
2516    __asm__ __volatile__ ("vmaxsb       17, 14, 15");
2517}
2518
2519static void test_vmaxsh (void)
2520{
2521    __asm__ __volatile__ ("vmaxsh       17, 14, 15");
2522}
2523
2524static void test_vmaxsw (void)
2525{
2526    __asm__ __volatile__ ("vmaxsw       17, 14, 15");
2527}
2528
2529static void test_vminub (void)
2530{
2531    __asm__ __volatile__ ("vminub       17, 14, 15");
2532}
2533
2534static void test_vminuh (void)
2535{
2536    __asm__ __volatile__ ("vminuh       17, 14, 15");
2537}
2538
2539static void test_vminuw (void)
2540{
2541    __asm__ __volatile__ ("vminuw       17, 14, 15");
2542}
2543
2544static void test_vminsb (void)
2545{
2546    __asm__ __volatile__ ("vminsb       17, 14, 15");
2547}
2548
2549static void test_vminsh (void)
2550{
2551    __asm__ __volatile__ ("vminsh       17, 14, 15");
2552}
2553
2554static void test_vminsw (void)
2555{
2556    __asm__ __volatile__ ("vminsw       17, 14, 15");
2557}
2558
2559static test_t tests_aa_ops_two[] = {
2560    { &test_vaddubm         , "     vaddubm", },
2561    { &test_vadduhm         , "     vadduhm", },
2562    { &test_vadduwm         , "     vadduwm", },
2563    { &test_vaddubs         , "     vaddubs", },
2564    { &test_vadduhs         , "     vadduhs", },
2565    { &test_vadduws         , "     vadduws", },
2566    { &test_vaddsbs         , "     vaddsbs", },
2567    { &test_vaddshs         , "     vaddshs", },
2568    { &test_vaddsws         , "     vaddsws", },
2569    { &test_vaddcuw         , "     vaddcuw", },
2570    { &test_vsububm         , "     vsububm", },
2571    { &test_vsubuhm         , "     vsubuhm", },
2572    { &test_vsubuwm         , "     vsubuwm", },
2573    { &test_vsububs         , "     vsububs", },
2574    { &test_vsubuhs         , "     vsubuhs", },
2575    { &test_vsubuws         , "     vsubuws", },
2576    { &test_vsubsbs         , "     vsubsbs", },
2577    { &test_vsubshs         , "     vsubshs", },
2578    { &test_vsubsws         , "     vsubsws", },
2579    { &test_vsubcuw         , "     vsubcuw", },
2580    { &test_vmuloub         , "     vmuloub", },
2581    { &test_vmulouh         , "     vmulouh", },
2582    { &test_vmulosb         , "     vmulosb", },
2583    { &test_vmulosh         , "     vmulosh", },
2584    { &test_vmuleub         , "     vmuleub", },
2585    { &test_vmuleuh         , "     vmuleuh", },
2586    { &test_vmulesb         , "     vmulesb", },
2587    { &test_vmulesh         , "     vmulesh", },
2588    { &test_vsumsws         , "     vsumsws", },
2589    { &test_vsum2sws        , "    vsum2sws", },
2590    { &test_vsum4ubs        , "    vsum4ubs", },
2591    { &test_vsum4sbs        , "    vsum4sbs", },
2592    { &test_vsum4shs        , "    vsum4shs", },
2593    { &test_vavgub          , "      vavgub", },
2594    { &test_vavguh          , "      vavguh", },
2595    { &test_vavguw          , "      vavguw", },
2596    { &test_vavgsb          , "      vavgsb", },
2597    { &test_vavgsh          , "      vavgsh", },
2598    { &test_vavgsw          , "      vavgsw", },
2599    { &test_vmaxub          , "      vmaxub", },
2600    { &test_vmaxuh          , "      vmaxuh", },
2601    { &test_vmaxuw          , "      vmaxuw", },
2602    { &test_vmaxsb          , "      vmaxsb", },
2603    { &test_vmaxsh          , "      vmaxsh", },
2604    { &test_vmaxsw          , "      vmaxsw", },
2605    { &test_vminub          , "      vminub", },
2606    { &test_vminuh          , "      vminuh", },
2607    { &test_vminuw          , "      vminuw", },
2608    { &test_vminsb          , "      vminsb", },
2609    { &test_vminsh          , "      vminsh", },
2610    { &test_vminsw          , "      vminsw", },
2611    { NULL,                   NULL,           },
2612};
2613#endif /* defined (HAS_ALTIVEC) */
2614
2615#if defined (HAS_ALTIVEC)
2616static void test_vand (void)
2617{
2618    __asm__ __volatile__ ("vand         17, 14, 15");
2619}
2620
2621static void test_vor (void)
2622{
2623    __asm__ __volatile__ ("vor          17, 14, 15");
2624}
2625
2626static void test_vxor (void)
2627{
2628    __asm__ __volatile__ ("vxor         17, 14, 15");
2629}
2630
2631static void test_vandc (void)
2632{
2633    __asm__ __volatile__ ("vandc        17, 14, 15");
2634}
2635
2636static void test_vnor (void)
2637{
2638    __asm__ __volatile__ ("vnor         17, 14, 15");
2639}
2640
2641static void test_vrlb (void)
2642{
2643    __asm__ __volatile__ ("vrlb         17, 14, 15");
2644}
2645
2646static void test_vrlh (void)
2647{
2648    __asm__ __volatile__ ("vrlh         17, 14, 15");
2649}
2650
2651static void test_vrlw (void)
2652{
2653    __asm__ __volatile__ ("vrlw         17, 14, 15");
2654}
2655
2656static void test_vslb (void)
2657{
2658    __asm__ __volatile__ ("vslb         17, 14, 15");
2659}
2660
2661static void test_vslh (void)
2662{
2663    __asm__ __volatile__ ("vslh         17, 14, 15");
2664}
2665
2666static void test_vslw (void)
2667{
2668    __asm__ __volatile__ ("vslw         17, 14, 15");
2669}
2670
2671static void test_vsrb (void)
2672{
2673    __asm__ __volatile__ ("vsrb         17, 14, 15");
2674}
2675
2676static void test_vsrh (void)
2677{
2678    __asm__ __volatile__ ("vsrh         17, 14, 15");
2679}
2680
2681static void test_vsrw (void)
2682{
2683    __asm__ __volatile__ ("vsrw         17, 14, 15");
2684}
2685
2686static void test_vsrab (void)
2687{
2688    __asm__ __volatile__ ("vsrab        17, 14, 15");
2689}
2690
2691static void test_vsrah (void)
2692{
2693    __asm__ __volatile__ ("vsrah        17, 14, 15");
2694}
2695
2696static void test_vsraw (void)
2697{
2698    __asm__ __volatile__ ("vsraw        17, 14, 15");
2699}
2700
2701static void test_vpkuhum (void)
2702{
2703    __asm__ __volatile__ ("vpkuhum      17, 14, 15");
2704}
2705
2706static void test_vpkuwum (void)
2707{
2708    __asm__ __volatile__ ("vpkuwum      17, 14, 15");
2709}
2710
2711static void test_vpkuhus (void)
2712{
2713    __asm__ __volatile__ ("vpkuhus      17, 14, 15");
2714}
2715
2716static void test_vpkuwus (void)
2717{
2718    __asm__ __volatile__ ("vpkuwus      17, 14, 15");
2719}
2720
2721static void test_vpkshus (void)
2722{
2723    __asm__ __volatile__ ("vpkshus      17, 14, 15");
2724}
2725
2726static void test_vpkswus (void)
2727{
2728    __asm__ __volatile__ ("vpkswus      17, 14, 15");
2729}
2730
2731static void test_vpkshss (void)
2732{
2733    __asm__ __volatile__ ("vpkshss      17, 14, 15");
2734}
2735
2736static void test_vpkswss (void)
2737{
2738    __asm__ __volatile__ ("vpkswss      17, 14, 15");
2739}
2740
2741static void test_vpkpx (void)
2742{
2743    __asm__ __volatile__ ("vpkpx        17, 14, 15");
2744}
2745
2746static void test_vmrghb (void)
2747{
2748    __asm__ __volatile__ ("vmrghb       17, 14, 15");
2749}
2750
2751static void test_vmrghh (void)
2752{
2753    __asm__ __volatile__ ("vmrghh       17, 14, 15");
2754}
2755
2756static void test_vmrghw (void)
2757{
2758    __asm__ __volatile__ ("vmrghw       17, 14, 15");
2759}
2760
2761static void test_vmrglb (void)
2762{
2763    __asm__ __volatile__ ("vmrglb       17, 14, 15");
2764}
2765
2766static void test_vmrglh (void)
2767{
2768    __asm__ __volatile__ ("vmrglh       17, 14, 15");
2769}
2770
2771static void test_vmrglw (void)
2772{
2773    __asm__ __volatile__ ("vmrglw       17, 14, 15");
2774}
2775
2776static void test_vslo (void)
2777{
2778    __asm__ __volatile__ ("vslo         17, 14, 15");
2779}
2780
2781static void test_vsro (void)
2782{
2783    __asm__ __volatile__ ("vsro         17, 14, 15");
2784}
2785
2786static test_t tests_al_ops_two[] = {
2787    { &test_vand            , "        vand", },
2788    { &test_vor             , "         vor", },
2789    { &test_vxor            , "        vxor", },
2790    { &test_vandc           , "       vandc", },
2791    { &test_vnor            , "        vnor", },
2792    { &test_vrlb            , "        vrlb", },
2793    { &test_vrlh            , "        vrlh", },
2794    { &test_vrlw            , "        vrlw", },
2795    { &test_vslb            , "        vslb", },
2796    { &test_vslh            , "        vslh", },
2797    { &test_vslw            , "        vslw", },
2798    { &test_vsrb            , "        vsrb", },
2799    { &test_vsrh            , "        vsrh", },
2800    { &test_vsrw            , "        vsrw", },
2801    { &test_vsrab           , "       vsrab", },
2802    { &test_vsrah           , "       vsrah", },
2803    { &test_vsraw           , "       vsraw", },
2804    { &test_vpkuhum         , "     vpkuhum", },
2805    { &test_vpkuwum         , "     vpkuwum", },
2806    { &test_vpkuhus         , "     vpkuhus", },
2807    { &test_vpkuwus         , "     vpkuwus", },
2808    { &test_vpkshus         , "     vpkshus", },
2809    { &test_vpkswus         , "     vpkswus", },
2810    { &test_vpkshss         , "     vpkshss", },
2811    { &test_vpkswss         , "     vpkswss", },
2812    { &test_vpkpx           , "       vpkpx", },
2813    { &test_vmrghb          , "      vmrghb", },
2814    { &test_vmrghh          , "      vmrghh", },
2815    { &test_vmrghw          , "      vmrghw", },
2816    { &test_vmrglb          , "      vmrglb", },
2817    { &test_vmrglh          , "      vmrglh", },
2818    { &test_vmrglw          , "      vmrglw", },
2819    { &test_vslo            , "        vslo", },
2820    { &test_vsro            , "        vsro", },
2821    { NULL,                   NULL,           },
2822};
2823#endif /* defined (HAS_ALTIVEC) */
2824
2825#if defined (HAS_ALTIVEC)
2826static void test_vupkhsb (void)
2827{
2828    __asm__ __volatile__ ("vupkhsb      17, 14");
2829}
2830
2831static void test_vupkhsh (void)
2832{
2833    __asm__ __volatile__ ("vupkhsh      17, 14");
2834}
2835
2836static void test_vupkhpx (void)
2837{
2838    __asm__ __volatile__ ("vupkhpx      17, 14");
2839}
2840
2841static void test_vupklsb (void)
2842{
2843    __asm__ __volatile__ ("vupklsb      17, 14");
2844}
2845
2846static void test_vupklsh (void)
2847{
2848    __asm__ __volatile__ ("vupklsh      17, 14");
2849}
2850
2851static void test_vupklpx (void)
2852{
2853    __asm__ __volatile__ ("vupklpx      17, 14");
2854}
2855
2856static test_t tests_al_ops_one[] = {
2857    { &test_vupkhsb         , "     vupkhsb", },
2858    { &test_vupkhsh         , "     vupkhsh", },
2859    { &test_vupkhpx         , "     vupkhpx", },
2860    { &test_vupklsb         , "     vupklsb", },
2861    { &test_vupklsh         , "     vupklsh", },
2862    { &test_vupklpx         , "     vupklpx", },
2863    { NULL,                   NULL,           },
2864};
2865#endif /* defined (HAS_ALTIVEC) */
2866
2867#if defined (HAS_ALTIVEC)
2868static void test_vcmpgtub (void)
2869{
2870    __asm__ __volatile__ ("vcmpgtub     17, 14, 15");
2871}
2872
2873static void test_vcmpgtuh (void)
2874{
2875    __asm__ __volatile__ ("vcmpgtuh     17, 14, 15");
2876}
2877
2878static void test_vcmpgtuw (void)
2879{
2880    __asm__ __volatile__ ("vcmpgtuw     17, 14, 15");
2881}
2882
2883static void test_vcmpgtsb (void)
2884{
2885    __asm__ __volatile__ ("vcmpgtsb     17, 14, 15");
2886}
2887
2888static void test_vcmpgtsh (void)
2889{
2890    __asm__ __volatile__ ("vcmpgtsh     17, 14, 15");
2891}
2892
2893static void test_vcmpgtsw (void)
2894{
2895    __asm__ __volatile__ ("vcmpgtsw     17, 14, 15");
2896}
2897
2898static void test_vcmpequb (void)
2899{
2900    __asm__ __volatile__ ("vcmpequb     17, 14, 15");
2901}
2902
2903static void test_vcmpequh (void)
2904{
2905    __asm__ __volatile__ ("vcmpequh     17, 14, 15");
2906}
2907
2908static void test_vcmpequw (void)
2909{
2910    __asm__ __volatile__ ("vcmpequw     17, 14, 15");
2911}
2912
2913static test_t tests_ac_ops_two[] = {
2914    { &test_vcmpgtub        , "    vcmpgtub", },
2915    { &test_vcmpgtuh        , "    vcmpgtuh", },
2916    { &test_vcmpgtuw        , "    vcmpgtuw", },
2917    { &test_vcmpgtsb        , "    vcmpgtsb", },
2918    { &test_vcmpgtsh        , "    vcmpgtsh", },
2919    { &test_vcmpgtsw        , "    vcmpgtsw", },
2920    { &test_vcmpequb        , "    vcmpequb", },
2921    { &test_vcmpequh        , "    vcmpequh", },
2922    { &test_vcmpequw        , "    vcmpequw", },
2923    { NULL,                   NULL,           },
2924};
2925#endif /* defined (HAS_ALTIVEC) */
2926
2927#if defined (HAS_ALTIVEC)
2928static void test_vcmpgtub_ (void)
2929{
2930    __asm__ __volatile__ ("vcmpgtub.    17, 14, 15");
2931}
2932
2933static void test_vcmpgtuh_ (void)
2934{
2935    __asm__ __volatile__ ("vcmpgtuh.    17, 14, 15");
2936}
2937
2938static void test_vcmpgtuw_ (void)
2939{
2940    __asm__ __volatile__ ("vcmpgtuw.    17, 14, 15");
2941}
2942
2943static void test_vcmpgtsb_ (void)
2944{
2945    __asm__ __volatile__ ("vcmpgtsb.    17, 14, 15");
2946}
2947
2948static void test_vcmpgtsh_ (void)
2949{
2950    __asm__ __volatile__ ("vcmpgtsh.    17, 14, 15");
2951}
2952
2953static void test_vcmpgtsw_ (void)
2954{
2955    __asm__ __volatile__ ("vcmpgtsw.    17, 14, 15");
2956}
2957
2958static void test_vcmpequb_ (void)
2959{
2960    __asm__ __volatile__ ("vcmpequb.    17, 14, 15");
2961}
2962
2963static void test_vcmpequh_ (void)
2964{
2965    __asm__ __volatile__ ("vcmpequh.    17, 14, 15");
2966}
2967
2968static void test_vcmpequw_ (void)
2969{
2970    __asm__ __volatile__ ("vcmpequw.    17, 14, 15");
2971}
2972
2973static test_t tests_acr_ops_two[] = {
2974    { &test_vcmpgtub_       , "   vcmpgtub.", },
2975    { &test_vcmpgtuh_       , "   vcmpgtuh.", },
2976    { &test_vcmpgtuw_       , "   vcmpgtuw.", },
2977    { &test_vcmpgtsb_       , "   vcmpgtsb.", },
2978    { &test_vcmpgtsh_       , "   vcmpgtsh.", },
2979    { &test_vcmpgtsw_       , "   vcmpgtsw.", },
2980    { &test_vcmpequb_       , "   vcmpequb.", },
2981    { &test_vcmpequh_       , "   vcmpequh.", },
2982    { &test_vcmpequw_       , "   vcmpequw.", },
2983    { NULL,                   NULL,           },
2984};
2985#endif /* defined (HAS_ALTIVEC) */
2986
2987#if defined (HAS_ALTIVEC)
2988static void test_vsl (void)
2989{
2990    __asm__ __volatile__ ("vsl          17, 14, 15");
2991}
2992
2993static void test_vsr (void)
2994{
2995    __asm__ __volatile__ ("vsr          17, 14, 15");
2996}
2997
2998extern void test_vspltb (void);
2999ASSEMBLY_FUNC("test_vspltb", "vspltb       17, 14, 0");
3000
3001extern void test_vsplth (void);
3002ASSEMBLY_FUNC("test_vsplth", "vsplth       17, 14, 0");
3003
3004extern void test_vspltw (void);
3005ASSEMBLY_FUNC("test_vspltw", "vspltw       17, 14, 0");
3006
3007extern void test_vspltisb (void);
3008ASSEMBLY_FUNC("test_vspltisb", "vspltisb       17, 0");
3009
3010extern void test_vspltish (void);
3011ASSEMBLY_FUNC("test_vspltish", "vspltish       17, 0");
3012
3013extern void test_vspltisw (void);
3014ASSEMBLY_FUNC("test_vspltisw", "vspltisw       17, 0");
3015
3016extern void test_vsldoi (void);
3017ASSEMBLY_FUNC("test_vsldoi", "vsldoi       17, 14, 15, 0");
3018
3019static void test_lvsl (void)
3020{
3021    __asm__ __volatile__ ("lvsl         17, 14, 15");
3022}
3023
3024static void test_lvsr (void)
3025{
3026    __asm__ __volatile__ ("lvsr         17, 14, 15");
3027}
3028
3029static test_t tests_av_int_ops_spe[] = {
3030    { &test_vsl             , "         vsl", },
3031    { &test_vsr             , "         vsr", },
3032    { &test_vspltb          , "      vspltb", },
3033    { &test_vsplth          , "      vsplth", },
3034    { &test_vspltw          , "      vspltw", },
3035    { &test_vspltisb        , "    vspltisb", },
3036    { &test_vspltish        , "    vspltish", },
3037    { &test_vspltisw        , "    vspltisw", },
3038    { &test_vsldoi          , "      vsldoi", },
3039    { &test_lvsl            , "        lvsl", },
3040    { &test_lvsr            , "        lvsr", },
3041    { NULL,                   NULL,           },
3042};
3043#endif /* defined (HAS_ALTIVEC) */
3044
3045#if defined (HAS_ALTIVEC)
3046static void test_lvebx (void)
3047{
3048    __asm__ __volatile__ ("lvebx        17,14,15");
3049}
3050
3051static void test_lvehx (void)
3052{
3053    __asm__ __volatile__ ("lvehx        17,14,15");
3054}
3055
3056static void test_lvewx (void)
3057{
3058    __asm__ __volatile__ ("lvewx        17,14,15");
3059}
3060
3061static void test_lvx (void)
3062{
3063    __asm__ __volatile__ ("lvx          17,14,15");
3064}
3065
3066static void test_lvxl (void)
3067{
3068    __asm__ __volatile__ ("lvxl         17,14,15");
3069}
3070
3071static test_t tests_ald_ops_two[] = {
3072    { &test_lvebx           , "       lvebx", },
3073    { &test_lvehx           , "       lvehx", },
3074    { &test_lvewx           , "       lvewx", },
3075    { &test_lvx             , "         lvx", },
3076    { &test_lvxl            , "        lvxl", },
3077    { NULL,                   NULL,           },
3078};
3079#endif /* defined (HAS_ALTIVEC) */
3080
3081#if defined (HAS_ALTIVEC)
3082static void test_stvebx (void)
3083{
3084    __asm__ __volatile__ ("stvebx       14,15,16");
3085}
3086
3087static void test_stvehx (void)
3088{
3089    __asm__ __volatile__ ("stvehx       14,15,16");
3090}
3091
3092static void test_stvewx (void)
3093{
3094    __asm__ __volatile__ ("stvewx       14,15,16");
3095}
3096
3097static void test_stvx (void)
3098{
3099    __asm__ __volatile__ ("stvx         14,15,16");
3100}
3101
3102static void test_stvxl (void)
3103{
3104    __asm__ __volatile__ ("stvxl        14,15,16");
3105}
3106
3107static test_t tests_ast_ops_three[] = {
3108    { &test_stvebx          , "      stvebx", },
3109    { &test_stvehx          , "      stvehx", },
3110    { &test_stvewx          , "      stvewx", },
3111    { &test_stvx            , "        stvx", },
3112    { &test_stvxl           , "       stvxl", },
3113    { NULL,                   NULL,           },
3114};
3115#endif /* defined (HAS_ALTIVEC) */
3116
3117#if defined (HAS_ALTIVEC)
3118#if 0
3119static void test_vmaddfp (void)
3120{
3121    __asm__ __volatile__ ("vmaddfp      17, 14, 15, 16");
3122}
3123
3124static void test_vnmsubfp (void)
3125{
3126    __asm__ __volatile__ ("vnmsubfp     17, 14, 15, 16");
3127}
3128#endif
3129
3130static test_t tests_afa_ops_three[] = {
3131//    { &test_vmaddfp         , "     vmaddfp", },   // TODO: Not yet supported
3132//    { &test_vnmsubfp        , "    vnmsubfp", },   // TODO: Not yet supported
3133    { NULL,                   NULL,           },
3134};
3135#endif /* defined (HAS_ALTIVEC) */
3136
3137#if defined (HAS_ALTIVEC)
3138static void test_vaddfp (void)
3139{
3140    __asm__ __volatile__ ("vaddfp       17, 14, 15");
3141}
3142
3143static void test_vsubfp (void)
3144{
3145    __asm__ __volatile__ ("vsubfp       17, 14, 15");
3146}
3147
3148static void test_vmaxfp (void)
3149{
3150    __asm__ __volatile__ ("vmaxfp       17, 14, 15");
3151}
3152
3153static void test_vminfp (void)
3154{
3155    __asm__ __volatile__ ("vminfp       17, 14, 15");
3156}
3157
3158static test_t tests_afa_ops_two[] = {
3159    { &test_vaddfp          , "      vaddfp", },
3160    { &test_vsubfp          , "      vsubfp", },
3161    { &test_vmaxfp          , "      vmaxfp", },
3162    { &test_vminfp          , "      vminfp", },
3163    { NULL,                   NULL,           },
3164};
3165#endif /* defined (HAS_ALTIVEC) */
3166
3167#if defined (HAS_ALTIVEC)
3168static void test_vrfin (void)
3169{
3170    __asm__ __volatile__ ("vrfin        17, 14");
3171}
3172
3173static void test_vrfiz (void)
3174{
3175    __asm__ __volatile__ ("vrfiz        17, 14");
3176}
3177
3178static void test_vrfip (void)
3179{
3180    __asm__ __volatile__ ("vrfip        17, 14");
3181}
3182
3183static void test_vrfim (void)
3184{
3185    __asm__ __volatile__ ("vrfim        17, 14");
3186}
3187
3188static void test_vrefp (void)
3189{
3190    __asm__ __volatile__ ("vrefp        17, 14");
3191}
3192
3193static void test_vrsqrtefp (void)
3194{
3195    __asm__ __volatile__ ("vrsqrtefp    17, 14");
3196}
3197
3198#if 0   // TODO: Not yet supported
3199static void test_vlogefp (void)
3200{
3201    __asm__ __volatile__ ("vlogefp      17, 14");
3202}
3203
3204static void test_vexptefp (void)
3205{
3206    __asm__ __volatile__ ("vexptefp     17, 14");
3207}
3208#endif
3209
3210static test_t tests_afa_ops_one[] = {
3211    { &test_vrfin           , "       vrfin", },
3212    { &test_vrfiz           , "       vrfiz", },
3213    { &test_vrfip           , "       vrfip", },
3214    { &test_vrfim           , "       vrfim", },
3215    { &test_vrefp           , "       vrefp", },
3216    { &test_vrsqrtefp       , "   vrsqrtefp", },
3217    //    { &test_vlogefp         , "     vlogefp", },   // TODO: Not yet supported
3218    //    { &test_vexptefp        , "    vexptefp", },   // TODO: Not yet supported
3219    { NULL,                   NULL,           },
3220};
3221#endif /* defined (HAS_ALTIVEC) */
3222
3223#if defined (HAS_ALTIVEC)
3224static void test_vcmpgtfp (void)
3225{
3226    __asm__ __volatile__ ("vcmpgtfp     17, 14, 15");
3227}
3228
3229static void test_vcmpeqfp (void)
3230{
3231    __asm__ __volatile__ ("vcmpeqfp     17, 14, 15");
3232}
3233
3234static void test_vcmpgefp (void)
3235{
3236    __asm__ __volatile__ ("vcmpgefp     17, 14, 15");
3237}
3238
3239static void test_vcmpbfp (void)
3240{
3241    __asm__ __volatile__ ("vcmpbfp      17, 14, 15");
3242}
3243
3244static test_t tests_afc_ops_two[] = {
3245    { &test_vcmpgtfp        , "    vcmpgtfp", },
3246    { &test_vcmpeqfp        , "    vcmpeqfp", },
3247    { &test_vcmpgefp        , "    vcmpgefp", },
3248    { &test_vcmpbfp         , "     vcmpbfp", },
3249    { NULL,                   NULL,           },
3250};
3251#endif /* defined (HAS_ALTIVEC) */
3252
3253#if defined (HAS_ALTIVEC)
3254static void test_vcmpgtfp_ (void)
3255{
3256    __asm__ __volatile__ ("vcmpgtfp.    17, 14, 15");
3257}
3258
3259static void test_vcmpeqfp_ (void)
3260{
3261    __asm__ __volatile__ ("vcmpeqfp.    17, 14, 15");
3262}
3263
3264static void test_vcmpgefp_ (void)
3265{
3266    __asm__ __volatile__ ("vcmpgefp.    17, 14, 15");
3267}
3268
3269static void test_vcmpbfp_ (void)
3270{
3271    __asm__ __volatile__ ("vcmpbfp.     17, 14, 15");
3272}
3273
3274static test_t tests_afcr_ops_two[] = {
3275    { &test_vcmpgtfp_       , "   vcmpgtfp.", },
3276    { &test_vcmpeqfp_       , "   vcmpeqfp.", },
3277    { &test_vcmpgefp_       , "   vcmpgefp.", },
3278    { &test_vcmpbfp_        , "    vcmpbfp.", },
3279    { NULL,                   NULL,           },
3280};
3281#endif /* defined (HAS_ALTIVEC) */
3282
3283#if defined (HAS_ALTIVEC)
3284extern void test_vcfux (void);
3285ASSEMBLY_FUNC("test_vcfux", "vcfux        17, 14, 0");
3286
3287extern void test_vcfsx (void);
3288ASSEMBLY_FUNC("test_vcfsx", "vcfsx        17, 14, 0");
3289
3290extern void test_vctuxs (void);
3291ASSEMBLY_FUNC("test_vctuxs", "vctuxs        17, 14, 0");
3292
3293extern void test_vctsxs (void);
3294ASSEMBLY_FUNC("test_vctsxs", "vctsxs        17, 14, 0");
3295
3296static test_t tests_av_float_ops_spe[] = {
3297    { &test_vcfux           , "       vcfux", },
3298    { &test_vcfsx           , "       vcfsx", },
3299    { &test_vctuxs          , "      vctuxs", },
3300    { &test_vctsxs          , "      vctsxs", },
3301    { NULL,                   NULL,           },
3302};
3303#endif /* defined (HAS_ALTIVEC) */
3304
3305#if defined (IS_PPC405)
3306static void test_macchw (void)
3307{
3308    __asm__ __volatile__ ("macchw       17, 14, 15");
3309}
3310
3311static void test_macchwo (void)
3312{
3313    __asm__ __volatile__ ("macchwo      17, 14, 15");
3314}
3315
3316static void test_macchws (void)
3317{
3318    __asm__ __volatile__ ("macchws      17, 14, 15");
3319}
3320
3321static void test_macchwso (void)
3322{
3323    __asm__ __volatile__ ("macchwso     17, 14, 15");
3324}
3325
3326static void test_macchwsu (void)
3327{
3328    __asm__ __volatile__ ("macchwsu     17, 14, 15");
3329}
3330
3331static void test_macchwsuo (void)
3332{
3333    __asm__ __volatile__ ("macchwsuo    17, 14, 15");
3334}
3335
3336static void test_macchwu (void)
3337{
3338    __asm__ __volatile__ ("macchwu      17, 14, 15");
3339}
3340
3341static void test_macchwuo (void)
3342{
3343    __asm__ __volatile__ ("macchwuo     17, 14, 15");
3344}
3345
3346static void test_machhw (void)
3347{
3348    __asm__ __volatile__ ("machhw       17, 14, 15");
3349}
3350
3351static void test_machhwo (void)
3352{
3353    __asm__ __volatile__ ("machhwo      17, 14, 15");
3354}
3355
3356static void test_machhws (void)
3357{
3358    __asm__ __volatile__ ("machhws      17, 14, 15");
3359}
3360
3361static void test_machhwso (void)
3362{
3363    __asm__ __volatile__ ("machhwso     17, 14, 15");
3364}
3365
3366static void test_machhwsu (void)
3367{
3368    __asm__ __volatile__ ("machhwsu     17, 14, 15");
3369}
3370
3371static void test_machhwsuo (void)
3372{
3373    __asm__ __volatile__ ("machhwsuo    17, 14, 15");
3374}
3375
3376static void test_machhwu (void)
3377{
3378    __asm__ __volatile__ ("machhwu      17, 14, 15");
3379}
3380
3381static void test_machhwuo (void)
3382{
3383    __asm__ __volatile__ ("machhwuo     17, 14, 15");
3384}
3385
3386static void test_maclhw (void)
3387{
3388    __asm__ __volatile__ ("maclhw       17, 14, 15");
3389}
3390
3391static void test_maclhwo (void)
3392{
3393    __asm__ __volatile__ ("maclhwo      17, 14, 15");
3394}
3395
3396static void test_maclhws (void)
3397{
3398    __asm__ __volatile__ ("maclhws      17, 14, 15");
3399}
3400
3401static void test_maclhwso (void)
3402{
3403    __asm__ __volatile__ ("maclhwso     17, 14, 15");
3404}
3405
3406static void test_maclhwsu (void)
3407{
3408    __asm__ __volatile__ ("maclhwsu     17, 14, 15");
3409}
3410
3411static void test_maclhwsuo (void)
3412{
3413    __asm__ __volatile__ ("maclhwsuo    17, 14, 15");
3414}
3415
3416static void test_maclhwu (void)
3417{
3418    __asm__ __volatile__ ("maclhwu      17, 14, 15");
3419}
3420
3421static void test_maclhwuo (void)
3422{
3423    __asm__ __volatile__ ("maclhwuo     17, 14, 15");
3424}
3425
3426static void test_mulchw (void)
3427{
3428    __asm__ __volatile__ ("mulchw       17, 14, 15");
3429}
3430
3431static void test_mulchwu (void)
3432{
3433    __asm__ __volatile__ ("mulchwu      17, 14, 15");
3434}
3435
3436static void test_mulhhw (void)
3437{
3438    __asm__ __volatile__ ("mulhhw       17, 14, 15");
3439}
3440
3441static void test_mulhhwu (void)
3442{
3443    __asm__ __volatile__ ("mulhhwu      17, 14, 15");
3444}
3445
3446static void test_mullhw (void)
3447{
3448    __asm__ __volatile__ ("mullhw       17, 14, 15");
3449}
3450
3451static void test_mullhwu (void)
3452{
3453    __asm__ __volatile__ ("mullhwu      17, 14, 15");
3454}
3455
3456static void test_nmacchw (void)
3457{
3458    __asm__ __volatile__ ("nmacchw      17, 14, 15");
3459}
3460
3461static void test_nmacchwo (void)
3462{
3463    __asm__ __volatile__ ("nmacchwo     17, 14, 15");
3464}
3465
3466static void test_nmacchws (void)
3467{
3468    __asm__ __volatile__ ("nmacchws     17, 14, 15");
3469}
3470
3471static void test_nmacchwso (void)
3472{
3473    __asm__ __volatile__ ("nmacchwso    17, 14, 15");
3474}
3475
3476static void test_nmachhw (void)
3477{
3478    __asm__ __volatile__ ("nmachhw      17, 14, 15");
3479}
3480
3481static void test_nmachhwo (void)
3482{
3483    __asm__ __volatile__ ("nmachhwo     17, 14, 15");
3484}
3485
3486static void test_nmachhws (void)
3487{
3488    __asm__ __volatile__ ("nmachhws     17, 14, 15");
3489}
3490
3491static void test_nmachhwso (void)
3492{
3493    __asm__ __volatile__ ("nmachhwso    17, 14, 15");
3494}
3495
3496static void test_nmaclhw (void)
3497{
3498    __asm__ __volatile__ ("nmaclhw      17, 14, 15");
3499}
3500
3501static void test_nmaclhwo (void)
3502{
3503    __asm__ __volatile__ ("nmaclhwo     17, 14, 15");
3504}
3505
3506static void test_nmaclhws (void)
3507{
3508    __asm__ __volatile__ ("nmaclhws     17, 14, 15");
3509}
3510
3511static void test_nmaclhwso (void)
3512{
3513    __asm__ __volatile__ ("nmaclhwso    17, 14, 15");
3514}
3515
3516static test_t tests_p4m_ops_two[] = {
3517    { &test_macchw          , "      macchw", },
3518    { &test_macchwo         , "     macchwo", },
3519    { &test_macchws         , "     macchws", },
3520    { &test_macchwso        , "    macchwso", },
3521    { &test_macchwsu        , "    macchwsu", },
3522    { &test_macchwsuo       , "   macchwsuo", },
3523    { &test_macchwu         , "     macchwu", },
3524    { &test_macchwuo        , "    macchwuo", },
3525    { &test_machhw          , "      machhw", },
3526    { &test_machhwo         , "     machhwo", },
3527    { &test_machhws         , "     machhws", },
3528    { &test_machhwso        , "    machhwso", },
3529    { &test_machhwsu        , "    machhwsu", },
3530    { &test_machhwsuo       , "   machhwsuo", },
3531    { &test_machhwu         , "     machhwu", },
3532    { &test_machhwuo        , "    machhwuo", },
3533    { &test_maclhw          , "      maclhw", },
3534    { &test_maclhwo         , "     maclhwo", },
3535    { &test_maclhws         , "     maclhws", },
3536    { &test_maclhwso        , "    maclhwso", },
3537    { &test_maclhwsu        , "    maclhwsu", },
3538    { &test_maclhwsuo       , "   maclhwsuo", },
3539    { &test_maclhwu         , "     maclhwu", },
3540    { &test_maclhwuo        , "    maclhwuo", },
3541    { &test_mulchw          , "      mulchw", },
3542    { &test_mulchwu         , "     mulchwu", },
3543    { &test_mulhhw          , "      mulhhw", },
3544    { &test_mulhhwu         , "     mulhhwu", },
3545    { &test_mullhw          , "      mullhw", },
3546    { &test_mullhwu         , "     mullhwu", },
3547    { &test_nmacchw         , "     nmacchw", },
3548    { &test_nmacchwo        , "    nmacchwo", },
3549    { &test_nmacchws        , "    nmacchws", },
3550    { &test_nmacchwso       , "   nmacchwso", },
3551    { &test_nmachhw         , "     nmachhw", },
3552    { &test_nmachhwo        , "    nmachhwo", },
3553    { &test_nmachhws        , "    nmachhws", },
3554    { &test_nmachhwso       , "   nmachhwso", },
3555    { &test_nmaclhw         , "     nmaclhw", },
3556    { &test_nmaclhwo        , "    nmaclhwo", },
3557    { &test_nmaclhws        , "    nmaclhws", },
3558    { &test_nmaclhwso       , "   nmaclhwso", },
3559    { NULL,                   NULL,           },
3560};
3561#endif /* defined (IS_PPC405) */
3562
3563#if defined (IS_PPC405)
3564static void test_macchw_ (void)
3565{
3566    __asm__ __volatile__ ("macchw.      17, 14, 15");
3567}
3568
3569static void test_macchwo_ (void)
3570{
3571    __asm__ __volatile__ ("macchwo.     17, 14, 15");
3572}
3573
3574static void test_macchws_ (void)
3575{
3576    __asm__ __volatile__ ("macchws.     17, 14, 15");
3577}
3578
3579static void test_macchwso_ (void)
3580{
3581    __asm__ __volatile__ ("macchwso.    17, 14, 15");
3582}
3583
3584static void test_macchwsu_ (void)
3585{
3586    __asm__ __volatile__ ("macchwsu.    17, 14, 15");
3587}
3588
3589static void test_macchwsuo_ (void)
3590{
3591    __asm__ __volatile__ ("macchwsuo.   17, 14, 15");
3592}
3593
3594static void test_macchwu_ (void)
3595{
3596    __asm__ __volatile__ ("macchwu.     17, 14, 15");
3597}
3598
3599static void test_macchwuo_ (void)
3600{
3601    __asm__ __volatile__ ("macchwuo.    17, 14, 15");
3602}
3603
3604static void test_machhw_ (void)
3605{
3606    __asm__ __volatile__ ("machhw.      17, 14, 15");
3607}
3608
3609static void test_machhwo_ (void)
3610{
3611    __asm__ __volatile__ ("machhwo.     17, 14, 15");
3612}
3613
3614static void test_machhws_ (void)
3615{
3616    __asm__ __volatile__ ("machhws.     17, 14, 15");
3617}
3618
3619static void test_machhwso_ (void)
3620{
3621    __asm__ __volatile__ ("machhwso.    17, 14, 15");
3622}
3623
3624static void test_machhwsu_ (void)
3625{
3626    __asm__ __volatile__ ("machhwsu.    17, 14, 15");
3627}
3628
3629static void test_machhwsuo_ (void)
3630{
3631    __asm__ __volatile__ ("machhwsuo.   17, 14, 15");
3632}
3633
3634static void test_machhwu_ (void)
3635{
3636    __asm__ __volatile__ ("machhwu.     17, 14, 15");
3637}
3638
3639static void test_machhwuo_ (void)
3640{
3641    __asm__ __volatile__ ("machhwuo.    17, 14, 15");
3642}
3643
3644static void test_maclhw_ (void)
3645{
3646    __asm__ __volatile__ ("maclhw.      17, 14, 15");
3647}
3648
3649static void test_maclhwo_ (void)
3650{
3651    __asm__ __volatile__ ("maclhwo.     17, 14, 15");
3652}
3653
3654static void test_maclhws_ (void)
3655{
3656    __asm__ __volatile__ ("maclhws.     17, 14, 15");
3657}
3658
3659static void test_maclhwso_ (void)
3660{
3661    __asm__ __volatile__ ("maclhwso.    17, 14, 15");
3662}
3663
3664static void test_maclhwsu_ (void)
3665{
3666    __asm__ __volatile__ ("maclhwsu.    17, 14, 15");
3667}
3668
3669static void test_maclhwsuo_ (void)
3670{
3671    __asm__ __volatile__ ("maclhwsuo.   17, 14, 15");
3672}
3673
3674static void test_maclhwu_ (void)
3675{
3676    __asm__ __volatile__ ("maclhwu.     17, 14, 15");
3677}
3678
3679static void test_maclhwuo_ (void)
3680{
3681    __asm__ __volatile__ ("maclhwuo.    17, 14, 15");
3682}
3683
3684static void test_mulchw_ (void)
3685{
3686    __asm__ __volatile__ ("mulchw.      17, 14, 15");
3687}
3688
3689static void test_mulchwu_ (void)
3690{
3691    __asm__ __volatile__ ("mulchwu.     17, 14, 15");
3692}
3693
3694static void test_mulhhw_ (void)
3695{
3696    __asm__ __volatile__ ("mulhhw.      17, 14, 15");
3697}
3698
3699static void test_mulhhwu_ (void)
3700{
3701    __asm__ __volatile__ ("mulhhwu.     17, 14, 15");
3702}
3703
3704static void test_mullhw_ (void)
3705{
3706    __asm__ __volatile__ ("mullhw.      17, 14, 15");
3707}
3708
3709static void test_mullhwu_ (void)
3710{
3711    __asm__ __volatile__ ("mullhwu.     17, 14, 15");
3712}
3713
3714static void test_nmacchw_ (void)
3715{
3716    __asm__ __volatile__ ("nmacchw.     17, 14, 15");
3717}
3718
3719static void test_nmacchwo_ (void)
3720{
3721    __asm__ __volatile__ ("nmacchwo.    17, 14, 15");
3722}
3723
3724static void test_nmacchws_ (void)
3725{
3726    __asm__ __volatile__ ("nmacchws.    17, 14, 15");
3727}
3728
3729static void test_nmacchwso_ (void)
3730{
3731    __asm__ __volatile__ ("nmacchwso.   17, 14, 15");
3732}
3733
3734static void test_nmachhw_ (void)
3735{
3736    __asm__ __volatile__ ("nmachhw.     17, 14, 15");
3737}
3738
3739static void test_nmachhwo_ (void)
3740{
3741    __asm__ __volatile__ ("nmachhwo.    17, 14, 15");
3742}
3743
3744static void test_nmachhws_ (void)
3745{
3746    __asm__ __volatile__ ("nmachhws.    17, 14, 15");
3747}
3748
3749static void test_nmachhwso_ (void)
3750{
3751    __asm__ __volatile__ ("nmachhwso.   17, 14, 15");
3752}
3753
3754static void test_nmaclhw_ (void)
3755{
3756    __asm__ __volatile__ ("nmaclhw.     17, 14, 15");
3757}
3758
3759static void test_nmaclhwo_ (void)
3760{
3761    __asm__ __volatile__ ("nmaclhwo.    17, 14, 15");
3762}
3763
3764static void test_nmaclhws_ (void)
3765{
3766    __asm__ __volatile__ ("nmaclhws.    17, 14, 15");
3767}
3768
3769static void test_nmaclhwso_ (void)
3770{
3771    __asm__ __volatile__ ("nmaclhwso.   17, 14, 15");
3772}
3773
3774static test_t tests_p4mc_ops_two[] = {
3775    { &test_macchw_         , "     macchw.", },
3776    { &test_macchwo_        , "    macchwo.", },
3777    { &test_macchws_        , "    macchws.", },
3778    { &test_macchwso_       , "   macchwso.", },
3779    { &test_macchwsu_       , "   macchwsu.", },
3780    { &test_macchwsuo_      , "  macchwsuo.", },
3781    { &test_macchwu_        , "    macchwu.", },
3782    { &test_macchwuo_       , "   macchwuo.", },
3783    { &test_machhw_         , "     machhw.", },
3784    { &test_machhwo_        , "    machhwo.", },
3785    { &test_machhws_        , "    machhws.", },
3786    { &test_machhwso_       , "   machhwso.", },
3787    { &test_machhwsu_       , "   machhwsu.", },
3788    { &test_machhwsuo_      , "  machhwsuo.", },
3789    { &test_machhwu_        , "    machhwu.", },
3790    { &test_machhwuo_       , "   machhwuo.", },
3791    { &test_maclhw_         , "     maclhw.", },
3792    { &test_maclhwo_        , "    maclhwo.", },
3793    { &test_maclhws_        , "    maclhws.", },
3794    { &test_maclhwso_       , "   maclhwso.", },
3795    { &test_maclhwsu_       , "   maclhwsu.", },
3796    { &test_maclhwsuo_      , "  maclhwsuo.", },
3797    { &test_maclhwu_        , "    maclhwu.", },
3798    { &test_maclhwuo_       , "   maclhwuo.", },
3799    { &test_mulchw_         , "     mulchw.", },
3800    { &test_mulchwu_        , "    mulchwu.", },
3801    { &test_mulhhw_         , "     mulhhw.", },
3802    { &test_mulhhwu_        , "    mulhhwu.", },
3803    { &test_mullhw_         , "     mullhw.", },
3804    { &test_mullhwu_        , "    mullhwu.", },
3805    { &test_nmacchw_        , "    nmacchw.", },
3806    { &test_nmacchwo_       , "   nmacchwo.", },
3807    { &test_nmacchws_       , "   nmacchws.", },
3808    { &test_nmacchwso_      , "  nmacchwso.", },
3809    { &test_nmachhw_        , "    nmachhw.", },
3810    { &test_nmachhwo_       , "   nmachhwo.", },
3811    { &test_nmachhws_       , "   nmachhws.", },
3812    { &test_nmachhwso_      , "  nmachhwso.", },
3813    { &test_nmaclhw_        , "    nmaclhw.", },
3814    { &test_nmaclhwo_       , "   nmaclhwo.", },
3815    { &test_nmaclhws_       , "   nmaclhws.", },
3816    { &test_nmaclhwso_      , "  nmaclhwso.", },
3817    { NULL,                   NULL,           },
3818};
3819#endif /* defined (IS_PPC405) */
3820
3821static test_table_t all_tests[] = {
3822    {
3823        tests_ia_ops_two      ,
3824        "PPC integer arith insns with two args",
3825        0x00010102,
3826    },
3827    {
3828        tests_iar_ops_two     ,
3829        "PPC integer arith insns with two args with flags update",
3830        0x01010102,
3831    },
3832    {
3833        tests_iac_ops_two     ,
3834        "PPC integer arith insns with two args and carry",
3835        0x02010102,
3836    },
3837    {
3838        tests_iacr_ops_two    ,
3839        "PPC integer arith insns with two args and carry with flags update",
3840        0x03010102,
3841    },
3842    {
3843        tests_il_ops_two      ,
3844        "PPC integer logical insns with two args",
3845        0x00010202,
3846    },
3847    {
3848        tests_ilr_ops_two     ,
3849        "PPC integer logical insns with two args with flags update",
3850        0x01010202,
3851    },
3852    {
3853        tests_icr_ops_two     ,
3854        "PPC integer compare insns (two args)",
3855        0x01010304,
3856    },
3857    {
3858        tests_icr_ops_two_i16 ,
3859        "PPC integer compare with immediate insns (two args)",
3860        0x01010305,
3861    },
3862    {
3863        tests_ia_ops_two_i16  ,
3864        "PPC integer arith insns\n    with one register + one 16 bits immediate args",
3865        0x00010106,
3866    },
3867    {
3868        tests_iar_ops_two_i16 ,
3869        "PPC integer arith insns\n    with one register + one 16 bits immediate args with flags update",
3870        0x01010106,
3871    },
3872    {
3873        tests_il_ops_two_i16  ,
3874        "PPC integer logical insns\n    with one register + one 16 bits immediate args",
3875        0x00010206,
3876    },
3877    {
3878        tests_ilr_ops_two_i16 ,
3879        "PPC integer logical insns\n    with one register + one 16 bits immediate args with flags update",
3880        0x01010206,
3881    },
3882    {
3883        tests_crl_ops_two     ,
3884        "PPC condition register logical insns - two operands",
3885        0x01010202,
3886    },
3887    {
3888        tests_iac_ops_one     ,
3889        "PPC integer arith insns with one arg and carry",
3890        0x02010101,
3891    },
3892    {
3893        tests_iacr_ops_one    ,
3894        "PPC integer arith insns with one arg and carry with flags update",
3895        0x03010101,
3896    },
3897    {
3898        tests_il_ops_one      ,
3899        "PPC integer logical insns with one arg",
3900        0x00010201,
3901    },
3902    {
3903        tests_ilr_ops_one     ,
3904        "PPC integer logical insns with one arg with flags update",
3905        0x01010201,
3906    },
3907    {
3908        tests_il_ops_spe      ,
3909        "PPC logical insns with special forms",
3910        0x00010207,
3911    },
3912    {
3913        tests_ilr_ops_spe     ,
3914        "PPC logical insns with special forms with flags update",
3915        0x01010207,
3916    },
3917    {
3918        tests_ild_ops_two_i16 ,
3919        "PPC integer load insns\n    with one register + one 16 bits immediate args with flags update",
3920        0x00010508,
3921    },
3922    {
3923        tests_ild_ops_two     ,
3924        "PPC integer load insns with two register args",
3925        0x00010509,
3926    },
3927    {
3928        tests_ist_ops_three_i16,
3929        "PPC integer store insns\n    with one register + one 16 bits immediate args with flags update",
3930        0x0001050a,
3931    },
3932    {
3933        tests_ist_ops_three   ,
3934        "PPC integer store insns with three register args",
3935        0x0001050b,
3936    },
3937#if !defined (NO_FLOAT)
3938    {
3939        tests_fa_ops_three    ,
3940        "PPC floating point arith insns with three args",
3941        0x00020103,
3942    },
3943#endif /* !defined (NO_FLOAT) */
3944#if !defined (NO_FLOAT)
3945    {
3946        tests_far_ops_three    ,
3947        "PPC floating point arith insns\n    with three args with flags update",
3948        0x01020103,
3949    },
3950#endif /* !defined (NO_FLOAT) */
3951#if !defined (NO_FLOAT)
3952    {
3953        tests_fa_ops_two      ,
3954        "PPC floating point arith insns with two args",
3955        0x00020102,
3956    },
3957#endif /* !defined (NO_FLOAT) */
3958#if !defined (NO_FLOAT)
3959    {
3960        tests_far_ops_two     ,
3961        "PPC floating point arith insns\n    with two args with flags update",
3962        0x01020102,
3963    },
3964#endif /* !defined (NO_FLOAT) */
3965#if !defined (NO_FLOAT)
3966    {
3967        tests_fcr_ops_two     ,
3968        "PPC floating point compare insns (two args)",
3969        0x01020304,
3970    },
3971#endif /* !defined (NO_FLOAT) */
3972#if !defined (NO_FLOAT)
3973    {
3974        tests_fa_ops_one      ,
3975        "PPC floating point arith insns with one arg",
3976        0x00020101,
3977    },
3978#endif /* !defined (NO_FLOAT) */
3979#if !defined (NO_FLOAT)
3980    {
3981        tests_far_ops_one     ,
3982        "PPC floating point arith insns\n    with one arg with flags update",
3983        0x01020101,
3984    },
3985#endif /* !defined (NO_FLOAT) */
3986#if !defined (NO_FLOAT)
3987    {
3988        tests_fl_ops_spe      ,
3989        "PPC floating point status register manipulation insns",
3990        0x00020207,
3991    },
3992#endif /* !defined (NO_FLOAT) */
3993#if !defined (NO_FLOAT)
3994    {
3995        tests_flr_ops_spe     ,
3996        "PPC floating point status register manipulation insns\n  with flags update",
3997        0x01020207,
3998    },
3999#endif /* !defined (NO_FLOAT) */
4000#if !defined (NO_FLOAT)
4001    {
4002        tests_fld_ops_two_i16 ,
4003        "PPC float load insns\n    with one register + one 16 bits immediate args with flags update",
4004        0x00020508,
4005    },
4006#endif /* !defined (NO_FLOAT) */
4007#if !defined (NO_FLOAT)
4008    {
4009        tests_fld_ops_two     ,
4010        "PPC float load insns with two register args",
4011        0x00020509,
4012    },
4013#endif /* !defined (NO_FLOAT) */
4014#if !defined (NO_FLOAT)
4015    {
4016        tests_fst_ops_three_i16,
4017        "PPC float store insns\n    with one register + one 16 bits immediate args with flags update",
4018        0x0002050a,
4019    },
4020#endif /* !defined (NO_FLOAT) */
4021#if !defined (NO_FLOAT)
4022    {
4023        tests_fst_ops_three   ,
4024        "PPC float store insns with three register args",
4025        0x0002050b,
4026    },
4027#endif /* !defined (NO_FLOAT) */
4028#if defined (HAS_ALTIVEC)
4029    {
4030        tests_aa_ops_three    ,
4031        "PPC altivec integer arith insns with three args",
4032        0x00040103,
4033    },
4034#endif /* defined (HAS_ALTIVEC) */
4035#if defined (HAS_ALTIVEC)
4036    {
4037        tests_al_ops_three    ,
4038        "PPC altivec integer logical insns with three args",
4039        0x00040203,
4040    },
4041#endif /* defined (HAS_ALTIVEC) */
4042#if defined (HAS_ALTIVEC)
4043    {
4044        tests_aa_ops_two      ,
4045        "PPC altivec integer arith insns with two args",
4046        0x00040102,
4047    },
4048#endif /* defined (HAS_ALTIVEC) */
4049#if defined (HAS_ALTIVEC)
4050    {
4051        tests_al_ops_two      ,
4052        "PPC altivec integer logical insns with two args",
4053        0x00040202,
4054    },
4055#endif /* defined (HAS_ALTIVEC) */
4056#if defined (HAS_ALTIVEC)
4057    {
4058        tests_al_ops_one      ,
4059        "PPC altivec integer logical insns with one arg",
4060        0x00040201,
4061    },
4062#endif /* defined (HAS_ALTIVEC) */
4063#if defined (HAS_ALTIVEC)
4064    {
4065        tests_ac_ops_two      ,
4066        "Altivec integer compare insns",
4067        0x00040302,
4068    },
4069#endif /* defined (HAS_ALTIVEC) */
4070#if defined (HAS_ALTIVEC)
4071    {
4072        tests_acr_ops_two     ,
4073        "Altivec integer compare insns with flags update",
4074        0x01040302,
4075    },
4076#endif /* defined (HAS_ALTIVEC) */
4077#if defined (HAS_ALTIVEC)
4078    {
4079        tests_av_int_ops_spe  ,
4080        "Altivec integer special insns",
4081        0x00040207,
4082    },
4083#endif /* defined (HAS_ALTIVEC) */
4084#if defined (HAS_ALTIVEC)
4085    {
4086        tests_ald_ops_two     ,
4087        "Altivec load insns with two register args",
4088        0x00040509,
4089    },
4090#endif /* defined (HAS_ALTIVEC) */
4091#if defined (HAS_ALTIVEC)
4092    {
4093        tests_ast_ops_three   ,
4094        "Altivec store insns with three register args",
4095        0x0004050b,
4096    },
4097#endif /* defined (HAS_ALTIVEC) */
4098#if defined (HAS_ALTIVEC)
4099    {
4100        tests_afa_ops_three   ,
4101        "Altivec floating point arith insns with three args",
4102        0x00050103,
4103    },
4104#endif /* defined (HAS_ALTIVEC) */
4105#if defined (HAS_ALTIVEC)
4106    {
4107        tests_afa_ops_two     ,
4108        "Altivec floating point arith insns with two args",
4109        0x00050102,
4110    },
4111#endif /* defined (HAS_ALTIVEC) */
4112#if defined (HAS_ALTIVEC)
4113    {
4114        tests_afa_ops_one     ,
4115        "Altivec floating point arith insns with one arg",
4116        0x00050101,
4117    },
4118#endif /* defined (HAS_ALTIVEC) */
4119#if defined (HAS_ALTIVEC)
4120    {
4121        tests_afc_ops_two     ,
4122        "Altivec floating point compare insns",
4123        0x00050302,
4124    },
4125#endif /* defined (HAS_ALTIVEC) */
4126#if defined (HAS_ALTIVEC)
4127    {
4128        tests_afcr_ops_two    ,
4129        "Altivec floating point compare insns with flags update",
4130        0x01050302,
4131    },
4132#endif /* defined (HAS_ALTIVEC) */
4133#if defined (HAS_ALTIVEC)
4134    {
4135        tests_av_float_ops_spe,
4136        "Altivec float special insns",
4137        0x00050207,
4138    },
4139#endif /* defined (HAS_ALTIVEC) */
4140#if defined (IS_PPC405)
4141    {
4142        tests_p4m_ops_two     ,
4143        "PPC 405 mac insns with three args",
4144        0x00030102,
4145    },
4146#endif /* defined (IS_PPC405) */
4147#if defined (IS_PPC405)
4148    {
4149        tests_p4mc_ops_two    ,
4150        "PPC 405 mac insns with three args with flags update",
4151        0x01030102,
4152    },
4153#endif /* defined (IS_PPC405) */
4154    { NULL,                   NULL,               0x00000000, },
4155};
4156
4157/* -------------- END #include "ops-ppc.c" -------------- */
4158
4159static int verbose = 0;
4160static int arg_list_size = 0;
4161
4162static double *fargs = NULL;
4163static int nb_fargs = 0;
4164static int nb_normal_fargs = 0;
4165static HWord_t *iargs = NULL;
4166static int nb_iargs = 0;
4167static uint16_t *ii16 = NULL;
4168static int nb_ii16 = 0;
4169
4170#if defined (HAS_ALTIVEC)
4171static vector unsigned int* viargs = NULL;
4172static int nb_viargs = 0;
4173static vector float* vfargs = NULL;
4174static int nb_vfargs = 0;
4175
4176//#define TEST_VSCR_SAT
4177#endif
4178
4179static inline void register_farg (void *farg,
4180                                  int s, uint16_t _exp, uint64_t mant)
4181{
4182   uint64_t tmp;
4183
4184   tmp = ((uint64_t)s << 63) | ((uint64_t)_exp << 52) | mant;
4185   *(uint64_t *)farg = tmp;
4186#ifndef __powerpc64__
4187   AB_DPRINTF("%d %03x %013llx => %016llx %0e\n",
4188#else
4189   AB_DPRINTF("%d %03x %013lx => %016lx %0e\n",
4190#endif
4191              s, _exp, mant, *(uint64_t *)farg, *(double *)farg);
4192}
4193
4194static void build_fargs_table (void)
4195{
4196   /* Double precision:
4197    * Sign goes from zero to one               (1 bit)
4198    * Exponent goes from 0 to ((1 << 12) - 1)  (11 bits)
4199    * Mantissa goes from 1 to ((1 << 52) - 1)  (52 bits)
4200    * + special values:
4201    * +0.0      : 0 0x000 0x0000000000000 => 0x0000000000000000
4202    * -0.0      : 1 0x000 0x0000000000000 => 0x8000000000000000
4203    * +infinity : 0 0x7FF 0x0000000000000 => 0x7FF0000000000000
4204    * -infinity : 1 0x7FF 0x0000000000000 => 0xFFF0000000000000
4205    * +QNaN     : 0 0x7FF 0x7FFFFFFFFFFFF => 0x7FF7FFFFFFFFFFFF
4206    * -QNaN     : 1 0x7FF 0x7FFFFFFFFFFFF => 0xFFF7FFFFFFFFFFFF
4207    * +SNaN     : 0 0x7FF 0x8000000000000 => 0x7FF8000000000000
4208    * -SNaN     : 1 0x7FF 0x8000000000000 => 0xFFF8000000000000
4209    * (8 values)
4210
4211    * Ref only:
4212    * Single precision
4213    * Sign:     1 bit
4214    * Exponent: 8 bits
4215    * Mantissa: 23 bits
4216    * +0.0      : 0 0x00 0x000000 => 0x00000000
4217    * -0.0      : 1 0x00 0x000000 => 0x80000000
4218    * +infinity : 0 0xFF 0x000000 => 0x7F800000
4219    * -infinity : 1 0xFF 0x000000 => 0xFF800000
4220    * +QNaN     : 0 0xFF 0x3FFFFF => 0x7FBFFFFF
4221    * -QNaN     : 1 0xFF 0x3FFFFF => 0xFFBFFFFF
4222    * +SNaN     : 0 0xFF 0x400000 => 0x7FC00000
4223    * -SNaN     : 1 0xFF 0x400000 => 0xFFC00000
4224    */
4225   uint64_t mant;
4226   uint16_t _exp, e0, e1;
4227   int s;
4228   int i=0;
4229
4230   /* Note: VEX isn't so hot with denormals, so don't bother
4231      testing them: set _exp > 0
4232   */
4233
4234   if ( arg_list_size == 1 ) {   // Large
4235      fargs = malloc(200 * sizeof(double));
4236      for (s=0; s<2; s++) {
4237         for (e0=0; e0<2; e0++) {
4238            for (e1=0x001; ; e1 = ((e1 + 1) << 2) + 6) {
4239               if (e1 >= 0x400)
4240                  e1 = 0x3fe;
4241               _exp = (e0 << 10) | e1;
4242               for (mant = 0x0000000000001ULL; mant < (1ULL << 52);
4243                    /* Add 'random' bits */
4244                    mant = ((mant + 0x4A6) << 13) + 0x359) {
4245                  register_farg(&fargs[i++], s, _exp, mant);
4246               }
4247               if (e1 == 0x3fe)
4248                  break;
4249            }
4250         }
4251      }
4252   } else {                      // Default
4253      fargs = malloc(16 * sizeof(double));
4254      for (s=0; s<2; s++) {                                // x2
4255//       for (e0=0; e0<2; e0++) {
4256            for (e1=0x001; ; e1 = ((e1 + 1) << 13) + 7) {  // x2
4257//          for (e1=0x001; ; e1 = ((e1 + 1) << 5) + 7) {   // x3
4258               if (e1 >= 0x400)
4259                  e1 = 0x3fe;
4260//             _exp = (e0 << 10) | e1;
4261               _exp = e1;
4262               for (mant = 0x0000000000001ULL; mant < (1ULL << 52);
4263                    /* Add 'random' bits */
4264                    mant = ((mant + 0x4A6) << 29) + 0x359) {  // x2
4265                  register_farg(&fargs[i++], s, _exp, mant);
4266               }
4267               if (e1 == 0x3fe)
4268                  break;
4269            }
4270//       }
4271      }
4272   }
4273
4274   /* To iterate over non-special values only */
4275   nb_normal_fargs = i;
4276
4277
4278   /* Special values */
4279   /* +0.0      : 0 0x000 0x0000000000000 */
4280   s = 0;
4281   _exp = 0x000;
4282   mant = 0x0000000000000ULL;
4283   register_farg(&fargs[i++], s, _exp, mant);
4284   /* -0.0      : 1 0x000 0x0000000000000 */
4285   s = 1;
4286   _exp = 0x000;
4287   mant = 0x0000000000000ULL;
4288   register_farg(&fargs[i++], s, _exp, mant);
4289   /* +infinity : 0 0x7FF 0x0000000000000  */
4290   s = 0;
4291   _exp = 0x7FF;
4292   mant = 0x0000000000000ULL;
4293   register_farg(&fargs[i++], s, _exp, mant);
4294   /* -infinity : 1 0x7FF 0x0000000000000 */
4295   s = 1;
4296   _exp = 0x7FF;
4297   mant = 0x0000000000000ULL;
4298   register_farg(&fargs[i++], s, _exp, mant);
4299   /* +QNaN     : 0 0x7FF 0x7FFFFFFFFFFFF */
4300   s = 0;
4301   _exp = 0x7FF;
4302   mant = 0x7FFFFFFFFFFFFULL;
4303   register_farg(&fargs[i++], s, _exp, mant);
4304   /* -QNaN     : 1 0x7FF 0x7FFFFFFFFFFFF */
4305   s = 1;
4306   _exp = 0x7FF;
4307   mant = 0x7FFFFFFFFFFFFULL;
4308   register_farg(&fargs[i++], s, _exp, mant);
4309   /* +SNaN     : 0 0x7FF 0x8000000000000 */
4310   s = 0;
4311   _exp = 0x7FF;
4312   mant = 0x8000000000000ULL;
4313   register_farg(&fargs[i++], s, _exp, mant);
4314   /* -SNaN     : 1 0x7FF 0x8000000000000 */
4315   s = 1;
4316   _exp = 0x7FF;
4317   mant = 0x8000000000000ULL;
4318   register_farg(&fargs[i++], s, _exp, mant);
4319   AB_DPRINTF("Registered %d fargs values\n", i);
4320
4321   nb_fargs = i;
4322}
4323
4324static void build_iargs_table (void)
4325{
4326   uint64_t tmp;
4327   int i=0;
4328
4329#ifndef __powerpc64__
4330   if (arg_list_size == 1) {                   // Large
4331      iargs = malloc(400 * sizeof(HWord_t));
4332      for (tmp=0; ; tmp = tmp + 1 + (tmp >> 1)) {
4333         if (tmp >= 0x100000000ULL)
4334            tmp = 0xFFFFFFFF;
4335         iargs[i++] = (HWord_t)tmp;
4336         AB_DPRINTF("val %08x\n", (HWord_t)tmp);
4337         if (tmp == 0xFFFFFFFF)
4338            break;
4339      }
4340   } else {                                    // Default
4341      iargs = malloc(10 * sizeof(HWord_t));
4342      // for (tmp = 0; ; tmp = 71*tmp + 1 + (tmp>>1)) {  // gives 8
4343      // for (tmp = 0; ; tmp = 100000*tmp + 1 + (tmp>>1)) {  // gives 4
4344      for (tmp=0; ; tmp = 999999*tmp + 999999) {  // gives 3
4345         if (tmp >= 0x100000000ULL)
4346            tmp = 0xFFFFFFFF;
4347         iargs[i++] = (HWord_t)tmp;
4348         AB_DPRINTF("val %08x\n", (HWord_t)tmp);
4349         if (tmp == 0xFFFFFFFF)
4350            break;
4351      }
4352   }
4353#else
4354   if (arg_list_size == 1) {                   // Large
4355      iargs = malloc(800 * sizeof(HWord_t));
4356      for (tmp=0; ; tmp = 2*tmp + 1 + (tmp >> 2)) {
4357         if ((long)tmp < 0 )
4358            tmp = 0xFFFFFFFFFFFFFFFFULL;
4359         iargs[i++] = tmp;
4360         AB_DPRINTF("val %016lx\n", tmp);
4361         if (tmp == 0xFFFFFFFFFFFFFFFFULL)
4362            break;
4363      }
4364   } else {                                    // Default
4365      iargs = malloc(20 * sizeof(HWord_t));
4366      // for (tmp=0; ; tmp = 9999*tmp + 999999) {  // gives 6
4367      for (tmp = 0; ; tmp = 123456789*tmp + 123456789999) {  // gives 3
4368         if ((long)tmp < 0 )
4369            tmp = 0xFFFFFFFFFFFFFFFFULL;
4370         iargs[i++] = tmp;
4371         AB_DPRINTF("val %016lx\n", tmp);
4372         if (tmp == 0xFFFFFFFFFFFFFFFFULL)
4373            break;
4374      }
4375   }
4376#endif // #ifndef __powerpc64__
4377
4378   AB_DPRINTF("Registered %d iargs values\n", i);
4379   nb_iargs = i;
4380}
4381
4382static void build_ii16_table (void)
4383{
4384   uint32_t tmp;
4385   int i=0;
4386
4387   if (arg_list_size == 1) {                   // Large
4388      ii16 = malloc(200 * sizeof(uint32_t));
4389      for (tmp=0; ; tmp = tmp + 1 + (tmp >> 2)) {
4390         if (tmp >= 0x10000)
4391            tmp = 0xFFFF;
4392         ii16[i++] = tmp;
4393         AB_DPRINTF("val %04x\n", tmp);
4394         if (tmp == 0xFFFF)
4395            break;
4396      }
4397   } else {                                    // Default
4398      ii16 = malloc(10 * sizeof(uint32_t));
4399      for (tmp=0; ; tmp = 999*tmp + 999) {  // gives 3
4400         if (tmp >= 0x10000)
4401            tmp = 0xFFFF;
4402         ii16[i++] = tmp;
4403         AB_DPRINTF("val %04x\n", tmp);
4404         if (tmp == 0xFFFF)
4405            break;
4406      }
4407   }
4408   AB_DPRINTF("Registered %d ii16 values\n", i);
4409   nb_ii16 = i;
4410}
4411
4412#if defined (HAS_ALTIVEC)
4413static void build_viargs_table (void)
4414{
4415#if !defined (ALTIVEC_ARGS_LARGE)
4416   unsigned int i=2;
4417   viargs = memalign16(i * sizeof(vector unsigned int));
4418   viargs[0] = (vector unsigned int) { 0x01020304,0x05060708,0x090A0B0C,0x0E0D0E0F };
4419   AB_DPRINTF_VEC32x4( viargs[0] );
4420   viargs[1] = (vector unsigned int) { 0xF1F2F3F4,0xF5F6F7F8,0xF9FAFBFC,0xFEFDFEFF };
4421   AB_DPRINTF_VEC32x4( viargs[1] );
4422#else
4423   unsigned int i,j;
4424   // build from iargs table (large/default already set)
4425   viargs = malloc(nb_iargs * sizeof(vector unsigned int));
4426   for (i=0; i<nb_iargs; i++) {
4427      j = iargs[i];
4428      viargs[i] = (vector unsigned int){ j, j*2, j*3, j*4 };
4429      AB_DPRINTF_VEC32x4( viargs[i] );
4430   }
4431#endif
4432
4433   AB_DPRINTF("Registered %d viargs values\n", i);
4434   nb_viargs = i;
4435}
4436
4437static inline void register_vfarg (vector float* vfarg,
4438                                  int s, uint8_t _exp, uint32_t mant)
4439{
4440   uint32_t tmp;
4441   vector uint32_t* vfargI = (vector uint32_t*)vfarg;
4442
4443   tmp = ((uint64_t)s << 31) | ((uint64_t)_exp << 23) | mant;
4444   *vfargI = (vector uint32_t){ tmp,tmp,tmp,tmp };
4445   AB_DPRINTF("%d %02x %06x => %08x %0e\n",
4446              s, _exp, mant, *((uint32_t*)&tmp), *(float*)&tmp);
4447}
4448
4449static void build_vfargs_table (void)
4450{
4451   /* Sign goes from zero to one
4452    * Exponent goes from 0 to ((1 << 9) - 1)
4453    * Mantissa goes from 1 to ((1 << 24) - 1)
4454    * + special values:
4455    * +0.0      : 0 0x00 0x000000            => 0x00000000
4456    * -0.0      : 1 0x00 0x000000            => 0x80000000
4457    * +infinity : 0 0xFF 0x000000            => 0x7F800000
4458    * -infinity : 1 0xFF 0x000000            => 0xFF800000
4459    * +SNaN     : 0 0xFF 0x7FFFFF (non-zero) => 0x7FFFFFFF
4460    * -SNaN     : 1 0xFF 0x7FFFFF (non-zero) => 0xFFFFFFFF
4461    * +QNaN     : 0 0xFF 0x3FFFFF (non-zero) => 0x7FBFFFFF
4462    * -QNaN     : 1 0xFF 0x3FFFFF (non-zero) => 0xFFBFFFFF
4463    * (8 values)
4464    */
4465   uint32_t mant;
4466   uint16_t _exp;
4467   int s;
4468   int i=0;
4469
4470
4471#if !defined (ALTIVEC_ARGS_LARGE)
4472   nb_vfargs = 12;
4473   vfargs = memalign16(nb_vfargs * sizeof(vector float));
4474
4475   // 4 values:
4476   for (s=0; s<2; s++) {
4477      for (_exp=0x5; ; _exp += 0x9D ) {
4478         if (_exp > 0xDF)
4479            break;
4480         for (mant = 0x3FFFFF; mant < 0x7FFFFF;
4481              mant = /* random */ ((mant + 0x1A6) << 31) + 0x159) {
4482            register_vfarg(&vfargs[i++], s, (uint8_t)_exp, mant);
4483         }
4484      }
4485   }
4486#else
4487   nb_vfargs = 50;
4488   vfargs = memalign16(nb_vfargs * sizeof(vector float));
4489
4490   for (s=0; s<2; s++) {
4491      for (_exp=0x0; ; _exp += 0x3F ) {
4492         //      for (_exp=0; ; _exp = ((_exp + 1) << 1) + 3) {
4493         if (_exp >= 0xFE)
4494            _exp = 0xFE;
4495         for (mant = 0x0; mant < 0x7FFFFF;
4496              mant = /* random */ ((mant + 0x4A6) << 5) + 0x359) {
4497            register_vfarg(&vfargs[i++], s, (uint8_t)_exp, mant);
4498         }
4499         if (_exp >= 0xFE)
4500            break;
4501      }
4502   }
4503#endif
4504
4505   /* Special values */
4506   /* +0.0      : 0 0x00 0x000000 */
4507   s = 0;
4508   _exp = 0x00;
4509   mant = 0x000000;
4510   register_vfarg(&vfargs[i++], s, _exp, mant);
4511   /* -0.0      : 1 0x00 0x000000 */
4512   s = 1;
4513   _exp = 0x00;
4514   mant = 0x000000;
4515   register_vfarg(&vfargs[i++], s, _exp, mant);
4516
4517   /* +infinity : 0 0xFF 0x000000  */
4518   s = 0;
4519   _exp = 0xFF;
4520   mant = 0x000000;
4521   register_vfarg(&vfargs[i++], s, _exp, mant);
4522   /* -infinity : 1 0xFF 0x000000 */
4523   s = 1;
4524   _exp = 0xFF;
4525   mant = 0x000000;
4526   register_vfarg(&vfargs[i++], s, _exp, mant);
4527
4528   /* NaN: _exponent all 1s, non-zero fraction */
4529   /* SNaN is a NaN with the most significant fraction bit clear.*/
4530   /* +SNaN     : 0 0xFF 0x7FFFFF */
4531   s = 0;
4532   _exp = 0xFF;
4533   mant = 0x7FFFFF;
4534   register_vfarg(&vfargs[i++], s, _exp, mant);
4535   /* -SNaN     : 1 0xFF 0x7FFFFF */
4536   s = 1;
4537   _exp = 0xFF;
4538   mant = 0x7FFFFF;
4539   register_vfarg(&vfargs[i++], s, _exp, mant);
4540
4541   /* QNaN is a NaN with the most significant fraction bit set */
4542   /* +QNaN     : 0 0xFF 0x3F0000 */
4543   s = 0;
4544   _exp = 0xFF;
4545   mant = 0x3FFFFF;
4546   register_vfarg(&vfargs[i++], s, _exp, mant);
4547   /* -QNaN     : 1 0xFF 0x3F0000 */
4548   s = 1;
4549   _exp = 0xFF;
4550   mant = 0x3FFFFF;
4551   register_vfarg(&vfargs[i++], s, _exp, mant);
4552   AB_DPRINTF("Registered %d vfargs values\n", i);
4553
4554   assert(i <= nb_vfargs);
4555   nb_vfargs = i;
4556}
4557#endif
4558
4559#if 0
4560static void dump_iargs (void)
4561{
4562   int i;
4563   for (i = 0; i < nb_iargs; i++) {
4564      printf("iarg %d: %08x %08x %08x\n", i, iargs[i],
4565             (unsigned int)&iargs[i], (unsigned int)iargs);
4566   }
4567}
4568
4569static void dump_iargs16 (void)
4570{
4571   int i;
4572   for (i = 0; i < nb_ii16; i++) {
4573      printf("iarg16 %d: %08x %08x %08x\n", i, ii16[i],
4574             (unsigned int)&ii16[i], (unsigned int)ii16);
4575   }
4576}
4577
4578static void dump_vfargs (void)
4579{
4580   vector float vf;
4581   float f;
4582   int i=0;
4583   for (i=0; i<nb_vfargs; i++) {
4584      vf = (vector float)vfargs[i];
4585      f  = ((float*)&vf)[0];
4586      printf("vfarg %3d: %24f : %08x\n", i, f, ((unsigned int*)&f)[0]);
4587   }
4588}
4589#endif
4590
4591static void test_int_three_args (const char* name, test_func_t func,
4592                                 unused uint32_t test_flags)
4593{
4594   volatile HWord_t res;
4595   volatile uint32_t flags, xer;
4596   int i, j, k;
4597
4598   for (i=0; i<nb_iargs; i++) {
4599      for (j=0; j<nb_iargs; j++) {
4600         for (k=0; k<nb_iargs; k++) {
4601            r14 = iargs[i];
4602            r15 = iargs[j];
4603            r16 = iargs[k];
4604
4605	    SET_CR_XER_ZERO;
4606            (*func)();
4607	    GET_CR_XER(flags,xer);
4608            res = r17;
4609
4610#ifndef __powerpc64__
4611            printf("%s %08x, %08x, %08x => %08x (%08x %08x)\n",
4612#else
4613            printf("%s %016llx, %016llx, %016llx => %016llx (%08x %08x)\n",
4614#endif
4615                   name, iargs[i], iargs[j], iargs[k], res, flags, xer);
4616         }
4617         if (verbose) printf("\n");
4618      }
4619   }
4620}
4621
4622static void test_int_two_args (const char* name, test_func_t func,
4623                               uint32_t test_flags)
4624{
4625   volatile HWord_t res;
4626   volatile uint32_t flags, xer, xer_orig;
4627   int i, j, is_div, zap_hi32;
4628
4629   // catches div, divwu, divo, divwu, divwuo, and . variants
4630   is_div = strstr(name, "divw") != NULL;
4631
4632   zap_hi32 = strstr(name, "mulhw") != NULL;
4633
4634   xer_orig = 0x00000000;
4635 redo:
4636   for (i=0; i<nb_iargs; i++) {
4637      for (j=0; j<nb_iargs; j++) {
4638
4639         /* result of division by zero is implementation dependent.
4640            don't test it. */
4641         if (is_div && iargs[j] == 0)
4642            continue;
4643
4644         r14 = iargs[i];
4645         r15 = iargs[j];
4646
4647         SET_XER(xer_orig);
4648         SET_CR_ZERO;
4649         (*func)();
4650         GET_CR_XER(flags,xer);
4651         res = r17;
4652
4653#ifndef __powerpc64__
4654         printf("%s %08x, %08x => %08x (%08x %08x)\n",
4655#else
4656         if (zap_hi32) res &= 0xFFFFFFFFULL;
4657         printf("%s %016llx, %016llx => %016llx (%08x %08x)\n",
4658#endif
4659                name, iargs[i], iargs[j], res, flags, xer);
4660      }
4661      if (verbose) printf("\n");
4662   }
4663   if ((test_flags & PPC_XER_CA) && xer_orig == 0x00000000) {
4664      xer_orig = 0x20000000;
4665      goto redo;
4666   }
4667}
4668
4669static void test_int_one_arg (const char* name, test_func_t func,
4670                               uint32_t test_flags)
4671{
4672   volatile HWord_t res;
4673   volatile uint32_t flags, xer, xer_orig;
4674   int i;
4675
4676   xer_orig = 0x00000000;
4677 redo:
4678   for (i=0; i<nb_iargs; i++) {
4679      r14 = iargs[i];
4680      SET_XER(xer_orig);
4681      SET_CR_ZERO;
4682      (*func)();
4683      res = r17;
4684      GET_CR_XER(flags,xer);
4685
4686#ifndef __powerpc64__
4687      printf("%s %08x => %08x (%08x %08x)\n",
4688#else
4689      printf("%s %016llx => %016llx (%08x %08x)\n",
4690#endif
4691             name, iargs[i], res, flags, xer);
4692   }
4693   if ((test_flags & PPC_XER_CA) && xer_orig == 0x00000000) {
4694      xer_orig = 0x20000000;
4695      goto redo;
4696   }
4697}
4698
4699static inline void invalidate_icache ( void *ptr, int nbytes )
4700{
4701   HWord_t startaddr = (HWord_t) ptr;
4702   HWord_t endaddr   = startaddr + nbytes;
4703   HWord_t cls       = 32; /*VG_(cache_line_size_ppc32);*/
4704   HWord_t addr;
4705
4706   startaddr &= ~(cls - 1);
4707   for (addr = startaddr; addr < endaddr; addr += cls)
4708      asm volatile("dcbst 0,%0" : : "r" (addr));
4709   asm volatile("sync");
4710   for (addr = startaddr; addr < endaddr; addr += cls)
4711      asm volatile("icbi 0,%0" : : "r" (addr));
4712   asm volatile("sync; isync");
4713}
4714
4715/* for god knows what reason, if this isn't inlined, the
4716   program segfaults. */
4717static inline
4718void _patch_op_imm (uint32_t *p_insn, uint16_t imm, int sh, int len)
4719{
4720   uint32_t mask = ((1 << len) - 1) << sh;
4721   *p_insn = (*p_insn & ~mask) | ((imm<<sh) & mask);
4722}
4723
4724static inline
4725void patch_op_imm (uint32_t* p_insn, uint16_t imm, int sh, int len)
4726{
4727   _patch_op_imm(p_insn, imm, sh, len);
4728   invalidate_icache(p_insn, 4);
4729}
4730
4731static inline
4732void patch_op_imm16 (uint32_t *p_insn, uint16_t imm)
4733{
4734   patch_op_imm(p_insn, imm, 0, 16);
4735}
4736
4737
4738/* Copy the 2 insn function starting at p_func_F to func_buf[], and
4739   return a possibly different pointer, which, when called, runs the
4740   copy in func_buf[]. */
4741static inline
4742test_func_t init_function( test_func_t p_func_F, uint32_t func_buf[] )
4743{
4744   uint32_t* p_func = (uint32_t*)p_func_F;
4745#ifndef __powerpc64__
4746   func_buf[0] = p_func[0];
4747   func_buf[1] = p_func[1];
4748   return (test_func_t)&func_buf[0];
4749#else
4750   /* p_func points to a function descriptor, the first word of which
4751      points to the real code.  Copy the code itself but not the
4752      descriptor, and just swizzle the descriptor's entry pointer. */
4753   uint64_t* descr = (uint64_t*)p_func;
4754   uint32_t* entry = (uint32_t*)(descr[0]);
4755   func_buf[0] = entry[0];
4756   func_buf[1] = entry[1];
4757   descr[0] = (uint64_t)&func_buf[0];
4758   return (test_func_t)descr;
4759#endif // #ifndef __powerpc64__
4760}
4761
4762
4763static void test_int_one_reg_imm16 (const char* name,
4764                                    test_func_t func_IN,
4765                                    unused uint32_t test_flags)
4766{
4767   volatile test_func_t func;
4768   uint32_t* func_buf = get_rwx_area();
4769   volatile HWord_t res;
4770   volatile uint32_t flags, xer;
4771   int i, j;
4772
4773   for (i=0; i<nb_iargs; i++) {
4774      for (j=0; j<nb_ii16; j++) {
4775         /* Patch up the instruction */
4776         func = init_function( func_IN, func_buf );
4777         patch_op_imm16(&func_buf[0], ii16[j]);
4778
4779         r14 = iargs[i];
4780
4781         SET_CR_XER_ZERO;
4782         (*func)();
4783         GET_CR_XER(flags,xer);
4784         res = r17;
4785
4786#ifndef __powerpc64__
4787         printf("%s %08x, %08x => %08x (%08x %08x)\n",
4788#else
4789         printf("%s %016llx, %08x => %016llx (%08x %08x)\n",
4790#endif
4791                name, iargs[i], ii16[j], res, flags, xer);
4792      }
4793      if (verbose) printf("\n");
4794   }
4795}
4796
4797/* Special test cases for:
4798 * rlwimi
4799 * rlwinm
4800 * rlwnm
4801 * srawi
4802 * mcrf
4803 * mcrfs
4804 * mcrxr_cb
4805 * mfcr_cb
4806 * mfspr_cb
4807 * mftb_cb
4808 * mtcrf_cb
4809 * mtspr_cb
4810
4811 __powerpc64__ only:
4812 * rldcl       rA,rS,SH,MB
4813 * rldcr       rA,rS,SH,ME
4814 * rldic       rA,rS,SH,MB
4815 * rldicl      rA,rS,SH,MB
4816 * rldicr      rA,rS,SH,ME
4817 * rldimi      rA,rS,SH,MB
4818 * sradi       rA,rS,SH
4819 */
4820
4821static void rlwi_cb (const char* name, test_func_t func_IN,
4822                     unused uint32_t test_flags)
4823{
4824   volatile test_func_t func;
4825   uint32_t* func_buf = get_rwx_area();
4826   volatile HWord_t res;
4827   volatile uint32_t flags, xer;
4828   int i, j, k, l, arg_step;
4829
4830   arg_step = (arg_list_size == 0) ? 31 : 3;
4831
4832   r17 = 0;  // rlwimi takes r17 as input: start with a clean slate.
4833
4834   for (i=0; i<nb_iargs; i++) {
4835      for (j=0; j<32; j+=arg_step) {
4836         for (k=0; k<32; k+=arg_step) {
4837            for (l=0; l<32; l+=arg_step) {
4838               /* Patch up the instruction */
4839               func = init_function( func_IN, func_buf );
4840               _patch_op_imm(&func_buf[0], j, 11, 5);
4841               _patch_op_imm(&func_buf[0], k, 6, 5);
4842               patch_op_imm(&func_buf[0], l, 1, 5);
4843
4844               r14 = iargs[i];
4845
4846               SET_CR_XER_ZERO;
4847               (*func)();
4848               GET_CR_XER(flags,xer);
4849               res = r17;
4850
4851#ifndef __powerpc64__
4852               printf("%s %08x, %2d, %2d, %2d => %08x (%08x %08x)\n",
4853#else
4854               printf("%s %016llx, %2d, %2d, %2d => %016llx (%08x %08x)\n",
4855#endif
4856                      name, iargs[i], j, k, l, res, flags, xer);
4857            }
4858            if (verbose) printf("\n");
4859         }
4860      }
4861   }
4862}
4863
4864static void rlwnm_cb (const char* name, test_func_t func_IN,
4865                      unused uint32_t test_flags)
4866{
4867   volatile test_func_t func;
4868   uint32_t* func_buf = get_rwx_area();
4869   volatile HWord_t res;
4870   volatile uint32_t flags, xer;
4871   int i, j, k, l, arg_step;
4872
4873   arg_step = (arg_list_size == 0) ? 31 : 3;
4874
4875   for (i=0; i<nb_iargs; i++) {
4876      for (j=0; j<nb_iargs; j++) {
4877         for (k=0; k<32; k+=arg_step) {
4878            for (l=0; l<32; l+=arg_step) {
4879               /* Patch up the instruction */
4880               func = init_function( func_IN, func_buf );
4881               _patch_op_imm(&func_buf[0], k, 6, 5);
4882               patch_op_imm(&func_buf[0], l, 1, 5);
4883
4884               r14 = iargs[i];
4885               r15 = iargs[j];
4886
4887               SET_CR_XER_ZERO;
4888               (*func)();
4889               GET_CR_XER(flags,xer);
4890               res = r17;
4891
4892#ifndef __powerpc64__
4893               printf("%s %08x, %08x, %2d, %2d => %08x (%08x %08x)\n",
4894#else
4895               printf("%s %016llx, %016llx, %2d, %2d => %016llx (%08x %08x)\n",
4896#endif
4897                      name, iargs[i], iargs[j], k, l, res, flags, xer);
4898            }
4899            if (verbose) printf("\n");
4900         }
4901      }
4902   }
4903}
4904
4905static void srawi_cb (const char* name, test_func_t func_IN,
4906                      unused uint32_t test_flags)
4907{
4908   volatile test_func_t func;
4909   uint32_t* func_buf = get_rwx_area();
4910   volatile HWord_t res;
4911   volatile uint32_t flags, xer;
4912   int i, j, arg_step;
4913
4914   arg_step = (arg_list_size == 0) ? 31 : 1;
4915
4916   for (i=0; i<nb_iargs; i++) {
4917      for (j=0; j<32; j+=arg_step) {
4918         /* Patch up the instruction */
4919         func = init_function( func_IN, func_buf );
4920         patch_op_imm(&func_buf[0], j, 11, 5);
4921
4922         r14 = iargs[i];
4923
4924         SET_CR_XER_ZERO;
4925         (*func)();
4926         GET_CR_XER(flags,xer);
4927         res = r17;
4928
4929#ifndef __powerpc64__
4930         printf("%s %08x, %2d => %08x (%08x %08x)\n",
4931#else
4932         printf("%s %016llx, %2d => %016llx (%08x %08x)\n",
4933#endif
4934                name, iargs[i], j, res, flags, xer);
4935      }
4936      if (verbose) printf("\n");
4937   }
4938}
4939
4940static void mcrf_cb (const char* name, test_func_t func_IN,
4941                      unused uint32_t test_flags)
4942{
4943   volatile test_func_t func;
4944   uint32_t* func_buf = get_rwx_area();
4945   volatile uint32_t flags, xer;
4946   int i, j, k, arg_step;
4947
4948   arg_step = (arg_list_size == 0) ? 7 : 1;
4949
4950   for (i=0; i<nb_iargs; i++) {
4951      for (j=0; j<8; j+=arg_step) {
4952         for (k=0; k<8; k+=arg_step) {
4953            /* Patch up the instruction */
4954            func = init_function( func_IN, func_buf );
4955            _patch_op_imm(&func_buf[0], j, 23, 3);
4956            patch_op_imm(&func_buf[0], k, 18, 3);
4957
4958            r14 = iargs[i];
4959
4960            SET_CR(r14);
4961            SET_XER_ZERO;
4962            (*func)();
4963            GET_CR_XER(flags,xer);
4964
4965#ifndef __powerpc64__
4966            printf("%s %d, %d (%08x) => (%08x %08x)\n",
4967#else
4968            printf("%s %d, %d (%016llx) => (%08x %08x)\n",
4969#endif
4970                   name, j, k, iargs[i], flags, xer);
4971         }
4972         if (verbose) printf("\n");
4973      }
4974   }
4975}
4976
4977static void mcrxr_cb (const char* name, test_func_t func_IN,
4978                      unused uint32_t test_flags)
4979{
4980   volatile test_func_t func;
4981   uint32_t* func_buf = get_rwx_area();
4982   volatile uint32_t flags, xer;
4983   int i, j, k, arg_step;
4984
4985   arg_step = 1; //(arg_list_size == 0) ? 7 : 1;
4986
4987   for (i=0; i<16; i+=arg_step) {
4988      j = i << 28;
4989      for (k=0; k<8; k+=arg_step) {
4990         /* Patch up the instruction */
4991         func = init_function( func_IN, func_buf );
4992         patch_op_imm(&func_buf[0], k, 23, 3);
4993
4994         r14 = j;
4995
4996	 SET_CR_ZERO;
4997	 SET_XER(r14);
4998         (*func)();
4999         GET_CR_XER(flags,xer);
5000
5001         printf("%s %d (%08x) => (%08x %08x)\n",
5002                name, k, j, flags, xer);
5003      }
5004      if (verbose) printf("\n");
5005   }
5006}
5007
5008static void mfcr_cb (const char* name, test_func_t func,
5009                     unused uint32_t test_flags)
5010{
5011   volatile HWord_t res;
5012   volatile uint32_t flags, xer;
5013   int i;
5014
5015   for (i=0; i<nb_iargs; i++) {
5016      r14 = iargs[i];
5017
5018      /* Set up flags for test */
5019      SET_CR(r14);
5020      SET_XER_ZERO;
5021      (*func)();
5022      GET_CR_XER(flags,xer);
5023      res = r17;
5024
5025#ifndef __powerpc64__
5026      printf("%s (%08x) => %08x (%08x %08x)\n",
5027#else
5028      printf("%s (%016llx) => %016llx (%08x %08x)\n",
5029#endif
5030             name, iargs[i], res, flags, xer);
5031   }
5032}
5033
5034// NOTE: Not using func: calling function kills lr
5035static void mfspr_cb (const char* name, test_func_t func,
5036                      unused uint32_t test_flags)
5037{
5038   //volatile uint32_t res, flags, xer, ctr, lr, tmpcr, tmpxer;
5039   volatile HWord_t res;
5040   int j, k;
5041   func = func; // just to stop compiler complaining
5042
5043   // mtxer followed by mfxer
5044   for (k=0; k<nb_iargs; k++) {
5045      j = iargs[k];
5046      __asm__ __volatile__(
5047         "mtxer %1\n"
5048         "\tmfxer %0"
5049         : /*out*/"=b"(res) : /*in*/"b"(j) : /*trashed*/"xer"
5050      );
5051      res &= 0xE000007F; /* rest of the bits are undefined */
5052
5053#ifndef __powerpc64__
5054      printf("%s 1 (%08x) -> mtxer -> mfxer => %08x\n",
5055#else
5056      printf("%s 1 (%08x) -> mtxer -> mfxer => %016llx\n",
5057#endif
5058             name, j, res);
5059   }
5060
5061   // mtlr followed by mflr
5062   for (k=0; k<nb_iargs; k++) {
5063      j = iargs[k];
5064      __asm__ __volatile__(
5065         "mtlr %1\n"
5066         "\tmflr %0"
5067         : /*out*/"=b"(res) : /*in*/"b"(j) : /*trashed*/"lr"
5068      );
5069
5070#ifndef __powerpc64__
5071      printf("%s 8 (%08x) ->  mtlr ->  mflr => %08x\n",
5072#else
5073      printf("%s 8 (%08x) ->  mtlr ->  mflr => %016llx\n",
5074#endif
5075             name, j, res);
5076   }
5077
5078   // mtctr followed by mfctr
5079   for (k=0; k<nb_iargs; k++) {
5080      j = iargs[k];
5081      __asm__ __volatile__(
5082         "mtctr %1\n"
5083         "\tmfctr %0"
5084         : /*out*/"=b"(res) : /*in*/"b"(j) : /*trashed*/"ctr"
5085      );
5086
5087#ifndef __powerpc64__
5088      printf("%s 9 (%08x) -> mtctr -> mfctr => %08x\n",
5089#else
5090      printf("%s 9 (%08x) -> mtctr -> mfctr => %016llx\n",
5091#endif
5092             name, j, res);
5093   }
5094}
5095
5096static void mtcrf_cb (const char* name, test_func_t func_IN,
5097                      unused uint32_t test_flags)
5098{
5099   volatile test_func_t func;
5100   uint32_t* func_buf = get_rwx_area();
5101   volatile uint32_t flags, xer;
5102   int i, j, arg_step;
5103
5104   arg_step = (arg_list_size == 0) ? 99 : 1;
5105
5106   for (i=0; i<nb_iargs; i++) {
5107      for (j=0; j<256; j+=arg_step) {
5108         /* Patch up the instruction */
5109         func = init_function( func_IN, func_buf );
5110         patch_op_imm(&func_buf[0], j, 12, 8);
5111
5112         r14 = iargs[i];
5113
5114         SET_CR_XER_ZERO;
5115         (*func)();
5116         GET_CR_XER(flags,xer);
5117
5118#ifndef __powerpc64__
5119         printf("%s %3d, %08x => (%08x %08x)\n",
5120#else
5121         printf("%s %3d, %016llx => (%08x %08x)\n",
5122#endif
5123                name, j, iargs[i], flags, xer);
5124      }
5125      if (verbose) printf("\n");
5126   }
5127}
5128
5129// NOTE: Not using func: calling function kills lr
5130static void mtspr_cb (const char* name, test_func_t func,
5131                      unused uint32_t test_flags)
5132{
5133}
5134
5135#ifdef __powerpc64__
5136static void rldc_cb (const char* name, test_func_t func_IN,
5137                     unused uint32_t test_flags)
5138{
5139   volatile test_func_t func;
5140   uint32_t* func_buf = get_rwx_area();
5141   volatile HWord_t res;
5142   volatile uint32_t flags, xer;
5143   int i, j, k, arg_step;
5144
5145   arg_step = (arg_list_size == 0) ? 7 : 3;
5146
5147   for (i=0; i<nb_iargs; i++) {
5148      for (j=0; j<nb_iargs; j++) {
5149         for (k=0; k<64; k+=arg_step) {
5150            /* Patch up the instruction */
5151            func = init_function( func_IN, func_buf );
5152            patch_op_imm(&func_buf[0], (((k & 0x1F)<<1) | ((k>>5)&1)), 5, 6);
5153
5154            r14 = iargs[i];
5155            r15 = iargs[j];
5156
5157            SET_CR_XER_ZERO;
5158            (*func)();
5159            GET_CR_XER(flags,xer);
5160            res = r17;
5161
5162            printf("%s %016llx, %016llx, %2d => %016llx (%08x %08x)\n",
5163                   name, iargs[i], iargs[j], k, res, flags, xer);
5164         }
5165         if (verbose) printf("\n");
5166      }
5167   }
5168}
5169
5170static void rldi_cb (const char* name, test_func_t func_IN,
5171                     unused uint32_t test_flags)
5172{
5173   volatile test_func_t func;
5174   uint32_t* func_buf = get_rwx_area();
5175   volatile HWord_t res;
5176   volatile uint32_t flags, xer;
5177   int i, j, k, arg_step;
5178
5179   arg_step = (arg_list_size == 0) ? 7 : 3;
5180
5181   for (i=0; i<nb_iargs; i++) {
5182      for (j=0; j<64; j+=arg_step) {     // SH
5183         for (k=0; k<64; k+=arg_step) {  // MB|ME
5184            /* Patch up the instruction */
5185            func = init_function( func_IN, func_buf );
5186            _patch_op_imm(&func_buf[0], (j & 0x1F), 11, 5);
5187            _patch_op_imm(&func_buf[0], ((j>>5)&1), 1, 1);
5188            patch_op_imm(&func_buf[0], (((k & 0x1F)<<1) | ((k>>5)&1)), 5, 6);
5189
5190            r14 = iargs[i];
5191
5192            SET_CR_XER_ZERO;
5193            (*func)();
5194            GET_CR_XER(flags,xer);
5195            res = r17;
5196
5197            printf("%s %016llx, %2d, %2d => %016llx (%08x %08x)\n",
5198                   name, iargs[i], j, k, res, flags, xer);
5199         }
5200         if (verbose) printf("\n");
5201      }
5202   }
5203}
5204
5205static void sradi_cb (const char* name, test_func_t func_IN,
5206                      unused uint32_t test_flags)
5207{
5208   volatile test_func_t func;
5209   uint32_t* func_buf = get_rwx_area();
5210   volatile HWord_t res;
5211   volatile uint32_t flags, xer;
5212   int i, j, arg_step;
5213
5214   arg_step = (arg_list_size == 0) ? 7 : 3;
5215
5216   for (i=0; i<nb_iargs; i++) {
5217      for (j=0; j<64; j+=arg_step) {     // SH
5218         /* Patch up the instruction */
5219         func = init_function( func_IN, func_buf );
5220         _patch_op_imm(&func_buf[0], (j & 0x1F), 11, 5);
5221         patch_op_imm(&func_buf[0], ((j>>5)&1), 1, 1);
5222
5223         r14 = iargs[i];
5224
5225         SET_CR_XER_ZERO;
5226         (*func)();
5227         GET_CR_XER(flags,xer);
5228         res = r17;
5229
5230         printf("%s %016llx, %2d => %016llx (%08x %08x)\n",
5231                name, iargs[i], j, res, flags, xer);
5232      }
5233      if (verbose) printf("\n");
5234   }
5235}
5236#endif // #ifdef __powerpc64__
5237
5238
5239typedef struct special_t special_t;
5240
5241struct special_t {
5242   const char *name;
5243   void (*test_cb)(const char* name, test_func_t func,
5244                   unused uint32_t test_flags);
5245};
5246
5247static void test_special (special_t *table,
5248                          const char* name, test_func_t func,
5249                          unused uint32_t test_flags)
5250{
5251   const char *tmp;
5252   int i;
5253
5254   for (tmp = name; isspace(*tmp); tmp++)
5255      continue;
5256   for (i=0; table[i].name != NULL; i++) {
5257#if 0
5258      fprintf(stderr, "look for handler for '%s' (%s)\n", name,
5259              table[i].name);
5260#endif
5261      if (strcmp(table[i].name, tmp) == 0) {
5262         (*table[i].test_cb)(name, func, test_flags);
5263         return;
5264      }
5265   }
5266   fprintf(stderr, "ERROR: no test found for op '%s'\n", name);
5267}
5268
5269static special_t special_int_ops[] = {
5270   {
5271      "rlwimi", /* One register + 3 5 bits immediate arguments */
5272      &rlwi_cb,
5273   },
5274   {
5275      "rlwimi.", /* One register + 3 5 bits immediate arguments */
5276      &rlwi_cb,
5277   },
5278   {
5279      "rlwinm", /* 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      "rlwnm",  /* Two registers + 2 5 bits immediate arguments */
5288      &rlwnm_cb,
5289   },
5290   {
5291      "rlwnm.",  /* Two registers + 2 5 bits immediate arguments */
5292      &rlwnm_cb,
5293   },
5294   {
5295      "srawi",  /* One register + 1 5 bits immediate arguments */
5296      &srawi_cb,
5297   },
5298   {
5299      "srawi.",  /* One register + 1 5 bits immediate arguments */
5300      &srawi_cb,
5301   },
5302   {
5303      "mcrf",  /* 2 3 bits immediate arguments */
5304      &mcrf_cb,
5305   },
5306#if 0
5307   {
5308      "mcrfs",  /* 2 3 bits immediate arguments */
5309      &mcrfs_cb,
5310   },
5311#endif
5312   {
5313      "mcrxr",  /* 1 3 bits immediate argument */
5314      &mcrxr_cb,
5315   },
5316   {
5317      "mfcr",  /* No arguments */
5318      &mfcr_cb,
5319   },
5320   {
5321      "mfspr",  /* 1 10 bits immediate argument */
5322      &mfspr_cb,
5323   },
5324#if 0
5325   {   // Move from time base
5326      "mftb",  /* 1 10 bits immediate arguments */
5327      &mftb_cb,
5328   },
5329#endif
5330   {
5331      "mtcrf",  /* One register + 1 8 bits immediate arguments */
5332      &mtcrf_cb,
5333   },
5334   {
5335      "mtspr",  /* One register + 1 10 bits immediate arguments */
5336      &mtspr_cb,
5337   },
5338#ifdef __powerpc64__
5339   {
5340      "rldcl",   /* Two registers + 1 6 bit immediate argument */
5341      &rldc_cb,
5342   },
5343   {
5344      "rldcl.",  /* Two registers + 1 6 bit immediate argument */
5345      &rldc_cb,
5346   },
5347   {
5348      "rldcr",   /* 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      "rldic",   /* One register + 2 6 bit immediate arguments */
5357      &rldi_cb,
5358   },
5359   {
5360      "rldic.",  /* One register + 2 6 bit immediate arguments */
5361      &rldi_cb,
5362   },
5363   {
5364      "rldicl",  /* 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      "rldicr",  /* 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      "rldimi",  /* 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      "sradi",  /* One register + 1 6 bit immediate argument */
5389      &sradi_cb,
5390   },
5391   {
5392      "sradi.", /* One register + 1 6 bit immediate argument */
5393      &sradi_cb,
5394   },
5395#endif // #ifdef __powerpc64__
5396   {
5397      NULL,
5398      NULL,
5399   },
5400};
5401
5402static void test_int_special (const char* name, test_func_t func,
5403                              uint32_t test_flags)
5404{
5405   test_special(special_int_ops, name, func, test_flags);
5406}
5407
5408
5409static void test_int_ld_one_reg_imm16 (const char* name,
5410                                       test_func_t func_IN,
5411                                       unused uint32_t test_flags)
5412{
5413   volatile test_func_t func;
5414   uint32_t* func_buf = get_rwx_area();
5415   volatile HWord_t res, base;
5416   volatile uint32_t flags, xer;
5417   int i, offs, is_lwa=0;
5418
5419#ifdef __powerpc64__
5420   is_lwa = strstr(name, "lwa") != NULL;
5421#endif
5422
5423   // +ve d
5424   base = (HWord_t)&iargs[0];
5425   for (i=0; i<nb_iargs; i++) {
5426      offs = i * sizeof(HWord_t);
5427
5428      /* Patch up the instruction */
5429      func = init_function( func_IN, func_buf );
5430      if (is_lwa)
5431         patch_op_imm(&func_buf[0], offs>>2, 2, 14);
5432      else
5433         patch_op_imm16(&func_buf[0], offs);
5434
5435      r14 = base;
5436
5437      SET_CR_XER_ZERO;
5438      (*func)();
5439      GET_CR_XER(flags,xer);
5440      res = r17;
5441
5442#ifndef __powerpc64__
5443      printf("%s %2d, (%08x) => %08x, %2d (%08x %08x)\n",
5444#else
5445      printf("%s %3d, (%016llx) => %016llx, %3lld (%08x %08x)\n",
5446#endif
5447             name, offs, iargs[i], res, r14-base, flags, xer);
5448   }
5449   if (verbose) printf("\n");
5450
5451   // -ve d
5452   base = (HWord_t)&iargs[nb_iargs-1];
5453   for (i = -nb_iargs+1; i<=0; i++) {
5454      offs = i * sizeof(HWord_t);
5455
5456      /* Patch up the instruction */
5457      func = init_function( func, func_buf );
5458      patch_op_imm16(&func_buf[0], offs);
5459
5460      r14 = base;
5461
5462      SET_CR_XER_ZERO;
5463      (*func)();
5464      GET_CR_XER(flags,xer);
5465      res = r17;
5466
5467#ifndef __powerpc64__
5468      printf("%s %2d, (%08x) => %08x, %2d (%08x %08x)\n",
5469#else
5470      printf("%s %3d, (%016llx) => %016llx, %3lld (%08x %08x)\n",
5471#endif
5472             name, offs, iargs[nb_iargs-1+i], res, r14-base, flags, xer);
5473   }
5474}
5475
5476static void test_int_ld_two_regs (const char* name,
5477                                  test_func_t func,
5478                                  unused uint32_t test_flags)
5479{
5480   volatile HWord_t res, base;
5481   volatile uint32_t flags, xer;
5482   int i, offs;
5483
5484   // +ve d
5485   base = (HWord_t)&iargs[0];
5486   for (i=0; i<nb_iargs; i++) {
5487      offs = i * sizeof(HWord_t);
5488      r14 = base;
5489      r15 = offs;
5490
5491      SET_CR_XER_ZERO;
5492      (*func)();
5493      GET_CR_XER(flags,xer);
5494      res = r17;
5495
5496#ifndef __powerpc64__
5497      printf("%s %d (%08x) => %08x, %d (%08x %08x)\n",
5498#else
5499      printf("%s %3d, (%016llx) => %016llx, %2lld (%08x %08x)\n",
5500#endif
5501             name, offs, iargs[i], res, r14-base, flags, xer);
5502   }
5503}
5504
5505static void test_int_st_two_regs_imm16 (const char* name,
5506                                        test_func_t func_IN,
5507                                        unused uint32_t test_flags)
5508{
5509   volatile test_func_t func;
5510   uint32_t* func_buf = get_rwx_area();
5511   volatile uint32_t flags, xer;
5512   int i, offs, k;
5513   HWord_t *iargs_priv, base;
5514
5515   // private iargs table to store to
5516   iargs_priv = malloc(nb_iargs * sizeof(HWord_t));
5517
5518   // +ve d
5519   base = (HWord_t)&iargs_priv[0];
5520   for (i=0; i<nb_iargs; i++) {
5521      for (k=0; k<nb_iargs; k++)  // clear array
5522         iargs_priv[k] = 0;
5523
5524      offs = i * sizeof(HWord_t);
5525
5526      /* Patch up the instruction */
5527      func = init_function( func_IN, func_buf );
5528      patch_op_imm16(&func_buf[0], offs);
5529
5530      r14 = iargs[i];             // read from iargs
5531      r15 = base;                 // store to r15 + offs
5532
5533      SET_CR_XER_ZERO;
5534      (*func)();
5535      GET_CR_XER(flags,xer);
5536
5537#ifndef __powerpc64__
5538      printf("%s %08x, %2d => %08x, %2d (%08x %08x)\n",
5539#else
5540      printf("%s %016llx, %3d => %016llx, %3lld (%08x %08x)\n",
5541#endif
5542             name, iargs[i], offs, iargs_priv[i], r15-base, flags, xer);
5543   }
5544   if (verbose) printf("\n");
5545
5546   // -ve d
5547   base = (HWord_t)&iargs_priv[nb_iargs-1];
5548   for (i = -nb_iargs+1; i<=0; i++) {
5549      for (k=0; k<nb_iargs; k++)  // clear array
5550         iargs_priv[k] = 0;
5551
5552      offs = i * sizeof(HWord_t);
5553
5554      /* Patch up the instruction */
5555      func = init_function( func, func_buf );
5556      patch_op_imm16(&func_buf[0], offs);
5557
5558      r14 = iargs[nb_iargs-1+i];  // read from iargs
5559      r15 = base;                 // store to r15 + offs
5560
5561      SET_CR_XER_ZERO;
5562      (*func)();
5563      GET_CR_XER(flags,xer);
5564
5565#ifndef __powerpc64__
5566      printf("%s %08x, %2d => %08x, %2d (%08x %08x)\n",
5567#else
5568      printf("%s %016llx, %3d => %016llx, %3lld (%08x %08x)\n",
5569#endif
5570             name, iargs[nb_iargs-1+i], offs, iargs_priv[nb_iargs-1+i],
5571             r15-base, flags, xer);
5572   }
5573   free(iargs_priv);
5574}
5575
5576static void test_int_st_three_regs (const char* name,
5577                                    test_func_t func,
5578                                    unused uint32_t test_flags)
5579{
5580   volatile uint32_t flags, xer;
5581   int i, offs, k;
5582   HWord_t *iargs_priv, base;
5583
5584   // private iargs table to store to
5585   iargs_priv = malloc(nb_iargs * sizeof(HWord_t));
5586
5587   base = (HWord_t)&iargs_priv[0];
5588   for (i=0; i<nb_iargs; i++) {
5589      for (k=0; k<nb_iargs; k++)  // clear array
5590         iargs_priv[k] = 0;
5591
5592      offs = i * sizeof(HWord_t);
5593      r14 = iargs[i];             // read from iargs
5594      r15 = base;                 // store to r15 + offs
5595      r16 = offs;
5596
5597      SET_CR_XER_ZERO;
5598      (*func)();
5599      GET_CR_XER(flags,xer);
5600
5601#ifndef __powerpc64__
5602      printf("%s %08x, %d => %08x, %d (%08x %08x)\n",
5603#else
5604      printf("%s %016llx, %3d => %016llx, %2lld (%08x %08x)\n",
5605#endif
5606             name, iargs[i], offs, iargs_priv[i], r15-base, flags, xer);
5607   }
5608   free(iargs_priv);
5609}
5610
5611
5612/* Used in do_tests, indexed by flags->nb_args
5613   Elements correspond to enum test_flags::num args
5614*/
5615static test_loop_t int_loops[] = {
5616   &test_int_one_arg,
5617   &test_int_two_args,
5618   &test_int_three_args,
5619   &test_int_two_args,
5620   &test_int_one_reg_imm16,
5621   &test_int_one_reg_imm16,
5622   &test_int_special,
5623   &test_int_ld_one_reg_imm16,
5624   &test_int_ld_two_regs,
5625   &test_int_st_two_regs_imm16,
5626   &test_int_st_three_regs,
5627};
5628
5629#if !defined (NO_FLOAT)
5630static void test_float_three_args (const char* name, test_func_t func,
5631                                   unused uint32_t test_flags)
5632{
5633   double res;
5634   uint64_t u0, u1, u2, ur;
5635   volatile uint32_t flags;
5636   int i, j, k;
5637
5638   /* Note: using nb_normal_fargs:
5639      - not testing special values for these insns
5640   */
5641
5642   for (i=0; i<nb_normal_fargs; i+=3) {
5643      for (j=0; j<nb_normal_fargs; j+=5) {
5644         for (k=0; k<nb_normal_fargs; k+=7) {
5645            u0 = *(uint64_t *)(&fargs[i]);
5646            u1 = *(uint64_t *)(&fargs[j]);
5647            u2 = *(uint64_t *)(&fargs[k]);
5648            f14 = fargs[i];
5649            f15 = fargs[j];
5650            f16 = fargs[k];
5651
5652            SET_FPSCR_ZERO;
5653            SET_CR_XER_ZERO;
5654            (*func)();
5655            GET_CR(flags);
5656            res = f17;
5657            ur = *(uint64_t *)(&res);
5658
5659            /* Note: zapping the bottom byte of the result,
5660               as vex's accuracy isn't perfect */
5661            ur &= 0xFFFFFFFFFFFFFF00ULL;
5662
5663#ifndef __powerpc64__
5664            printf("%s %016llx, %016llx, %016llx => %016llx",
5665#else
5666            printf("%s %016llx, %016llx, %016llx => %016llx",
5667#endif
5668                   name, u0, u1, u2, ur);
5669#if defined TEST_FLOAT_FLAGS
5670            printf(" (%08x)", flags);
5671#endif
5672            printf("\n");
5673         }
5674         if (verbose) printf("\n");
5675      }
5676   }
5677}
5678
5679static void test_float_two_args (const char* name, test_func_t func,
5680                                 unused uint32_t test_flags)
5681{
5682   double res;
5683   uint64_t u0, u1, ur;
5684   volatile uint32_t flags;
5685   int i, j;
5686
5687   for (i=0; i<nb_fargs; i+=3) {
5688      for (j=0; j<nb_fargs; j+=5) {
5689         u0 = *(uint64_t *)(&fargs[i]);
5690         u1 = *(uint64_t *)(&fargs[j]);
5691         f14 = fargs[i];
5692         f15 = fargs[j];
5693
5694         SET_FPSCR_ZERO;
5695         SET_CR_XER_ZERO;
5696         (*func)();
5697         GET_CR(flags);
5698         res = f17;
5699         ur = *(uint64_t *)(&res);
5700
5701#ifndef __powerpc64__
5702         printf("%s %016llx, %016llx => %016llx",
5703#else
5704         printf("%s %016llx, %016llx => %016llx",
5705#endif
5706                name, u0, u1, ur);
5707#if defined TEST_FLOAT_FLAGS
5708         printf(" (%08x)", flags);
5709#endif
5710         printf("\n");
5711      }
5712      if (verbose) printf("\n");
5713   }
5714}
5715
5716static void test_float_one_arg (const char* name, test_func_t func,
5717                                unused uint32_t test_flags)
5718{
5719   double res;
5720   uint64_t u0, ur;
5721   volatile uint32_t flags;
5722   int i;
5723   unsigned zap_hi_32bits, zap_lo_44bits, zap_lo_47bits;
5724
5725   /* if we're testing fctiw or fctiwz, zap the hi 32bits,
5726      as they're undefined */
5727   zap_hi_32bits = strstr(name, " fctiw")    != NULL  ? 1 : 0;
5728   zap_lo_44bits = strstr(name, " fres")     != NULL  ? 1 : 0;
5729   zap_lo_47bits = strstr(name, " frsqrte")  != NULL  ? 1 : 0;
5730
5731   assert(zap_hi_32bits + zap_lo_44bits + zap_lo_47bits <= 1);
5732
5733   for (i=0; i<nb_fargs; i++) {
5734      u0 = *(uint64_t *)(&fargs[i]);
5735      f14 = fargs[i];
5736
5737       SET_FPSCR_ZERO;
5738       SET_CR_XER_ZERO;
5739       (*func)();
5740       GET_CR(flags);
5741       res = f17;
5742       ur = *(uint64_t *)(&res);
5743
5744      if (zap_hi_32bits)
5745         ur &= 0x00000000FFFFFFFFULL;
5746      if (zap_lo_44bits)
5747         ur &= 0xFFFFF00000000000ULL;
5748      if (zap_lo_47bits)
5749         ur &= 0xFFFF800000000000ULL;
5750
5751#ifndef __powerpc64__
5752      printf("%s %016llx => %016llx",
5753#else
5754      printf("%s %016llx => %016llx",
5755#endif
5756             name, u0, ur);
5757#if defined TEST_FLOAT_FLAGS
5758      printf(" (%08x)", flags);
5759#endif
5760      printf("\n");
5761    }
5762}
5763
5764/* Special test cases for:
5765 * mffs
5766 * mtfsb0
5767 * mtfsb1
5768 */
5769static special_t special_float_ops[] = {
5770#if 0
5771   {
5772      "mffs",   /* One 5 bits immediate argument */
5773      &mffs_cb,
5774   },
5775   {
5776      "mffs.",   /* One 5 bits immediate argument */
5777      &mffs_cb,
5778   },
5779   {
5780      "mtfsb0", /* One 5 bits immediate argument */
5781      &mffs_cb,
5782   },
5783   {
5784      "mtfsb0.", /* One 5 bits immediate argument */
5785      &mffs_cb,
5786   },
5787   {
5788      "mtfsb1", /* One 5 bits immediate argument */
5789      &mffs_cb,
5790   },
5791   {
5792      "mtfsb1.", /* One 5 bits immediate argument */
5793      &mffs_cb,
5794   },
5795   {
5796      "mtfsf",  /* One register + 1 8 bits immediate argument */
5797      &mtfsf_cb,
5798   },
5799   {
5800      "mtfsf.",  /* One register + 1 8 bits immediate argument */
5801      &mtfsf_cb,
5802   },
5803   {
5804      "mtfsfi", /* One 5 bits argument + 1 5 bits argument */
5805      &mtfsfi_cb,
5806   },
5807   {
5808      "mtfsfi.", /* One 5 bits argument + 1 5 bits argument */
5809      &mtfsfi_cb,
5810   },
5811#endif
5812   {
5813      NULL,
5814      NULL,
5815   },
5816};
5817
5818static void test_float_special (const char* name, test_func_t func,
5819                                uint32_t test_flags)
5820{
5821   test_special(special_float_ops, name, func, test_flags);
5822}
5823
5824
5825static void test_float_ld_one_reg_imm16 (const char* name,
5826                                         test_func_t func_IN,
5827                                         unused uint32_t test_flags)
5828{
5829   volatile test_func_t func;
5830   uint32_t* func_buf = get_rwx_area();
5831   uint32_t base;
5832   volatile uint32_t flags, xer;
5833   volatile double src, res;
5834   int i, offs;
5835
5836   /* offset within [1-nb_fargs:nb_fargs] */
5837   for (i=1-nb_fargs; i<nb_fargs; i++) {
5838      offs = i * 8;      // offset = i * sizeof(double)
5839      if (i < 0) {
5840         src  = fargs[nb_fargs-1 + i];
5841         base = (HWord_t)&fargs[nb_fargs-1];
5842      } else {
5843         src = fargs[i];
5844         base = (HWord_t)&fargs[0];
5845      }
5846
5847      /* Patch up the instruction */
5848      func = init_function( func_IN, func_buf );
5849      patch_op_imm16(&func_buf[0], offs);
5850
5851      // load from fargs[idx] => r14 + offs
5852      r14 = base;
5853
5854      SET_CR_XER_ZERO;
5855      (*func)();
5856      GET_CR_XER(flags,xer);
5857      res = f17;
5858
5859#ifndef __powerpc64__
5860      printf("%s %016llx, %4d => %016llx, %4d",
5861#else
5862      printf("%s %016llx, %4d => %016llx, %4lld",
5863#endif
5864             name, double_to_bits(src), offs,
5865             double_to_bits(res), r14-base);
5866#if defined TEST_FLOAT_FLAGS
5867      printf(" (%08x %08x)", flags, xer);
5868#endif
5869      printf("\n");
5870   }
5871   if (verbose) printf("\n");
5872}
5873
5874static void test_float_ld_two_regs (const char* name,
5875                                    test_func_t func,
5876                                    unused uint32_t test_flags)
5877{
5878   volatile HWord_t base;
5879   volatile uint32_t flags, xer;
5880   volatile double src, res;
5881   int i, offs;
5882
5883   /* offset within [1-nb_fargs:nb_fargs] */
5884   for (i=1-nb_fargs; i<nb_fargs; i++) {
5885      offs = i * 8;                // offset = i * sizeof(double)
5886      if (i < 0) {                 // base reg = start of array
5887         src  = fargs[nb_fargs-1 + i];
5888         base = (HWord_t)&fargs[nb_fargs-1];
5889      } else {
5890         src  = fargs[i];
5891         base = (HWord_t)&fargs[0];
5892      }
5893
5894      r14 = base;
5895      r15 = offs;
5896
5897      SET_CR_XER_ZERO;
5898      (*func)();
5899      GET_CR_XER(flags,xer);
5900      res = f17;
5901
5902#ifndef __powerpc64__
5903      printf("%s %016llx, %4d => %016llx, %4d",
5904#else
5905      printf("%s %016llx, %4lld => %016llx, %4lld",
5906#endif
5907             name, double_to_bits(src), r15/*offs*/,
5908             double_to_bits(res), r14-base);
5909#if defined TEST_FLOAT_FLAGS
5910      printf(" (%08x %08x)", flags, xer);
5911#endif
5912      printf("\n");
5913   }
5914}
5915
5916static void test_float_st_two_regs_imm16 (const char* name,
5917                                          test_func_t func_IN,
5918                                          unused uint32_t test_flags)
5919{
5920   volatile test_func_t func;
5921   uint32_t* func_buf = get_rwx_area();
5922   HWord_t base;
5923   volatile uint32_t flags, xer;
5924   double src, *p_dst;
5925   int i, offs;
5926   double *fargs_priv;
5927   int nb_tmp_fargs = nb_fargs;
5928
5929
5930   /* if we're storing an fp single-precision, don't want nans
5931      - the vex implementation doesn't like them (yet)
5932      Note: This is actually a bigger problem: the vex implementation
5933      rounds these insns twice.  This leads to many rounding errors.
5934      For the small fargs set, however, this doesn't show up.
5935   */
5936   if (strstr(name, "stfs") != NULL)
5937      nb_tmp_fargs = nb_normal_fargs;
5938
5939
5940   // private fargs table to store to
5941   fargs_priv = malloc(nb_tmp_fargs * sizeof(double));
5942
5943   /* offset within [1-nb_tmp_fargs:nb_tmp_fargs] */
5944   for (i=1-nb_tmp_fargs; i<nb_tmp_fargs; i++) {
5945      offs = i * 8;    // offset = i * sizeof(double)
5946      if (i < 0) {
5947         src   =  fargs     [nb_tmp_fargs-1 + i];
5948         p_dst = &fargs_priv[nb_tmp_fargs-1 + i];
5949         base  = (HWord_t)&fargs_priv[nb_tmp_fargs-1];
5950      } else {
5951         src   =  fargs     [i];
5952         p_dst = &fargs_priv[i];
5953         base  = (HWord_t)&fargs_priv[0];
5954      }
5955      *p_dst = 0;  // clear dst
5956
5957      /* Patch up the instruction */
5958      func = init_function( func_IN, func_buf );
5959      patch_op_imm16(&func_buf[0], offs);
5960
5961      // read from fargs[idx] => f14
5962      // store to fargs_priv[idx] => r15 + offs
5963      f14 = src;
5964      r15 = base;
5965
5966      SET_CR_XER_ZERO;
5967      (*func)();
5968      GET_CR_XER(flags,xer);
5969
5970#ifndef __powerpc64__
5971      printf("%s %016llx, %4d => %016llx, %4d",
5972#else
5973      printf("%s %016llx, %4d => %016llx, %4lld",
5974#endif
5975             name, double_to_bits(src), offs,
5976             double_to_bits(*p_dst), r15-base);
5977#if defined TEST_FLOAT_FLAGS
5978      printf(" (%08x %08x)", flags, xer);
5979#endif
5980      printf("\n");
5981   }
5982   free(fargs_priv);
5983}
5984
5985static void test_float_st_three_regs (const char* name,
5986                                      test_func_t func,
5987                                      unused uint32_t test_flags)
5988{
5989   volatile HWord_t base;
5990   volatile uint32_t flags, xer;
5991   double src, *p_dst;
5992   int i, offs;
5993   double *fargs_priv;
5994   int nb_tmp_fargs = nb_fargs;
5995
5996
5997   /* if we're storing an fp single-precision, don't want nans
5998      - the vex implementation doesn't like them (yet)
5999      Note: This is actually a bigger problem: the vex implementation
6000      rounds these insns twice.  This leads to many rounding errors.
6001      For the small fargs set, however, this doesn't show up.
6002   */
6003   if (strstr(name, "stfs") != NULL)  // stfs(u)(x)
6004      nb_tmp_fargs = nb_normal_fargs;
6005
6006
6007   // private fargs table to store to
6008   fargs_priv = malloc(nb_tmp_fargs * sizeof(double));
6009
6010   //   /* offset within [1-nb_tmp_fargs:nb_tmp_fargs] */
6011   //   for (i=1-nb_tmp_fargs; i<nb_tmp_fargs; i++) {
6012   for (i=0; i<nb_tmp_fargs; i++) {
6013      offs = i * 8;    // offset = i * sizeof(double)
6014      if (i < 0) {
6015         src   =  fargs     [nb_tmp_fargs-1 + i];
6016         p_dst = &fargs_priv[nb_tmp_fargs-1 + i];
6017         base  = (HWord_t)&fargs_priv[nb_tmp_fargs-1];
6018      } else {
6019         src   =  fargs     [i];
6020         p_dst = &fargs_priv[i];
6021         base  = (HWord_t)&fargs_priv[0];
6022      }
6023      *p_dst = 0;  // clear dst
6024
6025      f14  = src;    // read from fargs
6026      r15  = base;   // store to r15 + offs
6027      r16  = offs;
6028
6029      SET_CR_XER_ZERO;
6030      (*func)();
6031      GET_CR_XER(flags,xer);
6032
6033#ifndef __powerpc64__
6034      printf("%s %016llx, %4d => %016llx, %4d",
6035#else
6036      printf("%s %016llx, %4lld => %016llx, %4lld",
6037#endif
6038             name, double_to_bits(src), r16/*offs*/,
6039             double_to_bits(*p_dst), r15-base);
6040#if defined TEST_FLOAT_FLAGS
6041      printf(" (%08x %08x)", flags, xer);
6042#endif
6043      printf("\n");
6044
6045
6046#if 0
6047      // print double precision result
6048#ifndef __powerpc64__
6049      printf("%s %016llx (%014e), %4d => %016llx (%014e), %08x (%08x %08x)\n",
6050#else
6051      printf("%s %016llx (%014e), %4d => %016llx (%014e), %08x (%08x %08x)\n",
6052#endif
6053             name, double_to_bits(src), src, offs,
6054             double_to_bits(*p_dst), *p_dst, r15, flags, xer);
6055
6056      // print single precision result
6057#ifndef __powerpc64__
6058      printf("%s %016llx (%014e), %4d => %08x (%f), %08x (%08x %08x)\n",
6059#else
6060      printf("%s %016llx (%014e), %4d => %08x (%f), %08x (%08x %08x)\n",
6061#endif
6062             name, double_to_bits(src), src, offs,
6063             (uint32_t)(double_to_bits(*p_dst) >> 32),
6064             bits_to_float( (uint32_t)(double_to_bits(*p_dst) >> 32) ),
6065             r15, flags, xer);
6066#endif
6067   }
6068   free(fargs_priv);
6069}
6070
6071
6072/* Used in do_tests, indexed by flags->nb_args
6073   Elements correspond to enum test_flags::num args
6074*/
6075static test_loop_t float_loops[] = {
6076   &test_float_one_arg,
6077   &test_float_two_args,
6078   &test_float_three_args,
6079   &test_float_two_args,
6080   NULL,
6081   NULL,
6082   &test_float_special,
6083   &test_float_ld_one_reg_imm16,
6084   &test_float_ld_two_regs,
6085   &test_float_st_two_regs_imm16,
6086   &test_float_st_three_regs,
6087};
6088#endif /* !defined (NO_FLOAT) */
6089
6090
6091#if defined (HAS_ALTIVEC)
6092
6093/* Ref: vector insns to test setting CR, VSCR:
6094         volatile vector unsigned int v1 =
6095            //            (vector unsigned int){ 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF };
6096            (vector unsigned int){ 0x80808080,0x80808080,0x80808080,0x80808080 };
6097         volatile vector unsigned int v2 =
6098            //            (vector unsigned int){ 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF };
6099            (vector unsigned int){ 0x01010101,0x01010101,0x01010101,0x01010101 };
6100         //__asm__ __volatile__ ("vcmpequw. 31,%0,%1" : : "v" (v1), "v" (v2));   // sets CR[6]
6101         //__asm__ __volatile__ ("vpkswss 31,%0,%1" : : "v" (v1), "v" (v2));     // sets VSCR[SAT]
6102         __asm__ __volatile__ ("vsubsbs 31,%0,%1" : : "v" (v1), "v" (v2));       // sets VSCR[SAT]
6103*/
6104
6105//#define DEFAULT_VSCR 0x00010000
6106#define DEFAULT_VSCR 0x0
6107
6108static void test_av_int_one_arg (const char* name, test_func_t func,
6109                                 unused uint32_t test_flags)
6110{
6111   volatile uint32_t flags, tmpcr;
6112   volatile vector unsigned int tmpvscr;
6113   volatile vector unsigned int vec_in, vec_out, vscr;
6114   unsigned int *src, *dst;
6115   int i;
6116#if defined TEST_VSCR_SAT
6117   unsigned int* p_vscr;
6118#endif
6119
6120   for (i=0; i<nb_viargs; i++) {
6121      /* Save flags */
6122      __asm__ __volatile__ ("mfcr   %0" : "=r"  (tmpcr));
6123      __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr));
6124
6125      vec_in  = (vector unsigned int)viargs[i];
6126      vec_out = (vector unsigned int){ 0,0,0,0 };
6127
6128      // reset VSCR and CR
6129      vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR };
6130      flags = 0;
6131      __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) );
6132      __asm__ __volatile__ ("mtcr   %0" : : "r" (flags));
6133
6134      // load input -> r14
6135      __asm__ __volatile__ ("vor 14,%0,%0" : : "v" (vec_in));
6136
6137      // do stuff
6138      (*func)();
6139
6140      // retrieve output <- r17
6141      __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out));
6142
6143      // get CR,VSCR flags
6144      __asm__ __volatile__ ("mfcr   %0" : "=r" (flags));
6145      __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr));
6146
6147      /* Restore flags */
6148      __asm__ __volatile__ ("mtcr   %0" : : "r"  (tmpcr));
6149      __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr));
6150
6151      src = (unsigned int*)&vec_in;
6152      dst = (unsigned int*)&vec_out;
6153
6154      printf("%s: %08x %08x %08x %08x\n", name,
6155             src[0], src[1], src[2], src[3]);
6156      printf("%s:  => %08x %08x %08x %08x ", name,
6157             dst[0], dst[1], dst[2], dst[3]);
6158#if defined TEST_VSCR_SAT
6159      p_vscr = (unsigned int*)&vscr;
6160      printf("(%08x, %08x)\n", flags, p_vscr[3]);
6161#else
6162      printf("(%08x)\n", flags);
6163#endif
6164   }
6165}
6166
6167static void test_av_int_two_args (const char* name, test_func_t func,
6168                                  unused uint32_t test_flags)
6169{
6170   volatile uint32_t flags, tmpcr;
6171   volatile vector unsigned int tmpvscr;
6172   volatile vector unsigned int vec_in1, vec_in2, vec_out, vscr;
6173   unsigned int *src1, *src2, *dst;
6174   int i,j;
6175#if defined TEST_VSCR_SAT
6176   unsigned int* p_vscr;
6177#endif
6178
6179   for (i=0; i<nb_viargs; i++) {
6180      vec_in1 = (vector unsigned int)viargs[i];
6181      for (j=0; j<nb_viargs; j++) {
6182         vec_in2 = (vector unsigned int)viargs[j];
6183         vec_out = (vector unsigned int){ 0,0,0,0 };
6184
6185         /* Save flags */
6186         __asm__ __volatile__ ("mfcr   %0" : "=r"  (tmpcr));
6187         __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr));
6188
6189         // reset VSCR and CR
6190         vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR };
6191         flags = 0;
6192         __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) );
6193         __asm__ __volatile__ ("mtcr   %0" : : "r" (flags));
6194
6195         // load inputs -> r14,r15
6196         __asm__ __volatile__ ("vor 14,%0,%0" : : "v" (vec_in1));
6197         __asm__ __volatile__ ("vor 15,%0,%0" : : "v" (vec_in2));
6198
6199         // do stuff
6200         (*func)();
6201
6202         // retrieve output <- r17
6203         __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out));
6204
6205         // get CR,VSCR flags
6206         __asm__ __volatile__ ("mfcr   %0" : "=r" (flags));
6207         __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr));
6208
6209         /* Restore flags */
6210         __asm__ __volatile__ ("mtcr   %0" : : "r"  (tmpcr));
6211         __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr));
6212
6213         src1 = (unsigned int*)&vec_in1;
6214         src2 = (unsigned int*)&vec_in2;
6215         dst  = (unsigned int*)&vec_out;
6216
6217         printf("%s: ", name);
6218         printf("%08x%08x%08x%08x, ", src1[0], src1[1], src1[2], src1[3]);
6219         printf("%08x%08x%08x%08x\n", src2[0], src2[1], src2[2], src2[3]);
6220         printf("%s:  => %08x %08x %08x %08x ", name,
6221                dst[0], dst[1], dst[2], dst[3]);
6222#if defined TEST_VSCR_SAT
6223         p_vscr = (unsigned int*)&vscr;
6224         printf("(%08x, %08x)\n", flags, p_vscr[3]);
6225#else
6226         printf("(%08x)\n", flags);
6227#endif
6228      }
6229      if (verbose) printf("\n");
6230   }
6231}
6232
6233static void test_av_int_three_args (const char* name, test_func_t func,
6234                                    unused uint32_t test_flags)
6235{
6236   volatile uint32_t flags, tmpcr;
6237   volatile vector unsigned int tmpvscr;
6238   volatile vector unsigned int vec_in1, vec_in2, vec_in3, vec_out, vscr;
6239   unsigned int *src1, *src2, *src3, *dst;
6240   int i,j,k;
6241#if defined TEST_VSCR_SAT
6242   unsigned int* p_vscr;
6243#endif
6244
6245   for (i=0; i<nb_viargs; i++) {
6246      vec_in1 = (vector unsigned int)viargs[i];
6247      for (j=0; j<nb_viargs; j++) {
6248         vec_in2 = (vector unsigned int)viargs[j];
6249         for (k=0; k<nb_viargs; k++) {
6250            vec_in3 = (vector unsigned int)viargs[k];
6251            vec_out = (vector unsigned int){ 0,0,0,0 };
6252
6253            /* Save flags */
6254            __asm__ __volatile__ ("mfcr   %0" : "=r"  (tmpcr));
6255            __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr));
6256
6257            // reset VSCR and CR
6258            vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR };
6259            flags = 0;
6260            __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) );
6261            __asm__ __volatile__ ("mtcr   %0" : : "r" (flags));
6262
6263            // load inputs -> r14,r15,r16
6264            __asm__ __volatile__ ("vor 14,%0,%0" : : "v" (vec_in1));
6265            __asm__ __volatile__ ("vor 15,%0,%0" : : "v" (vec_in2));
6266            __asm__ __volatile__ ("vor 16,%0,%0" : : "v" (vec_in3));
6267
6268            // do stuff
6269            (*func)();
6270
6271            // retrieve output <- r17
6272            __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out));
6273
6274            // get CR,VSCR flags
6275            __asm__ __volatile__ ("mfcr   %0" : "=r" (flags));
6276            __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr));
6277
6278            /* Restore flags */
6279            __asm__ __volatile__ ("mtcr   %0" : : "r"  (tmpcr));
6280            __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr));
6281
6282            src1 = (unsigned int*)&vec_in1;
6283            src2 = (unsigned int*)&vec_in2;
6284            src3 = (unsigned int*)&vec_in3;
6285            dst  = (unsigned int*)&vec_out;
6286
6287            printf("%s: %08x%08x%08x%08x, %08x%08x%08x%08x, %08x%08x%08x%08x\n", name,
6288                   src1[0], src1[1], src1[2], src1[3],
6289                   src2[0], src2[1], src2[2], src2[3],
6290                   src3[0], src3[1], src3[2], src3[3]);
6291
6292            printf("%s:  => %08x%08x%08x%08x ", name,
6293                   dst[0], dst[1], dst[2], dst[3]);
6294#if defined TEST_VSCR_SAT
6295            p_vscr = (unsigned int*)&vscr;
6296            printf("(%08x, %08x)\n", flags, p_vscr[3]);
6297#else
6298            printf("(%08x)\n", flags);
6299#endif
6300         }
6301         if (verbose) printf("\n");
6302      }
6303   }
6304}
6305
6306
6307static void vs128_cb (const char* name, test_func_t func,
6308                      unused uint32_t test_flags)
6309{
6310   volatile uint32_t flags, tmpcr;
6311   volatile vector unsigned int tmpvscr;
6312   volatile vector unsigned char vec_shft;
6313   volatile vector unsigned int vec_in1, vec_out, vscr;
6314   unsigned int *src1, *src2, *dst;
6315   int i,j;
6316#if defined TEST_VSCR_SAT
6317   unsigned int* p_vscr;
6318#endif
6319
6320   for (i=0; i<nb_viargs; i++) {
6321      vec_in1 = (vector unsigned int)viargs[i];
6322      for (j=0; j<8; j++) {
6323         /* low-order 3bits of every byte must be the same for the shift vector */
6324         vec_shft = (vector unsigned char) { j,j,j,j, j,j,j,j, j,j,j,j, j,j,j,j };
6325         vec_out  = (vector unsigned int){ 0,0,0,0 };
6326
6327         /* Save flags */
6328         __asm__ __volatile__ ("mfcr   %0" : "=r"  (tmpcr));
6329         __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr));
6330
6331         // reset VSCR and CR
6332         vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR };
6333         flags = 0;
6334         __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) );
6335         __asm__ __volatile__ ("mtcr   %0" : : "r" (flags));
6336
6337         // load inputs -> r14,r15
6338         __asm__ __volatile__ ("vor 14,%0,%0" : : "v" (vec_in1));
6339         __asm__ __volatile__ ("vor 15,%0,%0" : : "v" (vec_shft));
6340
6341         // do stuff
6342         (*func)();
6343
6344         // retrieve output <- r17
6345         __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out));
6346
6347         // get CR,VSCR flags
6348         __asm__ __volatile__ ("mfcr   %0" : "=r" (flags));
6349         __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr));
6350
6351         /* Restore flags */
6352         __asm__ __volatile__ ("mtcr   %0" : : "r"  (tmpcr));
6353         __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr));
6354
6355         src1 = (unsigned int*)&vec_in1;
6356         src2 = (unsigned int*)&vec_shft;
6357         dst  = (unsigned int*)&vec_out;
6358
6359         printf("%s: ", name);
6360         printf("%08x%08x%08x%08x, ", src1[0], src1[1], src1[2], src1[3]);
6361         printf("%08x%08x%08x%08x\n", src2[0], src2[1], src2[2], src2[3]);
6362
6363         printf("%s:  => %08x %08x %08x %08x ", name,
6364                dst[0], dst[1], dst[2], dst[3]);
6365#if defined TEST_VSCR_SAT
6366         p_vscr = (unsigned int*)&vscr;
6367         printf("(%08x, %08x)\n", flags, p_vscr[3]);
6368#else
6369         printf("(%08x)\n", flags);
6370#endif
6371      }
6372      if (verbose) printf("\n");
6373   }
6374}
6375
6376static void vsplt_cb (const char* name, test_func_t func_IN,
6377                      unused uint32_t test_flags)
6378{
6379   volatile test_func_t func;
6380   uint32_t* func_buf = get_rwx_area();
6381   volatile uint32_t flags, tmpcr;
6382   volatile vector unsigned int tmpvscr;
6383   volatile vector unsigned int vec_in1, vec_out, vscr;
6384   unsigned int *src1, *dst;
6385   int i,j;
6386#if defined TEST_VSCR_SAT
6387   unsigned int* p_vscr;
6388#endif
6389
6390   for (i=0; i<nb_viargs; i++) {
6391      vec_in1 = (vector unsigned int)viargs[i];
6392
6393      for (j=0; j<16; j+=3) {
6394         vec_out = (vector unsigned int){ 0,0,0,0 };
6395
6396         /* Patch up the instruction */
6397         func = init_function( func_IN, func_buf );
6398         patch_op_imm(&func_buf[0], j, 16, 5);
6399
6400         /* Save flags */
6401         __asm__ __volatile__ ("mfcr   %0" : "=r"  (tmpcr));
6402         __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr));
6403
6404         // reset VSCR and CR
6405         vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR };
6406         flags = 0;
6407         __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) );
6408         __asm__ __volatile__ ("mtcr   %0" : : "r" (flags));
6409
6410         // load input -> r14
6411         __asm__ __volatile__ ("vor 14,%0,%0" : : "v" (vec_in1));
6412
6413         // do stuff
6414         (*func)();
6415
6416         // retrieve output <- r17
6417         __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out));
6418
6419         // get CR,VSCR flags
6420         __asm__ __volatile__ ("mfcr   %0" : "=r" (flags));
6421         __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr));
6422
6423         /* Restore flags */
6424         __asm__ __volatile__ ("mtcr   %0" : : "r"  (tmpcr));
6425         __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr));
6426
6427         src1 = (unsigned int*)&vec_in1;
6428         dst  = (unsigned int*)&vec_out;
6429
6430         printf("%s: ", name);
6431         printf("%08x %08x %08x %08x, %u\n", src1[0], src1[1], src1[2], src1[3], j);
6432
6433         printf("%s:  => %08x %08x %08x %08x ", name,
6434                dst[0], dst[1], dst[2], dst[3]);
6435#if defined TEST_VSCR_SAT
6436         p_vscr = (unsigned int*)&vscr;
6437         printf("(%08x, %08x)\n", flags, p_vscr[3]);
6438#else
6439         printf("(%08x)\n", flags);
6440#endif
6441      }
6442      if (verbose) printf("\n");
6443   }
6444}
6445
6446static void vspltis_cb (const char* name, test_func_t func_IN,
6447                      unused uint32_t test_flags)
6448{
6449   volatile test_func_t func;
6450   uint32_t* func_buf = get_rwx_area();
6451   volatile uint32_t flags, tmpcr;
6452   volatile vector unsigned int tmpvscr;
6453   volatile vector unsigned int vec_out, vscr;
6454   unsigned int *dst;
6455   int i;
6456#if defined TEST_VSCR_SAT
6457   unsigned int* p_vscr;
6458#endif
6459
6460   for (i=0; i<32; i++) {
6461      vec_out = (vector unsigned int){ 0,0,0,0 };
6462
6463      /* Patch up the instruction */
6464      func = init_function( func_IN, func_buf );
6465      patch_op_imm(&func_buf[0], i, 16, 5);
6466
6467      /* Save flags */
6468      __asm__ __volatile__ ("mfcr   %0" : "=r"  (tmpcr));
6469      __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr));
6470
6471      // reset VSCR and CR
6472      vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR };
6473      flags = 0;
6474      __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) );
6475      __asm__ __volatile__ ("mtcr   %0" : : "r" (flags));
6476
6477      // do stuff
6478      (*func)();
6479
6480      // retrieve output <- r17
6481      __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out));
6482
6483      // get CR,VSCR flags
6484      __asm__ __volatile__ ("mfcr   %0" : "=r" (flags));
6485      __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr));
6486
6487      /* Restore flags */
6488      __asm__ __volatile__ ("mtcr   %0" : : "r"  (tmpcr));
6489      __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr));
6490
6491      dst = (unsigned int*)&vec_out;
6492
6493      printf("%s: %2d => ", name, i);
6494      printf("%08x %08x %08x %08x ", dst[0], dst[1], dst[2], dst[3]);
6495#if defined TEST_VSCR_SAT
6496      p_vscr = (unsigned int*)&vscr;
6497      printf("(%08x, %08x)\n", flags, p_vscr[3]);
6498#else
6499      printf("(%08x)\n", flags);
6500#endif
6501   }
6502}
6503
6504static void vsldoi_cb (const char* name, test_func_t func_IN,
6505                       unused uint32_t test_flags)
6506{
6507   volatile test_func_t func;
6508   uint32_t* func_buf = get_rwx_area();
6509   volatile uint32_t flags, tmpcr;
6510   volatile vector unsigned int tmpvscr;
6511   volatile vector unsigned int vec_in1, vec_in2, vec_out, vscr;
6512   unsigned int *src1, *src2, *dst;
6513   int i,j,k;
6514#if defined TEST_VSCR_SAT
6515   unsigned int* p_vscr;
6516#endif
6517
6518   for (i=0; i<nb_viargs; i++) {
6519      vec_in1 = (vector unsigned int)viargs[i];
6520      for (j=0; j<nb_viargs; j++) {
6521         vec_in2 = (vector unsigned int)viargs[j];
6522         for (k=0; k<16; k+=14) {
6523            vec_out = (vector unsigned int){ 0,0,0,0 };
6524
6525            /* Patch up the instruction */
6526            func = init_function( func_IN, func_buf );
6527            patch_op_imm(&func_buf[0], k, 6, 4);
6528
6529            /* Save flags */
6530            __asm__ __volatile__ ("mfcr   %0" : "=r"  (tmpcr));
6531            __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr));
6532
6533            // reset VSCR and CR
6534            vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR };
6535            flags = 0;
6536            __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) );
6537            __asm__ __volatile__ ("mtcr   %0" : : "r" (flags));
6538
6539            // load inputs -> r14,r15
6540            __asm__ __volatile__ ("vor 14,%0,%0" : : "v" (vec_in1));
6541            __asm__ __volatile__ ("vor 15,%0,%0" : : "v" (vec_in2));
6542
6543            // do stuff
6544            (*func)();
6545
6546            // retrieve output <- r17
6547            __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out));
6548
6549            // get CR,VSCR flags
6550            __asm__ __volatile__ ("mfcr   %0" : "=r" (flags));
6551            __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr));
6552
6553            /* Restore flags */
6554            __asm__ __volatile__ ("mtcr   %0" : : "r"  (tmpcr));
6555            __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr));
6556
6557            src1   = (unsigned int*)&vec_in1;
6558            src2   = (unsigned int*)&vec_in2;
6559            dst    = (unsigned int*)&vec_out;
6560
6561            printf("%s: ", name);
6562            printf("%08x%08x%08x%08x, %08x%08x%08x%08x, %u\n",
6563                   src1[0], src1[1], src1[2], src1[3],
6564                   src2[0], src2[1], src2[2], src2[3], k);
6565
6566            printf("%s:  => %08x %08x %08x %08x] ", name,
6567                   dst[0], dst[1], dst[2], dst[3]);
6568#if defined TEST_VSCR_SAT
6569            p_vscr = (unsigned int*)&vscr;
6570            printf("(%08x, %08x)\n", flags, p_vscr[3]);
6571#else
6572            printf("(%08x)\n", flags);
6573#endif
6574         }
6575         if (verbose) printf("\n");
6576      }
6577   }
6578}
6579
6580/* lvsl, lvsr */
6581static void lvs_cb (const char *name, test_func_t func,
6582                    unused uint32_t test_flags)
6583{
6584   volatile uint32_t flags, tmpcr;
6585   volatile vector unsigned int tmpvscr;
6586   volatile vector unsigned int vec_out, vscr;
6587   unsigned int *dst;
6588   int i;
6589#if defined TEST_VSCR_SAT
6590   unsigned int* p_vscr;
6591#endif
6592
6593   for (i=-1; i<17; i++) {
6594      vec_out = (vector unsigned int){ 0,0,0,0 };
6595
6596      // make sure start address is 16 aligned - use viargs[0]
6597      r15 = (HWord_t)&viargs[0];
6598      r14 = i;
6599
6600      /* Save flags */
6601      __asm__ __volatile__ ("mfcr   %0" : "=r"  (tmpcr));
6602      __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr));
6603
6604      // reset VSCR and CR
6605      vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR };
6606      flags = 0;
6607      __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) );
6608      __asm__ __volatile__ ("mtcr   %0" : : "r" (flags));
6609
6610      // do stuff
6611      (*func)();
6612
6613      // retrieve output <- r17
6614      __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out));
6615
6616      // get CR,VSCR flags
6617      __asm__ __volatile__ ("mfcr   %0" : "=r" (flags));
6618      __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr));
6619
6620      /* Restore flags */
6621      __asm__ __volatile__ ("mtcr   %0" : : "r"  (tmpcr));
6622      __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr));
6623
6624      dst = (unsigned int*)&vec_out;
6625
6626      printf("%s %3d, %3d", name, i, 0);
6627      printf(" => %08x %08x %08x %08x ", dst[0], dst[1], dst[2], dst[3]);
6628      printf("(%08x)\n", flags);
6629   }
6630   if (verbose) printf("\n");
6631}
6632
6633static special_t special_av_int_ops[] = {
6634   {
6635      "vsr", /* Two registers arguments */
6636      &vs128_cb,
6637   },
6638   {
6639      "vsl", /* Two registers arguments */
6640      &vs128_cb,
6641   },
6642   {
6643      "vspltb", /* One reg, one 5-bit uimm arguments */
6644      &vsplt_cb,
6645   },
6646   {
6647      "vsplth", /* One reg, one 5-bit uimm arguments */
6648      &vsplt_cb,
6649   },
6650   {
6651      "vspltw", /* One reg, one 5-bit uimm arguments */
6652      &vsplt_cb,
6653   },
6654   {
6655      "vspltisb", /* One reg, one 5-bit uimm arguments */
6656      &vspltis_cb,
6657   },
6658   {
6659      "vspltish", /* One reg, one 5-bit uimm arguments */
6660      &vspltis_cb,
6661   },
6662   {
6663      "vspltisw", /* One reg, one 5-bit uimm arguments */
6664      &vspltis_cb,
6665   },
6666   {
6667      "vsldoi", /* Two regs, one 4-bit uimm arguments */
6668      &vsldoi_cb,
6669   },
6670   {
6671      "lvsl", /* Two regs */
6672      &lvs_cb,
6673   },
6674   {
6675      "lvsr", /* Two regs */
6676      &lvs_cb,
6677   },
6678   {
6679      NULL,
6680      NULL,
6681   },
6682};
6683
6684static void test_av_int_special (const char* name, test_func_t func,
6685                                 uint32_t test_flags)
6686{
6687   test_special(special_av_int_ops, name, func, test_flags);
6688}
6689
6690static void test_av_int_ld_two_regs (const char *name,
6691                                  test_func_t func,
6692                                  unused uint32_t test_flags)
6693{
6694   volatile uint32_t flags, tmpcr;
6695   volatile vector unsigned int tmpvscr;
6696   volatile vector unsigned int vec_in, vec_out, vscr;
6697   unsigned int *src, *dst;
6698   int i,j, k, do_mask;
6699
6700   do_mask = 0;
6701   if (strstr(name, "lvebx") != NULL) do_mask = 1;
6702   if (strstr(name, "lvehx") != NULL) do_mask = 2;
6703   if (strstr(name, "lvewx") != NULL) do_mask = 4;
6704
6705   for (i=0; i<nb_viargs; i++) {
6706      for (j=0; j<16; j+=7) {
6707         vec_out = (vector unsigned int){ 0,0,0,0 };
6708
6709         // load from viargs array + some dis-alignment
6710         r15 = (HWord_t)&viargs[0];
6711         r14 = i*16 + j;
6712
6713         /* Save flags */
6714         __asm__ __volatile__ ("mfcr   %0" : "=r"  (tmpcr));
6715         __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr));
6716
6717         // reset VSCR and CR
6718         vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR };
6719         flags = 0;
6720         __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) );
6721         __asm__ __volatile__ ("mtcr   %0" : : "r" (flags));
6722
6723         // do stuff
6724         (*func)();
6725
6726         // retrieve output <- r17
6727         __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out));
6728
6729         // get CR,VSCR flags
6730         __asm__ __volatile__ ("mfcr   %0" : "=r" (flags));
6731         __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr));
6732
6733         /* Restore flags */
6734         __asm__ __volatile__ ("mtcr   %0" : : "r"  (tmpcr));
6735         __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr));
6736
6737         vec_in = (vector unsigned int)viargs[i];
6738         src = (unsigned int*)&vec_in;
6739         dst = (unsigned int*)&vec_out;
6740
6741         /* For lvebx/lvehx/lvewx, as per the documentation, all of
6742            the dest reg except the loaded bits are undefined
6743            afterwards.  And different CPUs really do produce
6744            different results.  So mask out bits of the result that
6745            are undefined so as to make the test work reliably. */
6746         if (do_mask == 1) {
6747            char* p = (char*)dst;
6748            for (k = 0; k < 16; k++)
6749               if (k != j)
6750                  p[k] = (char)0;
6751         }
6752         if (do_mask == 2) {
6753            short* p = (short*)dst;
6754            for (k = 0; k < 8; k++)
6755               if (k != (j>>1))
6756                  p[k] = (short)0;
6757         }
6758         if (do_mask == 4) {
6759            int* p = (int*)dst;
6760            for (k = 0; k < 4; k++)
6761               if (k != (j>>2))
6762                  p[k] = (int)0;
6763         }
6764
6765         printf("%s %3d, %08x %08x %08x %08x", name, j, src[0], src[1], src[2], src[3]);
6766         printf(" => %08x %08x %08x %08x ", dst[0], dst[1], dst[2], dst[3]);
6767         printf("(%08x)\n", flags);
6768      }
6769      if (verbose) printf("\n");
6770   }
6771}
6772
6773
6774static void test_av_int_st_three_regs (const char *name,
6775                                       test_func_t func,
6776                                       unused uint32_t test_flags)
6777{
6778   volatile uint32_t flags, tmpcr;
6779   volatile vector unsigned int tmpvscr;
6780   volatile vector unsigned int vec_in, vec_out, vscr;
6781   unsigned int *src, *dst;
6782   int i,j;
6783   vector unsigned int* viargs_priv;
6784
6785   // private viargs table to store to
6786   viargs_priv = memalign16(nb_viargs * sizeof(vector unsigned int));
6787   for (i=0; i<nb_viargs; i++)
6788      viargs_priv[i] = (vector unsigned int) { 0,0,0,0 };
6789
6790   for (i=0; i<nb_viargs; i++) {
6791      for (j=0; j<16; j+=7) {
6792         // read from viargs
6793         vec_in = (vector unsigned int)viargs[i];
6794
6795         // store to viargs_priv[0] + some dis-alignment
6796         r16 = (HWord_t)&viargs_priv[0];
6797         r15 = i*16 + j;
6798
6799         /* Save flags */
6800         __asm__ __volatile__ ("mfcr   %0" : "=r"  (tmpcr));
6801         __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr));
6802
6803         // reset VSCR and CR
6804         vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR };
6805         flags = 0;
6806         __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) );
6807         __asm__ __volatile__ ("mtcr   %0" : : "r" (flags));
6808
6809         // load inputs -> r14
6810         __asm__ __volatile__ ("vor 14,%0,%0" : : "v" (vec_in));
6811
6812         // do stuff
6813         (*func)();
6814
6815         // Output stored in viargs_priv
6816
6817         // get CR,VSCR flags
6818         __asm__ __volatile__ ("mfcr   %0" : "=r" (flags));
6819         __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr));
6820
6821         /* Restore flags */
6822         __asm__ __volatile__ ("mtcr   %0" : : "r"  (tmpcr));
6823         __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr));
6824
6825         vec_out = (vector unsigned int)viargs_priv[i];
6826         src = (unsigned int*)&vec_in;
6827         dst = (unsigned int*)&vec_out;
6828
6829         printf("%s %3d, %08x %08x %08x %08x", name, j, src[0], src[1], src[2], src[3]);
6830         printf(" => %08x %08x %08x %08x ", dst[0], dst[1], dst[2], dst[3]);
6831         printf("(%08x)\n", flags);
6832      }
6833      if (verbose) printf("\n");
6834   }
6835}
6836
6837/* Used in do_tests, indexed by flags->nb_args
6838   Elements correspond to enum test_flags::num args
6839*/
6840static test_loop_t altivec_int_loops[] = {
6841   &test_av_int_one_arg,
6842   &test_av_int_two_args,
6843   &test_av_int_three_args,
6844   &test_av_int_two_args,
6845   NULL,
6846   NULL,
6847   &test_av_int_special,
6848   NULL,
6849   &test_av_int_ld_two_regs,
6850   NULL,
6851   test_av_int_st_three_regs,
6852};
6853
6854
6855static void test_av_float_one_arg (const char* name, test_func_t func,
6856                                   unused uint32_t test_flags)
6857{
6858   volatile uint32_t flags, tmpcr;
6859   volatile vector unsigned int tmpvscr;
6860   volatile vector float vec_in, vec_out;
6861   volatile vector unsigned int vscr;
6862   unsigned int *src, *dst;
6863   int i;
6864#if defined TEST_VSCR_SAT
6865   unsigned int* p_vscr;
6866#endif
6867
6868   /* if we're doing an estimation operation, arrange to zap the
6869      bottom byte of the result as it's basically garbage, and differs
6870      between cpus */
6871   unsigned int mask
6872      = (strstr(name,"vrsqrtefp") != NULL ||
6873         strstr(name,    "vrefp") != NULL)
6874           ? 0xFFFFFF00 : 0xFFFFFFFF;
6875
6876   for (i=0; i<nb_vfargs; i++) {
6877      vec_in  = (vector float)vfargs[i];
6878      vec_out = (vector float){ 0.0, 0.0, 0.0, 0.0 };
6879
6880      /* Save flags */
6881      __asm__ __volatile__ ("mfcr   %0" : "=r"  (tmpcr));
6882      __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr));
6883
6884      // reset VSCR and CR
6885      vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR };
6886      flags = 0;
6887      __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) );
6888      __asm__ __volatile__ ("mtcr   %0" : : "r" (flags));
6889
6890      // load input -> r14
6891      __asm__ __volatile__ ("vor 14,%0,%0" : : "v" (vec_in));
6892
6893      // do stuff
6894      (*func)();
6895
6896      // retrieve output <- r17
6897      __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out));
6898
6899      // get CR,VSCR flags
6900      __asm__ __volatile__ ("mfcr   %0" : "=r" (flags));
6901      __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr));
6902
6903      /* Restore flags */
6904      __asm__ __volatile__ ("mtcr   %0" : : "r"  (tmpcr));
6905      __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr));
6906
6907      src = (unsigned int*)&vec_in;
6908      dst = (unsigned int*)&vec_out;
6909
6910      printf("%s: %08x %08x %08x %08x\n", name,
6911             src[0], src[1], src[2], src[3]);
6912      printf("%s:  => %08x %08x %08x %08x ", name,
6913             dst[0] & mask, dst[1] & mask, dst[2] & mask, dst[3] & mask);
6914#if defined TEST_VSCR_SAT
6915      p_vscr = (unsigned int*)&vscr;
6916      printf("(%08x, %08x)\n", flags, p_vscr[3]);
6917#else
6918      printf("(%08x)\n", flags);
6919#endif
6920   }
6921}
6922
6923static void test_av_float_two_args (const char* name, test_func_t func,
6924                                    unused uint32_t test_flags)
6925{
6926   volatile uint32_t flags, tmpcr;
6927   volatile vector unsigned int tmpvscr;
6928   volatile vector float vec_in1, vec_in2, vec_out;
6929   volatile vector unsigned int vscr;
6930   unsigned int *src1, *src2, *dst;
6931   int i,j;
6932#if defined TEST_VSCR_SAT
6933   unsigned int* p_vscr;
6934#endif
6935
6936   for (i=0; i<nb_vfargs; i++) {
6937      for (j=0; j<nb_vfargs; j+=3) {
6938         vec_in1 = (vector float)vfargs[i];
6939         vec_in2 = (vector float)vfargs[j];
6940         vec_out = (vector float){ 0.0, 0.0, 0.0, 0.0 };
6941
6942         /* Save flags */
6943         __asm__ __volatile__ ("mfcr   %0" : "=r"  (tmpcr));
6944         __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr));
6945
6946         // reset VSCR and CR
6947         vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR };
6948         flags = 0;
6949         __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) );
6950         __asm__ __volatile__ ("mtcr   %0" : : "r" (flags));
6951
6952         // load inputs -> r14,r15
6953         __asm__ __volatile__ ("vor 14,%0,%0" : : "v" (vec_in1));
6954         __asm__ __volatile__ ("vor 15,%0,%0" : : "v" (vec_in2));
6955
6956         // do stuff
6957         (*func)();
6958
6959         // retrieve output <- r17
6960         __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out));
6961
6962         // get CR,VSCR flags
6963         __asm__ __volatile__ ("mfcr   %0" : "=r" (flags));
6964         __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr));
6965
6966         /* Restore flags */
6967         __asm__ __volatile__ ("mtcr   %0" : : "r"  (tmpcr));
6968         __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr));
6969
6970         src1 = (unsigned int*)&vec_in1;
6971         src2 = (unsigned int*)&vec_in2;
6972         dst  = (unsigned int*)&vec_out;
6973
6974         printf("%s: %08x%08x%08x%08x, %08x%08x%08x%08x\n", name,
6975                src1[0], src1[1], src1[2], src1[3],
6976                src2[0], src2[1], src2[2], src2[3]);
6977         printf("%s:  => %08x %08x %08x %08x ", name,
6978                dst[0], dst[1], dst[2], dst[3]);
6979#if defined TEST_VSCR_SAT
6980         p_vscr = (unsigned int*)&vscr;
6981         printf("(%08x, %08x)\n", flags, p_vscr[3]);
6982#else
6983         printf("(%08x)\n", flags);
6984#endif
6985      }
6986      if (verbose) printf("\n");
6987   }
6988}
6989
6990static void test_av_float_three_args (const char* name, test_func_t func,
6991                                      unused uint32_t test_flags)
6992{
6993   volatile uint32_t flags, tmpcr;
6994   volatile vector unsigned int tmpvscr;
6995   volatile vector float vec_in1, vec_in2, vec_in3, vec_out;
6996   volatile vector unsigned int vscr;
6997   unsigned int *src1, *src2, *src3, *dst;
6998   int i,j,k;
6999#if defined TEST_VSCR_SAT
7000   unsigned int* p_vscr;
7001#endif
7002
7003   for (i=0; i<nb_vfargs; i++) {
7004      for (j=0; j<nb_vfargs; j+=3) {
7005         for (k=0; k<nb_vfargs; k+=5) {
7006            vec_in1 = (vector float)vfargs[i];
7007            vec_in2 = (vector float)vfargs[j];
7008            vec_in3 = (vector float)vfargs[k];
7009            vec_out = (vector float){ 0.0, 0.0, 0.0, 0.0 };
7010
7011            /* Save flags */
7012            __asm__ __volatile__ ("mfcr   %0" : "=r"  (tmpcr));
7013            __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr));
7014
7015            // reset VSCR and CR
7016            vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR };
7017            flags = 0;
7018            __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) );
7019            __asm__ __volatile__ ("mtcr   %0" : : "r" (flags));
7020
7021            // load inputs -> r14,r15,r16
7022            __asm__ __volatile__ ("vor 14,%0,%0" : : "v" (vec_in1));
7023            __asm__ __volatile__ ("vor 15,%0,%0" : : "v" (vec_in2));
7024            __asm__ __volatile__ ("vor 16,%0,%0" : : "v" (vec_in3));
7025
7026            // do stuff
7027            (*func)();
7028
7029            // retrieve output <- r17
7030            __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out));
7031
7032            // get CR,VSCR flags
7033            __asm__ __volatile__ ("mfcr   %0" : "=r" (flags));
7034            __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr));
7035
7036            /* Restore flags */
7037            __asm__ __volatile__ ("mtcr   %0" : : "r"  (tmpcr));
7038            __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr));
7039
7040            src1 = (unsigned int*)&vec_in1;
7041            src2 = (unsigned int*)&vec_in2;
7042            src3 = (unsigned int*)&vec_in3;
7043            dst  = (unsigned int*)&vec_out;
7044
7045            printf("%s: %08x%08x%08x%08x, %08x%08x%08x%08x, %08x%08x%08x%08x\n", name,
7046                   src1[0], src1[1], src1[2], src1[3],
7047                   src2[0], src2[1], src2[2], src2[3],
7048                   src3[0], src3[1], src3[2], src3[3]);
7049            printf("%s:  => %08x %08x %08x %08x ", name,
7050                   dst[0], dst[1], dst[2], dst[3]);
7051#if defined TEST_VSCR_SAT
7052            p_vscr = (unsigned int*)&vscr;
7053            printf("(%08x, %08x)\n", flags, p_vscr[3]);
7054#else
7055            printf("(%08x)\n", flags);
7056#endif
7057         }
7058         if (verbose) printf("\n");
7059      }
7060   }
7061}
7062
7063static void vcvt_cb (const char* name, test_func_t func_IN,
7064                     unused uint32_t test_flags)
7065{
7066   volatile test_func_t func;
7067   uint32_t* func_buf = get_rwx_area();
7068   volatile uint32_t flags, tmpcr;
7069   volatile vector unsigned int tmpvscr;
7070   volatile vector unsigned int vec_in, vec_out, vscr;
7071   unsigned int *src, *dst;
7072   int i,j;
7073#if defined TEST_VSCR_SAT
7074   unsigned int* p_vscr;
7075#endif
7076
7077   for (i=0; i<nb_vfargs; i++) {
7078      vec_in = (vector unsigned int)vfargs[i];
7079
7080      for (j=0; j<32; j+=9) {
7081         vec_out = (vector unsigned int){ 0,0,0,0 };
7082
7083         /* Patch up the instruction */
7084         func = init_function( func_IN, func_buf );
7085         patch_op_imm(&func_buf[0], j, 16, 5);
7086
7087         /* Save flags */
7088         __asm__ __volatile__ ("mfcr   %0" : "=r"  (tmpcr));
7089         __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr));
7090
7091         // reset VSCR and CR
7092         vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR };
7093         flags = 0;
7094         __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) );
7095         __asm__ __volatile__ ("mtcr   %0" : : "r" (flags));
7096
7097         // load input -> r14
7098         __asm__ __volatile__ ("vor 14,%0,%0" : : "v" (vec_in));
7099
7100         // do stuff
7101         (*func)();
7102
7103         // retrieve output <- r17
7104         __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out));
7105
7106         // get CR,VSCR flags
7107         __asm__ __volatile__ ("mfcr   %0" : "=r" (flags));
7108         __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr));
7109
7110         /* Restore flags */
7111         __asm__ __volatile__ ("mtcr   %0" : : "r"  (tmpcr));
7112         __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr));
7113
7114         src = (unsigned int*)&vec_in;
7115         dst = (unsigned int*)&vec_out;
7116
7117         printf("%s: %08x (%13e), %2u", name, src[0], *(float*)(&src[0]), j);
7118         printf(" => %08x (%13e) ", dst[0], *(float*)(&dst[0]));
7119//         printf(" => %08x ", dst[0]);
7120#if defined TEST_VSCR_SAT
7121            p_vscr = (unsigned int*)&vscr;
7122            printf("(%08x, %08x)\n", flags, p_vscr[3]);
7123#else
7124            printf("(%08x)\n", flags);
7125#endif
7126      }
7127      if (verbose) printf("\n");
7128   }
7129}
7130
7131static special_t special_av_float_ops[] = {
7132   {
7133      "vcfux", /* One reg, one 5-bit uimm argument */
7134      &vcvt_cb,
7135   },
7136   {
7137      "vcfsx", /* One reg, one 5-bit uimm argument */
7138      &vcvt_cb,
7139   },
7140   {
7141      "vctuxs", /* One reg, one 5-bit uimm argument */
7142      &vcvt_cb,
7143   },
7144   {
7145      "vcfux", /* One reg, one 5-bit uimm argument */
7146      &vcvt_cb,
7147   },
7148   {
7149      "vctsxs", /* One reg, one 5-bit uimm argument */
7150      &vcvt_cb,
7151   },
7152   {
7153      NULL,
7154      NULL,
7155   },
7156};
7157
7158static void test_av_float_special (const char* name, test_func_t func,
7159                                   uint32_t test_flags)
7160{
7161   test_special(special_av_float_ops, name, func, test_flags);
7162}
7163
7164/* Used in do_tests, indexed by flags->nb_args
7165   Elements correspond to enum test_flags::num args
7166*/
7167static test_loop_t altivec_float_loops[] = {
7168   &test_av_float_one_arg,
7169   &test_av_float_two_args,
7170   &test_av_float_three_args,
7171   &test_av_float_two_args,
7172   NULL,
7173   NULL,
7174   &test_av_float_special,
7175   NULL,
7176   NULL,
7177   NULL,
7178   NULL,
7179};
7180
7181#endif /* defined (HAS_ALTIVEC) */
7182
7183
7184#if defined (IS_PPC405)
7185static void test_ppc405 (const char* name, test_func_t func,
7186                         unused uint32_t test_flags)
7187{
7188   volatile uint32_t res, flags, xer, tmpcr, tmpxer;
7189   int i, j, k;
7190
7191   for (i=0; i<nb_iargs; i++) {
7192      for (j=0; j<nb_iargs; j++) {
7193         for (k=0; k<nb_iargs; k++) {
7194            r14 = iargs[i];
7195            r15 = iargs[j];
7196            /* Beware: the third argument and the result
7197             * are in the same register
7198             */
7199            r17 = iargs[k];
7200
7201            /* Save flags */
7202            __asm__ __volatile__ ("mfcr 18");
7203            tmpcr = r18;
7204            __asm__ __volatile__ ("mfxer 18");
7205            tmpxer = r18;
7206
7207            /* Set up flags for test */
7208            r18 = 0;
7209            __asm__ __volatile__ ("mtcr 18");
7210            __asm__ __volatile__ ("mtxer 18");
7211            (*func)();
7212            __asm__ __volatile__ ("mfcr 18");
7213            flags = r18;
7214            __asm__ __volatile__ ("mfxer 18");
7215            xer = r18;
7216            res = r17;
7217
7218            /* Restore flags */
7219            r18 = tmpcr;
7220            __asm__ __volatile__ ("mtcr 18");
7221            r18 = tmpxer;
7222            __asm__ __volatile__ ("mtxer 18");
7223
7224            printf("%s %08x, %08x, %08x => %08x (%08x %08x)\n",
7225                   name, iargs[i], iargs[j], iargs[k], res, flags, xer);
7226         }
7227         if (verbose) printf("\n");
7228      }
7229   }
7230}
7231#endif /* defined (IS_PPC405) */
7232
7233static int check_filter (char *filter)
7234{
7235   char *c;
7236   int ret = 1;
7237
7238   if (filter != NULL) {
7239      c = strchr(filter, '*');
7240      if (c != NULL) {
7241         *c = '\0';
7242         ret = 0;
7243      }
7244   }
7245
7246   return ret;
7247}
7248
7249static int check_name (const char* name, const char *filter,
7250                       int exact)
7251{
7252   int nlen, flen;
7253   int ret = 0;
7254
7255   if (filter != NULL) {
7256      for (; isspace(*name); name++)
7257         continue;
7258      FDPRINTF("Check '%s' againt '%s' (%s match)\n",
7259               name, filter, exact ? "exact" : "starting");
7260      nlen = strlen(name);
7261      flen = strlen(filter);
7262      if (exact) {
7263         if (nlen == flen && memcmp(name, filter, flen) == 0)
7264            ret = 1;
7265      } else {
7266         if (flen <= nlen && memcmp(name, filter, flen) == 0)
7267            ret = 1;
7268      }
7269   } else {
7270      ret = 1;
7271   }
7272   return ret;
7273}
7274
7275
7276
7277typedef struct insn_sel_flags_t_struct {
7278   int one_arg, two_args, three_args;
7279   int arith, logical, compare, ldst;
7280   int integer, floats, p405, altivec, faltivec;
7281   int cr;
7282} insn_sel_flags_t;
7283
7284static void do_tests ( insn_sel_flags_t seln_flags,
7285                       char *filter)
7286{
7287#if defined (IS_PPC405)
7288   test_loop_t tmpl;
7289#endif
7290   test_loop_t *loop;
7291   test_t *tests;
7292   int nb_args, type, family;
7293   int i, j, n;
7294   int exact;
7295
7296   exact = check_filter(filter);
7297   n = 0;
7298   for (i=0; all_tests[i].name != NULL; i++) {
7299      nb_args = all_tests[i].flags & PPC_NB_ARGS;
7300      /* Check number of arguments */
7301      if ((nb_args == 1 && !seln_flags.one_arg) ||
7302          (nb_args == 2 && !seln_flags.two_args) ||
7303          (nb_args == 3 && !seln_flags.three_args))
7304         continue;
7305      /* Check instruction type */
7306      type = all_tests[i].flags & PPC_TYPE;
7307      if ((type == PPC_ARITH   && !seln_flags.arith) ||
7308          (type == PPC_LOGICAL && !seln_flags.logical) ||
7309          (type == PPC_COMPARE && !seln_flags.compare) ||
7310          (type == PPC_LDST && !seln_flags.ldst))
7311         continue;
7312      /* Check instruction family */
7313      family = all_tests[i].flags & PPC_FAMILY;
7314      if ((family == PPC_INTEGER  && !seln_flags.integer) ||
7315          (family == PPC_FLOAT    && !seln_flags.floats) ||
7316          (family == PPC_405      && !seln_flags.p405) ||
7317          (family == PPC_ALTIVEC  && !seln_flags.altivec) ||
7318          (family == PPC_FALTIVEC && !seln_flags.faltivec))
7319         continue;
7320      /* Check flags update */
7321      if (((all_tests[i].flags & PPC_CR)  && seln_flags.cr == 0) ||
7322          (!(all_tests[i].flags & PPC_CR) && seln_flags.cr == 1))
7323         continue;
7324      /* All passed, do the tests */
7325      tests = all_tests[i].tests;
7326      /* Select the test loop */
7327      switch (family) {
7328      case PPC_INTEGER:
7329         loop = &int_loops[nb_args - 1];
7330         break;
7331      case PPC_FLOAT:
7332#if !defined (NO_FLOAT)
7333         loop = &float_loops[nb_args - 1];
7334         break;
7335#else
7336         fprintf(stderr, "Sorry. "
7337                 "PPC floating point instructions tests "
7338                 "are disabled on your host\n");
7339#endif /* !defined (NO_FLOAT) */
7340
7341      case PPC_405:
7342#if defined (IS_PPC405)
7343         tmpl = &test_ppc405;
7344         loop = &tmpl;
7345         break;
7346#else
7347         fprintf(stderr, "Sorry. "
7348                 "PPC405 instructions tests are disabled on your host\n");
7349         continue;
7350#endif /* defined (IS_PPC405) */
7351      case PPC_ALTIVEC:
7352#if defined (HAS_ALTIVEC)
7353         loop = &altivec_int_loops[nb_args - 1];
7354         break;
7355#else
7356         fprintf(stderr, "Sorry. "
7357                 "Altivec instructions tests are disabled on your host\n");
7358         continue;
7359#endif
7360      case PPC_FALTIVEC:
7361#if defined (HAS_ALTIVEC)
7362         loop = &altivec_float_loops[nb_args - 1];
7363         break;
7364#else
7365         fprintf(stderr, "Sorry. "
7366                 "Altivec float instructions tests "
7367                 "are disabled on your host\n");
7368#endif
7369         continue;
7370      default:
7371         printf("ERROR: unknown insn family %08x\n", family);
7372         continue;
7373      }
7374      if (1 || verbose > 0)
7375         printf("%s:\n", all_tests[i].name);
7376      for (j=0; tests[j].name != NULL; j++) {
7377         if (check_name(tests[j].name, filter, exact)) {
7378            if (verbose > 1)
7379               printf("Test instruction %s\n", tests[j].name);
7380            (*loop)(tests[j].name, tests[j].func, all_tests[i].flags);
7381            printf("\n");
7382            n++;
7383         }
7384        }
7385      if (verbose) printf("\n");
7386   }
7387   printf("All done. Tested %d different instructions\n", n);
7388}
7389
7390
7391static void usage (void)
7392{
7393#if !defined (USAGE_SIMPLE)
7394   fprintf(stderr,
7395           "jm-insns [-1] [-2] [-3] [-*] [-t <type>] [-f <family>] [-u] "
7396           "[-n <filter>] [-r <test_rigour>] [-h]\n"
7397           "\t-1: test opcodes with one argument\n"
7398           "\t-2: test opcodes with two arguments\n"
7399           "\t-3: test opcodes with three arguments\n"
7400           "\t-*: launch test without checking the number of arguments\n"
7401           "\t-t: launch test for instructions of type <type>\n"
7402           "\t    recognized types:\n"
7403           "\t\tarith (or a)\n"
7404           "\t\tlogical (or l)\n"
7405           "\t\tcompare (or c)\n"
7406           "\t\tstoreload (or s)\n"
7407           "\t-f: launch test for instructions of family <family>\n"
7408           "\t    recognized families:\n"
7409           "\t\tinteger (or i)\n"
7410           "\t\tfloat (or f)\n"
7411           "\t\tppc405 (or mac)\n"
7412           "\t\taltivec (or a)\n"
7413           "\t-u: test instructions that update flags\n"
7414           "\t-n: filter instructions with <filter>\n"
7415           "\t    <filter> can be in two forms:\n"
7416           "\t\tname  : filter functions that exactly match <name>\n"
7417           "\t\tname* : filter functions that start with <name>\n"
7418           "\t-r: set size of arg tables to use to define <test_rigour>\n"
7419           "\t    recognized types:\n"
7420           "\t\tlarge (or l)\n"
7421           "\t\tsmall (or s) - default\n"
7422           "\t-v: verbose (-v -v for more)\n"
7423           "\t-h: print this help\n"
7424           );
7425#else // #if !defined (USAGE_SIMPLE)
7426   fprintf(stderr,
7427           "Usage: jm-insns [OPTION]\n"
7428           "\t-i: test integer instructions (default)\n"
7429           "\t-f: test floating point instructions\n"
7430           "\t-a: test altivec instructions\n"
7431           "\t-A: test all (int, fp, altivec) instructions\n"
7432           "\t-v: be verbose\n"
7433           "\t-h: display this help and exit\n"
7434           );
7435#endif // #if !defined (USAGE_SIMPLE)
7436}
7437
7438
7439
7440int main (int argc, char **argv)
7441{
7442#if !defined (USAGE_SIMPLE)
7443////////////////////////////////////////////////////////////////////////
7444   unsigned char *tmp, *filter = NULL;
7445   insn_sel_flags_t flags;
7446   int c;
7447
7448   // check HWord_t really is a host word
7449   assert(sizeof(void*) == sizeof(HWord_t));
7450
7451   flags.one_arg    = 0;
7452   flags.two_args   = 0;
7453   flags.three_args = 0;
7454   flags.arith      = 0;
7455   flags.logical    = 0;
7456   flags.compare    = 0;
7457   flags.ldst       = 0;
7458   flags.integer    = 0;
7459   flags.floats     = 0;
7460   flags.p405       = 0;
7461   flags.altivec    = 0;
7462   flags.faltivec   = 0;
7463   flags.cr         = -1;
7464
7465   while ((c = getopt(argc, argv, "123t:f:n:r:uvh")) != -1) {
7466      switch (c) {
7467      case '1':
7468         flags.one_arg = 1;
7469         break;
7470      case '2':
7471         flags.two_args = 1;
7472         break;
7473      case '3':
7474         flags.three_args = 1;
7475         break;
7476      case 't':
7477         tmp = optarg;
7478         if (strcmp(tmp, "arith") == 0 || strcmp(tmp, "a") == 0) {
7479            flags.arith = 1;
7480         } else if (strcmp(tmp, "logical") == 0 || strcmp(tmp, "l") == 0) {
7481            flags.logical = 1;
7482         } else if (strcmp(tmp, "compare") == 0 || strcmp(tmp, "c") == 0) {
7483            flags.compare = 1;
7484         } else if (strcmp(tmp, "storeload") == 0 || strcmp(tmp, "s") == 0) {
7485            flags.ldst = 1;
7486         } else {
7487            goto bad_arg;
7488         }
7489         break;
7490      case 'f':
7491         tmp = optarg;
7492         if (strcmp(tmp, "integer") == 0 || strcmp(tmp, "i") == 0) {
7493            flags.integer = 1;
7494         } else if (strcmp(tmp, "float") == 0 || strcmp(tmp, "f") == 0) {
7495            flags.floats = 1;
7496         } else if (strcmp(tmp, "ppc405") == 0 || strcmp(tmp, "mac") == 0) {
7497            flags.p405 = 1;
7498         } else if (strcmp(tmp, "altivec") == 0 || strcmp(tmp, "a") == 0) {
7499            flags.altivec = 1;
7500            flags.faltivec = 1;
7501         } else {
7502            goto bad_arg;
7503         }
7504         break;
7505      case 'n':
7506         filter = optarg;
7507         break;
7508      case 'r':
7509         tmp = optarg;
7510         if (strcmp(tmp, "large") == 0 || strcmp(tmp, "l") == 0) {
7511            arg_list_size = 1;
7512         } else if (strcmp(tmp, "small") == 0 || strcmp(tmp, "s") == 0) {
7513            arg_list_size = 0;
7514         } else {
7515            goto bad_arg;
7516         }
7517         break;
7518
7519      case 'u':
7520         flags.cr = 1;
7521         break;
7522      case 'h':
7523         usage();
7524         return 0;
7525      case 'v':
7526         verbose++;
7527         break;
7528      default:
7529         usage();
7530         fprintf(stderr, "Unknown argument: '%c'\n", c);
7531         return 1;
7532      bad_arg:
7533         usage();
7534         fprintf(stderr, "Bad argument for '%c': '%s'\n", c, tmp);
7535         return 1;
7536      }
7537   }
7538   if (argc != optind) {
7539      usage();
7540      fprintf(stderr, "Bad number of arguments\n");
7541      return 1;
7542   }
7543
7544   // Default n_args
7545   if (flags.one_arg == 0 && flags.two_args == 0 && flags.three_args == 0) {
7546      flags.one_arg = 1;
7547      flags.two_args = 1;
7548      flags.three_args = 1;
7549   }
7550   // Default type
7551   if (flags.arith == 0 && flags.logical == 0 &&
7552       flags.compare == 0 && flags.ldst == 0) {
7553      flags.arith   = 1;
7554      flags.logical = 1;
7555      flags.compare = 1;
7556      flags.ldst    = 1;
7557   }
7558   // Default family
7559   if (flags.integer == 0 && flags.floats == 0 &&
7560       flags.p405 == 0 && flags.altivec == 0 && flags.faltivec == 0) {
7561      flags.integer  = 1;
7562      flags.floats   = 1;
7563      flags.p405     = 1;
7564      flags.altivec  = 1;
7565      flags.faltivec = 1;
7566   }
7567   // Default cr update
7568   if (flags.cr == -1)
7569      flags.cr = 2;       // both
7570
7571#else // #if !defined (USAGE_SIMPLE)
7572////////////////////////////////////////////////////////////////////////
7573   /* Simple usage:
7574      ./jm-insns -i   => int insns
7575      ./jm-insns -f   => fp  insns
7576      ./jm-insns -a   => av  insns
7577      ./jm-insns -A   => int, fp and avinsns
7578   */
7579   char *filter = NULL;
7580   insn_sel_flags_t flags;
7581   int c;
7582
7583   // Args
7584   flags.one_arg    = 1;
7585   flags.two_args   = 1;
7586   flags.three_args = 1;
7587   // Type
7588   flags.arith      = 1;
7589   flags.logical    = 1;
7590   flags.compare    = 1;
7591   flags.ldst       = 1;
7592   // Family
7593   flags.integer    = 0;
7594   flags.floats     = 0;
7595   flags.p405       = 0;
7596   flags.altivec    = 0;
7597   flags.faltivec   = 0;
7598   // Flags
7599   flags.cr         = 2;
7600
7601   while ((c = getopt(argc, argv, "ifahvA")) != -1) {
7602      switch (c) {
7603      case 'i':
7604         flags.integer  = 1;
7605         break;
7606      case 'f':
7607         flags.floats   = 1;
7608         break;
7609      case 'a':
7610         flags.altivec  = 1;
7611         flags.faltivec = 1;
7612         break;
7613      case 'A':
7614         flags.integer  = 1;
7615         flags.floats   = 1;
7616         flags.altivec  = 1;
7617         flags.faltivec = 1;
7618         break;
7619      case 'h':
7620         usage();
7621         return 0;
7622      case 'v':
7623         verbose++;
7624         break;
7625      default:
7626         usage();
7627         fprintf(stderr, "Unknown argument: '%c'\n", c);
7628         return 1;
7629      }
7630   }
7631
7632   arg_list_size = 0;
7633#endif // #if !defined (USAGE_SIMPLE)
7634
7635
7636   build_iargs_table();
7637   build_fargs_table();
7638   build_ii16_table();
7639#if defined (HAS_ALTIVEC)
7640   if (flags.altivec || flags.faltivec) {
7641      build_viargs_table();
7642      build_vfargs_table();
7643   }
7644#endif
7645   // dump_iargs();
7646   // dump_iargs16();
7647   // dump_vfargs();
7648
7649   if (verbose > 1) {
7650      printf("\nInstruction Selection:\n");
7651      printf("  n_args: \n");
7652      printf("    one_arg    = %d\n", flags.one_arg);
7653      printf("    two_args   = %d\n", flags.two_args);
7654      printf("    three_args = %d\n", flags.three_args);
7655      printf("  type: \n");
7656      printf("    arith      = %d\n", flags.arith);
7657      printf("    logical    = %d\n", flags.logical);
7658      printf("    compare    = %d\n", flags.compare);
7659      printf("    ldst       = %d\n", flags.ldst);
7660      printf("  family: \n");
7661      printf("    integer    = %d\n", flags.integer);
7662      printf("    floats     = %d\n", flags.floats);
7663      printf("    p405       = %d\n", flags.p405);
7664      printf("    altivec    = %d\n", flags.altivec);
7665      printf("    faltivec   = %d\n", flags.faltivec);
7666      printf("  cr update: \n");
7667      printf("    cr         = %d\n", flags.cr);
7668      printf("\n");
7669      printf("  num args: \n");
7670      printf("    iargs      - %d\n", nb_iargs);
7671      printf("    fargs      - %d\n", nb_fargs);
7672#if defined (HAS_ALTIVEC)
7673      printf("    viargs     - %d\n", nb_viargs);
7674      printf("    vfargs     - %d\n", nb_vfargs);
7675#endif
7676      printf("\n");
7677   }
7678
7679   do_tests( flags, filter );
7680
7681   return 0;
7682}
7683