coregrind/m_gdbserver/server.h: define memcpy and memset to VG_ variants
[valgrind.git] / none / tests / ppc64 / test_isa_2_07_part1.c
blob0efd39c1c376debe6d59239378ab5f5f8cd7585b
2 /* HOW TO COMPILE:
4 * 32bit build:
5 gcc -Winline -Wall -g -O -mregnames -maltivec -m32
6 * 64bit build:
7 gcc -Winline -Wall -g -O -mregnames -maltivec -m64
10 * test_isa_2_07_part1.c:
11 * PPC tests for the ISA 2.07. This file is based on the
12 * jm-insns.c file for the new instructions in the ISA 2.07. The
13 * test structure has been kept the same as the original file to
14 * the extent possible.
16 * Copyright (C) 2013 IBM
18 * Authors: Carl Love <carll@us.ibm.com>
19 * Maynard Johnson <maynardj@us.ibm.com>
21 * This program is free software; you can redistribute it and/or
22 * modify it under the terms of the GNU General Public License as
23 * published by the Free Software Foundation; either version 2 of the
24 * License, or (at your option) any later version.
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.
31 * You should have received a copy of the GNU General Public License
32 * along with this program; if not, see <http://www.gnu.org/licenses/>.
37 * Operation details
38 * -----------------
40 * The 'loops' (e.g. int_loops) do the actual work:
41 * - loops over as many arguments as the insn needs (regs | imms)
42 * - sets up the environment (reset cr,xer, assign src regs...)
43 * - maybe modifies the asm instn to test different imm args
44 * - calls the test function
45 * - retrieves relevant register data (rD,cr,xer,...)
46 * - prints argument and result data.
48 * More specifically...
50 * all_tests[i] holds insn tests
51 * - of which each holds: {instn_test_arr[], description, flags}
53 * flags hold 3 instn classifiers: {family, type, arg_type}
55 * // The main test loop:
56 * do_tests( user_ctl_flags ) {
57 * foreach(curr_test = all_test[i]) {
59 * // flags are used to control what tests are run:
60 * if (curr_test->flags && !user_ctl_flags)
61 * continue;
63 * // a 'loop_family_arr' is chosen based on the 'family' flag...
64 * switch(curr_test->flags->family) {
65 * case x: loop_family_arr = int_loops;
66 * ...
67 * }
69 * // ...and the actual test_loop to run is found by indexing into
70 * // the loop_family_arr with the 'arg_type' flag:
71 * test_loop = loop_family[curr_test->flags->arg_type]
73 * // finally, loop over all instn tests for this test:
74 * foreach (instn_test = curr_test->instn_test_arr[i]) {
76 * // and call the test_loop with the current instn_test function,name
77 * test_loop( instn_test->func, instn_test->name )
78 * }
79 * }
80 * }
85 /**********************************************************************/
87 /* Uncomment to enable output of CR flags for float tests */
88 //#define TEST_FLOAT_FLAGS
90 /* Uncomment to enable debug output */
91 //#define DEBUG_ARGS_BUILD
92 //#define DEBUG_FILTER
94 /**********************************************************************/
95 #include <stdio.h>
97 #ifdef HAS_ISA_2_07
99 #include "config.h"
100 #include <altivec.h>
101 #include <stdint.h>
103 #include <assert.h>
104 #include <ctype.h> // isspace
105 #include <stdlib.h>
106 #include <string.h>
107 #include <unistd.h> // getopt
109 #if !defined (__TEST_PPC_H__)
110 #define __TEST_PPC_H__
112 #include "tests/sys_mman.h"
113 #include "tests/malloc.h" // memalign16
115 #define STATIC_ASSERT(e) sizeof(struct { int:-!(e); })
117 /* Something of the same size as void*, so can be safely be coerced
118 * to/from a pointer type. Also same size as the host's gp registers.
119 * According to the AltiVec section of the GCC manual, the syntax does
120 * not allow the use of a typedef name as a type specifier in conjunction
121 * with the vector keyword, so typedefs uint[32|64]_t are #undef'ed here
122 * and redefined using #define.
124 #undef uint32_t
125 #undef uint64_t
126 #define uint32_t unsigned int
127 #define uint64_t unsigned long long int
129 #ifndef __powerpc64__
130 typedef uint32_t HWord_t;
131 #define ZERO 0
132 #else
133 typedef uint64_t HWord_t;
134 #define ZERO 0ULL
135 #endif /* __powerpc64__ */
137 #ifdef VGP_ppc64le_linux
138 #define isLE 1
139 #else
140 #define isLE 0
141 #endif
143 typedef uint64_t Word_t;
145 enum {
146 compile_time_test1 = STATIC_ASSERT(sizeof(uint32_t) == 4),
147 compile_time_test2 = STATIC_ASSERT(sizeof(uint64_t) == 8),
150 #define ALLCR "cr0","cr1","cr2","cr3","cr4","cr5","cr6","cr7"
152 #define SET_CR(_arg) \
153 __asm__ __volatile__ ("mtcr %0" : : "b"(_arg) : ALLCR );
155 #define SET_XER(_arg) \
156 __asm__ __volatile__ ("mtxer %0" : : "b"(_arg) : "xer" );
158 #define GET_CR(_lval) \
159 __asm__ __volatile__ ("mfcr %0" : "=b"(_lval) )
161 #define GET_XER(_lval) \
162 __asm__ __volatile__ ("mfxer %0" : "=b"(_lval) )
164 #define GET_CR_XER(_lval_cr,_lval_xer) \
165 do { GET_CR(_lval_cr); GET_XER(_lval_xer); } while (0)
167 #define SET_CR_ZERO \
168 SET_CR(0)
170 #define SET_XER_ZERO \
171 SET_XER(0)
173 #define SET_CR_XER_ZERO \
174 do { SET_CR_ZERO; SET_XER_ZERO; } while (0)
176 #define SET_FPSCR_ZERO \
177 do { double _d = 0.0; \
178 __asm__ __volatile__ ("mtfsf 0xFF, %0" : : "f"(_d) ); \
179 } while (0)
181 #define DEFAULT_VSCR 0x0
183 static vector unsigned long long vec_out, vec_inA, vec_inB, vec_inC;
184 static vector unsigned int vec_inA_wd, vec_inB_wd;
186 /* XXXX these must all be callee-save regs! */
187 register double f14 __asm__ ("fr14");
188 register double f15 __asm__ ("fr15");
189 register double f16 __asm__ ("fr16");
190 register double f17 __asm__ ("fr17");
191 register HWord_t r14 __asm__ ("r14");
192 register HWord_t r15 __asm__ ("r15");
193 register HWord_t r16 __asm__ ("r16");
194 register HWord_t r17 __asm__ ("r17");
196 typedef void (*test_func_t) (void);
197 typedef struct _test test_t;
198 typedef struct _test_table test_table_t;
199 struct _test {
200 test_func_t func;
201 const char *name;
204 struct _test_table {
205 test_t *tests;
206 const char *name;
207 uint32_t flags;
210 typedef void (*test_loop_t) (const char *name, test_func_t func,
211 uint32_t flags);
213 enum test_flags {
214 /* Nb arguments */
215 PPC_ONE_ARG = 0x00000001,
216 PPC_TWO_ARGS = 0x00000002,
217 PPC_THREE_ARGS = 0x00000003,
218 PPC_CMP_ARGS = 0x00000004, // family: compare
219 PPC_CMPI_ARGS = 0x00000005, // family: compare
220 PPC_TWO_I16 = 0x00000006, // family: arith/logical
221 PPC_SPECIAL = 0x00000007, // family: logical
222 PPC_LD_ARGS = 0x00000008, // family: ldst
223 PPC_LDX_ARGS = 0x00000009, // family: ldst
224 PPC_ST_ARGS = 0x0000000A, // family: ldst
225 PPC_STX_ARGS = 0x0000000B, // family: ldst
226 PPC_STQ_ARGS = 0x0000000C, // family: ldst, two args, imm
227 PPC_LDQ_ARGS = 0x0000000D, // family: ldst, two args, imm
228 PPC_STQX_ARGS = 0x0000000E, // family: ldst, three args
229 PPC_LDQX_ARGS = 0x0000000F, // family: ldst, three_args
230 PPC_NB_ARGS = 0x0000000F,
231 /* Type */
232 PPC_ARITH = 0x00000100,
233 PPC_LOGICAL = 0x00000200,
234 PPC_COMPARE = 0x00000300,
235 PPC_CROP = 0x00000400,
236 PPC_LDST = 0x00000500,
237 PPC_POPCNT = 0x00000600,
238 PPC_ARITH_DRES = 0x00000700,
239 PPC_DOUBLE_IN_IRES = 0x00000800,
240 PPC_MOV = 0x00000A00,
241 PPC_SHA_OR_BCD = 0x00000B00,
242 PPC_TYPE = 0x00000F00,
243 /* Family */
244 PPC_INTEGER = 0x00010000,
245 PPC_FLOAT = 0x00020000,
246 PPC_405 = 0x00030000, // Leave so we keep numbering consistent
247 PPC_ALTIVEC = 0x00040000,
248 PPC_FALTIVEC = 0x00050000,
249 PPC_ALTIVECD = 0x00060000, /* double word Altivec tests */
250 PPC_ALTIVECQ = 0x00070000,
251 PPC_FAMILY = 0x000F0000,
252 /* Flags: these may be combined, so use separate bitfields. */
253 PPC_CR = 0x01000000,
254 PPC_XER_CA = 0x02000000,
257 #endif /* !defined (__TEST_PPC_H__) */
259 /* -------------- END #include "test-ppc.h" -------------- */
262 #if defined (DEBUG_ARGS_BUILD)
263 #define AB_DPRINTF(fmt, args...) do { fprintf(stderr, fmt , ##args); } while (0)
264 #else
265 #define AB_DPRINTF(fmt, args...) do { } while (0)
266 #endif
269 #if defined (DEBUG_FILTER)
270 #define FDPRINTF(fmt, args...) do { fprintf(stderr, fmt , ##args); } while (0)
271 #else
272 #define FDPRINTF(fmt, args...) do { } while (0)
273 #endif
275 #define unused __attribute__ (( unused ))
277 typedef struct special {
278 const char *name;
279 void (*test_cb)(const char* name, test_func_t func,
280 unused uint32_t test_flags);
281 } special_t;
283 static void test_stq(void)
285 __asm__ __volatile__ ("stq %0, 0(%1)" : :"r" (r14), "r" (r16));
288 static test_t tests_istq_ops_two_i16[] = {
289 { &test_stq , "stq", },
290 { NULL, NULL, },
293 static void test_lq(void)
295 __asm__ __volatile__ ("lq %0, 0(%1)" : :"r" (r14), "r" (r16));
298 static test_t tests_ildq_ops_two_i16[] = {
299 { &test_lq , "lq", },
300 { NULL, NULL, },
303 #ifdef HAS_ISA_2_07
304 Word_t * mem_resv;
305 static void test_stbcx(void)
307 /* Have to do the lbarx to the memory address to create the reservation
308 * or the store will not occur.
310 __asm__ __volatile__ ("lbarx %0, %1, %2" : :"r" (r14), "r" (r16),"r" (r17));
311 r14 = (HWord_t) 0xABEFCD0145236789ULL;
312 r15 = (HWord_t) 0x1155337744226688ULL;
313 __asm__ __volatile__ ("stbcx. %0, %1, %2" : :"r" (r14), "r" (r16),"r" (r17));
316 static void test_sthcx(void)
318 /* Have to do the lharx to the memory address to create the reservation
319 * or the store will not occur.
321 __asm__ __volatile__ ("lharx %0, %1, %2" : :"r" (r14), "r" (r16),"r" (r17));
322 r14 = (HWord_t) 0xABEFCD0145236789ULL;
323 r15 = (HWord_t) 0x1155337744226688ULL;
324 __asm__ __volatile__ ("sthcx. %0, %1, %2" : :"r" (r14), "r" (r16),"r" (r17));
326 #endif
328 static void test_stqcx(void)
330 /* Have to do the lqarx to the memory address to create the reservation
331 * or the store will not occur.
333 __asm__ __volatile__ ("lqarx %0, %1, %2" : :"r" (r14), "r" (r16),"r" (r17));
334 r14 = (HWord_t) 0xABEFCD0145236789ULL;
335 r15 = (HWord_t) 0x1155337744226688ULL;
336 __asm__ __volatile__ ("stqcx. %0, %1, %2" : :"r" (r14), "r" (r16),"r" (r17));
339 static test_t tests_stq_ops_three[] = {
340 #ifdef HAS_ISA_2_07
341 { &test_stbcx , "stbcx.", },
342 { &test_sthcx , "sthcx.", },
343 #endif
344 { &test_stqcx , "stqcx.", },
345 { NULL, NULL, },
348 #ifdef HAS_ISA_2_07
349 static void test_lbarx(void)
351 __asm__ __volatile__ ("lbarx %0, %1, %2, 0" : :"r" (r14), "r" (r16),"r" (r17));
353 static void test_lharx(void)
355 __asm__ __volatile__ ("lharx %0, %1, %2, 0" : :"r" (r14), "r" (r16),"r" (r17));
357 #endif
358 static void test_lqarx(void)
360 __asm__ __volatile__ ("lqarx %0, %1, %2, 0" : :"r" (r14), "r" (r16),"r" (r17));
363 static test_t tests_ldq_ops_three[] = {
364 #ifdef HAS_ISA_2_07
365 { &test_lbarx , "lbarx", },
366 { &test_lharx , "lharx", },
367 #endif
368 { &test_lqarx , "lqarx", },
369 { NULL, NULL, },
372 static void test_fmrgew (void)
374 __asm__ __volatile__ ("fmrgew 17,14,15");
377 static void test_fmrgow (void)
379 __asm__ __volatile__ ("fmrgow 17,14,15");
384 // VSX move instructions
385 static void test_mfvsrd (void)
387 __asm__ __volatile__ ("mfvsrd %0,%x1" : "=r" (r14) : "wa" (vec_inA));
390 static void test_mfvsrwz (void)
392 __asm__ __volatile__ ("mfvsrwz %0,%x1" : "=r" (r14) : "wa" (vec_inA));
395 static void test_mtvsrd (void)
397 __asm__ __volatile__ ("mtvsrd %x0,%1" : "=wa" (vec_out) : "r" (r14));
400 static void test_mtvsrwz (void)
402 __asm__ __volatile__ ("mtvsrwz %x0,%1" : "=wa" (vec_out) : "r" (r14));
405 static void test_mtvsrwa (void)
407 __asm__ __volatile__ ("mtvsrwa %x0,%1" : "=wa" (vec_out) : "r" (r14));
410 static void test_mtfprwa (void)
412 __asm__ __volatile__ ("mtfprwa %x0,%1" : "=d" (vec_out) : "r" (r14));
415 static void test_mtvrwa (void)
417 __asm__ __volatile__ ("mtvrwa %0,%1" : "=v" (vec_out) : "r" (r14));
420 static void test_mtvrd (void)
422 __asm__ __volatile__ ("mtvrd %0,%1" : "=v" (vec_out) : "r" (r14));
425 static void test_mtfprd (void)
427 __asm__ __volatile__ ("mtfprd %0,%1" : "=d" (vec_out) : "r" (r14));
430 static test_t tests_move_ops_spe[] = {
431 { &test_mfvsrd , "mfvsrd" },
432 { &test_mfvsrwz , "mfvsrwz" },
433 { &test_mtvsrd , "mtvsrd" },
434 { &test_mtvsrwz , "mtvsrwz" },
435 { &test_mtfprwa , "mtfprwa" },
436 { &test_mtvsrwa , "mtvsrwa" },
437 { &test_mtfprd , "mtfprd" },
438 { &test_mtvrwa , "mtvrwa" },
439 { &test_mtvrd , "mtvrd" },
440 { NULL, NULL }
443 /* NOTE: Since these are "vector" instructions versus VSX, we must use
444 * vector constraints.
446 * Vector Double Word tests.
448 static void test_vpkudum (void)
450 __asm__ __volatile__ ("vpkudum %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
453 static void test_vaddudm (void)
455 __asm__ __volatile__ ("vaddudm %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
458 static void test_vsubudm (void)
460 __asm__ __volatile__ ("vsubudm %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
463 static void test_vmaxud (void)
465 __asm__ __volatile__ ("vmaxud %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
468 static void test_vmaxsd (void)
470 __asm__ __volatile__ ("vmaxsd %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
473 static void test_vminud (void)
475 __asm__ __volatile__ ("vminud %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
478 static void test_vminsd (void)
480 __asm__ __volatile__ ("vminsd %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
483 static void test_vcmpequd (void)
485 __asm__ __volatile__ ("vcmpequd %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
488 static void test_vcmpgtud (void)
490 __asm__ __volatile__ ("vcmpgtud %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
493 static void test_vcmpgtsd (void)
495 __asm__ __volatile__ ("vcmpgtsd %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
498 static void test_vrld (void)
500 __asm__ __volatile__ ("vrld %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
503 static void test_vsld (void)
505 __asm__ __volatile__ ("vsld %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
508 static void test_vsrad (void)
510 __asm__ __volatile__ ("vsrad %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
513 static void test_vsrd (void)
515 __asm__ __volatile__ ("vsrd %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
518 /* Vector Double Word saturate tests.*/
520 static void test_vpkudus (void)
522 __asm__ __volatile__ ("vpkudus %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
525 static void test_vpksdus (void)
527 __asm__ __volatile__ ("vpksdus %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
530 static void test_vpksdss (void)
532 __asm__ __volatile__ ("vpksdss %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
536 /* Vector unpack two words from one vector arg */
537 static void test_vupkhsw (void)
539 __asm__ __volatile__ ("vupkhsw %0, %1" : "=v" (vec_out): "v" (vec_inB_wd));
542 static void test_vupklsw (void)
544 __asm__ __volatile__ ("vupklsw %0, %1" : "=v" (vec_out): "v" (vec_inB_wd));
548 /* Vector Integer Word tests.*/
549 static void test_vmulouw (void)
551 __asm__ __volatile__ ("vmulouw %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
554 static void test_vmuluwm (void)
556 __asm__ __volatile__ ("vmuluwm %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
559 static void test_vmulosw (void)
561 __asm__ __volatile__ ("vmulosw %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
564 static void test_vmuleuw (void)
566 __asm__ __volatile__ ("vmuleuw %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
569 static void test_vmulesw (void)
571 __asm__ __volatile__ ("vmulesw %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
574 static void test_vmrgew (void)
576 __asm__ __volatile__ ("vmrgew %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
579 static void test_vmrgow (void)
581 __asm__ __volatile__ ("vmrgow %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
584 static void test_vpmsumb (void)
586 __asm__ __volatile__ ("vpmsumb %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
589 static void test_vpmsumh (void)
591 __asm__ __volatile__ ("vpmsumh %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
594 static void test_vpmsumw (void)
596 __asm__ __volatile__ ("vpmsumw %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
599 static void test_vpermxor (void)
601 __asm__ __volatile__ ("vpermxor %0, %1, %2, %3" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB),"v" (vec_inC));
604 static void test_vpmsumd (void)
606 __asm__ __volatile__ ("vpmsumd %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
609 static void test_vnand (void)
611 __asm__ __volatile__ ("vnand %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
614 static void test_vorc (void)
616 __asm__ __volatile__ ("vorc %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
619 static void test_veqv (void)
621 __asm__ __volatile__ ("veqv %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
624 static void test_vcipher (void)
626 __asm__ __volatile__ ("vcipher %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
629 static void test_vcipherlast (void)
631 __asm__ __volatile__ ("vcipherlast %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
634 static void test_vncipher (void)
636 __asm__ __volatile__ ("vncipher %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
639 static void test_vncipherlast (void)
641 __asm__ __volatile__ ("vncipherlast %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
644 static void test_vclzb (void)
646 __asm__ __volatile__ ("vclzb %0, %1" : "=v" (vec_out): "v" (vec_inB));
649 static void test_vclzw (void)
651 __asm__ __volatile__ ("vclzw %0, %1" : "=v" (vec_out): "v" (vec_inB));
654 static void test_vclzh (void)
656 __asm__ __volatile__ ("vclzh %0, %1" : "=v" (vec_out): "v" (vec_inB));
659 static void test_vclzd (void)
661 __asm__ __volatile__ ("vclzd %0, %1" : "=v" (vec_out): "v" (vec_inB));
664 static void test_vpopcntb (void)
666 __asm__ __volatile__ ("vpopcntb %0, %1" : "=v" (vec_out): "v" (vec_inB));
669 static void test_vpopcnth (void)
671 __asm__ __volatile__ ("vpopcnth %0, %1" : "=v" (vec_out): "v" (vec_inB));
674 static void test_vpopcntw (void)
676 __asm__ __volatile__ ("vpopcntw %0, %1" : "=v" (vec_out): "v" (vec_inB));
679 static void test_vpopcntd (void)
681 __asm__ __volatile__ ("vpopcntd %0, %1" : "=v" (vec_out): "v" (vec_inB));
684 static void test_vsbox (void)
686 __asm__ __volatile__ ("vsbox %0, %1" : "=v" (vec_out): "v" (vec_inB));
689 static int st_six;
690 static void test_vshasigmad (void)
692 switch (st_six) {
693 case 0x00:
694 __asm__ __volatile__ ("vshasigmad %0, %1, 0, 0" : "=v" (vec_out): "v" (vec_inA));
695 break;
696 case 0x0f:
697 __asm__ __volatile__ ("vshasigmad %0, %1, 0, 15" : "=v" (vec_out): "v" (vec_inA));
698 break;
699 case 0x10:
700 __asm__ __volatile__ ("vshasigmad %0, %1, 1, 0" : "=v" (vec_out): "v" (vec_inA));
701 break;
702 case 0x1f:
703 __asm__ __volatile__ ("vshasigmad %0, %1, 1, 15" : "=v" (vec_out): "v" (vec_inA));
704 break;
708 static void test_vshasigmaw (void)
710 switch (st_six) {
711 case 0x00:
712 __asm__ __volatile__ ("vshasigmaw %0, %1, 0, 0" : "=v" (vec_out): "v" (vec_inA));
713 break;
714 case 0x0f:
715 __asm__ __volatile__ ("vshasigmaw %0, %1, 0, 15" : "=v" (vec_out): "v" (vec_inA));
716 break;
717 case 0x10:
718 __asm__ __volatile__ ("vshasigmaw %0, %1, 1, 0" : "=v" (vec_out): "v" (vec_inA));
719 break;
720 case 0x1f:
721 __asm__ __volatile__ ("vshasigmaw %0, %1, 1, 15" : "=v" (vec_out): "v" (vec_inA));
722 break;
726 static int PS_bit;
727 static void test_bcdadd (void)
729 if (PS_bit)
730 __asm__ __volatile__ ("bcdadd. %0, %1, %2, 1" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
731 else
732 __asm__ __volatile__ ("bcdadd. %0, %1, %2, 0" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
735 static void test_bcdsub (void)
737 if (PS_bit)
738 __asm__ __volatile__ ("bcdsub. %0, %1, %2, 1" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
739 else
740 __asm__ __volatile__ ("bcdsub. %0, %1, %2, 0" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
743 static void test_vaddcuq (void)
745 __asm__ __volatile__ ("vaddcuq %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
748 static void test_vadduqm (void)
750 __asm__ __volatile__ ("vadduqm %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
753 static void test_vaddecuq (void)
755 __asm__ __volatile__ ("vaddecuq %0, %1, %2, %3" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB),"v" (vec_inC));
758 static void test_vaddeuqm (void)
760 __asm__ __volatile__ ("vaddeuqm %0, %1, %2, %3" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB),"v" (vec_inC));
763 static void test_vsubcuq (void)
765 __asm__ __volatile__ ("vsubcuq %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
768 static void test_vsubuqm (void)
770 __asm__ __volatile__ ("vsubuqm %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
773 static void test_vsubecuq (void)
775 __asm__ __volatile__ ("vsubecuq %0, %1, %2, %3" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB),"v" (vec_inC));
778 static void test_vsubeuqm (void)
780 __asm__ __volatile__ ("vsubeuqm %0, %1, %2, %3" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB),"v" (vec_inC));
783 static void test_vbpermq (void)
785 __asm__ __volatile__ ("vbpermq %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
788 static void test_vgbbd (void)
790 __asm__ __volatile__ ("vgbbd %0, %1" : "=v" (vec_out): "v" (vec_inB));
794 static test_t tests_aa_quadword_two_args[] = {
795 { &test_vaddcuq , "vaddcuq" },
796 { &test_vadduqm , "vadduqm" },
797 { &test_vsubcuq , "vsubcuq" },
798 { &test_vsubuqm , "vsubuqm" },
799 { &test_vbpermq , "vbpermq" },
800 { NULL , NULL },
803 static test_t tests_aa_quadword_three_args[] = {
804 { &test_vaddecuq , "vaddecuq" },
805 { &test_vaddeuqm , "vaddeuqm" },
806 { &test_vsubecuq , "vsubecuq" },
807 { &test_vsubeuqm , "vsubeuqm" },
808 { NULL , NULL },
811 static test_t tests_aa_bcd_ops[] = {
812 { &test_bcdadd , "bcdadd." },
813 { &test_bcdsub , "bcdsub." },
814 { NULL , NULL },
817 static test_t tests_aa_SHA_ops[] = {
818 { &test_vshasigmad , "vshasigmad" },
819 { &test_vshasigmaw , "vshasigmaw" },
820 { NULL , NULL },
823 static test_t tests_aa_ops_three[] = {
824 { &test_vpermxor , "vpermxor" },
825 { NULL , NULL },
828 static test_t tests_aa_word_ops_one_arg_dres[] = {
829 { &test_vupkhsw , "vupkhsw" },
830 { &test_vupklsw , "vupklsw" },
831 { NULL , NULL }
834 static test_t tests_aa_word_ops_two_args_dres[] = {
835 { &test_vmulouw , "vmulouw" },
836 { &test_vmuluwm , "vmuluwm" },
837 { &test_vmulosw , "vmulosw" },
838 { &test_vmuleuw , "vmuleuw" },
839 { &test_vmulesw , "vmulesw" },
840 { &test_vmrgew , "vmrgew" },
841 { &test_vmrgow , "vmrgow" },
842 { &test_vpmsumb , "vpmsumb" },
843 { &test_vpmsumh , "vpmsumh" },
844 { &test_vpmsumw , "vpmsumw" },
845 { NULL , NULL }
848 static test_t tests_aa_dbl_ops_two_args[] = {
849 { &test_vaddudm , "vaddudm", },
850 { &test_vsubudm , "vsubudm", },
851 { &test_vmaxud , "vmaxud", },
852 { &test_vmaxsd , "vmaxsd", },
853 { &test_vminud , "vminud", },
854 { &test_vminsd , "vminsd", },
855 { &test_vcmpequd , "vcmpequd", },
856 { &test_vcmpgtud , "vcmpgtud", },
857 { &test_vcmpgtsd , "vcmpgtsd", },
858 { &test_vrld , "vrld", },
859 { &test_vsld , "vsld", },
860 { &test_vsrad , "vsrad", },
861 { &test_vsrd , "vsrd", },
862 { &test_vpkudum , "vpkudum", },
863 { &test_vpmsumd , "vpmsumd", },
864 { &test_vnand , "vnand", },
865 { &test_vorc , "vorc", },
866 { &test_veqv , "veqv", },
867 { &test_vcipher , "vcipher" },
868 { &test_vcipherlast , "vcipherlast" },
869 { &test_vncipher , "vncipher" },
870 { &test_vncipherlast , "vncipherlast" },
871 { NULL , NULL, },
874 static test_t tests_aa_dbl_ops_one_arg[] = {
875 { &test_vclzb , "vclzb" },
876 { &test_vclzw , "vclzw" },
877 { &test_vclzh , "vclzh" },
878 { &test_vclzd , "vclzd" },
879 { &test_vpopcntb , "vpopcntb" },
880 { &test_vpopcnth , "vpopcnth" },
881 { &test_vpopcntw , "vpopcntw" },
882 { &test_vpopcntd , "vpopcntd" },
883 { &test_vsbox , "vsbox" },
884 { &test_vgbbd , "vgbbd" },
885 { NULL , NULL, }
888 static test_t tests_aa_dbl_to_int_two_args[] = {
889 { &test_vpkudus , "vpkudus", },
890 { &test_vpksdus , "vpksdus", },
891 { &test_vpksdss , "vpksdss", },
892 { NULL , NULL, },
895 static int verbose = 0;
896 static int arg_list_size = 0;
897 static unsigned long long * vdargs = NULL;
898 static unsigned long long * vdargs_x = NULL;
899 #define NB_VDARGS 9
900 #define NB_VDARGS_X 4
902 static void build_vdargs_table (void)
904 // Each VSX register holds two doubleword integer values
905 vdargs = memalign16(NB_VDARGS * sizeof(unsigned long long));
906 vdargs[0] = 0x0102030405060708ULL;
907 vdargs[1] = 0x090A0B0C0E0D0E0FULL;
908 vdargs[2] = 0xF1F2F3F4F5F6F7F8ULL;
909 vdargs[3] = 0xF9FAFBFCFEFDFEFFULL;
910 vdargs[4] = 0x00007FFFFFFFFFFFULL;
911 vdargs[5] = 0xFFFF000000000000ULL;
912 vdargs[6] = 0x0000800000000000ULL;
913 vdargs[7] = 0x0000000000000000ULL;
914 vdargs[8] = 0xFFFFFFFFFFFFFFFFULL;
916 vdargs_x = memalign16(NB_VDARGS_X * sizeof(unsigned long long));
917 vdargs_x[0] = 0x000000007c118a2bULL;
918 vdargs_x[1] = 0x00000000f1112345ULL;
919 vdargs_x[2] = 0x01F2F3F4F5F6F7F8ULL;
920 vdargs_x[3] = 0xF9FAFBFCFEFDFEFFULL;
923 static unsigned int * vwargs = NULL;
924 #define NB_VWARGS 8
926 static void build_vwargs_table (void)
928 // Each VSX register holds 4 integer word values
929 size_t i = 0;
930 vwargs = memalign(8, 8 * sizeof(int));
931 assert(vwargs);
932 assert(0 == ((8-1) & (unsigned long)vwargs));
933 vwargs[i++] = 0x01020304;
934 vwargs[i++] = 0x05060708;
935 vwargs[i++] = 0x090A0B0C;
936 vwargs[i++] = 0x0E0D0E0F;
937 vwargs[i++] = 0xF1F2F3F4;
938 vwargs[i++] = 0xF5F6F7F8;
939 vwargs[i++] = 0xF9FAFBFC;
940 vwargs[i++] = 0xFEFDFEFF;
943 static unsigned long long vbcd_args[] __attribute__ ((aligned (16))) = {
944 0x8045090189321003ULL, // Negative BCD value
945 0x001122334556677dULL,
946 0x0000107600000001ULL, // Positive BCD value
947 0x319293945142031aULL,
948 0x0ULL, // Valid BCD zero
949 0xaULL,
950 0x0ULL, // Invalid BCD zero (no sign code)
951 0x0ULL
953 //#define NUM_VBCD_VALS (sizeof vbcd_args/sizeof vbcd_args[0])
954 #define NUM_VBCD_VALS 8
956 static void build_vargs_table (void)
958 build_vdargs_table();
959 build_vwargs_table();
962 static double *fargs = NULL;
963 static int nb_fargs = 0;
965 static inline void register_farg (void *farg,
966 int s, uint16_t _exp, uint64_t mant)
968 uint64_t tmp;
970 tmp = ((uint64_t)s << 63) | ((uint64_t)_exp << 52) | mant;
971 *(uint64_t *)farg = tmp;
972 AB_DPRINTF("%d %03x %013llx => %016llx %0e\n",
973 s, _exp, mant, *(uint64_t *)farg, *(double *)farg);
976 static void build_fargs_table (void)
978 /* Double precision:
979 * Sign goes from zero to one (1 bit)
980 * Exponent goes from 0 to ((1 << 12) - 1) (11 bits)
981 * Mantissa goes from 1 to ((1 << 52) - 1) (52 bits)
982 * + special values:
983 * +0.0 : 0 0x000 0x0000000000000 => 0x0000000000000000
984 * -0.0 : 1 0x000 0x0000000000000 => 0x8000000000000000
985 * +infinity : 0 0x7FF 0x0000000000000 => 0x7FF0000000000000
986 * -infinity : 1 0x7FF 0x0000000000000 => 0xFFF0000000000000
987 * +QNaN : 0 0x7FF 0x8000000000000 => 0x7FF8000000000000
988 * -QNaN : 1 0x7FF 0x8000000000000 => 0xFFF8000000000000
989 * +SNaN : 0 0x7FF 0x7FFFFFFFFFFFF => 0x7FF7FFFFFFFFFFFF
990 * -SNaN : 1 0x7FF 0x7FFFFFFFFFFFF => 0xFFF7FFFFFFFFFFFF
991 * (8 values)
993 * Ref only:
994 * Single precision
995 * Sign: 1 bit
996 * Exponent: 8 bits
997 * Mantissa: 23 bits
998 * +0.0 : 0 0x00 0x000000 => 0x00000000
999 * -0.0 : 1 0x00 0x000000 => 0x80000000
1000 * +infinity : 0 0xFF 0x000000 => 0x7F800000
1001 * -infinity : 1 0xFF 0x000000 => 0xFF800000
1002 * +QNaN : 0 0xFF 0x400000 => 0x7FC00000
1003 * -QNaN : 1 0xFF 0x400000 => 0xFFC00000
1004 * +SNaN : 0 0xFF 0x3FFFFF => 0x7FBFFFFF
1005 * -SNaN : 1 0xFF 0x3FFFFF => 0xFFBFFFFF
1007 uint64_t mant;
1008 uint16_t _exp, e0, e1;
1009 int s;
1010 int i=0;
1012 /* Note: VEX isn't so hot with denormals, so don't bother
1013 testing them: set _exp > 0
1016 if ( arg_list_size == 1 ) { // Large
1017 fargs = malloc(200 * sizeof(double));
1018 for (s=0; s<2; s++) {
1019 for (e0=0; e0<2; e0++) {
1020 for (e1=0x001; ; e1 = ((e1 + 1) << 2) + 6) {
1021 if (e1 >= 0x400)
1022 e1 = 0x3fe;
1023 _exp = (e0 << 10) | e1;
1024 for (mant = 0x0000000000001ULL; mant < (1ULL << 52);
1025 /* Add 'random' bits */
1026 mant = ((mant + 0x4A6) << 13) + 0x359) {
1027 register_farg(&fargs[i++], s, _exp, mant);
1029 if (e1 == 0x3fe)
1030 break;
1034 } else { // Default
1035 fargs = malloc(16 * sizeof(double));
1036 for (s=0; s<2; s++) { // x2
1037 for (e1=0x001; ; e1 = ((e1 + 1) << 13) + 7) { // x2
1038 if (e1 >= 0x400)
1039 e1 = 0x3fe;
1040 _exp = e1;
1041 for (mant = 0x0000000000001ULL; mant < (1ULL << 52);
1042 /* Add 'random' bits */
1043 mant = ((mant + 0x4A6) << 29) + 0x359) { // x2
1044 register_farg(&fargs[i++], s, _exp, mant);
1046 if (e1 == 0x3fe)
1047 break;
1052 /* Special values */
1053 /* +0.0 : 0 0x000 0x0000000000000 */
1054 s = 0;
1055 _exp = 0x000;
1056 mant = 0x0000000000000ULL;
1057 register_farg(&fargs[i++], s, _exp, mant);
1058 /* -0.0 : 1 0x000 0x0000000000000 */
1059 s = 1;
1060 _exp = 0x000;
1061 mant = 0x0000000000000ULL;
1062 register_farg(&fargs[i++], s, _exp, mant);
1063 /* +infinity : 0 0x7FF 0x0000000000000 */
1064 s = 0;
1065 _exp = 0x7FF;
1066 mant = 0x0000000000000ULL;
1067 register_farg(&fargs[i++], s, _exp, mant);
1068 /* -infinity : 1 0x7FF 0x0000000000000 */
1069 s = 1;
1070 _exp = 0x7FF;
1071 mant = 0x0000000000000ULL;
1072 register_farg(&fargs[i++], s, _exp, mant);
1073 /* +QNaN : 0 0x7FF 0x7FFFFFFFFFFFF */
1074 s = 0;
1075 _exp = 0x7FF;
1076 mant = 0x7FFFFFFFFFFFFULL;
1077 register_farg(&fargs[i++], s, _exp, mant);
1078 /* -QNaN : 1 0x7FF 0x7FFFFFFFFFFFF */
1079 s = 1;
1080 _exp = 0x7FF;
1081 mant = 0x7FFFFFFFFFFFFULL;
1082 register_farg(&fargs[i++], s, _exp, mant);
1083 /* +SNaN : 0 0x7FF 0x8000000000000 */
1084 s = 0;
1085 _exp = 0x7FF;
1086 mant = 0x8000000000000ULL;
1087 register_farg(&fargs[i++], s, _exp, mant);
1088 /* -SNaN : 1 0x7FF 0x8000000000000 */
1089 s = 1;
1090 _exp = 0x7FF;
1091 mant = 0x8000000000000ULL;
1092 register_farg(&fargs[i++], s, _exp, mant);
1093 AB_DPRINTF("Registered %d fargs values\n", i);
1095 nb_fargs = i;
1100 static int check_filter (char *filter)
1102 char *c;
1103 int ret = 1;
1105 if (filter != NULL) {
1106 c = strchr(filter, '*');
1107 if (c != NULL) {
1108 *c = '\0';
1109 ret = 0;
1112 return ret;
1115 static int check_name (const char* name, const char *filter,
1116 int exact)
1118 int nlen, flen;
1119 int ret = 0;
1121 if (filter != NULL) {
1122 for (; isspace(*name); name++)
1123 continue;
1124 FDPRINTF("Check '%s' againt '%s' (%s match)\n",
1125 name, filter, exact ? "exact" : "starting");
1126 nlen = strlen(name);
1127 flen = strlen(filter);
1128 if (exact) {
1129 if (nlen == flen && memcmp(name, filter, flen) == 0)
1130 ret = 1;
1131 } else {
1132 if (flen <= nlen && memcmp(name, filter, flen) == 0)
1133 ret = 1;
1135 } else {
1136 ret = 1;
1138 return ret;
1142 typedef struct insn_sel_flags_t_struct {
1143 int one_arg, two_args, three_args;
1144 int arith, logical, compare, ldst;
1145 int integer, floats, altivec, faltivec;
1146 int cr;
1147 } insn_sel_flags_t;
1149 static void test_float_two_args (const char* name, test_func_t func,
1150 unused uint32_t test_flags)
1152 double res;
1153 Word_t u0, u1, ur;
1154 volatile uint32_t flags;
1155 int i, j;
1157 for (i=0; i<nb_fargs; i+=3) {
1158 for (j=0; j<nb_fargs; j+=5) {
1159 u0 = *(Word_t *)(&fargs[i]);
1160 u1 = *(Word_t *)(&fargs[j]);
1161 f14 = fargs[i];
1162 f15 = fargs[j];
1164 SET_FPSCR_ZERO;
1165 SET_CR_XER_ZERO;
1166 (*func)();
1167 GET_CR(flags);
1168 res = f17;
1169 ur = *(uint64_t *)(&res);
1171 printf("%s %016llx, %016llx => %016llx",
1172 name, u0, u1, ur);
1173 #if defined TEST_FLOAT_FLAGS
1174 printf(" (%08x)", flags);
1175 #endif
1176 printf("\n");
1178 if (verbose) printf("\n");
1183 static void mfvs(const char* name, test_func_t func,
1184 unused uint32_t test_flags)
1186 /* This test is for move instructions where the input is a scalar register
1187 * and the destination is a vector register.
1189 int i;
1190 volatile Word_t result;
1191 result = 0ULL;
1193 for (i=0; i < NB_VDARGS; i++) {
1194 r14 = ZERO;
1195 if (isLE)
1196 vec_inA = (vector unsigned long long){ 0ULL, vdargs[i] };
1197 else
1198 vec_inA = (vector unsigned long long){ vdargs[i], 0ULL };
1200 (*func)();
1201 result = r14;
1202 printf("%s: %016llx => %016llx\n", name, vdargs[i], result);
1206 static void mtvs(const char* name, test_func_t func,
1207 unused uint32_t test_flags)
1209 /* This test is for move instructions where the input is a scalar register
1210 * and the destination is a vector register.
1212 unsigned long long *dst;
1213 int i;
1215 for (i=0; i < NB_VDARGS; i++) {
1216 r14 = vdargs[i];
1217 vec_out = (vector unsigned long long){ 0ULL, 0ULL };
1219 (*func)();
1220 dst = (unsigned long long *) &vec_out;
1221 if (isLE)
1222 dst++;
1223 printf("%s: %016llx => %016llx\n", name, vdargs[i], *dst);
1227 static void mtvs2s(const char* name, test_func_t func,
1228 unused uint32_t test_flags)
1230 /* This test is the mtvsrwa instruction.
1232 unsigned long long *dst;
1233 int i;
1235 for (i=0; i < NB_VDARGS; i++) {
1236 // Only the lower half of the vdarg doubleword arg will be used as input by mtvsrwa
1237 unsigned int * src = (unsigned int *)&vdargs[i];
1238 if (!isLE)
1239 src++;
1240 r14 = vdargs[i];
1241 vec_out = (vector unsigned long long){ 0ULL, 0ULL };
1243 (*func)();
1244 // Only doubleword 0 is used in output
1245 dst = (unsigned long long *) &vec_out;
1246 if (isLE)
1247 dst++;
1248 printf("%s: %08x => %016llx\n", name, *src, *dst);
1252 static void test_special (special_t *table,
1253 const char* name, test_func_t func,
1254 unused uint32_t test_flags)
1256 const char *tmp;
1257 int i;
1259 for (tmp = name; isspace(*tmp); tmp++)
1260 continue;
1261 for (i=0; table[i].name != NULL; i++) {
1262 if (strcmp(table[i].name, tmp) == 0) {
1263 (*table[i].test_cb)(name, func, test_flags);
1264 return;
1267 fprintf(stderr, "ERROR: no test found for op '%s'\n", name);
1270 static special_t special_move_ops[] = {
1272 "mfvsrd", /* move from vector to scalar reg doubleword */
1273 &mfvs,
1276 "mtvsrd", /* move from scalar to vector reg doubleword */
1277 &mtvs,
1280 "mtvsrwa", /* mtvsrwa move from scalar to vector reg */
1281 &mtvs2s,
1284 "mtfprwa", /* (extended mnemonic for mtvsrwa) move from scalar to vector
1285 reg */
1286 &mtvs2s,
1289 "mfvsrwz", /* move from vector to scalar reg word */
1290 &mfvs,
1293 "mtvsrwz", /* move from scalar to vector reg word */
1294 &mtvs2s,
1297 "mtvrwa", /* (extended mnemonic for mtvsrwa) move to vsr word */
1298 &mtvs2s,
1301 "mtvrd", /* (extended mnemonic for mtvsrd) move to vsr double word */
1302 &mtvs,
1305 "mtfprd", /* (extended mnemonic for mtvsrd) move to float word */
1306 &mtvs,
1310 static void test_move_special(const char* name, test_func_t func,
1311 uint32_t test_flags)
1313 test_special(special_move_ops, name, func, test_flags);
1316 /* Vector Double Word tests */
1318 static void test_av_dint_two_args (const char* name, test_func_t func,
1319 unused uint32_t test_flags)
1322 unsigned long long * dst;
1323 unsigned int * dst_int;
1324 int i,j;
1325 int family = test_flags & PPC_FAMILY;
1326 int is_vpkudum, is_vpmsumd;
1327 if (strcmp(name, "vpkudum") == 0)
1328 is_vpkudum = 1;
1329 else
1330 is_vpkudum = 0;
1332 if (strcmp(name, "vpmsumd") == 0)
1333 is_vpmsumd = 1;
1334 else
1335 is_vpmsumd = 0;
1337 for (i = 0; i < NB_VDARGS - 1; i+=2) {
1338 if (isLE && family == PPC_ALTIVECQ)
1339 vec_inA = (vector unsigned long long){ vdargs[i+1], vdargs[i] };
1340 else
1341 vec_inA = (vector unsigned long long){ vdargs[i], vdargs[i+1] };
1342 for (j = 0; j < NB_VDARGS - 1; j+=2) {
1343 if (isLE && family == PPC_ALTIVECQ)
1344 vec_inB = (vector unsigned long long){ vdargs[j+1], vdargs[j] };
1345 else
1346 vec_inB = (vector unsigned long long){ vdargs[j], vdargs[j+1] };
1347 vec_out = (vector unsigned long long){ 0,0 };
1349 (*func)();
1350 dst_int = (unsigned int *)&vec_out;
1351 dst = (unsigned long long*)&vec_out;
1353 printf("%s: ", name);
1355 if (is_vpkudum) {
1356 printf("Inputs: %08llx %08llx %08llx %08llx\n", vdargs[i] & 0x00000000ffffffffULL,
1357 vdargs[i+1] & 0x00000000ffffffffULL, vdargs[j] & 0x00000000ffffffffULL,
1358 vdargs[j+1] & 0x00000000ffffffffULL);
1359 if (isLE)
1360 printf(" Output: %08x %08x %08x %08x\n", dst_int[2], dst_int[3],
1361 dst_int[0], dst_int[1]);
1362 else
1363 printf(" Output: %08x %08x %08x %08x\n", dst_int[0], dst_int[1],
1364 dst_int[2], dst_int[3]);
1365 } else if (is_vpmsumd) {
1366 printf("%016llx @@ %016llx ", vdargs[i], vdargs[j]);
1367 if (isLE)
1368 printf(" ==> %016llx\n", dst[1]);
1369 else
1370 printf(" ==> %016llx\n", dst[0]);
1371 printf("\t%016llx @@ %016llx ", vdargs[i+1], vdargs[j+1]);
1372 if (isLE)
1373 printf(" ==> %016llx\n", dst[0]);
1374 else
1375 printf(" ==> %016llx\n", dst[1]);
1376 } else if (family == PPC_ALTIVECQ) {
1377 if (isLE)
1378 printf("%016llx%016llx @@ %016llx%016llx ==> %016llx%016llx\n",
1379 vdargs[i], vdargs[i+1], vdargs[j], vdargs[j+1],
1380 dst[1], dst[0]);
1381 else
1382 printf("%016llx%016llx @@ %016llx%016llx ==> %016llx%016llx\n",
1383 vdargs[i], vdargs[i+1], vdargs[j], vdargs[j+1],
1384 dst[0], dst[1]);
1385 } else {
1386 printf("%016llx @@ %016llx ", vdargs[i], vdargs[j]);
1387 printf(" ==> %016llx\n", dst[0]);
1388 printf("\t%016llx @@ %016llx ", vdargs[i+1], vdargs[j+1]);
1389 printf(" ==> %016llx\n", dst[1]);
1395 static void test_av_dint_one_arg (const char* name, test_func_t func,
1396 unused uint32_t test_flags)
1399 unsigned long long * dst;
1400 int i;
1402 for (i = 0; i < NB_VDARGS - 1; i+=2) {
1403 vec_inB = (vector unsigned long long){ vdargs[i], vdargs[i+1] };
1404 vec_out = (vector unsigned long long){ 0,0 };
1406 (*func)();
1407 dst = (unsigned long long*)&vec_out;
1409 printf("%s: ", name);
1410 printf("%016llx @@ %016llx ", vdargs[i], vdargs[i + 1]);
1411 printf(" ==> %016llx%016llx\n", dst[0], dst[1]);
1415 static void test_av_dint_one_arg_SHA (const char* name, test_func_t func,
1416 unused uint32_t test_flags)
1418 unsigned long long * dst;
1419 int i, st, six;
1421 for (i = 0; i < NB_VDARGS - 1; i+=2) {
1422 vec_inA = (vector unsigned long long){ vdargs[i], vdargs[i+1] };
1423 vec_out = (vector unsigned long long){ 0,0 };
1425 for (st = 0; st < 2; st++) {
1426 for (six = 0; six < 16; six+=15) {
1427 st_six = (st << 4) | six;
1428 (*func)();
1429 dst = (unsigned long long*)&vec_out;
1431 printf("%s: ", name);
1432 printf("%016llx @@ %016llx ", vdargs[i], vdargs[i + 1]);
1433 printf(" ==> %016llx || %016llx\n", dst[0], dst[1]);
1439 static void test_av_bcd (const char* name, test_func_t func,
1440 unused uint32_t test_flags)
1442 unsigned long long * dst;
1443 int i, j;
1445 for (i = 0; i < NUM_VBCD_VALS - 1; i+=2) {
1446 if (isLE)
1447 vec_inA = (vector unsigned long long){ vbcd_args[i+1], vbcd_args[i]};
1448 else
1449 vec_inA = (vector unsigned long long){ vbcd_args[i], vbcd_args[i+1] };
1450 for (j = 0; j < NUM_VBCD_VALS - 1; j+=2) {
1451 if (isLE)
1452 vec_inB = (vector unsigned long long){ vbcd_args[j+1] , vbcd_args[j] };
1453 else
1454 vec_inB = (vector unsigned long long){ vbcd_args[j], vbcd_args[j+1] };
1455 vec_out = (vector unsigned long long){ 0, 0 };
1457 for (PS_bit = 0; PS_bit < 2; PS_bit++) {
1458 (*func)();
1459 dst = (unsigned long long*)&vec_out;
1460 printf("%s: ", name);
1461 printf("%016llx || %016llx @@ %016llx || %016llx",
1462 vbcd_args[i], vbcd_args[i + 1],
1463 vbcd_args[j], vbcd_args[j + 1]);
1464 if (isLE)
1465 printf(" ==> %016llx || %016llx\n", dst[1], dst[0]);
1466 else
1467 printf(" ==> %016llx || %016llx\n", dst[0], dst[1]);
1473 /* Vector doubleword-to-int tests, two input args, integer result */
1474 static void test_av_dint_to_int_two_args (const char* name, test_func_t func,
1475 unused uint32_t test_flags)
1478 unsigned int * dst_int;
1479 int i,j;
1480 for (i = 0; i < NB_VDARGS_X - 1; i+=2) {
1481 vec_inA = (vector unsigned long long){ vdargs_x[i], vdargs_x[i+1] };
1482 for (j = 0; j < NB_VDARGS_X - 1; j+=2) {
1483 vec_inB = (vector unsigned long long){ vdargs_x[j], vdargs_x[j+1] };
1484 vec_out = (vector unsigned long long){ 0,0 };
1486 (*func)();
1487 dst_int = (unsigned int *)&vec_out;
1489 printf("%s: ", name);
1490 printf("%016llx, %016llx @@ %016llx, %016llx ",
1491 vdargs_x[i], vdargs_x[i+1],
1492 vdargs_x[j], vdargs_x[j+1]);
1493 if (isLE)
1494 printf(" ==> %08x %08x %08x %08x\n", dst_int[2], dst_int[3],
1495 dst_int[0], dst_int[1]);
1496 else
1497 printf(" ==> %08x %08x %08x %08x\n", dst_int[0], dst_int[1],
1498 dst_int[2], dst_int[3]);
1503 /* Vector Word tests; two integer args, with double word result */
1505 static void test_av_wint_two_args_dres (const char* name, test_func_t func,
1506 unused uint32_t test_flags)
1509 unsigned long long * dst;
1510 int i,j;
1512 for (i = 0; i < NB_VWARGS; i+=4) {
1513 if (isLE)
1514 vec_inA_wd = (vector unsigned int){ vwargs[i+3], vwargs[i+2], vwargs[i+1], vwargs[i] };
1515 else
1516 vec_inA_wd = (vector unsigned int){ vwargs[i], vwargs[i+1], vwargs[i+2], vwargs[i+3] };
1517 for (j = 0; j < NB_VWARGS; j+=4) {
1518 if (isLE)
1519 vec_inB_wd = (vector unsigned int){ vwargs[j+3], vwargs[j+2], vwargs[j+1], vwargs[j] };
1520 else
1521 vec_inB_wd = (vector unsigned int){ vwargs[j], vwargs[j+1], vwargs[j+2], vwargs[j+3] };
1522 vec_out = (vector unsigned long long){ 0, 0 };
1524 (*func)();
1525 dst = (unsigned long long *)&vec_out;
1526 printf("%s: ", name);
1527 if (isLE)
1528 printf("%08x %08x %08x %08x ==> %016llx %016llx\n",
1529 vwargs[i], vwargs[i+1], vwargs[i+2], vwargs[i+3], dst[1], dst[0]);
1530 else
1531 printf("%08x %08x %08x %08x ==> %016llx %016llx\n",
1532 vwargs[i], vwargs[i+1], vwargs[i+2], vwargs[i+3], dst[0], dst[1]);
1537 /* Vector Word tests; one input arg, with double word result */
1539 static void test_av_wint_one_arg_dres (const char* name, test_func_t func,
1540 unused uint32_t test_flags)
1542 unsigned long long * dst;
1543 int i;
1544 for (i = 0; i < NB_VWARGS; i+=4) {
1545 if (isLE)
1546 vec_inB_wd = (vector unsigned int){ vwargs[i+3], vwargs[i+2], vwargs[i+1], vwargs[i] };
1547 else
1548 vec_inB_wd = (vector unsigned int){ vwargs[i], vwargs[i+1], vwargs[i+2], vwargs[i+3] };
1549 vec_out = (vector unsigned long long){ 0, 0 };
1551 (*func)();
1552 dst = (unsigned long long *)&vec_out;
1553 printf("%s: ", name);
1554 if (isLE)
1555 printf("%08x %08x %08x %08x ==> %016llx %016llx\n",
1556 vwargs[i], vwargs[i+1], vwargs[i+2], vwargs[i+3], dst[1], dst[0]);
1557 else
1558 printf("%08x %08x %08x %08x ==> %016llx %016llx\n",
1559 vwargs[i], vwargs[i+1], vwargs[i+2], vwargs[i+3], dst[0], dst[1]);
1564 static void test_int_stq_two_regs_imm16 (const char* name,
1565 test_func_t func_IN,
1566 unused uint32_t test_flags)
1568 /* Store quad word from register pair */
1569 int offs, k;
1570 HWord_t base;
1571 Word_t *iargs_priv;
1573 // private iargs table to store to, note storing pair of regs
1574 iargs_priv = memalign16(2 * sizeof(Word_t));
1576 base = (HWord_t)&iargs_priv[0];
1577 for (k = 0; k < 2; k++) // clear array
1578 iargs_priv[k] = 0;
1580 offs = 0;
1582 /* setup source register pair */
1583 r14 = (HWord_t) 0xABCDEF0123456789ULL;
1584 r15 = (HWord_t) 0x1133557722446688ULL;
1586 r16 = base; // store to r16 + offs
1588 (*func_IN)();
1590 #ifndef __powerpc64__
1591 printf("%s %08x,%08x, %2d => "
1592 #else
1593 printf("%s %016llx,%016llx, %3d => "
1594 #endif
1595 "%016llx,%016llx)\n",
1596 name, r14, r15, offs, iargs_priv[0], iargs_priv[1]);
1598 if (verbose) printf("\n");
1599 free(iargs_priv);
1603 static void test_int_stq_three_regs (const char* name,
1604 test_func_t func_IN,
1605 unused uint32_t test_flags)
1607 /* Store quad word from register pair */
1608 volatile uint32_t flags, xer;
1609 int k;
1610 HWord_t base;
1612 base = (HWord_t)&mem_resv[0];
1613 for (k = 0; k < 2; k++) // setup array for lqarx inst
1614 mem_resv[k] = k;
1616 /* setup source register pair for store */
1617 r14 = ZERO;
1618 r15 = ZERO;
1619 r16 = base; // store to r16 + r17
1620 r17 = ZERO;
1622 /* In order for the store to occur, the lqarx instruction must first
1623 * be used to load from the address thus creating a reservation at the
1624 * memory address. The lqarx instruction is done in the test_stqcx(),
1625 * then registers 14, r15 are changed to the data to be stored in memory
1626 * by the stqcx instruction.
1628 SET_CR_XER_ZERO;
1629 (*func_IN)();
1630 GET_CR_XER(flags,xer);
1631 #ifndef __powerpc64__
1632 printf("%s %08x,%08x, => "
1633 #else
1634 printf("%s %016llx,%016llx => "
1635 #endif
1636 "%016llx,%016llx; CR=%08x\n",
1637 name, r14, r15, mem_resv[0], mem_resv[1], flags);
1639 if (verbose) printf("\n");
1642 static void test_int_ldq_two_regs_imm16 (const char* name,
1643 test_func_t func_IN,
1644 unused uint32_t test_flags)
1646 /* load quad word from register pair */
1647 volatile uint32_t flags, xer;
1648 Word_t * mem_priv;
1649 HWord_t base;
1651 // private iargs table to store to, note storing pair of regs
1652 mem_priv = memalign16(2 * sizeof(Word_t)); // want 128-bits
1654 base = (HWord_t)&mem_priv[0];
1656 mem_priv[0] = 0xAACCEE0011335577ULL;
1657 mem_priv[1] = 0xABCDEF0123456789ULL;
1659 r14 = 0;
1660 r15 = 0;
1661 r16 = base; // fetch from r16 + offs
1662 SET_CR_XER_ZERO;
1663 (*func_IN)();
1664 GET_CR_XER(flags,xer);
1666 #ifndef __powerpc64__
1667 printf("%s (0x%016llx, 0x%016llx) => (reg_pair = %08x,%08x)\n",
1668 #else
1669 printf("%s (0x%016llx, 0x%016llx) => (reg_pair = 0x%016llx, 0x%016llx)\n",
1670 #endif
1671 name, mem_priv[0], mem_priv[1], r14, r15);
1673 if (verbose) printf("\n");
1675 free(mem_priv);
1678 static void test_int_ldq_three_regs (const char* name,
1679 test_func_t func_IN,
1680 unused uint32_t test_flags)
1682 /* load quad word from register pair */
1683 HWord_t base;
1685 base = (HWord_t)&mem_resv[0];
1687 mem_resv[0] = 0xAACCEE0011335577ULL;
1688 mem_resv[1] = 0xABCDEF0123456789ULL;
1690 r14 = 0;
1691 r15 = 0;
1692 r16 = base; // fetch from r16 + r17
1693 r17 = 0;
1695 (*func_IN)();
1697 #ifndef __powerpc64__
1698 printf("%s (0x%016llx, 0x%016llx) => (reg_pair = 0x%08x, 0x%08x)\n",
1699 #else
1700 printf("%s (0x%016llx, 0x%016llx) => (reg_pair = 0x%016llx, 0x%016llx)\n",
1701 #endif
1702 name, mem_resv[0], mem_resv[1], r14, r15);
1703 if (verbose) printf("\n");
1707 static void test_av_dint_three_args (const char* name, test_func_t func,
1708 unused uint32_t test_flags)
1711 unsigned long long * dst;
1712 int i,j, k;
1713 int family = test_flags & PPC_FAMILY;
1714 unsigned long long cin_vals[] = {
1715 // First pair of ULLs have LSB=0, so cin is '0'.
1716 // Second pair of ULLs have LSB=1, so cin is '1'.
1717 0xf000000000000000ULL, 0xf000000000000000ULL,
1718 0xf000000000000000ULL, 0xf000000000000001ULL
1720 for (i = 0; i < NB_VDARGS - 1; i+=2) {
1721 if (isLE)
1722 vec_inA = (vector unsigned long long){ vdargs[i+1], vdargs[i] };
1723 else
1724 vec_inA = (vector unsigned long long){ vdargs[i], vdargs[i+1] };
1725 for (j = 0; j < NB_VDARGS - 1; j+=2) {
1726 if (isLE)
1727 vec_inB = (vector unsigned long long){ vdargs[j+1], vdargs[j] };
1728 else
1729 vec_inB = (vector unsigned long long){ vdargs[j], vdargs[j+1] };
1730 for (k = 0; k < 4 - 1; k+=2) {
1731 if (family == PPC_ALTIVECQ) {
1732 if (isLE)
1733 vec_inC = (vector unsigned long long){ cin_vals[k+1], cin_vals[k] };
1734 else
1735 vec_inC = (vector unsigned long long){ cin_vals[k], cin_vals[k+1] };
1736 } else {
1737 if (isLE)
1738 vec_inC = (vector unsigned long long){ vdargs[k+1], vdargs[k] };
1739 else
1740 vec_inC = (vector unsigned long long){ vdargs[k], vdargs[k+1] };
1742 vec_out = (vector unsigned long long){ 0,0 };
1744 (*func)();
1745 dst = (unsigned long long*)&vec_out;
1746 printf("%s: ", name);
1747 if (family == PPC_ALTIVECQ) {
1748 if (isLE)
1749 printf("%016llx%016llx @@ %016llx%016llx @@ %llx ==> %016llx%016llx\n",
1750 vdargs[i], vdargs[i+1], vdargs[j], vdargs[j+1], cin_vals[k+1],
1751 dst[1], dst[0]);
1752 else
1753 printf("%016llx%016llx @@ %016llx%016llx @@ %llx ==> %016llx%016llx\n",
1754 vdargs[i], vdargs[i+1], vdargs[j], vdargs[j+1], cin_vals[k+1],
1755 dst[0], dst[1]);
1756 } else {
1757 printf("%016llx @@ %016llx @@ %016llx ", vdargs[i], vdargs[j], vdargs[k]);
1758 if (isLE)
1759 printf(" ==> %016llx\n", dst[1]);
1760 else
1761 printf(" ==> %016llx\n", dst[0]);
1762 printf("\t%016llx @@ %016llx @@ %016llx ", vdargs[i+1], vdargs[j+1], vdargs[k+1]);
1763 if (isLE)
1764 printf(" ==> %016llx\n", dst[0]);
1765 else
1766 printf(" ==> %016llx\n", dst[1]);
1774 /* The ALTIVEC_LOOPS and altive_loops defined below are used in do_tests.
1775 * Add new values to the end; do not change order, since the altivec_loops
1776 * array is indexed using the enumerated values defined by ALTIVEC_LOOPS.
1778 enum ALTIVEC_LOOPS {
1779 ALTV_MOV,
1780 ALTV_DINT,
1781 ALTV_INT_DRES,
1782 ALTV_DINT_IRES,
1783 ALTV_ONE_INT_DRES,
1784 ALTV_DINT_THREE_ARGS,
1785 ALTV_DINT_ONE_ARG,
1786 ALTV_SHA,
1787 ATLV_BCD
1790 static test_loop_t altivec_loops[] = {
1791 &test_move_special,
1792 &test_av_dint_two_args,
1793 &test_av_wint_two_args_dres,
1794 &test_av_dint_to_int_two_args,
1795 &test_av_wint_one_arg_dres,
1796 &test_av_dint_three_args,
1797 &test_av_dint_one_arg,
1798 &test_av_dint_one_arg_SHA,
1799 &test_av_bcd,
1800 NULL
1803 /* Used in do_tests, indexed by flags->nb_args
1804 Elements correspond to enum test_flags::num args
1806 static test_loop_t int_loops[] = {
1807 /* The #defines for the family, number registers need the array
1808 * to be properly indexed. This test is for the new ISA 2.0.7
1809 * instructions. The infrastructure has been left for the momemnt
1811 NULL, //&test_int_one_arg,
1812 NULL, //&test_int_two_args,
1813 NULL, //&test_int_three_args,
1814 NULL, //&test_int_two_args,
1815 NULL, //&test_int_one_reg_imm16,
1816 NULL, //&test_int_one_reg_imm16,
1817 NULL, //&test_int_special,
1818 NULL, //&test_int_ld_one_reg_imm16,
1819 NULL, //&test_int_ld_two_regs,
1820 NULL, //&test_int_st_two_regs_imm16,
1821 NULL, //&test_int_st_three_regs,
1822 &test_int_stq_two_regs_imm16,
1823 &test_int_ldq_two_regs_imm16,
1824 &test_int_stq_three_regs,
1825 &test_int_ldq_three_regs,
1828 /* Used in do_tests, indexed by flags->nb_args
1829 Elements correspond to enum test_flags::num args
1830 Must have NULL for last entry.
1832 static test_loop_t float_loops[] = {
1833 NULL,
1834 &test_float_two_args,
1838 static test_t tests_fa_ops_two[] = {
1839 { &test_fmrgew , "fmrgew", },
1840 { &test_fmrgow , "fmrgow", },
1841 { NULL, NULL, },
1844 static test_table_t all_tests[] = {
1846 tests_move_ops_spe,
1847 "PPC VSR special move insns",
1848 PPC_ALTIVECD | PPC_MOV | PPC_ONE_ARG,
1851 tests_aa_dbl_ops_two_args,
1852 "PPC altivec double word integer insns (arith, compare) with two args",
1853 PPC_ALTIVECD | PPC_ARITH | PPC_TWO_ARGS,
1856 tests_aa_word_ops_two_args_dres,
1857 "PPC altivec integer word instructions with two input args, double word result",
1858 PPC_ALTIVEC | PPC_ARITH_DRES | PPC_TWO_ARGS,
1861 tests_aa_dbl_to_int_two_args,
1862 "PPC altivec doubleword-to-integer instructions with two input args, saturated integer result",
1863 PPC_ALTIVECD | PPC_DOUBLE_IN_IRES | PPC_TWO_ARGS,
1866 tests_aa_word_ops_one_arg_dres,
1867 "PPC altivec integer word instructions with one input arg, double word result",
1868 PPC_ALTIVEC | PPC_ARITH_DRES | PPC_ONE_ARG,
1871 tests_istq_ops_two_i16,
1872 "PPC store quadword insns\n with one register + one 16 bits immediate args with flags update",
1873 0x0001050c,
1876 tests_ildq_ops_two_i16,
1877 "PPC load quadword insns\n with one register + one 16 bits immediate args with flags update",
1878 0x0001050d,
1881 tests_ldq_ops_three,
1882 "PPC load quadword insns\n with three register args",
1883 0x0001050f,
1886 tests_stq_ops_three,
1887 "PPC store quadword insns\n with three register args",
1888 0x0001050e,
1891 tests_fa_ops_two,
1892 "PPC floating point arith insns with two args",
1893 0x00020102,
1896 tests_aa_ops_three ,
1897 "PPC altivec integer logical insns with three args",
1898 0x00060203,
1901 tests_aa_dbl_ops_one_arg,
1902 "PPC altivec one vector input arg, hex result",
1903 0x00060201,
1906 tests_aa_SHA_ops,
1907 "PPC altivec SSH insns",
1908 0x00040B01,
1911 tests_aa_bcd_ops,
1912 "PPC altivec BCD insns",
1913 0x00040B02,
1916 tests_aa_quadword_two_args,
1917 "PPC altivec quadword insns, two input args",
1918 0x00070102,
1921 tests_aa_quadword_three_args,
1922 "PPC altivec quadword insns, three input args",
1923 0x00070103
1925 { NULL, NULL, 0x00000000, },
1928 static void do_tests ( insn_sel_flags_t seln_flags,
1929 char *filter)
1931 test_loop_t *loop;
1932 test_t *tests;
1933 int nb_args, type, family;
1934 int i, j, n;
1935 int exact;
1937 exact = check_filter(filter);
1938 n = 0;
1939 for (i=0; all_tests[i].name != NULL; i++) {
1940 nb_args = all_tests[i].flags & PPC_NB_ARGS;
1942 /* Check number of arguments */
1943 if ((nb_args == 1 && !seln_flags.one_arg) ||
1944 (nb_args == 2 && !seln_flags.two_args) ||
1945 (nb_args == 3 && !seln_flags.three_args)){
1946 continue;
1948 /* Check instruction type */
1949 type = all_tests[i].flags & PPC_TYPE;
1950 if ((type == PPC_ARITH && !seln_flags.arith) ||
1951 (type == PPC_LOGICAL && !seln_flags.logical) ||
1952 (type == PPC_COMPARE && !seln_flags.compare) ||
1953 (type == PPC_LDST && !seln_flags.ldst) ||
1954 (type == PPC_MOV && !seln_flags.ldst) ||
1955 (type == PPC_POPCNT && !seln_flags.arith)) {
1956 continue;
1959 /* Check instruction family */
1960 family = all_tests[i].flags & PPC_FAMILY;
1961 if ((family == PPC_INTEGER && !seln_flags.integer) ||
1962 (family == PPC_FLOAT && !seln_flags.floats) ||
1963 (family == PPC_ALTIVEC && !seln_flags.altivec) ||
1964 (family == PPC_ALTIVECD && !seln_flags.altivec) ||
1965 (family == PPC_ALTIVECQ && !seln_flags.altivec) ||
1966 (family == PPC_FALTIVEC && !seln_flags.faltivec)) {
1967 continue;
1969 /* Check flags update */
1970 if (((all_tests[i].flags & PPC_CR) && seln_flags.cr == 0) ||
1971 (!(all_tests[i].flags & PPC_CR) && seln_flags.cr == 1))
1972 continue;
1974 /* All passed, do the tests */
1975 tests = all_tests[i].tests;
1977 loop = NULL;
1979 /* Select the test loop */
1980 switch (family) {
1981 case PPC_INTEGER:
1982 mem_resv = memalign16(2 * sizeof(HWord_t)); // want 128-bits
1983 loop = &int_loops[nb_args - 1];
1984 break;
1986 case PPC_FLOAT:
1987 loop = &float_loops[nb_args - 1];
1988 break;
1990 case PPC_ALTIVECQ:
1991 if (nb_args == 2)
1992 loop = &altivec_loops[ALTV_DINT];
1993 else if (nb_args == 3)
1994 loop = &altivec_loops[ALTV_DINT_THREE_ARGS];
1995 break;
1996 case PPC_ALTIVECD:
1997 switch (type) {
1998 case PPC_MOV:
1999 loop = &altivec_loops[ALTV_MOV];
2000 break;
2001 case PPC_ARITH:
2002 loop = &altivec_loops[ALTV_DINT];
2003 break;
2004 case PPC_DOUBLE_IN_IRES:
2005 loop = &altivec_loops[ALTV_DINT_IRES];
2006 break;
2007 case PPC_LOGICAL:
2008 if (nb_args == 3)
2009 loop = &altivec_loops[ALTV_DINT_THREE_ARGS];
2010 else if (nb_args ==1)
2011 loop = &altivec_loops[ALTV_DINT_ONE_ARG];
2012 break;
2013 default:
2014 printf("No altivec test defined for type %x\n", type);
2016 break;
2018 case PPC_FALTIVEC:
2019 printf("Currently there are no floating altivec tests in this testsuite.\n");
2020 break;
2022 case PPC_ALTIVEC:
2023 switch (type) {
2024 case PPC_ARITH_DRES:
2026 switch (nb_args) {
2027 case 1:
2028 loop = &altivec_loops[ALTV_ONE_INT_DRES];
2029 break;
2030 case 2:
2031 loop = &altivec_loops[ALTV_INT_DRES];
2032 break;
2033 default:
2034 printf("No altivec test defined for number args %d\n", nb_args);
2036 break;
2038 case PPC_SHA_OR_BCD:
2039 if (nb_args == 1)
2040 loop = &altivec_loops[ALTV_SHA];
2041 else
2042 loop = &altivec_loops[ATLV_BCD];
2043 break;
2044 default:
2045 printf("No altivec test defined for type %x\n", type);
2047 break;
2049 default:
2050 printf("ERROR: unknown insn family %08x\n", family);
2051 continue;
2053 if (1 || verbose > 0)
2054 for (j=0; tests[j].name != NULL; j++) {
2055 if (check_name(tests[j].name, filter, exact)) {
2056 if (verbose > 1)
2057 printf("Test instruction %s\n", tests[j].name);
2058 if (loop != NULL)
2059 (*loop)(tests[j].name, tests[j].func, all_tests[i].flags);
2060 printf("\n");
2061 n++;
2064 if (verbose) printf("\n");
2066 printf("All done. Tested %d different instructions\n", n);
2070 static void usage (void)
2072 fprintf(stderr,
2073 "Usage: jm-insns [OPTION]\n"
2074 "\t-i: test integer instructions (default)\n"
2075 "\t-f: test floating point instructions\n"
2076 "\t-a: test altivec instructions\n"
2077 "\t-A: test all (int, fp, altivec) instructions\n"
2078 "\t-v: be verbose\n"
2079 "\t-h: display this help and exit\n"
2083 #endif
2085 int main (int argc, char **argv)
2087 #ifdef HAS_ISA_2_07
2088 /* Simple usage:
2089 ./jm-insns -i => int insns
2090 ./jm-insns -f => fp insns
2091 ./jm-insns -a => av insns
2092 ./jm-insns -A => int, fp and avinsns
2094 char *filter = NULL;
2095 insn_sel_flags_t flags;
2096 int c;
2098 // Args
2099 flags.one_arg = 1;
2100 flags.two_args = 1;
2101 flags.three_args = 1;
2102 // Type
2103 flags.arith = 1;
2104 flags.logical = 1;
2105 flags.compare = 1;
2106 flags.ldst = 1;
2107 // Family
2108 flags.integer = 0;
2109 flags.floats = 0;
2110 flags.altivec = 0;
2111 flags.faltivec = 0;
2112 // Flags
2113 flags.cr = 2;
2115 while ((c = getopt(argc, argv, "ifahvA")) != -1) {
2116 switch (c) {
2117 case 'i':
2118 flags.integer = 1;
2119 break;
2120 case 'f':
2121 build_fargs_table();
2122 flags.floats = 1;
2123 break;
2124 case 'a':
2125 flags.altivec = 1;
2126 flags.faltivec = 1;
2127 break;
2128 case 'A':
2129 flags.integer = 1;
2130 flags.floats = 1;
2131 flags.altivec = 1;
2132 flags.faltivec = 1;
2133 break;
2134 case 'h':
2135 usage();
2136 return 0;
2137 case 'v':
2138 verbose++;
2139 break;
2140 default:
2141 usage();
2142 fprintf(stderr, "Unknown argument: '%c'\n", c);
2143 return 1;
2147 arg_list_size = 0;
2149 build_vargs_table();
2150 if (verbose > 1) {
2151 printf("\nInstruction Selection:\n");
2152 printf(" n_args: \n");
2153 printf(" one_arg = %d\n", flags.one_arg);
2154 printf(" two_args = %d\n", flags.two_args);
2155 printf(" three_args = %d\n", flags.three_args);
2156 printf(" type: \n");
2157 printf(" arith = %d\n", flags.arith);
2158 printf(" logical = %d\n", flags.logical);
2159 printf(" compare = %d\n", flags.compare);
2160 printf(" ldst = %d\n", flags.ldst);
2161 printf(" family: \n");
2162 printf(" integer = %d\n", flags.integer);
2163 printf(" floats = %d\n", flags.floats);
2164 printf(" altivec = %d\n", flags.altivec);
2165 printf(" faltivec = %d\n", flags.faltivec);
2166 printf(" cr update: \n");
2167 printf(" cr = %d\n", flags.cr);
2168 printf("\n");
2171 do_tests( flags, filter );
2172 #else
2173 printf("NO ISA 2.07 SUPPORT\n");
2174 #endif
2175 return 0;