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