1
2 /* HOW TO COMPILE:
3
4 * 32bit build:
5 gcc -Winline -Wall -g -O -mregnames -maltivec -m32
6 * 64bit build:
7 gcc -Winline -Wall -g -O -mregnames -maltivec -m64
8
9
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.
15 *
16 * Copyright (C) 2013 IBM
17 *
18 * Authors: Carl Love <carll@us.ibm.com>
19 * Maynard Johnson <maynardj@us.ibm.com>
20 *
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.
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 /*
38 * Operation details
39 * -----------------
40 *
41 * The 'loops' (e.g. int_loops) do the actual work:
42 * - loops over as many arguments as the insn needs (regs | imms)
43 * - sets up the environment (reset cr,xer, assign src regs...)
44 * - maybe modifies the asm instn to test different imm args
45 * - calls the test function
46 * - retrieves relevant register data (rD,cr,xer,...)
47 * - prints argument and result data.
48 *
49 * More specifically...
50 *
51 * all_tests[i] holds insn tests
52 * - of which each holds: {instn_test_arr[], description, flags}
53 *
54 * flags hold 3 instn classifiers: {family, type, arg_type}
55 *
56 * // The main test loop:
57 * do_tests( user_ctl_flags ) {
58 * foreach(curr_test = all_test[i]) {
59 *
60 * // flags are used to control what tests are run:
61 * if (curr_test->flags && !user_ctl_flags)
62 * continue;
63 *
64 * // a 'loop_family_arr' is chosen based on the 'family' flag...
65 * switch(curr_test->flags->family) {
66 * case x: loop_family_arr = int_loops;
67 * ...
68 * }
69 *
70 * // ...and the actual test_loop to run is found by indexing into
71 * // the loop_family_arr with the 'arg_type' flag:
72 * test_loop = loop_family[curr_test->flags->arg_type]
73 *
74 * // finally, loop over all instn tests for this test:
75 * foreach (instn_test = curr_test->instn_test_arr[i]) {
76 *
77 * // and call the test_loop with the current instn_test function,name
78 * test_loop( instn_test->func, instn_test->name )
79 * }
80 * }
81 * }
82 *
83 */
84
85
86 /**********************************************************************/
87
88 /* Uncomment to enable output of CR flags for float tests */
89 //#define TEST_FLOAT_FLAGS
90
91 /* Uncomment to enable debug output */
92 //#define DEBUG_ARGS_BUILD
93 //#define DEBUG_FILTER
94
95 /**********************************************************************/
96 #include <stdio.h>
97
98 #ifdef HAS_ISA_2_07
99
100 #include "config.h"
101 #include <altivec.h>
102 #include <stdint.h>
103
104 #include <assert.h>
105 #include <ctype.h> // isspace
106 #include <stdlib.h>
107 #include <string.h>
108 #include <unistd.h> // getopt
109
110 #if !defined (__TEST_PPC_H__)
111 #define __TEST_PPC_H__
112
113 #include "tests/sys_mman.h"
114 #include "tests/malloc.h" // memalign16
115
116 #define STATIC_ASSERT(e) sizeof(struct { int:-!(e); })
117
118 /* Something of the same size as void*, so can be safely be coerced
119 * to/from a pointer type. Also same size as the host's gp registers.
120 * According to the AltiVec section of the GCC manual, the syntax does
121 * not allow the use of a typedef name as a type specifier in conjunction
122 * with the vector keyword, so typedefs uint[32|64]_t are #undef'ed here
123 * and redefined using #define.
124 */
125 #undef uint32_t
126 #undef uint64_t
127 #define uint32_t unsigned int
128 #define uint64_t unsigned long long int
129
130 #ifndef __powerpc64__
131 typedef uint32_t HWord_t;
132 #define ZERO 0
133 #else
134 typedef uint64_t HWord_t;
135 #define ZERO 0ULL
136 #endif /* __powerpc64__ */
137
138 typedef uint64_t Word_t;
139
140 enum {
141 compile_time_test1 = STATIC_ASSERT(sizeof(uint32_t) == 4),
142 compile_time_test2 = STATIC_ASSERT(sizeof(uint64_t) == 8),
143 };
144
145 #define ALLCR "cr0","cr1","cr2","cr3","cr4","cr5","cr6","cr7"
146
147 #define SET_CR(_arg) \
148 __asm__ __volatile__ ("mtcr %0" : : "b"(_arg) : ALLCR );
149
150 #define SET_XER(_arg) \
151 __asm__ __volatile__ ("mtxer %0" : : "b"(_arg) : "xer" );
152
153 #define GET_CR(_lval) \
154 __asm__ __volatile__ ("mfcr %0" : "=b"(_lval) )
155
156 #define GET_XER(_lval) \
157 __asm__ __volatile__ ("mfxer %0" : "=b"(_lval) )
158
159 #define GET_CR_XER(_lval_cr,_lval_xer) \
160 do { GET_CR(_lval_cr); GET_XER(_lval_xer); } while (0)
161
162 #define SET_CR_ZERO \
163 SET_CR(0)
164
165 #define SET_XER_ZERO \
166 SET_XER(0)
167
168 #define SET_CR_XER_ZERO \
169 do { SET_CR_ZERO; SET_XER_ZERO; } while (0)
170
171 #define SET_FPSCR_ZERO \
172 do { double _d = 0.0; \
173 __asm__ __volatile__ ("mtfsf 0xFF, %0" : : "f"(_d) ); \
174 } while (0)
175
176 #define DEFAULT_VSCR 0x0
177
178 static vector unsigned long long vec_out, vec_inA, vec_inB, vec_inC;
179 static vector unsigned int vec_inA_wd, vec_inB_wd;
180
181 /* XXXX these must all be callee-save regs! */
182 register double f14 __asm__ ("fr14");
183 register double f15 __asm__ ("fr15");
184 register double f16 __asm__ ("fr16");
185 register double f17 __asm__ ("fr17");
186 register HWord_t r14 __asm__ ("r14");
187 register HWord_t r15 __asm__ ("r15");
188 register HWord_t r16 __asm__ ("r16");
189 register HWord_t r17 __asm__ ("r17");
190
191 typedef void (*test_func_t) (void);
192 typedef struct _test test_t;
193 typedef struct _test_table test_table_t;
194 struct _test {
195 test_func_t func;
196 const char *name;
197 };
198
199 struct _test_table {
200 test_t *tests;
201 const char *name;
202 uint32_t flags;
203 };
204
205 typedef void (*test_loop_t) (const char *name, test_func_t func,
206 uint32_t flags);
207
208 enum test_flags {
209 /* Nb arguments */
210 PPC_ONE_ARG = 0x00000001,
211 PPC_TWO_ARGS = 0x00000002,
212 PPC_THREE_ARGS = 0x00000003,
213 PPC_CMP_ARGS = 0x00000004, // family: compare
214 PPC_CMPI_ARGS = 0x00000005, // family: compare
215 PPC_TWO_I16 = 0x00000006, // family: arith/logical
216 PPC_SPECIAL = 0x00000007, // family: logical
217 PPC_LD_ARGS = 0x00000008, // family: ldst
218 PPC_LDX_ARGS = 0x00000009, // family: ldst
219 PPC_ST_ARGS = 0x0000000A, // family: ldst
220 PPC_STX_ARGS = 0x0000000B, // family: ldst
221 PPC_STQ_ARGS = 0x0000000C, // family: ldst, two args, imm
222 PPC_LDQ_ARGS = 0x0000000D, // family: ldst, two args, imm
223 PPC_STQX_ARGS = 0x0000000E, // family: ldst, three args
224 PPC_LDQX_ARGS = 0x0000000F, // family: ldst, three_args
225 PPC_NB_ARGS = 0x0000000F,
226 /* Type */
227 PPC_ARITH = 0x00000100,
228 PPC_LOGICAL = 0x00000200,
229 PPC_COMPARE = 0x00000300,
230 PPC_CROP = 0x00000400,
231 PPC_LDST = 0x00000500,
232 PPC_POPCNT = 0x00000600,
233 PPC_ARITH_DRES = 0x00000700,
234 PPC_DOUBLE_IN_IRES = 0x00000800,
235 PPC_MOV = 0x00000A00,
236 PPC_SHA_OR_BCD = 0x00000B00,
237 PPC_TYPE = 0x00000F00,
238 /* Family */
239 PPC_INTEGER = 0x00010000,
240 PPC_FLOAT = 0x00020000,
241 PPC_405 = 0x00030000, // Leave so we keep numbering consistent
242 PPC_ALTIVEC = 0x00040000,
243 PPC_FALTIVEC = 0x00050000,
244 PPC_ALTIVECD = 0x00060000, /* double word Altivec tests */
245 PPC_ALTIVECQ = 0x00070000,
246 PPC_FAMILY = 0x000F0000,
247 /* Flags: these may be combined, so use separate bitfields. */
248 PPC_CR = 0x01000000,
249 PPC_XER_CA = 0x02000000,
250 };
251
252 #endif /* !defined (__TEST_PPC_H__) */
253
254 /* -------------- END #include "test-ppc.h" -------------- */
255
256
257 #if defined (DEBUG_ARGS_BUILD)
258 #define AB_DPRINTF(fmt, args...) do { fprintf(stderr, fmt , ##args); } while (0)
259 #else
260 #define AB_DPRINTF(fmt, args...) do { } while (0)
261 #endif
262
263
264 #if defined (DEBUG_FILTER)
265 #define FDPRINTF(fmt, args...) do { fprintf(stderr, fmt , ##args); } while (0)
266 #else
267 #define FDPRINTF(fmt, args...) do { } while (0)
268 #endif
269
270 #define unused __attribute__ (( unused ))
271
272 typedef struct special {
273 const char *name;
274 void (*test_cb)(const char* name, test_func_t func,
275 unused uint32_t test_flags);
276 } special_t;
277
test_stq(void)278 static void test_stq(void)
279 {
280 __asm__ __volatile__ ("stq %0, 0(%1)" : :"r" (r14), "r" (r16));
281 }
282
283 static test_t tests_istq_ops_two_i16[] = {
284 { &test_stq , "stq", },
285 { NULL, NULL, },
286 };
287
test_lq(void)288 static void test_lq(void)
289 {
290 __asm__ __volatile__ ("lq %0, 0(%1)" : :"r" (r14), "r" (r16));
291 }
292
293 static test_t tests_ildq_ops_two_i16[] = {
294 { &test_lq , "lq", },
295 { NULL, NULL, },
296 };
297
298
299 Word_t * mem_resv;
test_stqcx(void)300 static void test_stqcx(void)
301 {
302 /* Have to do the lqarx to the memory address to create the reservation
303 * or the store will not occur.
304 */
305 __asm__ __volatile__ ("lqarx %0, %1, %2" : :"r" (r14), "r" (r16),"r" (r17));
306 r14 = (HWord_t) 0xABEFCD0145236789ULL;
307 r15 = (HWord_t) 0x1155337744226688ULL;
308 __asm__ __volatile__ ("stqcx. %0, %1, %2" : :"r" (r14), "r" (r16),"r" (r17));
309 }
310
311 static test_t tests_stq_ops_three[] = {
312 { &test_stqcx , "stqcx.", },
313 { NULL, NULL, },
314 };
315
test_lqarx(void)316 static void test_lqarx(void)
317 {
318 __asm__ __volatile__ ("lqarx %0, %1, %2, 0" : :"r" (r14), "r" (r16),"r" (r17));
319 }
320
321 static test_t tests_ldq_ops_three[] = {
322 { &test_lqarx , "lqarx", },
323 { NULL, NULL, },
324 };
325
test_fmrgew(void)326 static void test_fmrgew (void)
327 {
328 __asm__ __volatile__ ("fmrgew 17,14,15");
329 };
330
test_fmrgow(void)331 static void test_fmrgow (void)
332 {
333 __asm__ __volatile__ ("fmrgow 17,14,15");
334 };
335
336
337
338 // VSX move instructions
test_mfvsrd(void)339 static void test_mfvsrd (void)
340 {
341 __asm__ __volatile__ ("mfvsrd %0,%x1" : "=r" (r14) : "ws" (vec_inA));
342 };
343
test_mfvsrwz(void)344 static void test_mfvsrwz (void)
345 {
346 __asm__ __volatile__ ("mfvsrwz %0,%x1" : "=r" (r14) : "ws" (vec_inA));
347 };
348
test_mtvsrd(void)349 static void test_mtvsrd (void)
350 {
351 __asm__ __volatile__ ("mtvsrd %x0,%1" : "=ws" (vec_out) : "r" (r14));
352 };
353
test_mtvsrwz(void)354 static void test_mtvsrwz (void)
355 {
356 __asm__ __volatile__ ("mtvsrwz %x0,%1" : "=ws" (vec_out) : "r" (r14));
357 };
358
359
test_mtfprwa(void)360 static void test_mtfprwa (void)
361 {
362 __asm__ __volatile__ ("mtfprwa %x0,%1" : "=ws" (vec_out) : "r" (r14));
363 };
364
365 static test_t tests_move_ops_spe[] = {
366 { &test_mfvsrd , "mfvsrd" },
367 { &test_mfvsrwz , "mfvsrwz" },
368 { &test_mtvsrd , "mtvsrd" },
369 { &test_mtvsrwz , "mtvsrwz" },
370 { &test_mtfprwa , "mtfprwa" },
371 { NULL, NULL }
372 };
373
374 /* NOTE: Since these are "vector" instructions versus VSX, we must use
375 * vector constraints.
376 *
377 * Vector Double Word tests.
378 */
test_vpkudum(void)379 static void test_vpkudum (void)
380 {
381 __asm__ __volatile__ ("vpkudum %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
382 }
383
test_vaddudm(void)384 static void test_vaddudm (void)
385 {
386 __asm__ __volatile__ ("vaddudm %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
387 }
388
test_vsubudm(void)389 static void test_vsubudm (void)
390 {
391 __asm__ __volatile__ ("vsubudm %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
392 }
393
test_vmaxud(void)394 static void test_vmaxud (void)
395 {
396 __asm__ __volatile__ ("vmaxud %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
397 }
398
test_vmaxsd(void)399 static void test_vmaxsd (void)
400 {
401 __asm__ __volatile__ ("vmaxsd %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
402 }
403
test_vminud(void)404 static void test_vminud (void)
405 {
406 __asm__ __volatile__ ("vminud %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
407 }
408
test_vminsd(void)409 static void test_vminsd (void)
410 {
411 __asm__ __volatile__ ("vminsd %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
412 }
413
test_vcmpequd(void)414 static void test_vcmpequd (void)
415 {
416 __asm__ __volatile__ ("vcmpequd %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
417 }
418
test_vcmpgtud(void)419 static void test_vcmpgtud (void)
420 {
421 __asm__ __volatile__ ("vcmpgtud %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
422 }
423
test_vcmpgtsd(void)424 static void test_vcmpgtsd (void)
425 {
426 __asm__ __volatile__ ("vcmpgtsd %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
427 }
428
test_vrld(void)429 static void test_vrld (void)
430 {
431 __asm__ __volatile__ ("vrld %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
432 }
433
test_vsld(void)434 static void test_vsld (void)
435 {
436 __asm__ __volatile__ ("vsld %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
437 }
438
test_vsrad(void)439 static void test_vsrad (void)
440 {
441 __asm__ __volatile__ ("vsrad %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
442 }
443
test_vsrd(void)444 static void test_vsrd (void)
445 {
446 __asm__ __volatile__ ("vsrd %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
447 }
448
449 /* Vector Double Word saturate tests.*/
450
test_vpkudus(void)451 static void test_vpkudus (void)
452 {
453 __asm__ __volatile__ ("vpkudus %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
454 }
455
test_vpksdus(void)456 static void test_vpksdus (void)
457 {
458 __asm__ __volatile__ ("vpksdus %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
459 }
460
test_vpksdss(void)461 static void test_vpksdss (void)
462 {
463 __asm__ __volatile__ ("vpksdss %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
464 }
465
466
467 /* Vector unpack two words from one vector arg */
test_vupkhsw(void)468 static void test_vupkhsw (void)
469 {
470 __asm__ __volatile__ ("vupkhsw %0, %1" : "=v" (vec_out): "v" (vec_inB_wd));
471 }
472
test_vupklsw(void)473 static void test_vupklsw (void)
474 {
475 __asm__ __volatile__ ("vupklsw %0, %1" : "=v" (vec_out): "v" (vec_inB_wd));
476 }
477
478
479 /* Vector Integer Word tests.*/
test_vmulouw(void)480 static void test_vmulouw (void)
481 {
482 __asm__ __volatile__ ("vmulouw %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
483 }
484
test_vmuluwm(void)485 static void test_vmuluwm (void)
486 {
487 __asm__ __volatile__ ("vmuluwm %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
488 }
489
test_vmulosw(void)490 static void test_vmulosw (void)
491 {
492 __asm__ __volatile__ ("vmulosw %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
493 }
494
test_vmuleuw(void)495 static void test_vmuleuw (void)
496 {
497 __asm__ __volatile__ ("vmuleuw %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
498 }
499
test_vmulesw(void)500 static void test_vmulesw (void)
501 {
502 __asm__ __volatile__ ("vmulesw %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
503 }
504
test_vmrgew(void)505 static void test_vmrgew (void)
506 {
507 __asm__ __volatile__ ("vmrgew %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
508 }
509
test_vmrgow(void)510 static void test_vmrgow (void)
511 {
512 __asm__ __volatile__ ("vmrgow %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
513 }
514
test_vpmsumb(void)515 static void test_vpmsumb (void)
516 {
517 __asm__ __volatile__ ("vpmsumb %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
518 }
519
test_vpmsumh(void)520 static void test_vpmsumh (void)
521 {
522 __asm__ __volatile__ ("vpmsumh %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
523 }
524
test_vpmsumw(void)525 static void test_vpmsumw (void)
526 {
527 __asm__ __volatile__ ("vpmsumw %0, %1, %2" : "=v" (vec_out): "v" (vec_inA_wd),"v" (vec_inB_wd));
528 }
529
test_vpermxor(void)530 static void test_vpermxor (void)
531 {
532 __asm__ __volatile__ ("vpermxor %0, %1, %2, %3" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB),"v" (vec_inC));
533 }
534
test_vpmsumd(void)535 static void test_vpmsumd (void)
536 {
537 __asm__ __volatile__ ("vpmsumd %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
538 }
539
test_vnand(void)540 static void test_vnand (void)
541 {
542 __asm__ __volatile__ ("vnand %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
543 }
544
test_vorc(void)545 static void test_vorc (void)
546 {
547 __asm__ __volatile__ ("vorc %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
548 }
549
test_veqv(void)550 static void test_veqv (void)
551 {
552 __asm__ __volatile__ ("veqv %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
553 }
554
test_vcipher(void)555 static void test_vcipher (void)
556 {
557 __asm__ __volatile__ ("vcipher %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
558 }
559
test_vcipherlast(void)560 static void test_vcipherlast (void)
561 {
562 __asm__ __volatile__ ("vcipherlast %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
563 }
564
test_vncipher(void)565 static void test_vncipher (void)
566 {
567 __asm__ __volatile__ ("vncipher %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
568 }
569
test_vncipherlast(void)570 static void test_vncipherlast (void)
571 {
572 __asm__ __volatile__ ("vncipherlast %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
573 }
574
test_vclzb(void)575 static void test_vclzb (void)
576 {
577 __asm__ __volatile__ ("vclzb %0, %1" : "=v" (vec_out): "v" (vec_inB));
578 }
579
test_vclzw(void)580 static void test_vclzw (void)
581 {
582 __asm__ __volatile__ ("vclzw %0, %1" : "=v" (vec_out): "v" (vec_inB));
583 }
584
test_vclzh(void)585 static void test_vclzh (void)
586 {
587 __asm__ __volatile__ ("vclzh %0, %1" : "=v" (vec_out): "v" (vec_inB));
588 }
589
test_vclzd(void)590 static void test_vclzd (void)
591 {
592 __asm__ __volatile__ ("vclzd %0, %1" : "=v" (vec_out): "v" (vec_inB));
593 }
594
test_vpopcntb(void)595 static void test_vpopcntb (void)
596 {
597 __asm__ __volatile__ ("vpopcntb %0, %1" : "=v" (vec_out): "v" (vec_inB));
598 }
599
test_vpopcnth(void)600 static void test_vpopcnth (void)
601 {
602 __asm__ __volatile__ ("vpopcnth %0, %1" : "=v" (vec_out): "v" (vec_inB));
603 }
604
test_vpopcntw(void)605 static void test_vpopcntw (void)
606 {
607 __asm__ __volatile__ ("vpopcntw %0, %1" : "=v" (vec_out): "v" (vec_inB));
608 }
609
test_vpopcntd(void)610 static void test_vpopcntd (void)
611 {
612 __asm__ __volatile__ ("vpopcntd %0, %1" : "=v" (vec_out): "v" (vec_inB));
613 }
614
test_vsbox(void)615 static void test_vsbox (void)
616 {
617 __asm__ __volatile__ ("vsbox %0, %1" : "=v" (vec_out): "v" (vec_inB));
618 }
619
620 static int st_six;
test_vshasigmad(void)621 static void test_vshasigmad (void)
622 {
623 switch (st_six) {
624 case 0x00:
625 __asm__ __volatile__ ("vshasigmad %0, %1, 0, 0" : "=v" (vec_out): "v" (vec_inA));
626 break;
627 case 0x0f:
628 __asm__ __volatile__ ("vshasigmad %0, %1, 0, 15" : "=v" (vec_out): "v" (vec_inA));
629 break;
630 case 0x10:
631 __asm__ __volatile__ ("vshasigmad %0, %1, 1, 0" : "=v" (vec_out): "v" (vec_inA));
632 break;
633 case 0x1f:
634 __asm__ __volatile__ ("vshasigmad %0, %1, 1, 15" : "=v" (vec_out): "v" (vec_inA));
635 break;
636 }
637 }
638
test_vshasigmaw(void)639 static void test_vshasigmaw (void)
640 {
641 switch (st_six) {
642 case 0x00:
643 __asm__ __volatile__ ("vshasigmaw %0, %1, 0, 0" : "=v" (vec_out): "v" (vec_inA));
644 break;
645 case 0x0f:
646 __asm__ __volatile__ ("vshasigmaw %0, %1, 0, 15" : "=v" (vec_out): "v" (vec_inA));
647 break;
648 case 0x10:
649 __asm__ __volatile__ ("vshasigmaw %0, %1, 1, 0" : "=v" (vec_out): "v" (vec_inA));
650 break;
651 case 0x1f:
652 __asm__ __volatile__ ("vshasigmaw %0, %1, 1, 15" : "=v" (vec_out): "v" (vec_inA));
653 break;
654 }
655 }
656
657 static int PS_bit;
test_bcdadd(void)658 static void test_bcdadd (void)
659 {
660 if (PS_bit)
661 __asm__ __volatile__ ("bcdadd. %0, %1, %2, 1" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
662 else
663 __asm__ __volatile__ ("bcdadd. %0, %1, %2, 0" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
664 }
665
test_bcdsub(void)666 static void test_bcdsub (void)
667 {
668 if (PS_bit)
669 __asm__ __volatile__ ("bcdsub. %0, %1, %2, 1" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
670 else
671 __asm__ __volatile__ ("bcdsub. %0, %1, %2, 0" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
672 }
673
test_vaddcuq(void)674 static void test_vaddcuq (void)
675 {
676 __asm__ __volatile__ ("vaddcuq %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
677 }
678
test_vadduqm(void)679 static void test_vadduqm (void)
680 {
681 __asm__ __volatile__ ("vadduqm %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
682 }
683
test_vaddecuq(void)684 static void test_vaddecuq (void)
685 {
686 __asm__ __volatile__ ("vaddecuq %0, %1, %2, %3" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB),"v" (vec_inC));
687 }
688
test_vaddeuqm(void)689 static void test_vaddeuqm (void)
690 {
691 __asm__ __volatile__ ("vaddeuqm %0, %1, %2, %3" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB),"v" (vec_inC));
692 }
693
test_vsubcuq(void)694 static void test_vsubcuq (void)
695 {
696 __asm__ __volatile__ ("vsubcuq %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
697 }
698
test_vsubuqm(void)699 static void test_vsubuqm (void)
700 {
701 __asm__ __volatile__ ("vsubuqm %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
702 }
703
test_vsubecuq(void)704 static void test_vsubecuq (void)
705 {
706 __asm__ __volatile__ ("vsubecuq %0, %1, %2, %3" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB),"v" (vec_inC));
707 }
708
test_vsubeuqm(void)709 static void test_vsubeuqm (void)
710 {
711 __asm__ __volatile__ ("vsubeuqm %0, %1, %2, %3" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB),"v" (vec_inC));
712 }
713
test_vbpermq(void)714 static void test_vbpermq (void)
715 {
716 __asm__ __volatile__ ("vbpermq %0, %1, %2" : "=v" (vec_out): "v" (vec_inA),"v" (vec_inB));
717 }
718
test_vgbbd(void)719 static void test_vgbbd (void)
720 {
721 __asm__ __volatile__ ("vgbbd %0, %1" : "=v" (vec_out): "v" (vec_inB));
722 }
723
724
725 static test_t tests_aa_quadword_two_args[] = {
726 { &test_vaddcuq , "vaddcuq" },
727 { &test_vadduqm , "vadduqm" },
728 { &test_vsubcuq , "vsubcuq" },
729 { &test_vsubuqm , "vsubuqm" },
730 { &test_vbpermq , "vbpermq" },
731 { NULL , NULL },
732 };
733
734 static test_t tests_aa_quadword_three_args[] = {
735 { &test_vaddecuq , "vaddecuq" },
736 { &test_vaddeuqm , "vaddeuqm" },
737 { &test_vsubecuq , "vsubecuq" },
738 { &test_vsubeuqm , "vsubeuqm" },
739 { NULL , NULL },
740 };
741
742 static test_t tests_aa_bcd_ops[] = {
743 { &test_bcdadd , "bcdadd." },
744 { &test_bcdsub , "bcdsub." },
745 { NULL , NULL },
746 };
747
748 static test_t tests_aa_SHA_ops[] = {
749 { &test_vshasigmad , "vshasigmad" },
750 { &test_vshasigmaw , "vshasigmaw" },
751 { NULL , NULL },
752 };
753
754 static test_t tests_aa_ops_three[] = {
755 { &test_vpermxor , "vpermxor" },
756 { NULL , NULL },
757 };
758
759 static test_t tests_aa_word_ops_one_arg_dres[] = {
760 { &test_vupkhsw , "vupkhsw" },
761 { &test_vupklsw , "vupklsw" },
762 { NULL , NULL }
763 };
764
765 static test_t tests_aa_word_ops_two_args_dres[] = {
766 { &test_vmulouw , "vmulouw" },
767 { &test_vmuluwm , "vmuluwm" },
768 { &test_vmulosw , "vmulosw" },
769 { &test_vmuleuw , "vmuleuw" },
770 { &test_vmulesw , "vmulesw" },
771 { &test_vmrgew , "vmrgew" },
772 { &test_vmrgow , "vmrgow" },
773 { &test_vpmsumb , "vpmsumb" },
774 { &test_vpmsumh , "vpmsumh" },
775 { &test_vpmsumw , "vpmsumw" },
776 { NULL , NULL }
777 };
778
779 static test_t tests_aa_dbl_ops_two_args[] = {
780 { &test_vaddudm , "vaddudm", },
781 { &test_vsubudm , "vsubudm", },
782 { &test_vmaxud , "vmaxud", },
783 { &test_vmaxsd , "vmaxsd", },
784 { &test_vminud , "vminud", },
785 { &test_vminsd , "vminsd", },
786 { &test_vcmpequd , "vcmpequd", },
787 { &test_vcmpgtud , "vcmpgtud", },
788 { &test_vcmpgtsd , "vcmpgtsd", },
789 { &test_vrld , "vrld", },
790 { &test_vsld , "vsld", },
791 { &test_vsrad , "vsrad", },
792 { &test_vsrd , "vsrd", },
793 { &test_vpkudum , "vpkudum", },
794 { &test_vpmsumd , "vpmsumd", },
795 { &test_vnand , "vnand", },
796 { &test_vorc , "vorc", },
797 { &test_veqv , "veqv", },
798 { &test_vcipher , "vcipher" },
799 { &test_vcipherlast , "vcipherlast" },
800 { &test_vncipher , "vncipher" },
801 { &test_vncipherlast , "vncipherlast" },
802 { NULL , NULL, },
803 };
804
805 static test_t tests_aa_dbl_ops_one_arg[] = {
806 { &test_vclzb , "vclzb" },
807 { &test_vclzw , "vclzw" },
808 { &test_vclzh , "vclzh" },
809 { &test_vclzd , "vclzd" },
810 { &test_vpopcntb , "vpopcntb" },
811 { &test_vpopcnth , "vpopcnth" },
812 { &test_vpopcntw , "vpopcntw" },
813 { &test_vpopcntd , "vpopcntd" },
814 { &test_vsbox , "vsbox" },
815 { &test_vgbbd , "vgbbd" },
816 { NULL , NULL, }
817 };
818
819 static test_t tests_aa_dbl_to_int_two_args[] = {
820 { &test_vpkudus , "vpkudus", },
821 { &test_vpksdus , "vpksdus", },
822 { &test_vpksdss , "vpksdss", },
823 { NULL , NULL, },
824 };
825
826 static int verbose = 0;
827 static int arg_list_size = 0;
828 static unsigned long long * vdargs = NULL;
829 static unsigned long long * vdargs_x = NULL;
830 #define NB_VDARGS 4
831
build_vdargs_table(void)832 static void build_vdargs_table (void)
833 {
834 // Each VSX register holds two doubleword integer values
835 vdargs = memalign16(NB_VDARGS * sizeof(unsigned long long));
836 vdargs[0] = 0x0102030405060708ULL;
837 vdargs[1] = 0x090A0B0C0E0D0E0FULL;
838 vdargs[2] = 0xF1F2F3F4F5F6F7F8ULL;
839 vdargs[3] = 0xF9FAFBFCFEFDFEFFULL;
840
841 vdargs_x = memalign16(NB_VDARGS * sizeof(unsigned long long));
842 vdargs_x[0] = 0x000000007c118a2bULL;
843 vdargs_x[1] = 0x00000000f1112345ULL;
844 vdargs_x[2] = 0x01F2F3F4F5F6F7F8ULL;
845 vdargs_x[3] = 0xF9FAFBFCFEFDFEFFULL;
846 }
847
848 static unsigned int * vwargs = NULL;
849 #define NB_VWARGS 8
850
build_vwargs_table(void)851 static void build_vwargs_table (void)
852 {
853 // Each VSX register holds 4 integer word values
854 size_t i = 0;
855 vwargs = memalign(8, 8 * sizeof(int));
856 assert(vwargs);
857 assert(0 == ((8-1) & (unsigned long)vwargs));
858 vwargs[i++] = 0x01020304;
859 vwargs[i++] = 0x05060708;
860 vwargs[i++] = 0x090A0B0C;
861 vwargs[i++] = 0x0E0D0E0F;
862 vwargs[i++] = 0xF1F2F3F4;
863 vwargs[i++] = 0xF5F6F7F8;
864 vwargs[i++] = 0xF9FAFBFC;
865 vwargs[i++] = 0xFEFDFEFF;
866 }
867
868 static unsigned long long vbcd_args[] __attribute__ ((aligned (16))) = {
869 0x8045090189321003ULL, // Negative BCD value
870 0x001122334556677dULL,
871 0x0000107600000001ULL, // Positive BCD value
872 0x319293945142031aULL,
873 0x0ULL, // Valid BCD zero
874 0xaULL,
875 0x0ULL, // Invalid BCD zero (no sign code)
876 0x0ULL
877 };
878 #define NUM_VBCD_VALS (sizeof vbcd_args/sizeof vbcd_args[0])
879
build_vargs_table(void)880 static void build_vargs_table (void)
881 {
882 build_vdargs_table();
883 build_vwargs_table();
884 }
885
886 static double *fargs = NULL;
887 static int nb_fargs = 0;
888
register_farg(void * farg,int s,uint16_t _exp,uint64_t mant)889 static inline void register_farg (void *farg,
890 int s, uint16_t _exp, uint64_t mant)
891 {
892 uint64_t tmp;
893
894 tmp = ((uint64_t)s << 63) | ((uint64_t)_exp << 52) | mant;
895 *(uint64_t *)farg = tmp;
896 AB_DPRINTF("%d %03x %013llx => %016llx %0e\n",
897 s, _exp, mant, *(uint64_t *)farg, *(double *)farg);
898 }
899
build_fargs_table(void)900 static void build_fargs_table (void)
901 {
902 /* Double precision:
903 * Sign goes from zero to one (1 bit)
904 * Exponent goes from 0 to ((1 << 12) - 1) (11 bits)
905 * Mantissa goes from 1 to ((1 << 52) - 1) (52 bits)
906 * + special values:
907 * +0.0 : 0 0x000 0x0000000000000 => 0x0000000000000000
908 * -0.0 : 1 0x000 0x0000000000000 => 0x8000000000000000
909 * +infinity : 0 0x7FF 0x0000000000000 => 0x7FF0000000000000
910 * -infinity : 1 0x7FF 0x0000000000000 => 0xFFF0000000000000
911 * +QNaN : 0 0x7FF 0x8000000000000 => 0x7FF8000000000000
912 * -QNaN : 1 0x7FF 0x8000000000000 => 0xFFF8000000000000
913 * +SNaN : 0 0x7FF 0x7FFFFFFFFFFFF => 0x7FF7FFFFFFFFFFFF
914 * -SNaN : 1 0x7FF 0x7FFFFFFFFFFFF => 0xFFF7FFFFFFFFFFFF
915 * (8 values)
916
917 * Ref only:
918 * Single precision
919 * Sign: 1 bit
920 * Exponent: 8 bits
921 * Mantissa: 23 bits
922 * +0.0 : 0 0x00 0x000000 => 0x00000000
923 * -0.0 : 1 0x00 0x000000 => 0x80000000
924 * +infinity : 0 0xFF 0x000000 => 0x7F800000
925 * -infinity : 1 0xFF 0x000000 => 0xFF800000
926 * +QNaN : 0 0xFF 0x400000 => 0x7FC00000
927 * -QNaN : 1 0xFF 0x400000 => 0xFFC00000
928 * +SNaN : 0 0xFF 0x3FFFFF => 0x7FBFFFFF
929 * -SNaN : 1 0xFF 0x3FFFFF => 0xFFBFFFFF
930 */
931 uint64_t mant;
932 uint16_t _exp, e0, e1;
933 int s;
934 int i=0;
935
936 /* Note: VEX isn't so hot with denormals, so don't bother
937 testing them: set _exp > 0
938 */
939
940 if ( arg_list_size == 1 ) { // Large
941 fargs = malloc(200 * sizeof(double));
942 for (s=0; s<2; s++) {
943 for (e0=0; e0<2; e0++) {
944 for (e1=0x001; ; e1 = ((e1 + 1) << 2) + 6) {
945 if (e1 >= 0x400)
946 e1 = 0x3fe;
947 _exp = (e0 << 10) | e1;
948 for (mant = 0x0000000000001ULL; mant < (1ULL << 52);
949 /* Add 'random' bits */
950 mant = ((mant + 0x4A6) << 13) + 0x359) {
951 register_farg(&fargs[i++], s, _exp, mant);
952 }
953 if (e1 == 0x3fe)
954 break;
955 }
956 }
957 }
958 } else { // Default
959 fargs = malloc(16 * sizeof(double));
960 for (s=0; s<2; s++) { // x2
961 for (e1=0x001; ; e1 = ((e1 + 1) << 13) + 7) { // x2
962 if (e1 >= 0x400)
963 e1 = 0x3fe;
964 _exp = e1;
965 for (mant = 0x0000000000001ULL; mant < (1ULL << 52);
966 /* Add 'random' bits */
967 mant = ((mant + 0x4A6) << 29) + 0x359) { // x2
968 register_farg(&fargs[i++], s, _exp, mant);
969 }
970 if (e1 == 0x3fe)
971 break;
972 }
973 }
974 }
975
976 /* Special values */
977 /* +0.0 : 0 0x000 0x0000000000000 */
978 s = 0;
979 _exp = 0x000;
980 mant = 0x0000000000000ULL;
981 register_farg(&fargs[i++], s, _exp, mant);
982 /* -0.0 : 1 0x000 0x0000000000000 */
983 s = 1;
984 _exp = 0x000;
985 mant = 0x0000000000000ULL;
986 register_farg(&fargs[i++], s, _exp, mant);
987 /* +infinity : 0 0x7FF 0x0000000000000 */
988 s = 0;
989 _exp = 0x7FF;
990 mant = 0x0000000000000ULL;
991 register_farg(&fargs[i++], s, _exp, mant);
992 /* -infinity : 1 0x7FF 0x0000000000000 */
993 s = 1;
994 _exp = 0x7FF;
995 mant = 0x0000000000000ULL;
996 register_farg(&fargs[i++], s, _exp, mant);
997 /* +QNaN : 0 0x7FF 0x7FFFFFFFFFFFF */
998 s = 0;
999 _exp = 0x7FF;
1000 mant = 0x7FFFFFFFFFFFFULL;
1001 register_farg(&fargs[i++], s, _exp, mant);
1002 /* -QNaN : 1 0x7FF 0x7FFFFFFFFFFFF */
1003 s = 1;
1004 _exp = 0x7FF;
1005 mant = 0x7FFFFFFFFFFFFULL;
1006 register_farg(&fargs[i++], s, _exp, mant);
1007 /* +SNaN : 0 0x7FF 0x8000000000000 */
1008 s = 0;
1009 _exp = 0x7FF;
1010 mant = 0x8000000000000ULL;
1011 register_farg(&fargs[i++], s, _exp, mant);
1012 /* -SNaN : 1 0x7FF 0x8000000000000 */
1013 s = 1;
1014 _exp = 0x7FF;
1015 mant = 0x8000000000000ULL;
1016 register_farg(&fargs[i++], s, _exp, mant);
1017 AB_DPRINTF("Registered %d fargs values\n", i);
1018
1019 nb_fargs = i;
1020 }
1021
1022
1023
check_filter(char * filter)1024 static int check_filter (char *filter)
1025 {
1026 char *c;
1027 int ret = 1;
1028
1029 if (filter != NULL) {
1030 c = strchr(filter, '*');
1031 if (c != NULL) {
1032 *c = '\0';
1033 ret = 0;
1034 }
1035 }
1036 return ret;
1037 }
1038
check_name(const char * name,const char * filter,int exact)1039 static int check_name (const char* name, const char *filter,
1040 int exact)
1041 {
1042 int nlen, flen;
1043 int ret = 0;
1044
1045 if (filter != NULL) {
1046 for (; isspace(*name); name++)
1047 continue;
1048 FDPRINTF("Check '%s' againt '%s' (%s match)\n",
1049 name, filter, exact ? "exact" : "starting");
1050 nlen = strlen(name);
1051 flen = strlen(filter);
1052 if (exact) {
1053 if (nlen == flen && memcmp(name, filter, flen) == 0)
1054 ret = 1;
1055 } else {
1056 if (flen <= nlen && memcmp(name, filter, flen) == 0)
1057 ret = 1;
1058 }
1059 } else {
1060 ret = 1;
1061 }
1062 return ret;
1063 }
1064
1065
1066 typedef struct insn_sel_flags_t_struct {
1067 int one_arg, two_args, three_args;
1068 int arith, logical, compare, ldst;
1069 int integer, floats, altivec, faltivec;
1070 int cr;
1071 } insn_sel_flags_t;
1072
test_float_two_args(const char * name,test_func_t func,unused uint32_t test_flags)1073 static void test_float_two_args (const char* name, test_func_t func,
1074 unused uint32_t test_flags)
1075 {
1076 double res;
1077 Word_t u0, u1, ur;
1078 volatile uint32_t flags;
1079 int i, j;
1080
1081 for (i=0; i<nb_fargs; i+=3) {
1082 for (j=0; j<nb_fargs; j+=5) {
1083 u0 = *(Word_t *)(&fargs[i]);
1084 u1 = *(Word_t *)(&fargs[j]);
1085 f14 = fargs[i];
1086 f15 = fargs[j];
1087
1088 SET_FPSCR_ZERO;
1089 SET_CR_XER_ZERO;
1090 (*func)();
1091 GET_CR(flags);
1092 res = f17;
1093 ur = *(uint64_t *)(&res);
1094
1095 printf("%s %016llx, %016llx => %016llx",
1096 name, u0, u1, ur);
1097 #if defined TEST_FLOAT_FLAGS
1098 printf(" (%08x)", flags);
1099 #endif
1100 printf("\n");
1101 }
1102 if (verbose) printf("\n");
1103 }
1104 }
1105
1106
mfvs(const char * name,test_func_t func,unused uint32_t test_flags)1107 static void mfvs(const char* name, test_func_t func,
1108 unused uint32_t test_flags)
1109 {
1110 /* This test is for move instructions where the input is a scalar register
1111 * and the destination is a vector register.
1112 */
1113 int i;
1114 volatile Word_t result;
1115 result = 0ULL;
1116
1117 for (i=0; i < NB_VDARGS; i++) {
1118 r14 = ZERO;
1119 vec_inA = (vector unsigned long long){ vdargs[i], 0ULL };
1120
1121 (*func)();
1122 result = r14;
1123 printf("%s: %016llx => %016llx\n", name, vdargs[i], result);
1124 }
1125 }
1126
mtvs(const char * name,test_func_t func,unused uint32_t test_flags)1127 static void mtvs(const char* name, test_func_t func,
1128 unused uint32_t test_flags)
1129 {
1130 /* This test is for move instructions where the input is a scalar register
1131 * and the destination is a vector register.
1132 */
1133 unsigned long long *dst;
1134 int i;
1135
1136 for (i=0; i < NB_VDARGS; i++) {
1137 r14 = vdargs[i];
1138 vec_out = (vector unsigned long long){ 0ULL, 0ULL };
1139
1140 (*func)();
1141 dst = (unsigned long long *) &vec_out;
1142 printf("%s: %016llx => %016llx\n", name, vdargs[i], *dst);
1143 }
1144 }
1145
mtvs2s(const char * name,test_func_t func,unused uint32_t test_flags)1146 static void mtvs2s(const char* name, test_func_t func,
1147 unused uint32_t test_flags)
1148 {
1149 /* This test is the mtvsrwa instruction.
1150 */
1151 unsigned long long *dst;
1152 int i;
1153
1154 for (i=0; i < NB_VDARGS; i++) {
1155 // Only the lower half of the vdarg doubleword arg will be used as input by mtvsrwa
1156 unsigned int * src = (unsigned int *)&vdargs[i];
1157 src++;
1158 r14 = vdargs[i];
1159 vec_out = (vector unsigned long long){ 0ULL, 0ULL };
1160
1161 (*func)();
1162 // Only doubleword 0 is used in output
1163 dst = (unsigned long long *) &vec_out;
1164 printf("%s: %08x => %016llx\n", name, *src, *dst);
1165 }
1166 }
1167
test_special(special_t * table,const char * name,test_func_t func,unused uint32_t test_flags)1168 static void test_special (special_t *table,
1169 const char* name, test_func_t func,
1170 unused uint32_t test_flags)
1171 {
1172 const char *tmp;
1173 int i;
1174
1175 for (tmp = name; isspace(*tmp); tmp++)
1176 continue;
1177 for (i=0; table[i].name != NULL; i++) {
1178 if (strcmp(table[i].name, tmp) == 0) {
1179 (*table[i].test_cb)(name, func, test_flags);
1180 return;
1181 }
1182 }
1183 fprintf(stderr, "ERROR: no test found for op '%s'\n", name);
1184 }
1185
1186 static special_t special_move_ops[] = {
1187 {
1188 "mfvsrd", /* move from vector to scalar reg doubleword */
1189 &mfvs,
1190 },
1191 {
1192 "mtvsrd", /* move from scalar to vector reg doubleword */
1193 &mtvs,
1194 },
1195 {
1196 "mtfprwa", /* (extended mnemonic for mtvsrwa) move from scalar to vector reg with two’s-complement */
1197 &mtvs2s,
1198 },
1199 {
1200 "mfvsrwz", /* move from vector to scalar reg word */
1201 &mfvs,
1202 },
1203 {
1204 "mtvsrwz", /* move from scalar to vector reg word */
1205 &mtvs2s,
1206 }
1207 };
1208
test_move_special(const char * name,test_func_t func,uint32_t test_flags)1209 static void test_move_special(const char* name, test_func_t func,
1210 uint32_t test_flags)
1211 {
1212 test_special(special_move_ops, name, func, test_flags);
1213 }
1214
1215 /* Vector Double Word tests */
1216
test_av_dint_two_args(const char * name,test_func_t func,unused uint32_t test_flags)1217 static void test_av_dint_two_args (const char* name, test_func_t func,
1218 unused uint32_t test_flags)
1219 {
1220
1221 unsigned long long * dst;
1222 unsigned int * dst_int;
1223 int i,j;
1224 int family = test_flags & PPC_FAMILY;
1225 int is_vpkudum;
1226 if (strcmp(name, "vpkudum") == 0)
1227 is_vpkudum = 1;
1228 else
1229 is_vpkudum = 0;
1230
1231 for (i = 0; i < NB_VDARGS; i+=2) {
1232 vec_inA = (vector unsigned long long){ vdargs[i], vdargs[i+1] };
1233 for (j = 0; j < NB_VDARGS; j+=2) {
1234 vec_inB = (vector unsigned long long){ vdargs[j], vdargs[j+1] };
1235 vec_out = (vector unsigned long long){ 0,0 };
1236
1237 (*func)();
1238 dst_int = (unsigned int *)&vec_out;
1239 dst = (unsigned long long*)&vec_out;
1240
1241 printf("%s: ", name);
1242
1243 if (is_vpkudum) {
1244 printf("Inputs: %08llx %08llx %08llx %08llx\n", vdargs[i] & 0x00000000ffffffffULL,
1245 vdargs[i+1] & 0x00000000ffffffffULL, vdargs[j] & 0x00000000ffffffffULL,
1246 vdargs[j+1] & 0x00000000ffffffffULL);
1247 printf(" Output: %08x %08x %08x %08x\n", dst_int[0], dst_int[1],
1248 dst_int[2], dst_int[3]);
1249 } else if (family == PPC_ALTIVECQ) {
1250 printf("%016llx%016llx @@ %016llx%016llx ==> %016llx%016llx\n",
1251 vdargs[i], vdargs[i+1], vdargs[j], vdargs[j+1],
1252 dst[0], dst[1]);
1253 } else {
1254 printf("%016llx @@ %016llx ", vdargs[i], vdargs[j]);
1255 printf(" ==> %016llx\n", dst[0]);
1256 printf("\t%016llx @@ %016llx ", vdargs[i+1], vdargs[j+1]);
1257 printf(" ==> %016llx\n", dst[1]);
1258 }
1259 }
1260 }
1261 }
1262
test_av_dint_one_arg(const char * name,test_func_t func,unused uint32_t test_flags)1263 static void test_av_dint_one_arg (const char* name, test_func_t func,
1264 unused uint32_t test_flags)
1265 {
1266
1267 unsigned long long * dst;
1268 int i;
1269
1270 for (i = 0; i < NB_VDARGS; i+=2) {
1271 vec_inB = (vector unsigned long long){ vdargs[i], vdargs[i+1] };
1272 vec_out = (vector unsigned long long){ 0,0 };
1273
1274 (*func)();
1275 dst = (unsigned long long*)&vec_out;
1276
1277 printf("%s: ", name);
1278 printf("%016llx @@ %016llx ", vdargs[i], vdargs[i + 1]);
1279 printf(" ==> %016llx%016llx\n", dst[0], dst[1]);
1280 }
1281 }
1282
test_av_dint_one_arg_SHA(const char * name,test_func_t func,unused uint32_t test_flags)1283 static void test_av_dint_one_arg_SHA (const char* name, test_func_t func,
1284 unused uint32_t test_flags)
1285 {
1286 unsigned long long * dst;
1287 int i, st, six;
1288
1289 for (i = 0; i < NB_VDARGS; i+=2) {
1290 vec_inA = (vector unsigned long long){ vdargs[i], vdargs[i+1] };
1291 vec_out = (vector unsigned long long){ 0,0 };
1292
1293 for (st = 0; st < 2; st++) {
1294 for (six = 0; six < 16; six+=15) {
1295 st_six = (st << 4) | six;
1296 (*func)();
1297 dst = (unsigned long long*)&vec_out;
1298
1299 printf("%s: ", name);
1300 printf("%016llx @@ %016llx ", vdargs[i], vdargs[i + 1]);
1301 printf(" ==> %016llx || %016llx\n", dst[0], dst[1]);
1302 }
1303 }
1304 }
1305 }
1306
test_av_bcd(const char * name,test_func_t func,unused uint32_t test_flags)1307 static void test_av_bcd (const char* name, test_func_t func,
1308 unused uint32_t test_flags)
1309 {
1310 unsigned long long * dst;
1311 int i, j;
1312
1313 for (i = 0; i < NUM_VBCD_VALS; i+=2) {
1314 vec_inA = (vector unsigned long long){ vbcd_args[i], vbcd_args[i +1 ] };
1315 for (j = 0; j < NUM_VBCD_VALS; j+=2) {
1316 vec_inB = (vector unsigned long long){ vbcd_args[j], vbcd_args[j +1 ] };
1317 vec_out = (vector unsigned long long){ 0, 0 };
1318
1319 for (PS_bit = 0; PS_bit < 2; PS_bit++) {
1320 (*func)();
1321 dst = (unsigned long long*)&vec_out;
1322 printf("%s: ", name);
1323 printf("%016llx || %016llx @@ %016llx || %016llx",
1324 vbcd_args[i], vbcd_args[i + 1],
1325 vbcd_args[j], vbcd_args[j + 1]);
1326 printf(" ==> %016llx || %016llx\n", dst[0], dst[1]);
1327 }
1328 }
1329 }
1330 }
1331
1332 /* Vector doubleword-to-int tests, two input args, integer result */
test_av_dint_to_int_two_args(const char * name,test_func_t func,unused uint32_t test_flags)1333 static void test_av_dint_to_int_two_args (const char* name, test_func_t func,
1334 unused uint32_t test_flags)
1335 {
1336
1337 unsigned int * dst_int;
1338 int i,j;
1339 for (i = 0; i < NB_VDARGS; i+=2) {
1340 vec_inA = (vector unsigned long long){ vdargs_x[i], vdargs_x[i+1] };
1341 for (j = 0; j < NB_VDARGS; j+=2) {
1342 vec_inB = (vector unsigned long long){ vdargs_x[j], vdargs_x[j+1] };
1343 vec_out = (vector unsigned long long){ 0,0 };
1344
1345 (*func)();
1346 dst_int = (unsigned int *)&vec_out;
1347
1348 printf("%s: ", name);
1349 printf("%016llx, %016llx @@ %016llx, %016llx ",
1350 vdargs_x[i], vdargs_x[i+1],
1351 vdargs_x[j], vdargs_x[j+1]);
1352 printf(" ==> %08x %08x %08x %08x\n", dst_int[0], dst_int[1],
1353 dst_int[2], dst_int[3]);
1354 }
1355 }
1356 }
1357
1358 /* Vector Word tests; two integer args, with double word result */
1359
test_av_wint_two_args_dres(const char * name,test_func_t func,unused uint32_t test_flags)1360 static void test_av_wint_two_args_dres (const char* name, test_func_t func,
1361 unused uint32_t test_flags)
1362 {
1363
1364 unsigned long long * dst;
1365 int i,j;
1366
1367 for (i = 0; i < NB_VWARGS; i+=4) {
1368 vec_inA_wd = (vector unsigned int){ vwargs[i], vwargs[i+1], vwargs[i+2], vwargs[i+3] };
1369 for (j = 0; j < NB_VWARGS; j+=4) {
1370 vec_inB_wd = (vector unsigned int){ vwargs[j], vwargs[j+1], vwargs[j+2], vwargs[j+3] };
1371 vec_out = (vector unsigned long long){ 0, 0 };
1372
1373 (*func)();
1374 dst = (unsigned long long *)&vec_out;
1375 printf("%s: ", name);
1376 printf("%08x %08x %08x %08x ==> %016llx %016llx\n",
1377 vwargs[i], vwargs[i+1], vwargs[i+2], vwargs[i+3], dst[0], dst[1]);
1378 }
1379 }
1380 }
1381
1382 /* Vector Word tests; one input arg, with double word result */
1383
test_av_wint_one_arg_dres(const char * name,test_func_t func,unused uint32_t test_flags)1384 static void test_av_wint_one_arg_dres (const char* name, test_func_t func,
1385 unused uint32_t test_flags)
1386 {
1387 unsigned long long * dst;
1388 int i;
1389 for (i = 0; i < NB_VWARGS; i+=4) {
1390 vec_inB_wd = (vector unsigned int){ vwargs[i], vwargs[i+1], vwargs[i+2], vwargs[i+3] };
1391 vec_out = (vector unsigned long long){ 0, 0 };
1392
1393 (*func)();
1394 dst = (unsigned long long *)&vec_out;
1395 printf("%s: ", name);
1396 printf("%08x %08x %08x %08x ==> %016llx %016llx\n",
1397 vwargs[i], vwargs[i+1], vwargs[i+2], vwargs[i+3], dst[0], dst[1]);
1398 }
1399 }
1400
1401
test_int_stq_two_regs_imm16(const char * name,test_func_t func_IN,unused uint32_t test_flags)1402 static void test_int_stq_two_regs_imm16 (const char* name,
1403 test_func_t func_IN,
1404 unused uint32_t test_flags)
1405 {
1406 /* Store quad word from register pair */
1407 int offs, k;
1408 HWord_t base;
1409 Word_t *iargs_priv;
1410
1411 // private iargs table to store to, note storing pair of regs
1412 iargs_priv = memalign16(2 * sizeof(Word_t));
1413
1414 base = (HWord_t)&iargs_priv[0];
1415 for (k = 0; k < 2; k++) // clear array
1416 iargs_priv[k] = 0;
1417
1418 offs = 0;
1419
1420 /* setup source register pair */
1421 r14 = (HWord_t) 0xABCDEF0123456789ULL;
1422 r15 = (HWord_t) 0x1133557722446688ULL;
1423
1424 r16 = base; // store to r16 + offs
1425
1426 (*func_IN)();
1427
1428 #ifndef __powerpc64__
1429 printf("%s %08x,%08x, %2d => "
1430 #else
1431 printf("%s %016llx,%016llx, %3d => "
1432 #endif
1433 "%016llx,%016llx)\n",
1434 name, r14, r15, offs, iargs_priv[0], iargs_priv[1]);
1435
1436 if (verbose) printf("\n");
1437 free(iargs_priv);
1438 }
1439
1440
test_int_stq_three_regs(const char * name,test_func_t func_IN,unused uint32_t test_flags)1441 static void test_int_stq_three_regs (const char* name,
1442 test_func_t func_IN,
1443 unused uint32_t test_flags)
1444 {
1445 /* Store quad word from register pair */
1446 volatile uint32_t flags, xer;
1447 int k;
1448 HWord_t base;
1449
1450 base = (HWord_t)&mem_resv[0];
1451 for (k = 0; k < 2; k++) // setup array for lqarx inst
1452 mem_resv[k] = k;
1453
1454 /* setup source register pair for store */
1455 r14 = ZERO;
1456 r15 = ZERO;
1457 r16 = base; // store to r16 + r17
1458 r17 = ZERO;
1459
1460 /* In order for the store to occur, the lqarx instruction must first
1461 * be used to load from the address thus creating a reservation at the
1462 * memory address. The lqarx instruction is done in the test_stqcx(),
1463 * then registers 14, r15 are changed to the data to be stored in memory
1464 * by the stqcx instruction.
1465 */
1466 SET_CR_XER_ZERO;
1467 (*func_IN)();
1468 GET_CR_XER(flags,xer);
1469 #ifndef __powerpc64__
1470 printf("%s %08x,%08x, => "
1471 #else
1472 printf("%s %016llx,%016llx => "
1473 #endif
1474 "%016llx,%016llx; CR=%08x\n",
1475 name, r14, r15, mem_resv[0], mem_resv[1], flags);
1476
1477 if (verbose) printf("\n");
1478 }
1479
test_int_ldq_two_regs_imm16(const char * name,test_func_t func_IN,unused uint32_t test_flags)1480 static void test_int_ldq_two_regs_imm16 (const char* name,
1481 test_func_t func_IN,
1482 unused uint32_t test_flags)
1483 {
1484 /* load quad word from register pair */
1485 volatile uint32_t flags, xer;
1486 Word_t * mem_priv;
1487 HWord_t base;
1488
1489 // private iargs table to store to, note storing pair of regs
1490 mem_priv = memalign16(2 * sizeof(Word_t)); // want 128-bits
1491
1492 base = (HWord_t)&mem_priv[0];
1493
1494 mem_priv[0] = 0xAACCEE0011335577ULL;
1495 mem_priv[1] = 0xABCDEF0123456789ULL;
1496
1497 r14 = 0;
1498 r15 = 0;
1499 r16 = base; // fetch from r16 + offs
1500 SET_CR_XER_ZERO;
1501 (*func_IN)();
1502 GET_CR_XER(flags,xer);
1503
1504 #ifndef __powerpc64__
1505 printf("%s (0x%016llx, 0x%016llx) => (reg_pair = %08x,%08x)\n",
1506 #else
1507 printf("%s (0x%016llx, 0x%016llx) => (reg_pair = 0x%016llx, 0x%016llx)\n",
1508 #endif
1509 name, mem_priv[0], mem_priv[1], r14, r15);
1510
1511 if (verbose) printf("\n");
1512
1513 free(mem_priv);
1514 }
1515
test_int_ldq_three_regs(const char * name,test_func_t func_IN,unused uint32_t test_flags)1516 static void test_int_ldq_three_regs (const char* name,
1517 test_func_t func_IN,
1518 unused uint32_t test_flags)
1519 {
1520 /* load quad word from register pair */
1521 HWord_t base;
1522
1523 base = (HWord_t)&mem_resv[0];
1524
1525 mem_resv[0] = 0xAACCEE0011335577ULL;
1526 mem_resv[1] = 0xABCDEF0123456789ULL;
1527
1528 r14 = 0;
1529 r15 = 0;
1530 r16 = base; // fetch from r16 + r17
1531 r17 = 0;
1532
1533 (*func_IN)();
1534
1535 #ifndef __powerpc64__
1536 printf("%s (0x%016llx, 0x%016llx) => (reg_pair = 0x%08x, 0x%08x)\n",
1537 #else
1538 printf("%s (0x%016llx, 0x%016llx) => (reg_pair = 0x%016llx, 0x%016llx)\n",
1539 #endif
1540 name, mem_resv[0], mem_resv[1], r14, r15);
1541 if (verbose) printf("\n");
1542
1543 }
1544
test_av_dint_three_args(const char * name,test_func_t func,unused uint32_t test_flags)1545 static void test_av_dint_three_args (const char* name, test_func_t func,
1546 unused uint32_t test_flags)
1547 {
1548
1549 unsigned long long * dst;
1550 int i,j, k;
1551 int family = test_flags & PPC_FAMILY;
1552 unsigned long long cin_vals[] = {
1553 // First pair of ULLs have LSB=0, so cin is '0'.
1554 // Second pair of ULLs have LSB=1, so cin is '1'.
1555 0xf000000000000000ULL, 0xf000000000000000ULL,
1556 0xf000000000000000ULL, 0xf000000000000001ULL
1557 };
1558 for (i = 0; i < NB_VDARGS; i+=2) {
1559 vec_inA = (vector unsigned long long){ vdargs[i], vdargs[i+1] };
1560 for (j = 0; j < NB_VDARGS; j+=2) {
1561 vec_inB = (vector unsigned long long){ vdargs[j], vdargs[j+1] };
1562 for (k = 0; k < 4; k+=2) {
1563 if (family == PPC_ALTIVECQ)
1564 vec_inC = (vector unsigned long long){ cin_vals[k], cin_vals[k+1] };
1565 else
1566 vec_inC = (vector unsigned long long){ vdargs[k], vdargs[k+1] };
1567 vec_out = (vector unsigned long long){ 0,0 };
1568
1569 (*func)();
1570 dst = (unsigned long long*)&vec_out;
1571 printf("%s: ", name);
1572 if (family == PPC_ALTIVECQ) {
1573 printf("%016llx%016llx @@ %016llx%016llx @@ %llx ==> %016llx%016llx\n",
1574 vdargs[i], vdargs[i+1], vdargs[j], vdargs[j+1], cin_vals[k+1],
1575 dst[0], dst[1]);
1576 } else {
1577 printf("%016llx @@ %016llx @@ %016llx ", vdargs[i], vdargs[j], vdargs[k]);
1578 printf(" ==> %016llx\n", dst[0]);
1579 printf("\t%016llx @@ %016llx @@ %016llx ", vdargs[i+1], vdargs[j+1], vdargs[k+1]);
1580 printf(" ==> %016llx\n", dst[1]);
1581 }
1582 }
1583 }
1584 }
1585 }
1586
1587
1588 /* The ALTIVEC_LOOPS and altive_loops defined below are used in do_tests.
1589 * Add new values to the end; do not change order, since the altivec_loops
1590 * array is indexed using the enumerated values defined by ALTIVEC_LOOPS.
1591 */
1592 enum ALTIVEC_LOOPS {
1593 ALTV_MOV,
1594 ALTV_DINT,
1595 ALTV_INT_DRES,
1596 ALTV_DINT_IRES,
1597 ALTV_ONE_INT_DRES,
1598 ALTV_DINT_THREE_ARGS,
1599 ALTV_DINT_ONE_ARG,
1600 ALTV_SHA,
1601 ATLV_BCD
1602 };
1603
1604 static test_loop_t altivec_loops[] = {
1605 &test_move_special,
1606 &test_av_dint_two_args,
1607 &test_av_wint_two_args_dres,
1608 &test_av_dint_to_int_two_args,
1609 &test_av_wint_one_arg_dres,
1610 &test_av_dint_three_args,
1611 &test_av_dint_one_arg,
1612 &test_av_dint_one_arg_SHA,
1613 &test_av_bcd,
1614 NULL
1615 };
1616
1617 /* Used in do_tests, indexed by flags->nb_args
1618 Elements correspond to enum test_flags::num args
1619 */
1620 static test_loop_t int_loops[] = {
1621 /* The #defines for the family, number registers need the array
1622 * to be properly indexed. This test is for the new ISA 2.0.7
1623 * instructions. The infrastructure has been left for the momemnt
1624 */
1625 NULL, //&test_int_one_arg,
1626 NULL, //&test_int_two_args,
1627 NULL, //&test_int_three_args,
1628 NULL, //&test_int_two_args,
1629 NULL, //&test_int_one_reg_imm16,
1630 NULL, //&test_int_one_reg_imm16,
1631 NULL, //&test_int_special,
1632 NULL, //&test_int_ld_one_reg_imm16,
1633 NULL, //&test_int_ld_two_regs,
1634 NULL, //&test_int_st_two_regs_imm16,
1635 NULL, //&test_int_st_three_regs,
1636 &test_int_stq_two_regs_imm16,
1637 &test_int_ldq_two_regs_imm16,
1638 &test_int_stq_three_regs,
1639 &test_int_ldq_three_regs,
1640 };
1641
1642 /* Used in do_tests, indexed by flags->nb_args
1643 Elements correspond to enum test_flags::num args
1644 Must have NULL for last entry.
1645 */
1646 static test_loop_t float_loops[] = {
1647 NULL,
1648 &test_float_two_args,
1649 };
1650
1651
1652 static test_t tests_fa_ops_two[] = {
1653 { &test_fmrgew , "fmrgew", },
1654 { &test_fmrgow , "fmrgow", },
1655 { NULL, NULL, },
1656 };
1657
1658 static test_table_t all_tests[] = {
1659 {
1660 tests_move_ops_spe,
1661 "PPC VSR special move insns",
1662 PPC_ALTIVECD | PPC_MOV | PPC_ONE_ARG,
1663 },
1664 {
1665 tests_aa_dbl_ops_two_args,
1666 "PPC altivec double word integer insns (arith, compare) with two args",
1667 PPC_ALTIVECD | PPC_ARITH | PPC_TWO_ARGS,
1668 },
1669 {
1670 tests_aa_word_ops_two_args_dres,
1671 "PPC altivec integer word instructions with two input args, double word result",
1672 PPC_ALTIVEC | PPC_ARITH_DRES | PPC_TWO_ARGS,
1673 },
1674 {
1675 tests_aa_dbl_to_int_two_args,
1676 "PPC altivec doubleword-to-integer instructions with two input args, saturated integer result",
1677 PPC_ALTIVECD | PPC_DOUBLE_IN_IRES | PPC_TWO_ARGS,
1678 },
1679 {
1680 tests_aa_word_ops_one_arg_dres,
1681 "PPC altivec integer word instructions with one input arg, double word result",
1682 PPC_ALTIVEC | PPC_ARITH_DRES | PPC_ONE_ARG,
1683 },
1684 {
1685 tests_istq_ops_two_i16,
1686 "PPC store quadword insns\n with one register + one 16 bits immediate args with flags update",
1687 0x0001050c,
1688 },
1689 {
1690 tests_ildq_ops_two_i16,
1691 "PPC load quadword insns\n with one register + one 16 bits immediate args with flags update",
1692 0x0001050d,
1693 },
1694 {
1695 tests_ldq_ops_three,
1696 "PPC load quadword insns\n with three register args",
1697 0x0001050f,
1698 },
1699 {
1700 tests_stq_ops_three,
1701 "PPC store quadword insns\n with three register args",
1702 0x0001050e,
1703 },
1704 {
1705 tests_fa_ops_two,
1706 "PPC floating point arith insns with two args",
1707 0x00020102,
1708 },
1709 {
1710 tests_aa_ops_three ,
1711 "PPC altivec integer logical insns with three args",
1712 0x00060203,
1713 },
1714 {
1715 tests_aa_dbl_ops_one_arg,
1716 "PPC altivec one vector input arg, hex result",
1717 0x00060201,
1718 },
1719 {
1720 tests_aa_SHA_ops,
1721 "PPC altivec SSH insns",
1722 0x00040B01,
1723 },
1724 {
1725 tests_aa_bcd_ops,
1726 "PPC altivec BCD insns",
1727 0x00040B02,
1728 },
1729 {
1730 tests_aa_quadword_two_args,
1731 "PPC altivec quadword insns, two input args",
1732 0x00070102,
1733 },
1734 {
1735 tests_aa_quadword_three_args,
1736 "PPC altivec quadword insns, three input args",
1737 0x00070103
1738 },
1739 { NULL, NULL, 0x00000000, },
1740 };
1741
do_tests(insn_sel_flags_t seln_flags,char * filter)1742 static void do_tests ( insn_sel_flags_t seln_flags,
1743 char *filter)
1744 {
1745 test_loop_t *loop;
1746 test_t *tests;
1747 int nb_args, type, family;
1748 int i, j, n;
1749 int exact;
1750
1751 exact = check_filter(filter);
1752 n = 0;
1753 for (i=0; all_tests[i].name != NULL; i++) {
1754 nb_args = all_tests[i].flags & PPC_NB_ARGS;
1755
1756 /* Check number of arguments */
1757 if ((nb_args == 1 && !seln_flags.one_arg) ||
1758 (nb_args == 2 && !seln_flags.two_args) ||
1759 (nb_args == 3 && !seln_flags.three_args)){
1760 continue;
1761 }
1762 /* Check instruction type */
1763 type = all_tests[i].flags & PPC_TYPE;
1764 if ((type == PPC_ARITH && !seln_flags.arith) ||
1765 (type == PPC_LOGICAL && !seln_flags.logical) ||
1766 (type == PPC_COMPARE && !seln_flags.compare) ||
1767 (type == PPC_LDST && !seln_flags.ldst) ||
1768 (type == PPC_MOV && !seln_flags.ldst) ||
1769 (type == PPC_POPCNT && !seln_flags.arith)) {
1770 continue;
1771 }
1772
1773 /* Check instruction family */
1774 family = all_tests[i].flags & PPC_FAMILY;
1775 if ((family == PPC_INTEGER && !seln_flags.integer) ||
1776 (family == PPC_FLOAT && !seln_flags.floats) ||
1777 (family == PPC_ALTIVEC && !seln_flags.altivec) ||
1778 (family == PPC_ALTIVECD && !seln_flags.altivec) ||
1779 (family == PPC_ALTIVECQ && !seln_flags.altivec) ||
1780 (family == PPC_FALTIVEC && !seln_flags.faltivec)) {
1781 continue;
1782 }
1783 /* Check flags update */
1784 if (((all_tests[i].flags & PPC_CR) && seln_flags.cr == 0) ||
1785 (!(all_tests[i].flags & PPC_CR) && seln_flags.cr == 1))
1786 continue;
1787
1788 /* All passed, do the tests */
1789 tests = all_tests[i].tests;
1790
1791 loop = NULL;
1792
1793 /* Select the test loop */
1794 switch (family) {
1795 case PPC_INTEGER:
1796 mem_resv = memalign16(2 * sizeof(HWord_t)); // want 128-bits
1797 loop = &int_loops[nb_args - 1];
1798 break;
1799
1800 case PPC_FLOAT:
1801 loop = &float_loops[nb_args - 1];
1802 break;
1803
1804 case PPC_ALTIVECQ:
1805 if (nb_args == 2)
1806 loop = &altivec_loops[ALTV_DINT];
1807 else if (nb_args == 3)
1808 loop = &altivec_loops[ALTV_DINT_THREE_ARGS];
1809 break;
1810 case PPC_ALTIVECD:
1811 switch (type) {
1812 case PPC_MOV:
1813 loop = &altivec_loops[ALTV_MOV];
1814 break;
1815 case PPC_ARITH:
1816 loop = &altivec_loops[ALTV_DINT];
1817 break;
1818 case PPC_DOUBLE_IN_IRES:
1819 loop = &altivec_loops[ALTV_DINT_IRES];
1820 break;
1821 case PPC_LOGICAL:
1822 if (nb_args == 3)
1823 loop = &altivec_loops[ALTV_DINT_THREE_ARGS];
1824 else if (nb_args ==1)
1825 loop = &altivec_loops[ALTV_DINT_ONE_ARG];
1826 break;
1827 default:
1828 printf("No altivec test defined for type %x\n", type);
1829 }
1830 break;
1831
1832 case PPC_FALTIVEC:
1833 printf("Currently there are no floating altivec tests in this testsuite.\n");
1834 break;
1835
1836 case PPC_ALTIVEC:
1837 switch (type) {
1838 case PPC_ARITH_DRES:
1839 {
1840 switch (nb_args) {
1841 case 1:
1842 loop = &altivec_loops[ALTV_ONE_INT_DRES];
1843 break;
1844 case 2:
1845 loop = &altivec_loops[ALTV_INT_DRES];
1846 break;
1847 default:
1848 printf("No altivec test defined for number args %d\n", nb_args);
1849 }
1850 break;
1851 }
1852 case PPC_SHA_OR_BCD:
1853 if (nb_args == 1)
1854 loop = &altivec_loops[ALTV_SHA];
1855 else
1856 loop = &altivec_loops[ATLV_BCD];
1857 break;
1858 default:
1859 printf("No altivec test defined for type %x\n", type);
1860 }
1861 break;
1862
1863 default:
1864 printf("ERROR: unknown insn family %08x\n", family);
1865 continue;
1866 }
1867 if (1 || verbose > 0)
1868 for (j=0; tests[j].name != NULL; j++) {
1869 if (check_name(tests[j].name, filter, exact)) {
1870 if (verbose > 1)
1871 printf("Test instruction %s\n", tests[j].name);
1872 if (loop != NULL)
1873 (*loop)(tests[j].name, tests[j].func, all_tests[i].flags);
1874 printf("\n");
1875 n++;
1876 }
1877 }
1878 if (verbose) printf("\n");
1879 }
1880 printf("All done. Tested %d different instructions\n", n);
1881 }
1882
1883
usage(void)1884 static void usage (void)
1885 {
1886 fprintf(stderr,
1887 "Usage: jm-insns [OPTION]\n"
1888 "\t-i: test integer instructions (default)\n"
1889 "\t-f: test floating point instructions\n"
1890 "\t-a: test altivec instructions\n"
1891 "\t-A: test all (int, fp, altivec) instructions\n"
1892 "\t-v: be verbose\n"
1893 "\t-h: display this help and exit\n"
1894 );
1895 }
1896
1897 #endif
1898
main(int argc,char ** argv)1899 int main (int argc, char **argv)
1900 {
1901 #ifdef HAS_ISA_2_07
1902 /* Simple usage:
1903 ./jm-insns -i => int insns
1904 ./jm-insns -f => fp insns
1905 ./jm-insns -a => av insns
1906 ./jm-insns -A => int, fp and avinsns
1907 */
1908 char *filter = NULL;
1909 insn_sel_flags_t flags;
1910 int c;
1911
1912 // Args
1913 flags.one_arg = 1;
1914 flags.two_args = 1;
1915 flags.three_args = 1;
1916 // Type
1917 flags.arith = 1;
1918 flags.logical = 1;
1919 flags.compare = 1;
1920 flags.ldst = 1;
1921 // Family
1922 flags.integer = 0;
1923 flags.floats = 0;
1924 flags.altivec = 0;
1925 flags.faltivec = 0;
1926 // Flags
1927 flags.cr = 2;
1928
1929 while ((c = getopt(argc, argv, "ifahvA")) != -1) {
1930 switch (c) {
1931 case 'i':
1932 flags.integer = 1;
1933 break;
1934 case 'f':
1935 build_fargs_table();
1936 flags.floats = 1;
1937 break;
1938 case 'a':
1939 flags.altivec = 1;
1940 flags.faltivec = 1;
1941 break;
1942 case 'A':
1943 flags.integer = 1;
1944 flags.floats = 1;
1945 flags.altivec = 1;
1946 flags.faltivec = 1;
1947 break;
1948 case 'h':
1949 usage();
1950 return 0;
1951 case 'v':
1952 verbose++;
1953 break;
1954 default:
1955 usage();
1956 fprintf(stderr, "Unknown argument: '%c'\n", c);
1957 return 1;
1958 }
1959 }
1960
1961 arg_list_size = 0;
1962
1963 build_vargs_table();
1964 if (verbose > 1) {
1965 printf("\nInstruction Selection:\n");
1966 printf(" n_args: \n");
1967 printf(" one_arg = %d\n", flags.one_arg);
1968 printf(" two_args = %d\n", flags.two_args);
1969 printf(" three_args = %d\n", flags.three_args);
1970 printf(" type: \n");
1971 printf(" arith = %d\n", flags.arith);
1972 printf(" logical = %d\n", flags.logical);
1973 printf(" compare = %d\n", flags.compare);
1974 printf(" ldst = %d\n", flags.ldst);
1975 printf(" family: \n");
1976 printf(" integer = %d\n", flags.integer);
1977 printf(" floats = %d\n", flags.floats);
1978 printf(" altivec = %d\n", flags.altivec);
1979 printf(" faltivec = %d\n", flags.faltivec);
1980 printf(" cr update: \n");
1981 printf(" cr = %d\n", flags.cr);
1982 printf("\n");
1983 }
1984
1985 do_tests( flags, filter );
1986 #else
1987 printf("NO ISA 2.07 SUPPORT\n");
1988 #endif
1989 return 0;
1990 }
1991