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