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