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