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