Bug 497723 - forgot to restore callgrind output cleanup
[valgrind.git] / none / tests / ppc64 / test_isa_3_0.c
blob6eca370a39cc14edc233dd631c4a52be42274a8d
1 /* HOW TO COMPILE:
2 * 64bit build:
3 * gcc -Winline -Wall -g -O -mregnames -maltivec -m64
4 */
6 /*
7 * test_isa_3_0.c:
8 * Copyright (C) 2016-2017 Carl Love <cel@us.ibm.com>
9 * Copyright (C) 2016-2017 Will Schmidt <will_schmidt@vnet.ibm.com>
11 * This testfile contains tests for the ISA 3.0 instructions.
12 * The framework of this test file was based on the framework
13 * of the jm-insns.c testfile, whose original author was
14 * Jocelyn Mayer.
18 * This program is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License V2
20 * as published by the Free Software Foundation
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, see <http://www.gnu.org/licenses/>.
32 * Theory of operations:
33 * a few registers are reserved for the test program:
34 * r14...r18
35 * f14...f18
36 * - pre-load test values in r14 through r17
37 * - patch the test opcode if any immediate operands are
38 * required
39 * - execute the tested opcode.
40 * CR and FPSCR are cleared before every test.
41 * results in {r,f}17
42 * check FPSCR for floating point operations.
46 * Operation details
47 * -----------------
48 * The 'test' functions (via all_tests[]) are wrappers of
49 * single __asm__ instructions
51 * The 'loops' (e.g. int_loops) do the actual work:
52 * - loops over as many arguments as the instruction needs (regs | imms)
53 * - sets up the environment (reset cr, assign src regs...)
54 * - maybe modifies the asm instruction to test different immediate args
55 * - call the test function
56 * - retrieve relevant register data (rD,cr,...)
57 * - prints argument and result data.
59 * all_tests[i] holds instruction tests
60 * - of which each holds: {instn_test_arr[], description, flags}
62 * flags hold 3 instruction classifiers: {family, type, arg_type}
64 * // The main test loop:
65 * do_tests( user_ctl_flags ) {
66 * foreach(curr_test = all_test[i]) {
68 * // flags are used to control what tests are run:
69 * if (curr_test->flags && !user_ctl_flags)
70 * continue;
72 * // a 'loop_family_arr' is chosen based on the 'family' flag...
73 * switch(curr_test->flags->family) {
74 * case x: loop_family_arr = int_loops;
75 * ...
76 * }
78 * // ...and the actual test_loop to run is found by indexing into
79 * // the loop_family_arr with the 'arg_type' flag:
80 * test_loop = loop_family[curr_test->flags->arg_type]
82 * // finally, loop over all instn tests for this test:
83 * foreach (instn_test = curr_test->instn_test_arr[i]) {
85 * // and call the test_loop with the current instn_test function,name
86 * test_loop( instn_test->func, instn_test->name )
87 * }
88 * }
89 * }
92 #include <stdio.h>
93 #include <stdint.h>
95 /* This test is only valid on machines that support IBM POWER ISA 3.0. */
96 #ifdef HAS_ISA_3_00
98 #include <assert.h>
99 #include <ctype.h> // isspace
100 #include <stdlib.h>
101 #include <string.h>
102 #include <unistd.h> // getopt
103 #include <altivec.h> // vector
105 #undef DEBUG_VECTOR_PERMUTE
106 static int verbose = 0;
108 #include "../ppc64/ppc64_helpers.h" // SET_CR() and friends.
110 #define VERBOSE_FUNCTION_CALLOUT \
111 if (verbose) \
112 printf("Test Harness Function: %s\n", __FUNCTION__);
114 /* generic out-of-range reporting.
115 * Note: results are typically 'undefined' in these cases, so rather than
116 * pushing through and getting potentially random results, avoid the check.
117 * The caller should suppress output when insert_extract_error is set. */
118 #define vinsertextract_err \
119 insert_extract_error = 1; \
120 if (verbose > 1) \
121 printf("Expected error - index out of range in %s (%d)\n", \
122 __FUNCTION__, x_index);
124 #define MAX(x, y) (x > y ? x : y)
126 /* Used in do_tests, indexed by flags->nb_args
127 Elements correspond to enum test_flags::num args
130 /* XXXX these must all be callee-save regs! */
131 register HWord_t r14 __asm__ ("r14");
132 register HWord_t r15 __asm__ ("r15");
133 register HWord_t r16 __asm__ ("r16");
134 register HWord_t r17 __asm__ ("r17");
135 register double f14 __asm__ ("fr14");
136 register double f15 __asm__ ("fr15");
138 /* globals used for vector tests */
139 static vector unsigned long vec_xa, vec_xb, vec_xc, vec_xt;
141 /* globals for the condition register fields. These are used to
142 * capture the condition register values immediately after the
143 * instruction under test is tested.
144 * This is to help prevent other test overhead, switch statements,
145 * compares, what-not from interfering.
147 unsigned long local_cr;
148 unsigned long local_fpscr;
149 unsigned long local_xer;
150 volatile unsigned int cr_value;
152 /* global for holding the DFP values */
153 dfp_val_t dfp_value;
155 /* individual instruction tests */
156 typedef void (*test_func_t) (void);
157 struct test_list_t {
158 test_func_t func;
159 const char *name;
161 typedef struct test_list_t test_list_t;
163 /* global variable, used to pass shift info down to the test functions.*/
164 volatile int x_shift;
166 /* Indicator for DCMX (Data Class Mask) matches. */
167 volatile int dcmx_match;
169 /* Error indicator to determine of the UIN (Unsigned Immediate) field
170 * from insert/extract was out of range */
171 volatile int insert_extract_error;
173 /* vector splat value */
174 volatile int x_splat;
175 volatile int dfp_significance;
177 /* global variable, ... vector insert functions. */
178 volatile int x_index;
180 /* global variable, used to pass shift info down to the test functions.*/
181 /* Also used to control DRM,RM values for mffs* functions. */
182 volatile int x_shift;
184 /* groups of instruction tests, calling individual tests */
185 typedef void (*test_group_t) (const char *name, test_func_t func,
186 unsigned int test_flags);
188 enum test_flags {
189 /* Nb arguments */
190 PPC_ONE_ARG = 0x00000001,
191 PPC_TWO_ARGS = 0x00000002,
192 PPC_THREE_ARGS = 0x00000003,
193 PPC_FOUR_ARGS = 0x00000004,
194 PPC_COMPARE_ARGS = 0x00000005,
195 PPC_LD_ARGS = 0x00000006,
196 PPC_ST_ARGS = 0x00000007,
197 PPC_ONE_IMM = 0x00000008,
198 PPC_ONE_GPR_ONE_VEC = 0x00000009,
199 PPC_NB_ARGS_MASK = 0x0000000F,
201 /* Type */
202 PPC_ARITH = 0x00000100,
203 PPC_LOGICAL = 0x00000200,
204 PPC_COMPARE = 0x00000300,
205 PPC_LDST = 0x00000400,
206 PPC_POPCNT = 0x00000500,
207 PPC_INSERTEXTRACT = 0x00000600,
208 PPC_PERMUTE = 0x00000700,
209 PPC_ROUND = 0x00000800,
210 PPC_TYPE_MASK = 0x00000F00,
212 /* Family */
213 PPC_INTEGER = 0x00010000,
214 PPC_ALTIVEC = 0x00030000,
215 PPC_ALTIVEC_QUAD = 0x00040000,
216 PPC_ALTIVEC_DOUBLE = 0x00050000,
217 PPC_DFP = 0x00060000,
218 PPC_BCD = 0x00070000,
219 PPC_MISC = 0x00080000,
220 PPC_NO_OP = 0x00090000,
221 PPC_PC_IMMEDIATE = 0x000A0000,
222 PPC_MFFS = 0x000B0000,
223 PPC_FAMILY_MASK = 0x000F0000,
225 /* Flags: these may be combined, so use separate bit-fields. */
226 PPC_CR = 0x01000000,
227 PPC_XER_CA = 0x02000000,
230 static void test_cnttzw (void)
232 __asm__ __volatile__ ("cnttzw 17, 14");
235 static void test_cnttzd (void)
237 __asm__ __volatile__ ("cnttzd 17, 14");
240 static void test_dotted_cnttzw (void)
242 __asm__ __volatile__ ("cnttzw. 17, 14");
245 static void test_dotted_cnttzd (void)
247 __asm__ __volatile__ ("cnttzd. 17, 14");
250 static test_list_t testgroup_logical_one[] = {
251 { &test_cnttzw , "cnttzw" },
252 { &test_cnttzd , "cnttzd" },
253 { &test_dotted_cnttzw, "cnttzw." },
254 { &test_dotted_cnttzd, "cnttzd." },
255 { NULL , NULL },
258 static void test_modsw (void)
260 __asm__ __volatile__ ("modsw 17, 14, 15");
263 static void test_moduw (void)
265 __asm__ __volatile__ ("moduw 17, 14, 15");
268 static void test_modsd (void)
270 __asm__ __volatile__ ("modsd 17, 14, 15");
273 static void test_modud (void)
275 __asm__ __volatile__ ("modud 17, 14, 15");
278 static void test_addex(void) {
279 /* addex RT,RA,RB,CY # at the time of this writing, only CY=0 is valid. CY values of 1,2,3 are reserved. */
280 __asm__ __volatile__ ("addex %0, %1, %2, 0" : "=r" (r17) : "r" (r14), "r" (r15) );
283 static test_list_t testgroup_ia_ops_two[] = {
284 { &test_modsw, "modsw" },
285 { &test_moduw, "moduw" },
286 { &test_modsd, "modsd" },
287 { &test_modud, "modud" },
288 { &test_addex, "addex" },
289 { NULL , NULL },
292 static void test_dotted_extswsli (void)
294 switch(x_shift) {
295 case SH_0:
296 __asm__ __volatile__ ("extswsli. %0, %1, %2" : "=r" (r17) : "r" (r14), "i" (SH_0) );
297 break;
299 case SH_1:
300 __asm__ __volatile__ ("extswsli. %0, %1, %2" : "=r" (r17) : "r" (r14), "i" (SH_1) );
301 break;
303 case SH_2:
304 __asm__ __volatile__ ("extswsli. %0, %1, %2" : "=r" (r17) : "r" (r14), "i" (SH_2) );
305 break;
307 case SH_3:
308 __asm__ __volatile__ ("extswsli. %0, %1, %2" : "=r" (r17) : "r" (r14), "i" (SH_3) );
309 break;
311 default:
312 printf("Unhandled shift value for extswsli. %d\n", x_shift);
316 static void test_extswsli (void)
318 switch(x_shift) {
319 case SH_0:
320 __asm__ __volatile__ ("extswsli %0, %1, %2" : "=r" (r17) : "r" (r14), "i"(SH_0));
321 break;
323 case SH_1:
324 __asm__ __volatile__ ("extswsli %0, %1, %2" : "=r" (r17) : "r" (r14), "i"(SH_1));
325 break;
327 case SH_2:
328 __asm__ __volatile__ ("extswsli %0, %1, %2" : "=r" (r17) : "r" (r14), "i"(SH_2));
329 break;
331 case SH_3:
332 __asm__ __volatile__ ("extswsli %0, %1, %2" : "=r" (r17) : "r" (r14), "i"(SH_3));
333 break;
335 default:
336 printf("Unhandled shift value for extswsli %d\n", x_shift);
340 static test_list_t testgroup_shifted_one[] = {
341 { &test_extswsli , "extswsli " },
342 { &test_dotted_extswsli, "extswsli." },
343 { NULL , NULL },
346 static void test_maddhd (void)
348 __asm__ __volatile__ ("maddhd 17, 14, 15, 16");
350 static void test_maddhdu (void)
352 __asm__ __volatile__ ("maddhdu 17, 14, 15, 16");
354 static void test_maddld (void)
356 __asm__ __volatile__ ("maddld 17, 14, 15, 16");
359 static test_list_t testgroup_three_args[] = {
360 { &test_maddhd , "maddhd " },
361 { &test_maddhdu, "maddhdu" },
362 { &test_maddld , "maddld " },
363 { NULL , NULL },
366 /* VSX vector permutes. */
367 static void test_xxperm (void)
369 __asm__ __volatile__ ("xxperm %x0, %x1, %x2" : "+wa" (vec_xt): "wa" (vec_xa), "wa" (vec_xb));
372 /* VSX vector permute, right indexed. */
373 static void test_xxpermr (void)
375 __asm__ __volatile__ ("xxpermr %x0, %x1, %x2" : "+wa" (vec_xt): "wa" (vec_xa), "wa" (vec_xb));
378 static test_list_t testgroup_vsx_xxpermute[] = {
379 { &test_xxperm , "xxperm" },
380 { &test_xxpermr, "xxpermr" },
381 { NULL , NULL },
384 static void test_vabsdub(void) {
385 __asm__ __volatile__ ("vabsdub %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
388 static void test_vabsduh(void) {
389 __asm__ __volatile__ ("vabsduh %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
392 static void test_vabsduw(void) {
393 __asm__ __volatile__ ("vabsduw %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
396 static void test_vcmpneb(void) {
397 __asm__ __volatile__ ("vcmpneb %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
400 static void test_dotted_vcmpneb(void) {
401 __asm__ __volatile__ ("vcmpneb. %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
404 static void test_vcmpnezb(void) {
405 __asm__ __volatile__ ("vcmpnezb %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
408 static void test_dotted_vcmpnezb(void) {
409 __asm__ __volatile__ ("vcmpnezb. %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
412 static void test_vcmpneh(void) {
413 __asm__ __volatile__ ("vcmpneh %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
416 static void test_dotted_vcmpneh(void) {
417 __asm__ __volatile__ ("vcmpneh. %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
420 static void test_vcmpnezh(void) {
421 __asm__ __volatile__ ("vcmpnezh %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
424 static void test_dotted_vcmpnezh(void) {
425 __asm__ __volatile__ ("vcmpnezh. %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
428 static void test_vcmpnew(void) {
429 __asm__ __volatile__ ("vcmpnew %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
432 static void test_dotted_vcmpnew(void) {
433 __asm__ __volatile__ ("vcmpnew. %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
436 static void test_vcmpnezw(void) {
437 __asm__ __volatile__ ("vcmpnezw %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
440 static void test_dotted_vcmpnezw(void) {
441 __asm__ __volatile__ ("vcmpnezw. %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
444 static void test_vrlwmi(void) {
445 __asm__ __volatile__ ("vrlwmi %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
448 static void test_vrldmi(void) {
449 __asm__ __volatile__ ("vrldmi %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
452 static void test_vbpermd(void) {
453 /* vector bit permute doubleword */
454 __asm__ __volatile__ ("vbpermd %0, %1, %2 " : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
457 static void test_vrlwnm(void) {
458 __asm__ __volatile__ ("vrlwnm %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
461 static void test_vrldnm(void) {
462 __asm__ __volatile__ ("vrldnm %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
465 static void test_xviexpdp(void) {
466 __asm__ __volatile__ ("xviexpdp %x0, %x1, %x2 " : "+wa" (vec_xt): "wa" (vec_xa), "wa" (vec_xb));
469 static void test_xviexpsp(void) {
470 __asm__ __volatile__ ("xviexpsp %x0, %x1, %x2 " : "+wa" (vec_xt): "wa" (vec_xa), "wa" (vec_xb));
473 static test_list_t testgroup_vsx_absolute[] = {
474 { &test_vabsdub , "vabsdub" },
475 { &test_vabsduh , "vabsduh" },
476 { &test_vabsduw , "vabsduw" },
477 { &test_vcmpneb , "vcmpneb" },
478 { &test_dotted_vcmpneb , "vcmpneb." },
479 { &test_vcmpnezb , "vcmpnezb" },
480 { &test_dotted_vcmpnezb, "vcmpnezb." },
481 { &test_vcmpneh , "vcmpneh" },
482 { &test_dotted_vcmpneh , "vcmpneh." },
483 { &test_vcmpnezh , "vcmpnezh" },
484 { &test_dotted_vcmpnezh, "vcmpnezh." },
485 { &test_vcmpnew , "vcmpnew" },
486 { &test_dotted_vcmpnew , "vcmpnew." },
487 { &test_vcmpnezw , "vcmpnezw" },
488 { &test_dotted_vcmpnezw, "vcmpnezw." },
489 { &test_vrlwnm , "vrlwnm" },
490 { &test_vrlwmi , "vrlwmi" },
491 { &test_vrldnm , "vrldnm" },
492 { &test_vrldmi , "vrldmi" },
493 { &test_vbpermd , "vbpermd" },
494 { &test_xviexpdp , "xviexpdp" },
495 { &test_xviexpsp , "xviexpsp" },
496 { NULL , NULL },
499 static void test_vpermr(void)
500 { /* vector permute right-indexed */
501 __asm__ __volatile__ ("vpermr %0, %1, %2, %3 " : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb), "v" (vec_xc));
504 static void test_vmsumudm(void)
505 { /* vector multiply-sum unsigned byte modulo. */
506 __asm__ __volatile__ ("vmsumudm %0, %1, %2, %3 " : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb), "v" (vec_xc));
509 /* vector, 3->1 unique; four arguments. xt, xa, xb, xc (xc = permute) */
510 static test_list_t testgroup_vector_four[] = {
511 { &test_vpermr, "vpermr" },
512 { &test_vmsumudm, "vmsumudm" },
513 { NULL , NULL },
516 /* vector insert instructions */
517 #define VINSERTB(X) __asm__ __volatile__ ("vinsertb %0, %1, %2" : "+v" (vec_xt) : "v" (vec_xb), "i"(X));
519 #define VINSERTH(X) __asm__ __volatile__ ("vinserth %0, %1, %2" : "+v" (vec_xt) : "v" (vec_xb), "i"(X));
521 #define VINSERTW(X) __asm__ __volatile__ ("vinsertw %0, %1, %2" : "+v" (vec_xt) : "v" (vec_xb), "i"(X));
523 #define VINSERTD(X) __asm__ __volatile__ ("vinsertd %0, %1, %2" : "+v" (vec_xt) : "v" (vec_xb), "i"(X));
525 #define VEXTRACTUB(X) __asm__ __volatile__ ("vextractub %0, %1, %2" : "+v" (vec_xt) : "v" (vec_xb), "i"(X));
527 #define VEXTRACTUH(X) __asm__ __volatile__ ("vextractuh %0, %1, %2" : "+v" (vec_xt) : "v" (vec_xb), "i"(X));
529 #define VEXTRACTUW(X) __asm__ __volatile__ ("vextractuw %0, %1, %2" : "+v" (vec_xt) : "v" (vec_xb), "i"(X));
531 #define VEXTRACTD(X) __asm__ __volatile__ ("vextractd %0, %1, %2" : "+v" (vec_xt) : "v" (vec_xb), "i"(X));
533 #define XXINSERTW(X) __asm__ __volatile__ ("xxinsertw %x0, %x1, %2" : "+wa" (vec_xt) : "wa" (vec_xb), "i"(X));
535 #define XXEXTRACTUW(X) __asm__ __volatile__ ("xxextractuw %x0, %x1, %2" : "+wa" (vec_xt) : "wa" (vec_xb), "i"(X));
537 static void test_vinsertb (void)
539 switch(x_index) {
540 case 0: VINSERTB( 0); break;
541 case 1: VINSERTB( 1); break;
542 case 2: VINSERTB( 2); break;
543 case 3: VINSERTB( 3); break;
544 case 4: VINSERTB( 4); break;
545 case 5: VINSERTB( 5); break;
546 case 6: VINSERTB( 6); break;
547 case 7: VINSERTB( 7); break;
548 case 8: VINSERTB( 8); break;
549 case 9: VINSERTB( 9); break;
550 case 10: VINSERTB(10); break;
551 case 11: VINSERTB(11); break;
552 case 12: VINSERTB(12); break;
553 case 13: VINSERTB(13); break;
554 case 14: VINSERTB(14); break;
555 case 15: VINSERTB(15); break;
556 default:
557 vinsertextract_err;
558 break;
562 static void test_vinserth (void)
564 switch(x_index) {
565 case 0: VINSERTH(0); break;
566 case 1: VINSERTH(1); break;
567 case 2: VINSERTH(2); break;
568 case 3: VINSERTH(3); break;
569 case 4: VINSERTH(4); break;
570 case 5: VINSERTH(5); break;
571 case 6: VINSERTH(6); break;
572 case 7: VINSERTH(7); break;
573 case 8: VINSERTH(8); break;
574 case 9: VINSERTH(9); break;
575 case 10: VINSERTH(10); break;
576 case 11: VINSERTH(11); break;
577 case 12: VINSERTH(12); break;
578 case 13: VINSERTH(13); break;
579 case 14: VINSERTH(14); break;
580 default:
581 vinsertextract_err;
582 break;
586 static void test_vinsertw (void)
588 switch(x_index) {
589 case 0: VINSERTW(0); break;
590 case 1: VINSERTW(1); break;
591 case 2: VINSERTW(2); break;
592 case 3: VINSERTW(3); break;
593 case 4: VINSERTW(4); break;
594 case 5: VINSERTW(5); break;
595 case 6: VINSERTW(6); break;
596 case 7: VINSERTW(7); break;
597 case 8: VINSERTW(8); break;
598 case 9: VINSERTW(9); break;
599 case 10: VINSERTW(10); break;
600 case 11: VINSERTW(11); break;
601 case 12: VINSERTW(12); break;
602 default:
603 vinsertextract_err;
604 break;
608 static void test_vinsertd (void)
610 switch(x_index) {
611 case 0: VINSERTD(0); break;
612 case 1: VINSERTD(1); break;
613 case 2: VINSERTD(2); break;
614 case 3: VINSERTD(3); break;
615 case 4: VINSERTD(4); break;
616 case 5: VINSERTD(5); break;
617 case 6: VINSERTD(6); break;
618 case 7: VINSERTD(7); break;
619 case 8: VINSERTD(8); break;
620 default:
621 vinsertextract_err;
622 break;
626 /* extracts */
627 static void test_vextractub (void)
629 switch(x_index) {
630 case 0: VEXTRACTUB( 0); break;
631 case 1: VEXTRACTUB( 1); break;
632 case 2: VEXTRACTUB( 2); break;
633 case 3: VEXTRACTUB( 3); break;
634 case 4: VEXTRACTUB( 4); break;
635 case 5: VEXTRACTUB( 5); break;
636 case 6: VEXTRACTUB( 6); break;
637 case 7: VEXTRACTUB( 7); break;
638 case 8: VEXTRACTUB( 8); break;
639 case 9: VEXTRACTUB( 9); break;
640 case 10: VEXTRACTUB(10); break;
641 case 11: VEXTRACTUB(11); break;
642 case 12: VEXTRACTUB(12); break;
643 case 13: VEXTRACTUB(13); break;
644 case 14: VEXTRACTUB(14); break;
645 case 15: VEXTRACTUB(15); break;
646 default:
647 vinsertextract_err;
648 break;
652 static void test_vextractuh (void)
654 switch(x_index) {
655 case 0: VEXTRACTUH( 0); break;
656 case 1: VEXTRACTUH( 1); break;
657 case 2: VEXTRACTUH( 2); break;
658 case 3: VEXTRACTUH( 3); break;
659 case 4: VEXTRACTUH( 4); break;
660 case 5: VEXTRACTUH( 5); break;
661 case 6: VEXTRACTUH( 6); break;
662 case 7: VEXTRACTUH( 7); break;
663 case 8: VEXTRACTUH( 8); break;
664 case 9: VEXTRACTUH( 9); break;
665 case 10: VEXTRACTUH(10); break;
666 case 11: VEXTRACTUH(11); break;
667 case 12: VEXTRACTUH(12); break;
668 case 13: VEXTRACTUH(13); break;
669 case 14: VEXTRACTUH(14); break;
670 default:
671 vinsertextract_err;
672 break;
676 static void test_vextractuw (void)
678 switch(x_index) {
679 case 0: VEXTRACTUW( 0); break;
680 case 1: VEXTRACTUW( 1); break;
681 case 2: VEXTRACTUW( 2); break;
682 case 3: VEXTRACTUW( 3); break;
683 case 4: VEXTRACTUW( 4); break;
684 case 5: VEXTRACTUW( 5); break;
685 case 6: VEXTRACTUW( 6); break;
686 case 7: VEXTRACTUW( 7); break;
687 case 8: VEXTRACTUW( 8); break;
688 case 9: VEXTRACTUW( 9); break;
689 case 10: VEXTRACTUW(10); break;
690 case 11: VEXTRACTUW(11); break;
691 default:
692 vinsertextract_err;
693 break;
697 static void test_vextractd (void)
699 switch(x_index) {
700 case 0: VEXTRACTD( 0); break;
701 case 1: VEXTRACTD( 1); break;
702 case 2: VEXTRACTD( 2); break;
703 case 3: VEXTRACTD( 3); break;
704 case 4: VEXTRACTD( 4); break;
705 case 5: VEXTRACTD( 5); break;
706 case 6: VEXTRACTD( 6); break;
707 case 7: VEXTRACTD( 7); break;
708 case 8: VEXTRACTD( 8); break;
709 default:
710 vinsertextract_err;
711 break;
715 static void test_xxinsertw (void)
717 switch(x_index) {
718 case 0: XXINSERTW( 0); break;
719 case 1: XXINSERTW( 1); break;
720 case 2: XXINSERTW( 2); break;
721 case 3: XXINSERTW( 3); break;
722 case 4: XXINSERTW( 4); break;
723 case 5: XXINSERTW( 5); break;
724 case 6: XXINSERTW( 6); break;
725 case 7: XXINSERTW( 7); break;
726 case 8: XXINSERTW( 8); break;
727 case 9: XXINSERTW( 9); break;
728 case 10: XXINSERTW(10); break;
729 case 11: XXINSERTW(11); break;
730 case 12: XXINSERTW(12); break;
731 default:
732 vinsertextract_err;
733 break;
737 static void test_xxextractuw (void)
739 switch(x_index) {
740 case 0: XXEXTRACTUW( 0); break;
741 case 1: XXEXTRACTUW( 1); break;
742 case 2: XXEXTRACTUW( 2); break;
743 case 3: XXEXTRACTUW( 3); break;
744 case 4: XXEXTRACTUW( 4); break;
745 case 5: XXEXTRACTUW( 5); break;
746 case 6: XXEXTRACTUW( 6); break;
747 case 7: XXEXTRACTUW( 7); break;
748 case 8: XXEXTRACTUW( 8); break;
749 case 9: XXEXTRACTUW( 9); break;
750 case 10: XXEXTRACTUW(10); break;
751 case 11: XXEXTRACTUW(11); break;
752 case 12: XXEXTRACTUW(12); break;
753 default:
754 vinsertextract_err;
755 break;
759 static test_list_t testgroup_vector_inserts[] = {
760 { &test_vinsertb , "vinsertb " },
761 { &test_vinserth , "vinserth " },
762 { &test_vinsertw , "vinsertw " },
763 { &test_vinsertd , "vinsertd " },
764 { &test_vextractub , "vextractub " },
765 { &test_vextractuh , "vextractuh " },
766 { &test_vextractuw , "vextractuw " },
767 { &test_vextractd , "vextractd " },
768 { &test_xxinsertw , "xxinsertw " },
769 { &test_xxextractuw, "xxextractuw" },
770 { NULL , NULL },
773 static void test_xxspltib(void)
774 { /* vector splat byte */
775 switch(x_splat) {
776 case SPLAT0: __asm__ __volatile__ ("xxspltib %x0, %1 " : "=wa"(vec_xt) : "i"(SPLAT0)); break;
778 case SPLAT1: __asm__ __volatile__ ("xxspltib %x0, %1 " : "=wa"(vec_xt) : "i"(SPLAT1)); break;
780 case SPLAT2: __asm__ __volatile__ ("xxspltib %x0, %1 " : "=wa"(vec_xt) : "i"(SPLAT2)); break;
782 case SPLAT3: __asm__ __volatile__ ("xxspltib %x0, %1 " : "=wa"(vec_xt) : "i"(SPLAT3)); break;
784 case SPLAT4: __asm__ __volatile__ ("xxspltib %x0, %1 " : "=wa"(vec_xt) : "i"(SPLAT4)); break;
786 default:
787 printf("Unhandled splat value for %s %d\n", __FUNCTION__, x_splat);
791 static test_list_t testgroup_vector_immediate[] = {
792 { &test_xxspltib, "xxspltib" },
793 { NULL , NULL },
796 /* vector reverse bytes ... */
797 static void test_xxbrh(void)
798 { /* vector reverse byte halfword*/
799 __asm__ __volatile__ ("xxbrh %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa));
802 static void test_xxbrw(void)
803 { /* vector reverse byte word*/
804 __asm__ __volatile__ ("xxbrw %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa));
807 static void test_xxbrd(void)
808 { /* vector reverse byte double*/
809 __asm__ __volatile__ ("xxbrd %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa));
812 static void test_xxbrq(void)
813 { /* vector reverse byte */
814 __asm__ __volatile__ ("xxbrq %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa));
817 static void test_xvxexpdp(void) {
818 __asm__ __volatile__ ("xvxexpdp %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa));
821 static void test_xvxexpsp(void) {
822 __asm__ __volatile__ ("xvxexpsp %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa));
825 static void test_xvxsigdp(void) {
826 __asm__ __volatile__ ("xvxsigdp %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa));
829 static void test_xvxsigsp(void) {
830 __asm__ __volatile__ ("xvxsigsp %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa));
833 static test_list_t testgroup_vector_logical_one[] = {
834 { &test_xxbrh , "xxbrh" },
835 { &test_xxbrw , "xxbrw" },
836 { &test_xxbrd , "xxbrd" },
837 { &test_xxbrq , "xxbrq" },
838 { &test_xvxexpdp, "xvxexpdp" },
839 { &test_xvxexpsp, "xvxexpsp" },
840 { &test_xvxsigdp, "xvxsigdp" },
841 { &test_xvxsigsp, "xvxsigsp" },
842 { NULL , NULL },
845 static void test_xsxexpdp(void) {
846 __asm__ __volatile__ ("xsxexpdp %0, %x1 " : "=r" (r17) : "wa" (vec_xa));
849 static void test_xsxsigdp(void) {
850 __asm__ __volatile__ ("xsxsigdp %0, %x1 " : "=r" (r17) : "wa" (vec_xa));
853 static test_list_t testgroup_gpr_vector_logical_one[] = {
854 { &test_xsxexpdp, "xsxexpdp" },
855 { &test_xsxsigdp, "xsxsigdp" },
856 { NULL , NULL },
859 static void test_lxvx(void) {
860 __asm__ __volatile__ ("lxvx %x0, 14, 15" : "=wa" (vec_xt));
863 static void test_lxvwsx(void) {
864 __asm__ __volatile__ ("lxvwsx %x0, 14, 15" : "=wa" (vec_xt));
867 static void test_lxvh8x(void) {
868 __asm__ __volatile__ ("lxvh8x %x0, 14, 15" : "=wa" (vec_xt));
871 static void test_lxvb16x(void) {
872 __asm__ __volatile__ ("lxvb16x %x0, 14, 15" : "=wa" (vec_xt));
875 static void test_stxvx(void) {
876 __asm__ __volatile__ ("stxvx %x0, 14, 15" :: "wa" (vec_xt));
879 static void test_stxvh8x(void) {
880 __asm__ __volatile__ ("stxvh8x %x0, 14, 15" :: "wa" (vec_xt));
883 static void test_stxvb16x(void) {
884 __asm__ __volatile__ ("stxvb16x %x0, 14, 15" :: "wa" (vec_xt));
887 static test_list_t testgroup_vector_loadstore[] = {
888 { &test_lxvx , "lxvx" },
889 { &test_lxvwsx , "lxvwsx" },
890 { &test_lxvh8x , "lxvh8x" },
891 { &test_lxvb16x , "lxvb16x" },
892 { &test_stxvx , "stxvx" },
893 { &test_stxvh8x , "stxvh8x" },
894 { &test_stxvb16x, "stxvb16x" },
895 { NULL , NULL },
898 static void test_lxvl(void) {
899 __asm__ __volatile__ ("lxvl %x0, 14, 15" : "=wa" (vec_xt));
902 static void test_stxvl(void) {
903 __asm__ __volatile__ ("stxvl %x0, 14, 15" :: "wa" (vec_xt));
906 static void test_lxvll(void) {
907 __asm__ __volatile__ ("lxvll %x0, 14, 15" : "=wa" (vec_xt));
910 static void test_stxvll(void) {
911 __asm__ __volatile__ ("stxvll %x0, 14, 15" :: "wa" (vec_xt));
914 static void test_lxsibzx(void) {
915 __asm__ __volatile__ ("lxsibzx %x0, 14, 15" : "=wa" (vec_xt));
918 static void test_lxsihzx(void) {
919 __asm__ __volatile__ ("lxsihzx %x0, 14, 15" : "=wa" (vec_xt));
922 static void test_stxsibx(void) {
923 __asm__ __volatile__ ("stxsibx %x0, 14, 15" :: "wa" (vec_xt));
926 static void test_stxsihx(void) {
927 __asm__ __volatile__ ("stxsihx %x0, 14, 15" :: "wa" (vec_xt));
930 /* d-form vsx load/store */
931 static void test_lxsd_0(void) {
932 __asm__ __volatile__ ("lxsd %0, 0(%1) " : "=v"(vec_xt) : "r"(r14));
935 static void test_stxsd_0(void) {
936 __asm__ __volatile__ ("stxsd %0, 0(%1)" : : "v"(vec_xt), "r"(r14));
939 static void test_lxsd_16(void) {
940 __asm__ __volatile__ ("lxsd %0, 16(%1)" : "=v"(vec_xt) : "r"(r14));
943 static void test_stxsd_16(void) {
944 __asm__ __volatile__ ("stxsd %0, 16(%1)" : : "v"(vec_xt), "r"(r14));
947 static void test_lxssp_0(void) {
948 __asm__ __volatile__ ("lxssp %0, 0(%1)" : "=v"(vec_xt) : "r"(r14));
951 static void test_stxssp_0(void) {
952 __asm__ __volatile__ ("stxssp %0, 0(%1)" : : "v"(vec_xt), "r"(r14));
955 static void test_lxssp_16(void) {
956 __asm__ __volatile__ ("lxssp %0, 16(%1)" : "=v"(vec_xt) : "r"(r14));
959 static void test_stxssp_16(void) {
960 __asm__ __volatile__ ("stxssp %0, 16(%1)" : : "v"(vec_xt), "r"(r14));
963 static void test_lxv_0(void) {
964 __asm__ __volatile__ ("lxv %x0, 0(%1)" : "=wa"(vec_xt) : "r"(r14));
967 static void test_stxv_0(void) {
968 __asm__ __volatile__ ("stxv %x0, 0(%1)" : : "wa"(vec_xt), "r"(r14));
971 static void test_lxv_16(void) {
972 __asm__ __volatile__ ("lxv %x0, 16(%1)" : "=wa"(vec_xt) : "r"(r14));
975 static void test_stxv_16(void) {
976 __asm__ __volatile__ ("stxv %x0, 16(%1)" : : "wa"(vec_xt), "r"(r14));
979 static test_list_t testgroup_vector_scalar_loadstore_length[] = {
980 { &test_lxvl , "lxvl " },
981 { &test_lxvll , "lxvll " },
982 { &test_lxsibzx , "lxsibzx " },
983 { &test_lxsihzx , "lxsihzx " },
984 { &test_stxvl , "stxvl " },
985 { &test_stxvll , "stxvll " },
986 { &test_stxsibx , "stxsibx " },
987 { &test_stxsihx , "stxsihx " },
988 { &test_lxsd_0 , "lxsd 0 " },
989 { &test_stxsd_0 , "stxsd 0 " },
990 { &test_lxsd_16 , "lxsd 16 " },
991 { &test_stxsd_16 , "stxsd 16 " },
992 { &test_lxssp_0 , "lxssp 0 " },
993 { &test_stxssp_0 , "stxssp 0 " },
994 { &test_lxssp_16 , "lxssp 16 " },
995 { &test_stxssp_16, "stxssp 16" },
996 { &test_lxv_0 , "lxv 0 " },
997 { &test_stxv_0 , "stxv 0 " },
998 { &test_lxv_16 , "lxv 16 " },
999 { &test_stxv_16 , "stxv 16 " },
1000 { NULL , NULL },
1003 /* move from/to VSR */
1004 static void test_mfvsrld (void)
1006 __asm__ __volatile__ ("mfvsrld %0, %x1" : "=r" (r14) : "wa" (vec_xt));
1009 static void test_mtvsrdd (void)
1011 __asm__ __volatile__ ("mtvsrdd %x0, 14, 15" : "=wa" (vec_xt));
1014 static void test_mtvsrws (void)
1015 { /* To fit in better with the caller for the mfvsrdd test, use r15
1016 * instead of r14 as input here.
1018 __asm__ __volatile__ ("mtvsrws %x0, 15" : "=wa" (vec_xt));
1021 static test_list_t testgroup_vectorscalar_move_tofrom[] = {
1022 { &test_mfvsrld, "mfvsrld" }, /* RA, XS */
1023 { &test_mtvsrdd, "mtvsrdd" }, /* XT, RA, RB */
1024 { &test_mtvsrws, "mtvsrws" }, /* XT, RA */
1025 { NULL , NULL },
1028 /* vector count {leading, trailing} zero least-significant bits byte.
1029 * roughly... how many leading/trailing bytes are even. */
1030 static void test_vclzlsbb(void) {
1031 __asm__ __volatile__ ("vclzlsbb %0, %1" : "=r"(r14) : "v"(vec_xb));
1034 static void test_vctzlsbb(void) {
1035 __asm__ __volatile__ ("vctzlsbb %0, %1" : "=r"(r14) : "v"(vec_xb));
1038 static test_list_t testgroup_vector_count_bytes[] = {
1039 { &test_vclzlsbb, "vclzlsbb" },
1040 { &test_vctzlsbb, "vctzlsbb" },
1041 { NULL , NULL },
1044 static void test_vextsb2w(void) {
1045 __asm__ __volatile__ ("vextsb2w %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1048 static void test_vextsb2d(void) {
1049 __asm__ __volatile__ ("vextsb2d %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1052 static void test_vextsh2w(void) {
1053 __asm__ __volatile__ ("vextsh2w %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1056 static void test_vextsh2d(void) {
1057 __asm__ __volatile__ ("vextsh2d %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1060 static void test_vextsw2d(void) {
1061 __asm__ __volatile__ ("vextsw2d %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1064 static void test_vnegw(void) {
1065 __asm__ __volatile__ ("vnegw %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1068 static void test_vnegd(void) {
1069 __asm__ __volatile__ ("vnegd %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1072 static void test_vprtybw(void) {
1073 __asm__ __volatile__ ("vprtybw %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1076 static void test_vprtybd(void) {
1077 __asm__ __volatile__ ("vprtybd %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1080 static void test_vprtybq(void) {
1081 __asm__ __volatile__ ("vprtybq %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1084 static void test_vctzb(void) {
1085 __asm__ __volatile__ ("vctzb %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1088 static void test_vctzh(void) {
1089 __asm__ __volatile__ ("vctzh %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1092 static void test_vctzw(void) {
1093 __asm__ __volatile__ ("vctzw %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1096 static void test_vctzd(void) {
1097 __asm__ __volatile__ ("vctzd %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1100 static test_list_t testgroup_vector_extend_sign[] = {
1101 { &test_vextsb2w, "vextsb2w" },
1102 { &test_vextsb2d, "vextsb2d" },
1103 { &test_vextsh2w, "vextsh2w" },
1104 { &test_vextsh2d, "vextsh2d" },
1105 { &test_vextsw2d, "vextsw2d" },
1106 { &test_vnegw , "vnegw " },
1107 { &test_vnegd , "vnegd " },
1108 { &test_vprtybw , "vprtybw " },
1109 { &test_vprtybd , "vprtybd " },
1110 { &test_vprtybq , "vprtybq " },
1111 { &test_vctzb , "vctzb " },
1112 { &test_vctzh , "vctzh " },
1113 { &test_vctzw , "vctzw " },
1114 { &test_vctzd , "vctzd " },
1115 { NULL , NULL },
1118 static void test_vextublx(void) {
1119 __asm__ __volatile__ ("vextublx %0, %1, %2" : "=r"(r14) : "r" (r15), "v" (vec_xb));
1122 static void test_vextubrx(void) {
1123 __asm__ __volatile__ ("vextubrx %0, %1, %2" : "=r"(r14) : "r"(r15), "v"(vec_xb));
1126 static void test_vextuhlx(void) {
1127 if (r15 > 14) return; // limit to 14 halfwords
1128 __asm__ __volatile__ ("vextuhlx %0, %1, %2" : "=r"(r14) : "r"(r15), "v"(vec_xb));
1131 static void test_vextuhrx(void) {
1132 if (r15 > 14) return; // limit to 14 halfwords
1133 __asm__ __volatile__ ("vextuhrx %0, %1, %2" : "=r"(r14) : "r"(r15), "v"(vec_xb));
1136 static void test_vextuwlx(void) {
1137 if (r15 > 12) return; // limit to 12 words
1138 __asm__ __volatile__ ("vextuwlx %0, %1, %2" : "=r"(r14) : "r"(r15), "v"(vec_xb));
1141 static void test_vextuwrx(void) {
1142 if (r15 > 12) return; // limit to 12 words
1143 __asm__ __volatile__ ("vextuwrx %0, %1, %2" : "=r"(r14) : "r"(r15), "v"(vec_xb));
1146 static test_list_t testgroup_vector_extract[] = {
1147 { &test_vextublx, "vextublx" },
1148 { &test_vextubrx, "vextubrx" },
1149 { &test_vextuhlx, "vextuhlx" },
1150 { &test_vextuhrx, "vextuhrx" },
1151 { &test_vextuwlx, "vextuwlx" },
1152 { &test_vextuwrx, "vextuwrx" },
1153 { NULL , NULL },
1156 #define XSCMPEXPDP(x) \
1157 SET_FPSCR_ZERO \
1158 SET_CR_ZERO \
1159 __asm__ __volatile__ \
1160 ("xscmpexpdp %0, %x1, %x2"::"i"(x), "wa"(vec_xa), "wa"(vec_xb));\
1161 GET_CR(local_cr); \
1162 GET_FPSCR(local_fpscr);
1164 static void test_xscmpexpdp(void) {
1165 switch(x_index) {
1166 case 0: XSCMPEXPDP(0); break;
1167 case 1: XSCMPEXPDP(1); break;
1168 case 2: XSCMPEXPDP(2); break;
1169 case 3: XSCMPEXPDP(3); break;
1170 case 4: XSCMPEXPDP(4); break;
1171 case 5: XSCMPEXPDP(5); break;
1172 case 6: XSCMPEXPDP(6); break;
1173 case 7: XSCMPEXPDP(7); break;
1174 default:
1175 printf("Unhandled shift value for %s %x\n", __FUNCTION__, x_index);
1179 static void test_xscmpeqdp(void) {
1180 __asm__ __volatile__ ("xscmpeqdp %x0, %x1, %x2 " : "+wa" (vec_xt): "wa" (vec_xa), "wa" (vec_xb));
1183 static void test_xscmpgtdp(void) {
1184 __asm__ __volatile__ ("xscmpgtdp %x0, %x1, %x2 " : "+wa" (vec_xt): "wa" (vec_xa), "wa" (vec_xb));
1187 static void test_xscmpgedp(void) {
1188 __asm__ __volatile__ ("xscmpgedp %x0, %x1, %x2 " : "+wa" (vec_xt): "wa" (vec_xa), "wa" (vec_xb));
1191 static void test_xsmincdp(void) {
1192 __asm__ __volatile__ ("xsmincdp %x0, %x1, %x2 " : "+wa" (vec_xt): "wa" (vec_xa), "wa" (vec_xb));
1195 static void test_xsmaxcdp(void) {
1196 __asm__ __volatile__ ("xsmaxcdp %x0, %x1, %x2 " : "+wa" (vec_xt): "wa" (vec_xa), "wa" (vec_xb));
1199 static test_list_t testgroup_vector_scalar_compare_double[] = {
1200 { &test_xscmpexpdp , "xscmpexpdp " },
1201 { &test_xscmpeqdp , "xscmpeqdp " },
1202 { &test_xscmpgtdp , "xscmpgtdp " },
1203 { &test_xscmpgedp , "xscmpgedp " },
1204 { &test_xsmincdp , "xsmincdp " },
1205 { &test_xsmaxcdp , "xsmaxcdp " },
1206 { NULL , NULL },
1209 #define XSTSTDCQP(R,DCMX) \
1210 SET_FPSCR_ZERO \
1211 SET_CR_ZERO \
1212 __asm__ __volatile__ \
1213 ("xststdcqp %0, %1, %2":: "i"(R), "v"(vec_xb), "i"(DCMX)); \
1214 GET_CR(local_cr); \
1215 GET_FPSCR(local_fpscr); \
1216 SET_FPSCR_ZERO \
1217 SET_CR_ZERO
1219 #define XSTSTDCDP(R,DCMX) \
1220 SET_FPSCR_ZERO \
1221 SET_CR_ZERO \
1222 __asm__ __volatile__ \
1223 ("xststdcdp %0, %x1, %2":: "i"(R), "wa"(vec_xb), "i"(DCMX)); \
1224 GET_CR(local_cr); \
1225 GET_FPSCR(local_fpscr); \
1226 SET_FPSCR_ZERO \
1227 SET_CR_ZERO
1229 #define XSTSTDCSP(R,DCMX) \
1230 SET_FPSCR_ZERO \
1231 SET_CR_ZERO \
1232 __asm__ __volatile__ \
1233 ("xststdcsp %0, %x1, %2":: "i"(R), "wa"(vec_xb), "i"(DCMX)); \
1234 GET_CR(local_cr); \
1235 GET_FPSCR(local_fpscr); \
1236 SET_CR_ZERO
1238 #define XVTSTDCDP(R,DCMX) \
1239 SET_FPSCR_ZERO \
1240 SET_CR_ZERO \
1241 __asm__ __volatile__ \
1242 ("xvtstdcdp %x0, %x1, %2": "=wa"(vec_xt) : "wa"(vec_xb), "i"(DCMX)); \
1243 GET_CR(local_cr); \
1244 GET_FPSCR(local_fpscr); \
1245 SET_FPSCR_ZERO \
1246 SET_CR_ZERO
1248 #define XVTSTDCSP(R,DCMX) \
1249 SET_FPSCR_ZERO \
1250 SET_CR_ZERO \
1251 __asm__ __volatile__ \
1252 ("xvtstdcsp %x0, %x1, %2": "=wa"(vec_xt) : "wa"(vec_xb), "i"(DCMX)); \
1253 GET_CR(local_cr); \
1254 GET_FPSCR(local_fpscr); \
1255 SET_FPSCR_ZERO \
1256 SET_CR_ZERO
1258 static void test_xststdcqp(void) {
1259 switch(x_index) {
1260 case 1: XSTSTDCQP(3, 0x01); break; /* NaN */
1261 case 2: XSTSTDCQP(3, 0x02); break; /* +inf */
1262 case 3: XSTSTDCQP(3, 0x04); break; /* -inf */
1263 case 4: XSTSTDCQP(3, 0x08); break; /* +zero */
1264 case 5: XSTSTDCQP(3, 0x10); break; /* -zero */
1265 case 6: XSTSTDCQP(3, 0x20); break; /* +denormal */
1266 case 7: XSTSTDCQP(3, 0x40); break; /* -denormal */
1267 case 0: XSTSTDCQP(3, 0x7f); break; /* all of the above */
1271 static void test_xststdcdp(void) {
1272 switch(x_index) {
1273 case 1: XSTSTDCDP(3, 0x01); break; /* NaN */
1274 case 2: XSTSTDCDP(3, 0x02); break; /* +inf */
1275 case 3: XSTSTDCDP(3, 0x04); break; /* -inf */
1276 case 4: XSTSTDCDP(3, 0x08); break; /* +zero */
1277 case 5: XSTSTDCDP(3, 0x10); break; /* -zero */
1278 case 6: XSTSTDCDP(3, 0x20); break; /* +denormal */
1279 case 7: XSTSTDCDP(3, 0x40); break; /* -denormal */
1280 case 0: XSTSTDCDP(3, 0x7f); break; /* all of the above */
1284 static void test_xststdcsp(void) {
1285 switch(x_index) {
1286 case 1: XSTSTDCSP(3, 0x01); break; /* NaN */
1287 case 2: XSTSTDCSP(3, 0x02); break; /* +inf */
1288 case 3: XSTSTDCSP(3, 0x04); break; /* -inf */
1289 case 4: XSTSTDCSP(3, 0x08); break; /* +zero */
1290 case 5: XSTSTDCSP(3, 0x10); break; /* -zero */
1291 case 6: XSTSTDCSP(3, 0x20); break; /* +denormal */
1292 case 7: XSTSTDCSP(3, 0x40); break; /* -denormal */
1293 case 0: XSTSTDCSP(3, 0x7f); break; /* all of the above */
1297 static void test_xvtstdcdp(void) {
1298 switch(x_index) {
1299 case 1: XVTSTDCDP(3, 0x01); break; /* NaN */
1300 case 2: XVTSTDCDP(3, 0x02); break; /* +inf */
1301 case 3: XVTSTDCDP(3, 0x04); break; /* -inf */
1302 case 4: XVTSTDCDP(3, 0x08); break; /* +zero */
1303 case 5: XVTSTDCDP(3, 0x10); break; /* -zero */
1304 case 6: XVTSTDCDP(3, 0x20); break; /* +denormal */
1305 case 7: XVTSTDCDP(3, 0x40); break; /* -denormal */
1306 case 0: XVTSTDCDP(3, 0x7f); break; /* all of the above */
1310 /* Note: Due to the test groupings, the input for the xvtstdcsp test is
1311 * actually 'double'. It is good enough for this test, but may wish to break
1312 * this one out eventually.
1314 static void test_xvtstdcsp(void) {
1315 switch(x_index) {
1316 case 1: XVTSTDCSP(3, 0x01); break; /* NaN */
1317 case 2: XVTSTDCSP(3, 0x02); break; /* +inf */
1318 case 3: XVTSTDCSP(3, 0x04); break; /* -inf */
1319 case 4: XVTSTDCSP(3, 0x08); break; /* +zero */
1320 case 5: XVTSTDCSP(3, 0x10); break; /* -zero */
1321 case 6: XVTSTDCSP(3, 0x20); break; /* +denormal */
1322 case 7: XVTSTDCSP(3, 0x40); break; /* -denormal */
1323 case 0: XVTSTDCSP(3, 0x7f); break; /* all of the above */
1327 static test_list_t testgroup_vector_scalar_data_class[] = {
1328 { &test_xststdcqp, "xststdcqp " },
1329 { &test_xststdcdp, "xststdcdp " },
1330 { &test_xststdcsp, "xststdcsp " },
1331 { &test_xvtstdcsp, "xvtstdcsp " },
1332 { &test_xvtstdcdp, "xvtstdcdp " },
1333 { NULL , NULL },
1336 static void test_setb (void) {
1337 /* setb RT,BFA
1338 * BFA is a 3-bit field. */
1340 switch(x_index) {
1341 case 0:SET_CR0_FIELD(cr_value);
1342 __asm__ __volatile__ ("setb %0, 0" : "=r" (r14)); break;
1344 case 1:SET_CR1_FIELD(cr_value);
1345 __asm__ __volatile__ ("setb %0, 1" : "=r" (r14)); break;
1347 case 2:SET_CR2_FIELD(cr_value);
1348 __asm__ __volatile__ ("setb %0, 2" : "=r" (r14)); break;
1350 case 3:SET_CR3_FIELD(cr_value);
1351 __asm__ __volatile__ ("setb %0, 3" : "=r" (r14)); break;
1353 case 4:SET_CR4_FIELD(cr_value);
1354 __asm__ __volatile__ ("setb %0, 4" : "=r" (r14)); break;
1356 case 5:SET_CR5_FIELD(cr_value);
1357 __asm__ __volatile__ ("setb %0, 5" : "=r" (r14)); break;
1359 case 6:SET_CR6_FIELD(cr_value);
1360 __asm__ __volatile__ ("setb %0, 6" : "=r" (r14)); break;
1362 case 7:SET_CR7_FIELD(cr_value);
1363 __asm__ __volatile__ ("setb %0, 7" : "=r" (r14)); break;
1366 GET_CR(local_cr);
1368 if (verbose) {
1369 dissect_cr(local_cr);
1373 static test_list_t testgroup_set_boolean[] = {
1374 { &test_setb, "setb"},
1375 { NULL , NULL },
1378 /* cmprb l = 0:
1379 * compares r14 = src with range specified by values in r15
1380 * bits (48:55 - 56:63)].
1382 * cmprb l=1:
1383 * compares r14 = src with ranges between two pairs of values, as above and
1384 * also in r15 bits (32:39 - 40:47 .
1386 static void test_cmprb_l0() {
1387 /* Clear condition code reg (CR) immediately before test
1388 * instruction, read CR and clear immediately after test
1389 * instruction. Otherwise, the CR gets corrupted and depending
1390 * on optimization level, strange loop control flow issues
1391 * occur because CR has been messed with.
1393 switch(x_index) {
1394 case 0: SET_CR_ZERO;
1395 __asm__ __volatile__ ("cmprb 0, 0, %0, %1" : : "r"(r14), "r"(r15));
1396 GET_CR(local_cr); SET_CR_ZERO; break;
1398 case 1: SET_CR_ZERO;
1399 __asm__ __volatile__ ("cmprb 1, 0, %0, %1" : : "r"(r14), "r"(r15));
1400 GET_CR(local_cr); SET_CR_ZERO; break;
1402 case 2: SET_CR_ZERO;
1403 __asm__ __volatile__ ("cmprb 2, 0, %0, %1" : : "r"(r14), "r"(r15));
1404 GET_CR(local_cr); SET_CR_ZERO; break;
1406 case 3: SET_CR_ZERO;
1407 __asm__ __volatile__ ("cmprb 3, 0, %0, %1" : : "r"(r14), "r"(r15));
1408 GET_CR(local_cr); SET_CR_ZERO; break;
1410 case 4: SET_CR_ZERO;
1411 __asm__ __volatile__ ("cmprb 4, 0, %0, %1" : : "r"(r14), "r"(r15));
1412 GET_CR(local_cr); SET_CR_ZERO; break;
1414 case 5: SET_CR_ZERO;
1415 __asm__ __volatile__ ("cmprb 5, 0, %0, %1" : : "r"(r14), "r"(r15));
1416 GET_CR(local_cr); SET_CR_ZERO; break;
1418 case 6: SET_CR_ZERO;
1419 __asm__ __volatile__ ("cmprb 6, 0, %0, %1" : : "r"(r14), "r"(r15));
1420 GET_CR(local_cr); SET_CR_ZERO; break;
1422 case 7: SET_CR_ZERO;
1423 __asm__ __volatile__ ("cmprb 7, 0, %0, %1" : : "r"(r14), "r"(r15));
1424 GET_CR(local_cr); SET_CR_ZERO; break;
1428 static void test_cmprb_l1() {
1429 /* Clear condition code reg (CR) immediately before test
1430 * instruction, read CR and clear immediately after test
1431 * instruction. Otherwise, the CR gets corrupted and depending
1432 * on optimization level, strange loop control flow issues
1433 * occur because CR has been messed with.
1435 switch(x_index) {
1436 case 0: SET_CR_ZERO;
1437 __asm__ __volatile__ ("cmprb 0, 1 ,%0, %1" : : "r"(r14), "r"(r15));
1438 GET_CR(local_cr); SET_CR_ZERO; break;
1440 case 1: SET_CR_ZERO;
1441 __asm__ __volatile__ ("cmprb 1, 1, %0, %1" : : "r"(r14), "r"(r15));
1442 GET_CR(local_cr); SET_CR_ZERO; break;
1444 case 2: SET_CR_ZERO;
1445 __asm__ __volatile__ ("cmprb 2, 1, %0, %1" : : "r"(r14), "r"(r15));
1446 GET_CR(local_cr); SET_CR_ZERO; break;
1448 case 3: SET_CR_ZERO;
1449 __asm__ __volatile__ ("cmprb 3, 1, %0, %1" : : "r"(r14), "r"(r15));
1450 GET_CR(local_cr); SET_CR_ZERO; break;
1452 case 4: SET_CR_ZERO;
1453 __asm__ __volatile__ ("cmprb 4, 1, %0, %1" : : "r"(r14), "r"(r15));
1454 GET_CR(local_cr); SET_CR_ZERO; break;
1456 case 5: SET_CR_ZERO;
1457 __asm__ __volatile__ ("cmprb 5, 1, %0, %1" : : "r"(r14), "r"(r15));
1458 GET_CR(local_cr); SET_CR_ZERO; break;
1460 case 6: SET_CR_ZERO;
1461 __asm__ __volatile__ ("cmprb 6, 1, %0, %1" : : "r"(r14), "r"(r15));
1462 GET_CR(local_cr); SET_CR_ZERO; break;
1464 case 7: SET_CR_ZERO;
1465 __asm__ __volatile__ ("cmprb 7, 1, %0, %1" : : "r"(r14), "r"(r15));
1466 GET_CR(local_cr); SET_CR_ZERO; break;
1470 static void test_cmpeqb() {
1471 /* Clear condition code reg (CR) immediately before test
1472 * instruction, read CR and clear immediately after test
1473 * instruction. Otherwise, the CR gets corrupted and depending
1474 * on optimization level, strange loop control flow issues
1475 * occur because CR has been messed with.
1477 switch(x_index) {
1478 case 0: SET_CR_ZERO;
1479 __asm__ __volatile__ ("cmpeqb 0,%0, %1" : : "r"(r14), "r"(r15));
1480 GET_CR(local_cr); SET_CR_ZERO; break;
1482 case 1: SET_CR_ZERO;
1483 __asm__ __volatile__ ("cmpeqb 1,%0, %1" : : "r"(r14), "r"(r15));
1484 GET_CR(local_cr); SET_CR_ZERO; break;
1486 case 2: SET_CR_ZERO;
1487 __asm__ __volatile__ ("cmpeqb 2,%0, %1" : : "r"(r14), "r"(r15));
1488 GET_CR(local_cr); SET_CR_ZERO; break;
1490 case 3: SET_CR_ZERO;
1491 __asm__ __volatile__ ("cmpeqb 3,%0, %1" : : "r"(r14), "r"(r15));
1492 GET_CR(local_cr); SET_CR_ZERO; break;
1494 case 4: SET_CR_ZERO;
1495 __asm__ __volatile__ ("cmpeqb 4,%0, %1" : : "r"(r14), "r"(r15));
1496 GET_CR(local_cr); SET_CR_ZERO; break;
1498 case 5: SET_CR_ZERO;
1499 __asm__ __volatile__ ("cmpeqb 5,%0, %1" : : "r"(r14), "r"(r15));
1500 GET_CR(local_cr); SET_CR_ZERO; break;
1502 case 6: SET_CR_ZERO;
1503 __asm__ __volatile__ ("cmpeqb 6,%0, %1" : : "r"(r14), "r"(r15));
1504 GET_CR(local_cr); SET_CR_ZERO; break;
1506 case 7: SET_CR_ZERO;
1507 __asm__ __volatile__ ("cmpeqb 7,%0, %1" : : "r"(r14), "r"(r15));
1508 GET_CR(local_cr); SET_CR_ZERO; break;
1512 static test_list_t testgroup_char_compare[] = {
1513 { &test_cmprb_l0, "cmprb l=0" },
1514 { &test_cmprb_l1, "cmprb l=1" },
1515 { &test_cmpeqb , "cmpeqb" },
1516 { NULL , NULL },
1519 static void test_bcdtrunc_p0(void) {
1520 __asm__ __volatile__ ("bcdtrunc. %0, %1, %2, 0": "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1523 static void test_bcdtrunc_p1(void) {
1524 __asm__ __volatile__ ("bcdtrunc. %0, %1, %2, 1": "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1527 static void test_bcdutrunc(void) {
1528 __asm__ __volatile__ ("bcdutrunc. %0, %1, %2 ": "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1531 static void test_bcdadd_p0(void) {
1532 __asm__ __volatile__ ("bcdadd. %0, %1, %2, 0" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1535 static void test_bcdadd_p1(void) {
1536 __asm__ __volatile__ ("bcdadd. %0, %1, %2, 1" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1539 static void test_bcdsub_p0(void) {
1540 __asm__ __volatile__ ("bcdsub. %0, %1, %2, 0" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1543 static void test_bcdsub_p1(void) {
1544 __asm__ __volatile__ ("bcdsub. %0, %1, %2, 1" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1547 static void test_bcdcpsgn(void) {
1548 __asm__ __volatile__ ("bcdcpsgn. %0, %1, %2 ": "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1551 static void test_bcdctz_p0(void) {
1552 __asm__ __volatile__ ("bcdctz. %0, %1, 0 " : "=v"(vec_xt) : "v"(vec_xb));
1555 static void test_bcdctz_p1(void) {
1556 __asm__ __volatile__ ("bcdctz. %0, %1, 1 " : "=v"(vec_xt) : "v"(vec_xb));
1559 static void test_bcdsetsgn_p0(void) {
1560 __asm__ __volatile__ ("bcdsetsgn. %0, %1, 0 " : "=v"(vec_xt) : "v"(vec_xb));
1563 static void test_bcdsetsgn_p1(void) {
1564 __asm__ __volatile__ ("bcdsetsgn. %0, %1, 1 " : "=v"(vec_xt) : "v"(vec_xb));
1567 static void test_bcds_p0(void) {
1568 __asm__ __volatile__ ("bcds. %0, %1, %2, 0" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1571 static void test_bcds_p1(void) {
1572 __asm__ __volatile__ ("bcds. %0, %1, %2, 1" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1575 static void test_bcdus(void) {
1576 __asm__ __volatile__ ("bcdus. %0, %1, %2 " : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1579 static void test_bcdsr_p0(void) {
1580 __asm__ __volatile__ ("bcdsr. %0, %1, %2, 0" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1583 static void test_bcdsr_p1(void) {
1584 __asm__ __volatile__ ("bcdsr. %0, %1, %2, 1" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1587 static void test_bcdcfn_p0(void) {
1588 __asm__ __volatile__ ("bcdcfn. %0, %1, 0 " : "=v"(vec_xt) : "v"(vec_xb));
1591 static void test_bcdcfn_p1(void) {
1592 __asm__ __volatile__ ("bcdcfn. %0, %1, 1 " : "=v"(vec_xt) : "v"(vec_xb));
1595 static void test_bcdcfz_p0(void) {
1596 __asm__ __volatile__ ("bcdcfz. %0, %1, 0 " : "=v"(vec_xt) : "v"(vec_xb));
1599 static void test_bcdcfz_p1(void) {
1600 __asm__ __volatile__ ("bcdcfz. %0, %1, 1 " : "=v"(vec_xt) : "v"(vec_xb));
1603 static void test_bcdctn(void) {
1604 __asm__ __volatile__ ("bcdctn. %0, %1 " : "=v"(vec_xt) : "v"(vec_xb));
1607 static void test_vmul10uq(void) {
1608 __asm__ __volatile__ ("vmul10uq %0, %1 " : "=v"(vec_xt) : "v"(vec_xa));
1611 static void test_vmul10cuq(void) {
1612 __asm__ __volatile__ ("vmul10cuq %0, %1 " : "=v"(vec_xt) : "v"(vec_xa));
1615 static void test_vmul10euq(void) {
1616 __asm__ __volatile__ ("vmul10euq %0, %1, %2 " : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1619 static void test_vmul10ecuq(void) {
1620 __asm__ __volatile__ ("vmul10ecuq %0, %1, %2 " : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1623 static void test_bcdctsq(void) {
1624 __asm__ __volatile__ ("bcdctsq. %0, %1 " : "=v"(vec_xt) : "v"(vec_xb));
1627 static void test_bcdcfsq_p0(void) {
1628 __asm__ __volatile__ ("bcdcfsq. %0, %1, 0 " : "=v"(vec_xt) : "v"(vec_xb));
1631 static void test_bcdcfsq_p1(void) {
1632 __asm__ __volatile__ ("bcdcfsq. %0, %1, 1 " : "=v"(vec_xt) : "v"(vec_xb));
1635 static test_list_t testgroup_bcd_misc[] = {
1636 { &test_bcdadd_p0 , "bcdadd. p0" },
1637 { &test_bcdadd_p1 , "bcdadd. p1" },
1638 { &test_bcdsub_p0 , "bcdsub. p0" },
1639 { &test_bcdsub_p1 , "bcdsub. p1" },
1640 { &test_bcdcfn_p0 , "bcdcfn. p0" },
1641 { &test_bcdcfn_p1 , "bcdcfn. p1" },
1642 { &test_bcdcfz_p0 , "bcdcfz. p0" }, /* The p0, p1 substrings are used later */
1643 { &test_bcdcfz_p1 , "bcdcfz. p1" }, /* " " */
1644 { &test_bcdctn , "bcdctn. " },
1645 { &test_bcdctz_p0 , "bcdctz. p0" }, /* note: p0, p1 substrings are used later */
1646 { &test_bcdctz_p1 , "bcdctz. p1" }, /* " " */
1647 { &test_bcdcpsgn , "bcdcpsgn." },
1648 { &test_bcdsetsgn_p0, "bcdsetsgn. p0" },
1649 { &test_bcdsetsgn_p1, "bcdsetsgn. p1" },
1650 { &test_bcds_p0 , "bcds. p0" },
1651 { &test_bcds_p1 , "bcds. p1" },
1652 { &test_bcdus , "bcdus. " },
1653 { &test_bcdsr_p0 , "bcdsr. p0" },
1654 { &test_bcdsr_p1 , "bcdsr. p1" },
1655 { &test_bcdtrunc_p0 , "bcdtrunc. p0" },
1656 { &test_bcdtrunc_p1 , "bcdtrunc. p1" },
1657 { &test_bcdutrunc , "bcdutrunc. " },
1658 { &test_vmul10uq , "vmul10uq " },
1659 { &test_vmul10cuq , "vmul10cuq " },
1660 { &test_vmul10euq , "vmul10euq " },
1661 { &test_vmul10ecuq , "vmul10ecuq " },
1662 { &test_bcdctsq , "bcdctsq." },
1663 { &test_bcdcfsq_p0 , "bcdcfsq. p0" },
1664 { &test_bcdcfsq_p1 , "bcdcfsq. p1" },
1665 { NULL , NULL },
1668 static void test_wait(void) {
1669 __asm__ __volatile__ ("wait 0" : :);
1672 static test_list_t testgroup_noop_misc[] = {
1673 { &test_wait, "wait ",},
1674 { NULL , NULL, },
1677 /* The significance field can be any values within bits 10-15 of the
1678 * instruction. For this test, limiting the values to one per bit location.
1680 static void test_dtstsfi() {
1681 _Decimal128 df14 = dfp_value.dec_val128;
1682 switch(dfp_significance) {
1683 case 0x00: __asm__ __volatile__ ("dtstsfi 3, 0x00, %0" : : "f" (df14));
1684 GET_CR(local_cr); break;
1686 case 0x01: __asm__ __volatile__ ("dtstsfi 3, 0x01, %0" : : "f" (df14));
1687 GET_CR(local_cr); break;
1689 case 0x02: __asm__ __volatile__ ("dtstsfi 3, 0x02, %0" : : "f" (df14));
1690 GET_CR(local_cr); break;
1692 case 0x03: __asm__ __volatile__ ("dtstsfi 3, 0x03, %0" : : "f" (df14));
1693 GET_CR(local_cr); break;
1695 case 0x04: __asm__ __volatile__ ("dtstsfi 3, 0x04, %0" : : "f" (df14));
1696 GET_CR(local_cr); break;
1698 case 0x06: __asm__ __volatile__ ("dtstsfi 3, 0x06, %0" : : "f" (df14));
1699 GET_CR(local_cr); break;
1701 case 0x08: __asm__ __volatile__ ("dtstsfi 3, 0x08, %0" : : "f" (df14));
1702 GET_CR(local_cr); break;
1704 case 0x0c: __asm__ __volatile__ ("dtstsfi 3, 0x0c, %0" : : "f" (df14));
1705 GET_CR(local_cr); break;
1707 case 0x10: __asm__ __volatile__ ("dtstsfi 3, 0x10, %0" : : "f" (df14));
1708 GET_CR(local_cr); break;
1710 case 0x18: __asm__ __volatile__ ("dtstsfi 3, 0x18, %0" : : "f" (df14));
1711 GET_CR(local_cr); break;
1713 case 0x20: __asm__ __volatile__ ("dtstsfi 3, 0x20, %0" : : "f" (df14));
1714 GET_CR(local_cr); break;
1718 static void test_dtstsfiq() {
1719 _Decimal128 df14 = dfp_value.dec_val128;
1720 switch(dfp_significance) {
1721 case 0x00: SET_CR_ZERO;
1722 __asm__ __volatile__ ("dtstsfiq 3, 0x00, %0" : : "d" (df14));
1723 GET_CR(local_cr); break;
1725 case 0x01: SET_CR_ZERO;
1726 __asm__ __volatile__ ("dtstsfiq 3, 0x01, %0" : : "d" (df14));
1727 GET_CR(local_cr); break;
1729 case 0x02: SET_CR_ZERO;
1730 __asm__ __volatile__ ("dtstsfiq 3, 0x02, %0" : : "d" (df14));
1731 GET_CR(local_cr); break;
1733 case 0x03: SET_CR_ZERO;
1734 __asm__ __volatile__ ("dtstsfiq 3, 0x03, %0" : : "d" (df14));
1735 GET_CR(local_cr); break;
1737 case 0x04: SET_CR_ZERO;
1738 __asm__ __volatile__ ("dtstsfiq 3, 0x04, %0" : : "d" (df14));
1739 GET_CR(local_cr); break;
1741 case 0x06: SET_CR_ZERO;
1742 __asm__ __volatile__ ("dtstsfiq 3, 0x06, %0" : : "d" (df14));
1743 GET_CR(local_cr); break;
1745 case 0x08: SET_CR_ZERO;
1746 __asm__ __volatile__ ("dtstsfiq 3, 0x08, %0" : : "d" (df14));
1747 GET_CR(local_cr); break;
1749 case 0x0c: SET_CR_ZERO;
1750 __asm__ __volatile__ ("dtstsfiq 3, 0x0c, %0" : : "d" (df14));
1751 GET_CR(local_cr); break;
1753 case 0x10: SET_CR_ZERO;
1754 __asm__ __volatile__ ("dtstsfiq 3, 0x10, %0" : : "d" (df14));
1755 GET_CR(local_cr); break;
1757 case 0x18: SET_CR_ZERO;
1758 __asm__ __volatile__ ("dtstsfiq 3, 0x18, %0" : : "d" (df14));
1759 GET_CR(local_cr); break;
1761 case 0x20: SET_CR_ZERO;
1762 __asm__ __volatile__ ("dtstsfiq 3, 0x20, %0" : : "d" (df14));
1763 GET_CR(local_cr); break;
1767 static test_list_t testgroup_dfp_significance[] = {
1768 { &test_dtstsfi , "dtstsfi" },
1769 { &test_dtstsfiq, "dtstsfiq" },
1770 { NULL , NULL },
1773 static void test_addpcis(void) {
1774 switch (x_index) {
1775 case 0x0: __asm__ __volatile__ ("addpcis 14, %0" : : "i"(0x0) ); break;
1776 case 0x1: __asm__ __volatile__ ("addpcis 14, %0" : : "i"(0x1) ); break;
1777 case 0x2: __asm__ __volatile__ ("addpcis 14, %0" : : "i"(0x2) ); break;
1778 case 0x3: __asm__ __volatile__ ("addpcis 14, %0" : : "i"(0x40) ); break;
1779 case 0x4: __asm__ __volatile__ ("addpcis 14, %0" : : "i"(0x800) ); break;
1780 case 0x5: __asm__ __volatile__ ("addpcis 14, %0" : : "i"(0x2000) ); break;
1781 case 0x6: __asm__ __volatile__ ("addpcis 14, %0" : : "i"(0x7fff) ); break;
1782 case 0x7: __asm__ __volatile__ ("addpcis 14, %0" : : "i"(0x8000) ); break;
1783 case 0x8: __asm__ __volatile__ ("addpcis 14, -%0" : : "i"(0x0) ); break;
1784 case 0x9: __asm__ __volatile__ ("addpcis 14, -%0" : : "i"(0x1) ); break;
1785 case 0xa: __asm__ __volatile__ ("addpcis 14, -%0" : : "i"(0x2) ); break;
1786 case 0xb: __asm__ __volatile__ ("addpcis 14, -%0" : : "i"(0x40) ); break;
1787 case 0xc: __asm__ __volatile__ ("addpcis 14, -%0" : : "i"(0x800) ); break;
1788 case 0xd: __asm__ __volatile__ ("addpcis 14, -%0" : : "i"(0x2000) ); break;
1789 case 0xe: __asm__ __volatile__ ("addpcis 14, -%0" : : "i"(0x7fff) ); break;
1790 case 0xf: __asm__ __volatile__ ("addpcis 14, -%0" : : "i"(0x8000) ); break;
1794 static void test_subpcis(void) {
1795 switch (x_index) {
1796 case 0x0: __asm__ __volatile__ ("subpcis 14, %0" : : "i"(0x0) ); break;
1797 case 0x1: __asm__ __volatile__ ("subpcis 14, %0" : : "i"(0x1) ); break;
1798 case 0x2: __asm__ __volatile__ ("subpcis 14, %0" : : "i"(0x2) ); break;
1799 case 0x3: __asm__ __volatile__ ("subpcis 14, %0" : : "i"(0x40) ); break;
1800 case 0x4: __asm__ __volatile__ ("subpcis 14, %0" : : "i"(0x800) ); break;
1801 case 0x5: __asm__ __volatile__ ("subpcis 14, %0" : : "i"(0x2000) ); break;
1802 case 0x6: __asm__ __volatile__ ("subpcis 14, %0" : : "i"(0x7fff) ); break;
1803 case 0x7: __asm__ __volatile__ ("subpcis 14, %0" : : "i"(0x8000) ); break;
1804 case 0x8: __asm__ __volatile__ ("subpcis 14, -%0" : : "i"(0x0) ); break;
1805 case 0x9: __asm__ __volatile__ ("subpcis 14, -%0" : : "i"(0x1) ); break;
1806 case 0xa: __asm__ __volatile__ ("subpcis 14, -%0" : : "i"(0x2) ); break;
1807 case 0xb: __asm__ __volatile__ ("subpcis 14, -%0" : : "i"(0x40) ); break;
1808 case 0xc: __asm__ __volatile__ ("subpcis 14, -%0" : : "i"(0x80) ); break;
1809 case 0xd: __asm__ __volatile__ ("subpcis 14, -%0" : : "i"(0x200) ); break;
1810 case 0xe: __asm__ __volatile__ ("subpcis 14, -%0" : : "i"(0x7fff) ); break;
1811 case 0xf: __asm__ __volatile__ ("subpcis 14, -%0" : : "i"(0x8000) ); break;
1815 static test_list_t testgroup_pc_immediate_misc[] = {
1816 { &test_addpcis, "addpcis " },
1817 { &test_subpcis, "subpcis " },
1818 { NULL , NULL },
1821 static void test_xsiexpdp(void) {
1822 __asm__ __volatile__ ("xsiexpdp %x0, %1, %2 " : "+wa" (vec_xt): "r" (r14), "r" (r15));
1825 static void test_xscvhpdp(void) {
1826 __asm__ __volatile__ ("xscvhpdp %x0, %x1 " : "+wa" (vec_xt) : "wa" (vec_xb));
1829 static void test_xscvdphp(void) {
1830 __asm__ __volatile__ ("xscvdphp %x0, %x1 " : "+wa" (vec_xt) : "wa" (vec_xb));
1833 static void test_xvcvhpsp(void) {
1834 __asm__ __volatile__ ("xvcvhpsp %x0, %x1 " : "+wa" (vec_xt) : "wa" (vec_xb));
1837 static void test_xvcvsphp(void) {
1838 __asm__ __volatile__ ("xvcvsphp %x0, %x1 " : "+wa" (vec_xt) : "wa" (vec_xb));
1841 static test_list_t testgroup_vector_scalar_two_double[] = {
1842 { &test_xsiexpdp, "xsiexpdp" },
1843 { &test_xscvhpdp, "xscvhpdp" },
1844 { &test_xscvdphp, "xscvdphp" },
1845 { &test_xvcvhpsp, "xvcvhpsp" },
1846 { &test_xvcvsphp, "xvcvsphp" },
1847 { NULL , NULL },
1851 static void test_xsabsqp(void) {
1852 __asm__ __volatile__ ("xsabsqp %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1855 static void test_xscvdpqp(void) {
1856 __asm__ __volatile__ ("xscvdpqp %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1859 static void test_xscvqpdp(void) {
1860 __asm__ __volatile__ ("xscvqpdp %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1863 static void test_xscvqpdpo(void) {
1864 __asm__ __volatile__ ("xscvqpdpo %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1867 static void test_xscvqpsdz(void) {
1868 __asm__ __volatile__ ("xscvqpsdz %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1871 static void test_xscvqpswz(void) {
1872 __asm__ __volatile__ ("xscvqpswz %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1875 static void test_xscvqpudz(void) {
1876 __asm__ __volatile__ ("xscvqpudz %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1879 static void test_xscvqpuwz(void) {
1880 __asm__ __volatile__ ("xscvqpuwz %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1883 static void test_xscvsdqp(void) {
1884 __asm__ __volatile__ ("xscvsdqp %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1887 static void test_xscvudqp(void) {
1888 __asm__ __volatile__ ("xscvudqp %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1891 static void test_xsxexpqp(void) {
1892 __asm__ __volatile__ ("xsxexpqp %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1895 static void test_xsxsigqp(void) {
1896 __asm__ __volatile__ ("xsxsigqp %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1899 static void test_xsnegqp(void) {
1900 __asm__ __volatile__ ("xsnegqp %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1903 static void test_xsnabsqp(void) {
1904 __asm__ __volatile__ ("xsnabsqp %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1907 static void test_xssqrtqp(void) {
1908 __asm__ __volatile__ ("xssqrtqp %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1911 static void test_xssqrtqpo(void) {
1912 __asm__ __volatile__ ("xssqrtqpo %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1915 static test_list_t testgroup_vector_scalar_two_quad[] = {
1916 { &test_xsabsqp , "xsabsqp " },
1917 { &test_xscvdpqp , "xscvdpqp " },
1918 { &test_xscvqpdp , "xscvqpdp " },
1919 { &test_xscvqpdpo, "xscvqpdpo " },
1920 { &test_xscvqpsdz, "xscvqpsdz " },
1921 { &test_xscvqpswz, "xscvqpswz " },
1922 { &test_xscvqpudz, "xscvqpudz " },
1923 { &test_xscvqpuwz, "xscvqpuwz " },
1924 { &test_xscvsdqp , "xscvsdqp " },
1925 { &test_xscvudqp , "xscvudqp " },
1926 { &test_xsxexpqp , "xsxexpqp " },
1927 { &test_xsxsigqp , "xsxsigqp " },
1928 { &test_xsnegqp , "xsnegqp " },
1929 { &test_xsnabsqp , "xsnabsqp " },
1930 { &test_xssqrtqp , "xssqrtqp " },
1931 { &test_xssqrtqpo, "xssqrtqpo " },
1932 { NULL , NULL },
1935 static void test_xsaddqp(void) {
1936 __asm__ __volatile__ ("xsaddqp %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1939 static void test_xsaddqpo(void) {
1940 __asm__ __volatile__ ("xsaddqpo %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1943 static void test_xscpsgnqp(void) {
1944 __asm__ __volatile__ ("xscpsgnqp %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1947 static void test_xsdivqp(void) {
1948 __asm__ __volatile__ ("xsdivqp %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1951 static void test_xsdivqpo(void) {
1952 __asm__ __volatile__ ("xsdivqpo %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1955 static void test_xsiexpqp(void) {
1956 __asm__ __volatile__ ("xsiexpqp %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1959 static void test_xsmaddqp(void) {
1960 __asm__ __volatile__ ("xsmaddqp %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1963 static void test_xsmaddqpo(void) {
1964 __asm__ __volatile__ ("xsmaddqpo %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1967 static void test_xsmsubqp(void) {
1968 __asm__ __volatile__ ("xsmsubqp %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1971 static void test_xsmsubqpo(void) {
1972 __asm__ __volatile__ ("xsmsubqpo %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1975 static void test_xsmulqp(void) {
1976 __asm__ __volatile__ ("xsmulqp %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1979 static void test_xsmulqpo(void) {
1980 __asm__ __volatile__ ("xsmulqpo %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1983 static void test_xsnmaddqp(void) {
1984 __asm__ __volatile__ ("xsnmaddqp %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1987 static void test_xsnmaddqpo(void) {
1988 __asm__ __volatile__ ("xsnmaddqpo %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1991 static void test_xsnmsubqp(void) {
1992 __asm__ __volatile__ ("xsnmsubqp %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1995 static void test_xsnmsubqpo(void) {
1996 __asm__ __volatile__ ("xsnmsubqpo %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1999 static void test_xssubqp(void) {
2000 __asm__ __volatile__ ("xssubqp %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
2003 static void test_xssubqpo(void) {
2004 __asm__ __volatile__ ("xssubqpo %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
2007 static test_list_t testgroup_vector_three_quad[] = {
2008 { &test_xsaddqp , "xsaddqp " },
2009 { &test_xsaddqpo , "xsaddqpo " },
2010 { &test_xscpsgnqp , "xscpsgnqp " },
2011 { &test_xsdivqp , "xsdivqp " },
2012 { &test_xsdivqpo , "xsdivqpo " },
2013 { &test_xsiexpqp , "xsiexpqp " },
2014 { &test_xsmaddqp , "xsmaddqp " },
2015 { &test_xsmaddqpo , "xsmaddqpo " },
2016 { &test_xsmsubqp , "xsmsubqp " },
2017 { &test_xsmsubqpo , "xsmsubqpo " },
2018 { &test_xsmulqp , "xsmulqp " },
2019 { &test_xsmulqpo , "xsmulqpo " },
2020 { &test_xsnmaddqp , "xsnmaddqp " },
2021 { &test_xsnmaddqpo, "xsnmaddqpo " },
2022 { &test_xsnmsubqp , "xsnmsubqp " },
2023 { &test_xsnmsubqpo, "xsnmsubqpo " },
2024 { &test_xssubqp , "xssubqp " },
2025 { &test_xssubqpo , "xssubqpo " },
2026 { NULL , NULL },
2029 #define XSCMPEXPQP(x) \
2030 SET_FPSCR_ZERO \
2031 SET_CR_ZERO \
2032 __asm__ __volatile__ \
2033 ("xscmpexpqp %0, %1, %2" :: "i"(x), "v"(vec_xa), "v"(vec_xb)); \
2034 GET_CR(local_cr); \
2035 GET_FPSCR(local_fpscr);
2037 #define XSCMPOQP(x) \
2038 SET_FPSCR_ZERO \
2039 SET_CR_ZERO \
2040 __asm__ __volatile__ \
2041 ("xscmpoqp %0, %1, %2" :: "i"(x), "v"(vec_xa), "v"(vec_xb)); \
2042 GET_CR(local_cr); \
2043 GET_FPSCR(local_fpscr);
2045 #define XSCMPUQP(x) \
2046 SET_FPSCR_ZERO \
2047 SET_CR_ZERO \
2048 __asm__ __volatile__ \
2049 ("xscmpuqp %0, %1, %2"::"i"(x), "v"(vec_xa), "v"(vec_xb)); \
2050 GET_CR(local_cr); \
2051 GET_FPSCR(local_fpscr);
2053 static void test_xscmpexpqp(void) {
2054 switch(x_index) {
2055 case 0: XSCMPEXPQP(0); break;
2056 case 1: XSCMPEXPQP(1); break;
2057 case 2: XSCMPEXPQP(2); break;
2058 case 3: XSCMPEXPQP(3); break;
2059 case 4: XSCMPEXPQP(4); break;
2060 case 5: XSCMPEXPQP(5); break;
2061 case 6: XSCMPEXPQP(6); break;
2062 case 7: XSCMPEXPQP(7); break;
2063 default:
2064 printf("Unhandled shift value for %s %x\n", __FUNCTION__, x_index);
2068 static void test_xscmpoqp(void) {
2069 switch(x_index) {
2070 case 0: XSCMPOQP(0); break;
2071 case 1: XSCMPOQP(1); break;
2072 case 2: XSCMPOQP(2); break;
2073 case 3: XSCMPOQP(3); break;
2074 case 4: XSCMPOQP(4); break;
2075 case 5: XSCMPOQP(5); break;
2076 case 6: XSCMPOQP(6); break;
2077 case 7: XSCMPOQP(7); break;
2078 default:
2079 printf("Unhandled shift value for %s %x\n", __FUNCTION__, x_index);
2083 static void test_xscmpuqp(void) {
2084 switch(x_index) {
2085 case 0: XSCMPUQP(0); break;
2086 case 1: XSCMPUQP(1); break;
2087 case 2: XSCMPUQP(2); break;
2088 case 3: XSCMPUQP(3); break;
2089 case 4: XSCMPUQP(4); break;
2090 case 5: XSCMPUQP(5); break;
2091 case 6: XSCMPUQP(6); break;
2092 case 7: XSCMPUQP(7); break;
2093 default:
2094 printf("Unhandled shift value for %s %x\n", __FUNCTION__, x_index);
2098 static test_list_t testgroup_vector_scalar_compare_quads[] = {
2099 { &test_xscmpexpqp, "xscmpexpqp" },
2100 { &test_xscmpoqp , "xscmpoqp " },
2101 { &test_xscmpuqp , "xscmpuqp " },
2102 { NULL , NULL },
2105 #define XSRQPI(R,RMC) \
2106 SET_FPSCR_ZERO \
2107 SET_CR_ZERO \
2108 __asm__ __volatile__ \
2109 ("xsrqpi %1, %0, %2, %3" : "=v"(vec_xt) : "i"(R), "v"(vec_xb), "i"(RMC)); \
2110 GET_CR(local_cr); \
2111 GET_FPSCR(local_fpscr);
2113 #define XSRQPIX(R,RMC) \
2114 SET_FPSCR_ZERO \
2115 SET_CR_ZERO \
2116 __asm__ __volatile__ \
2117 ("xsrqpix %1, %0, %2, %3" : "=v"(vec_xt) : "i"(R), "v"(vec_xb), "i"(RMC));\
2118 GET_CR(local_cr); \
2119 GET_FPSCR(local_fpscr);
2121 #define XSRQPXP(R,RMC) \
2122 SET_FPSCR_ZERO \
2123 SET_CR_ZERO \
2124 __asm__ __volatile__ \
2125 ("xsrqpxp %1, %0, %2, %3" : "=v"(vec_xt) : "i"(R), "v"(vec_xb), "i"(RMC));\
2126 GET_CR(local_cr); \
2127 GET_FPSCR(local_fpscr);
2129 /* For the scalar round to quad instructions, x_index is used to key into
2130 * two fields; x_index bit [2] becomes the one-bit 'R' and x_index bits [0, 1]
2131 * becomes the two-bit 'RMC'.
2133 static void test_xsrqpi(void) {
2134 switch(x_index) {
2135 case 0: XSRQPI(0, 0); break;
2136 case 1: XSRQPI(0, 1); break;
2137 case 2: XSRQPI(0, 2); break;
2138 case 3: XSRQPI(0, 3); break;
2139 case 4: XSRQPI(1, 0); break;
2140 case 5: XSRQPI(1, 1); break;
2141 case 6: XSRQPI(1, 2); break;
2142 case 7: XSRQPI(1, 3); break;
2145 static void test_xsrqpix(void) {
2146 switch(x_index) {
2147 case 0: XSRQPIX(0, 0); break;
2148 case 1: XSRQPIX(0, 1); break;
2149 case 2: XSRQPIX(0, 2); break;
2150 case 3: XSRQPIX(0, 3); break;
2151 case 4: XSRQPIX(1, 0); break;
2152 case 5: XSRQPIX(1, 1); break;
2153 case 6: XSRQPIX(1, 2); break;
2154 case 7: XSRQPIX(1, 3); break;
2158 static void test_xsrqpxp(void) {
2159 switch(x_index) {
2160 case 0: XSRQPXP(0, 0); break;
2161 case 1: XSRQPXP(0, 1); break;
2162 case 2: XSRQPXP(0, 2); break;
2163 case 3: XSRQPXP(0, 3); break;
2164 case 4: XSRQPXP(1, 0); break;
2165 case 5: XSRQPXP(1, 1); break;
2166 case 6: XSRQPXP(1, 2); break;
2167 case 7: XSRQPXP(1, 3); break;
2171 static test_list_t testgroup_vector_scalar_rounding_quads[] = {
2172 { &test_xsrqpi , "xsrqpi " },
2173 { &test_xsrqpix, "xsrqpix" },
2174 { &test_xsrqpxp, "xsrqpxp" },
2175 { NULL , NULL },
2178 /* Move From FPSCR variants:
2179 * Move From FpScr [ &
2180 * Clear Enables |
2181 * Lightweight |
2182 * Control [&
2183 * set DRN [ Immediate] |
2184 * set RN [ Immediate ] ]]
2186 /* mffs FRT # Move From FPSCR*/
2187 static void test_mffs (void) {
2188 SET_FPSCR_ZERO
2189 __asm__ __volatile__ ("mffs %0" : "=f"(f14) );
2190 GET_FPSCR(local_fpscr);
2191 SET_FPSCR_ZERO
2194 /* mffsce FRT # Move From FPSCR and Clear Enables */
2195 static void test_mffsce (void) {
2196 SET_FPSCR_ZERO
2197 __asm__ __volatile__ ("mffsce %0" : "=f"(f14) );
2198 GET_FPSCR(local_fpscr);
2199 SET_FPSCR_ZERO
2202 /* mffscdrn FRT,FRB # Move From FpScr and Control &set DRN */
2203 static void test_mffscdrn (void) {
2204 SET_FPSCR_ZERO
2205 __asm__ __volatile__ ("mffscdrn %0,%1" : "=f"(f14): "f"(f15) );
2206 GET_FPSCR(local_fpscr);
2207 SET_FPSCR_ZERO
2210 /* mffscdrni FRT,DRM # Move From FpScr & Control &set DRN Immediate*/
2211 static void test_mffscdrni (void) {
2212 switch(x_shift) {
2213 default:
2214 case 0:
2215 SET_FPSCR_ZERO
2216 __asm__ __volatile__ ("mffscdrni %0,0" : "=f"(f14) );
2217 GET_FPSCR(local_fpscr);
2218 SET_FPSCR_ZERO
2219 break;
2220 case 1:
2221 SET_FPSCR_ZERO
2222 __asm__ __volatile__ ("mffscdrni %0,1" : "=f"(f14) );
2223 GET_FPSCR(local_fpscr);
2224 SET_FPSCR_ZERO
2225 break;
2226 case 2:
2227 SET_FPSCR_ZERO
2228 __asm__ __volatile__ ("mffscdrni %0,2" : "=f"(f14) );
2229 GET_FPSCR(local_fpscr);
2230 SET_FPSCR_ZERO
2231 break;
2235 /* mffscrn FRT,FRB # Move From FpScr and Control &set RN*/
2236 static void test_mffscrn (void) {
2237 SET_FPSCR_ZERO
2238 __asm__ __volatile__ ("mffscrn %0,%1" : "=f"(f14):"f"(f15));
2239 GET_FPSCR(local_fpscr);
2240 SET_FPSCR_ZERO
2243 /* mffscrni FRT,RM # Move from FpScr and Control &set RN Immediate*/
2244 static void test_mffscrni (void) {
2245 switch(x_shift) {
2246 case 0:
2247 SET_FPSCR_ZERO
2248 __asm__ __volatile__ ("mffscrni %0,0" : "=f"(f14) );
2249 GET_FPSCR(local_fpscr);
2250 SET_FPSCR_ZERO
2251 break;
2252 case 1:
2253 SET_FPSCR_ZERO
2254 __asm__ __volatile__ ("mffscrni %0,1" : "=f"(f14) );
2255 GET_FPSCR(local_fpscr);
2256 SET_FPSCR_ZERO
2257 break;
2258 case 2:
2259 SET_FPSCR_ZERO
2260 __asm__ __volatile__ ("mffscrni %0,2" : "=f"(f14) );
2261 GET_FPSCR(local_fpscr);
2262 SET_FPSCR_ZERO
2263 break;
2267 /* mffsl FRT # Move From FpScr Lightweight */
2268 static void test_mffsl (void) {
2269 SET_FPSCR_ZERO
2270 __asm__ __volatile__ ("mffsl %0" : "=f"(f14) );
2271 GET_FPSCR(local_fpscr);
2272 SET_FPSCR_ZERO
2275 /* mffs* instructions using FRT only. */
2276 /* Note to self - Watch DRM,RM fields. */
2277 static test_list_t testgroup_mffs_misc[] = {
2278 { &test_mffsce, "mffsce" },
2279 { &test_mffsl, "mffsl" },
2280 { &test_mffs, "mffs" },
2281 { NULL , NULL },
2284 /* mffs* instructions using FRT,FRB. */
2285 static test_list_t testgroup_mffs_misc_one[] = {
2286 { &test_mffscdrni, "mffscdrni" },
2287 { &test_mffscdrn, "mffscdrn" },
2288 { &test_mffscrni, "mffscrni" },
2289 { &test_mffscrn, "mffscrn" },
2290 { NULL , NULL },
2294 /* ###### begin all_tests table. */
2296 /* table containing all of the instruction groups */
2297 struct test_group_table_t {
2298 test_list_t *tests;
2299 const char *name;
2300 unsigned int flags;
2303 typedef struct test_group_table_t test_group_table_t;
2305 static test_group_table_t all_tests[] = {
2307 testgroup_ia_ops_two,
2308 "PPC integer arith instructions with two args",
2309 PPC_INTEGER | PPC_ARITH | PPC_TWO_ARGS,
2312 testgroup_shifted_one,
2313 "ppc one argument plus shift",
2314 PPC_MISC | PPC_CR | PPC_TWO_ARGS,
2317 testgroup_three_args,
2318 "ppc three parameter ops",
2319 PPC_INTEGER | PPC_ARITH | PPC_THREE_ARGS,
2322 testgroup_logical_one,
2323 "ppc count zeros",
2324 PPC_INTEGER | PPC_LOGICAL | PPC_ONE_ARG,
2327 testgroup_set_boolean,
2328 "ppc set boolean",
2329 PPC_INTEGER | PPC_LOGICAL | PPC_ONE_IMM,
2332 testgroup_char_compare,
2333 "ppc char compare",
2334 PPC_INTEGER | PPC_COMPARE,
2337 testgroup_vsx_absolute,
2338 "ppc vector absolutes",
2339 PPC_ALTIVEC | PPC_ARITH | PPC_TWO_ARGS,
2342 testgroup_vector_immediate,
2343 "ppc vector logical immediate",
2344 PPC_ALTIVEC | PPC_LOGICAL | PPC_ONE_IMM,
2347 testgroup_vector_logical_one,
2348 "ppc vector logical one",
2349 PPC_ALTIVEC | PPC_LOGICAL | PPC_ONE_ARG,
2352 testgroup_gpr_vector_logical_one,
2353 "ppc gpr vector logical one",
2354 PPC_ALTIVEC | PPC_LOGICAL | PPC_ONE_GPR_ONE_VEC,
2357 testgroup_vector_extend_sign,
2358 "ppc vector extend sign",
2359 PPC_ALTIVEC | PPC_LOGICAL | PPC_TWO_ARGS,
2362 testgroup_vector_three_quad,
2363 "ppc vector three quad",
2364 PPC_ALTIVEC | PPC_LOGICAL | PPC_THREE_ARGS,
2367 testgroup_vector_scalar_two_quad,
2368 "ppc vector scalar quad",
2369 PPC_ALTIVEC_QUAD | PPC_LOGICAL | PPC_TWO_ARGS,
2372 testgroup_vector_scalar_compare_quads,
2373 "ppc vector scalar compare exponents quads",
2374 PPC_ALTIVEC_QUAD | PPC_COMPARE | PPC_COMPARE_ARGS,
2377 testgroup_vector_scalar_rounding_quads,
2378 "ppc vector scalar rounding quads",
2379 PPC_ALTIVEC_QUAD | PPC_ROUND,
2382 testgroup_vsx_xxpermute,
2383 "ppc vector permutes",
2384 PPC_ALTIVEC | PPC_PERMUTE,
2387 testgroup_vector_four,
2388 "ppc vector three args + dest",
2389 PPC_ALTIVEC | PPC_LOGICAL | PPC_FOUR_ARGS,
2392 testgroup_vector_inserts,
2393 "ppc vector inserts",
2394 PPC_ALTIVEC | PPC_INSERTEXTRACT | PPC_ONE_IMM,
2397 testgroup_vector_extract,
2398 "ppc vector extract from vector to reg",
2399 PPC_ALTIVEC | PPC_INSERTEXTRACT | PPC_TWO_ARGS,
2402 testgroup_vector_count_bytes,
2403 "ppc vector count leading/trailing bytes",
2404 PPC_ALTIVEC | PPC_POPCNT,
2407 testgroup_vector_scalar_loadstore_length,
2408 "ppc vector load/store",
2409 PPC_ALTIVEC | PPC_LDST | PPC_ONE_IMM,
2412 testgroup_vector_loadstore,
2413 "ppc vector load/store",
2414 PPC_ALTIVEC | PPC_LDST | PPC_TWO_ARGS,
2417 testgroup_vectorscalar_move_tofrom,
2418 "ppc vector scalar move to/from",
2419 PPC_MISC | PPC_TWO_ARGS,
2422 testgroup_vector_scalar_compare_double,
2423 "ppc vector scalar compare doubles",
2424 PPC_ALTIVEC_DOUBLE | PPC_COMPARE | PPC_COMPARE_ARGS,
2427 testgroup_vector_scalar_data_class,
2428 "ppc vector scalar test data class tests",
2429 PPC_ALTIVEC_DOUBLE | PPC_COMPARE | PPC_ONE_ARG,
2432 testgroup_vector_scalar_two_double,
2433 "ppc vector scalar tests against float double two args ",
2434 PPC_ALTIVEC_DOUBLE | PPC_COMPARE | PPC_TWO_ARGS,
2437 testgroup_dfp_significance,
2438 "ppc dfp significance",
2439 PPC_DFP,
2442 testgroup_bcd_misc,
2443 "ppc bcd misc",
2444 PPC_BCD,
2447 testgroup_noop_misc,
2448 "ppc noop misc",
2449 PPC_NO_OP,
2452 testgroup_pc_immediate_misc,
2453 "ppc addpc_misc",
2454 PPC_PC_IMMEDIATE,
2457 testgroup_mffs_misc,
2458 "ppc mffpscr",
2459 PPC_MFFS,
2462 testgroup_mffs_misc_one,
2463 "ppc mffpscr",
2464 PPC_MFFS,
2466 { NULL, NULL, 0x00000000, },
2469 #define instruction_touches_xer(instruction_name) \
2470 (strncmp(instruction_name, "addex", 5) == 0)
2472 static void testfunction_int_two_args (const char* instruction_name,
2473 test_func_t func,
2474 unsigned int test_flags)
2476 volatile HWord_t res;
2477 volatile unsigned int cr;
2478 int i, j;
2480 VERBOSE_FUNCTION_CALLOUT
2482 for (i = 0; i < nb_iargs; i++) {
2483 for (j = 0; j < nb_iargs; j++) {
2485 r14 = iargs[i];
2486 r15 = iargs[j];
2488 SET_CR_ZERO;
2489 (*func)();
2490 GET_CR(cr);
2491 GET_XER(local_xer);
2492 res = r17;
2494 printf("%s %016lx, %016lx => %016lx (%08x)",
2495 instruction_name, (long unsigned)iargs[i],
2496 (long unsigned)iargs[j], (long unsigned)res,
2497 cr);
2498 if (instruction_touches_xer(instruction_name)) {
2499 dissect_xer(local_xer);
2501 printf("\n");
2503 if (verbose) printf("\n");
2507 #define instruction_sets_cr0_to_zero(inst_name) \
2508 ( (strncmp(inst_name, "cnttzw.", 7) == 0 ) || \
2509 (strncmp(inst_name, "cnttzd.", 7) == 0 ) )
2511 static void testfunction_logical_one (const char* instruction_name,
2512 test_func_t func,
2513 unsigned int test_flags) {
2514 int i;
2515 volatile HWord_t res;
2516 volatile unsigned int cr;
2518 VERBOSE_FUNCTION_CALLOUT
2520 for (i = 0; i < nb_iargs; i++) {
2522 r14 = iargs[i];
2524 /* The logical instructions will set CR fields to zero, so
2525 * lets start with some non zero content in CR0.
2527 SET_CR0_FIELD(0xF);
2529 (*func)();
2531 res = r17;
2532 GET_CR(cr);
2534 printf("%s %016lx => %016lx",
2535 instruction_name, (long unsigned)iargs[i], (long unsigned)res);
2537 if (instruction_sets_cr0_to_zero(instruction_name)
2538 && ((cr & 0xF0000000) != 0 )) {
2539 /* The dotted version sets the CR0 to 0, verify */
2540 printf(" Expected cr0 to be zero, it is (%08x)\n", cr & 0xF0000000);
2542 printf("\n");
2544 if (verbose) printf("\n");
2548 void testfunction_one_arg_with_shift (const char* instruction_name,
2549 test_func_t test_function,
2550 unsigned int ignore_test_flags)
2552 /*This function uses global variable x_shift */
2553 volatile HWord_t res;
2554 volatile unsigned int cr;
2555 int i, j;
2557 VERBOSE_FUNCTION_CALLOUT
2559 for (i = 0; i < SHIFT_VALUES_SIZE; i++) {
2560 for (j = 0; j < SHIFT_ARRAY_SIZE; j++) {
2562 r14 = values_to_shift[i];
2563 x_shift = shift_amounts[j];
2565 SET_CR_ZERO;
2567 (*test_function)();
2569 GET_CR(cr);
2570 res = r17;
2572 printf("%s %016lx, %016lx => %016lx (%08x)\n",
2573 instruction_name, (long unsigned)values_to_shift[i],
2574 (long unsigned)x_shift, (long unsigned)res, cr);
2579 static void testfunction_three_args (const char* instruction_name,
2580 test_func_t test_function,
2581 unsigned int ignore_test_flags)
2583 volatile HWord_t res;
2584 volatile unsigned int cr;
2585 int i, j, l;
2587 VERBOSE_FUNCTION_CALLOUT
2589 for (i = 0; i < nb_iargs; i++) {
2590 for (j = 0; j < nb_iargs; j++) {
2591 for (l = 0; l < nb_iargs; l++) {
2592 r14 = iargs[i];
2593 r15 = iargs[j];
2594 r16 = iargs[l];
2596 SET_CR_ZERO;
2598 (*test_function)();
2600 GET_CR(cr);
2601 res = r17;
2603 printf("%s %016lx, %016lx, %016lx => %016lx (%08x)\n",
2604 instruction_name,
2605 (long unsigned)r14, (long unsigned)r15,
2606 (long unsigned)r16, (long unsigned)res,
2607 cr);
2613 static void testfunction_vector_absolute (const char* instruction_name,
2614 test_func_t test_function,
2615 unsigned int ignore_test_flags)
2617 /* Notes:
2618 * iterate across xa, xb values.
2619 * Results are in xt.
2621 volatile unsigned int cr;
2622 int i, j;
2624 VERBOSE_FUNCTION_CALLOUT
2626 for (i = 0; i < nb_vargs; i += 4) {
2627 /* patterns more interesting when shifted like so.. */
2628 for (j = 0; j < nb_vpcv; j += 2) {
2630 vec_xa = (vector unsigned long){vsxargs[i], vsxargs[i+1]};
2631 vec_xb = (vector unsigned long){vsxargs[j], vsxargs[j]};
2632 vec_xt = (vector unsigned long){0, 0};
2634 printf("%s xa:%016lx %016lx xb:%016lx %016lx ",
2635 instruction_name,
2636 (unsigned long)vec_xa[1], (unsigned long)vec_xa[0],
2637 (unsigned long)vec_xb[1], (unsigned long)vec_xb[0]
2639 printf(" => ");
2641 SET_CR_ZERO;
2643 (*test_function)();
2645 GET_CR(cr);
2647 printf(" xt:%016lx %016lx (%08x)\n", (unsigned long)vec_xt[1],
2648 (unsigned long)vec_xt[0], cr);
2650 if (verbose) printf("\n");
2654 static void testfunction_vector_xxpermute (const char* instruction_name,
2655 test_func_t test_function,
2656 unsigned int ignore_test_flags)
2658 /* Notes:
2659 * VSX permute uses both xt and xa as source registers.
2660 * Permute control vector is in xb.
2661 * Results are in xt.
2663 volatile unsigned int cr;
2664 int i, j;
2666 VERBOSE_FUNCTION_CALLOUT
2668 for (i = 0; i < nb_vargs; i += 4) {
2669 for (j = 0; j < nb_vpcv; j += 2) {
2671 vec_xa = (vector unsigned long){vsxargs[i], vsxargs[i+1]};
2672 vec_xt = (vector unsigned long){vsxargs[i+2], vsxargs[i+3]};
2673 vec_xb = (vector unsigned long){vpcv[j], vpcv[j+1]};
2675 printf("%s %016lx %016lx %016lx %016lx, pcv[%016lx %016lx] => ",
2676 instruction_name,
2677 (unsigned long)vec_xa[1], (unsigned long)vec_xa[0],
2678 (unsigned long)vec_xt[1], (unsigned long)vec_xt[0],
2679 (unsigned long)vec_xb[1], (unsigned long)vec_xb[0]);
2681 SET_CR_ZERO;
2683 (*test_function)();
2685 GET_CR(cr);
2687 printf(" %016lx %016lx (%08x)\n", (unsigned long)vec_xt[1],
2688 (unsigned long)vec_xt[0], cr);
2690 #if defined (DEBUG_VECTOR_PERMUTE)
2691 printf("DEBUG:%s %016lx %016lx %016lx %016lx, pcv[%016lx %016lx]\n",
2692 ignore_name,
2693 (unsigned long)vec_xa[1], (unsigned long)vec_xa[0],
2694 (unsigned long)vec_xt[1], (unsigned long)vec_xt[0],
2695 (unsigned long)vec_xb[1], (unsigned long)vec_xb[0]);
2696 #endif
2698 if (verbose) printf("\n");
2702 static void testfunction_vector_logical_one (const char* instruction_name,
2703 test_func_t test_function,
2704 unsigned int ignore_test_flags)
2706 /* Notes:
2707 * vector instructions with one input, one output.
2708 * xt, xa
2710 int i;
2711 int t;
2713 VERBOSE_FUNCTION_CALLOUT
2715 for (i = 0; i < nb_vargs; i += 2) {
2717 vec_xa = (vector unsigned long){vsxargs[i], vsxargs[i+1]};
2718 for (t = 0; t < 2; t++) {
2719 vec_xt[0] = (t == 0) ? 0 : 0xffffffffffffffff;
2720 vec_xt[1] = (t == 0) ? 0 : 0xffffffffffffffff;
2722 printf("%s xa:%016lx %016lx xt:%016lx %016lx => ",
2723 instruction_name,
2724 (unsigned long)vec_xa[1], (unsigned long)vec_xa[0],
2725 (unsigned long)vec_xt[1], (unsigned long)vec_xt[0]);
2727 (*test_function)();
2729 printf(" xt:%016lx %016lx\n",
2730 (unsigned long)vec_xt[1], (unsigned long)vec_xt[0]);
2733 if (verbose) printf("\n");
2736 static void testfunction_gpr_vector_logical_one (const char* instruction_name,
2737 test_func_t test_function,
2738 unsigned int ignore_test_flags)
2740 /* Notes:
2741 * vector instructions with one vector input, one GPR output.
2742 * rt, xa
2744 int i;
2745 volatile HWord_t res;
2747 VERBOSE_FUNCTION_CALLOUT
2749 for (i = 0; i < nb_vargs; i += 2) {
2751 vec_xa = (vector unsigned long){vsxargs[i], vsxargs[i+1]};
2752 r17 = 0;
2753 res = r17;
2755 printf("%s rt xt:%016lx %016lx => ",
2756 instruction_name,
2757 (unsigned long)vec_xa[1], (unsigned long)vec_xa[0]);
2759 (*test_function)();
2761 printf(" rt: %016lx\n", (long unsigned)res);
2763 if (verbose) printf("\n");
2766 static void testfunction_vector_logical_four (const char* instruction_name,
2767 test_func_t test_function,
2768 unsigned int ignore_test_flags) {
2769 /* Notes:
2770 * vector instructions with three input arguments, one output.
2771 * xt, xa, xb, xc.
2772 * Permute control vector is in xc.
2773 * Results are in xt.
2775 volatile unsigned int cr;
2776 int i, j;
2777 int p;
2779 VERBOSE_FUNCTION_CALLOUT
2781 for (i = 0; i < nb_vargs; i += 4) {
2782 for (j = 0; j < nb_vargs; j += 4) {
2783 for (p = 0; p < nb_vpcv; p += 2) {
2785 vec_xa = (vector unsigned long){vsxargs[i], vsxargs[i+1]};
2786 vec_xb = (vector unsigned long){vsxargs[j], vsxargs[j+1]};
2787 vec_xc = (vector unsigned long){vpcv[p], vpcv[p+1]};
2789 printf("%s %016lx %016lx %016lx %016lx, pcv[%016lx %016lx] => ",
2790 instruction_name,
2791 (unsigned long)vec_xa[1], (unsigned long)vec_xa[0],
2792 (unsigned long)vec_xb[1], (unsigned long)vec_xb[0],
2793 (unsigned long)vec_xc[1], (unsigned long)vec_xc[0]);
2795 SET_CR_ZERO;
2797 (*test_function)();
2799 GET_CR(cr);
2801 printf(" %016lx %016lx (%08x)\n", (unsigned long)vec_xt[1],
2802 (unsigned long)vec_xt[0], cr);
2806 if (verbose) printf("\n");
2810 static
2811 void testfunction_vector_insert_or_extract_immediate (const char* instruction_name,
2812 test_func_t test_function,
2813 unsigned int ignore_test_flags) {
2814 /* Uses global variable x_index */
2815 /* uses global variable insert_extract_error */
2816 int i;
2817 int t;
2819 VERBOSE_FUNCTION_CALLOUT
2821 /* for the insert and extract tests, we deliberately use only a
2822 * subset of the vsxargs array as input data.
2824 for (i = 2; i < 9 ; i += 4) { /* index into vsxargs[] array */
2826 /* Note:
2827 * Determining the proper offset for {extract, insert} byte, halfword,
2828 * word, double would complicate things. For simplicity, allow the
2829 * sub-functions to ignore input that would be invalid. Catch and
2830 * suppress output for those cases per the global variable.
2832 for (x_index = 0; x_index < 16 ; x_index++) {
2833 vec_xb[0] = (unsigned long)vsxargs[i];
2834 vec_xb[1] = (unsigned long)vsxargs[i+1];
2836 /* Run each test against all zeros and then all ones,
2837 * This is intended to help any bitfield changes stand out.
2839 for (t = 0; t < 2; t++) {
2841 vec_xt[0] = (t == 0) ? 0 : 0xffffffffffffffff;
2842 vec_xt[1] = (t == 0) ? 0 : 0xffffffffffffffff;
2844 insert_extract_error = 0;
2846 (*test_function)();
2848 if (!insert_extract_error) {
2849 printf("%s %016lx %016lx [%d] (into%s) => ",
2850 instruction_name, (unsigned long)vec_xb[1],
2851 (unsigned long)vec_xb[0], x_index,
2852 (t == 0 ? " zeros" : " ones") );
2854 printf("%016lx %016lx\n", (unsigned long)vec_xt[1],
2855 (unsigned long)vec_xt[0]);
2863 static void testfunction_vector_immediate (const char * instruction_name,
2864 test_func_t test_function,
2865 unsigned int ignore_test_flags) {
2866 /* Uses global variable x_splat */
2867 int i;
2868 int t;
2870 VERBOSE_FUNCTION_CALLOUT
2872 for (i = 0; i < SPLAT_ARRAY_SIZE; i++) {
2873 x_splat = splat_values[i];
2874 for (t = 0; t < 2; t++) {
2875 vec_xt[0] = (t == 0) ? 0 : 0xffffffffffffffff;
2876 vec_xt[1] = (t == 0) ? 0 : 0xffffffffffffffff;
2878 printf("%s %016lx %016lx [%2x] => ",
2879 instruction_name, (unsigned long)vec_xt[1],
2880 (unsigned long)vec_xt[0], x_splat);
2882 (*test_function)();
2884 printf("%016lx %016lx\n", (unsigned long)vec_xt[1],
2885 (unsigned long)vec_xt[0]);
2890 static void testfunction_vector_loadstore (const char* instruction_name,
2891 test_func_t test_function,
2892 unsigned int ignore_flags) {
2893 /* exercises vector loads from memory, and vector stores from memory.
2894 * <load or store instruction> XS, RA, RB
2895 * For these tests, RA will be zero.
2896 * EA is then, simply, RB.
2898 int i;
2899 int buffer_pattern;
2901 VERBOSE_FUNCTION_CALLOUT
2903 for (i = 0; i < nb_vargs; i += 2) {
2905 vec_xt = (vector unsigned long){vsxargs[i], vsxargs[i+1]};
2906 r14 = 0;
2907 r15 = (unsigned long) & buffer;
2909 for (buffer_pattern = 0; buffer_pattern < MAX_BUFFER_PATTERNS;
2910 buffer_pattern++) {
2912 /* set patterns on both ends */
2913 initialize_buffer(buffer_pattern);
2915 printf("%s ", instruction_name);
2916 printf("%016lx %016lx ", (unsigned long)vec_xt[1],
2917 (unsigned long)vec_xt[0]);
2918 dump_small_buffer();
2919 printf(" =>\n");
2921 (*test_function)();
2923 printf(" %016lx %016lx ", (unsigned long)vec_xt[1],
2924 (unsigned long)vec_xt[0]);
2925 dump_small_buffer();
2926 printf("\n");
2932 static void testfunction_vectorscalar_move_tofrom (const char * instruction_name,
2933 test_func_t test_function,
2934 unsigned int ignore_test_flags) {
2935 /* Move to / move from vector scalar. spin through simple variants of
2936 * both the VSR and the register.
2937 * for simplicity, RA from 'mtvsrdd xt, ra, rb' is 0.
2939 int i, v;
2941 VERBOSE_FUNCTION_CALLOUT
2943 for (i = 0; i < PATTERN_SIZE; i++) {
2944 for (v = 0; v < PATTERN_SIZE; v++) {
2945 /* if i==v, patterns will match, so just skip these as
2946 * non-interesting..
2948 if (i == v) continue;
2949 r14 = 0;
2950 r15 = pattern[i%PATTERN_SIZE];
2951 vec_xt[0] = pattern[v%PATTERN_SIZE];
2952 vec_xt[1] = pattern[v%PATTERN_SIZE];
2954 printf("%s ", instruction_name);
2955 printf("%016lx %016lx %lx %016lx ", (unsigned long)vec_xt[1],
2956 (unsigned long)vec_xt[0],
2957 (long unsigned)r14, (long unsigned)r15 );
2959 (*test_function)();
2961 printf("=> %016lx %016lx %lx %016lx", (unsigned long)vec_xt[1],
2962 (unsigned long)vec_xt[0],
2963 (long unsigned)r14, (long unsigned)r15 );
2964 printf("\n");
2969 /* Some of the load/store vector instructions load 64 bits, upper 64 bits
2970 * are undefined.
2972 #define load_4_bytes(instruction_name) ( \
2973 (strncmp(instruction_name, "lxssp ",5) == 0) )
2975 /* Some of the load/store vector instructions use a length value that
2976 * is stored in bits 0:7 of RB. */
2977 #define uses_bits_0to7(instruction_name) ( \
2978 (strncmp(instruction_name, "lxvl " ,5) == 0) || \
2979 (strncmp(instruction_name, "lxvll " ,6) == 0) || \
2980 (strncmp(instruction_name, "stxvl " ,6) == 0) || \
2981 (strncmp(instruction_name, "stxvll ",7) == 0) )
2983 static void testfunction_vector_scalar_loadstore_length (const char* instruction_name,
2984 test_func_t test_function,
2985 unsigned int ignore_flags) {
2986 /* exercises vector loads from memory, and vector stores from memory.
2987 * with length specification.
2988 * <load or store instruction> XS, RA, RB
2989 * For these tests, RA (i.e. EA) is address of source/dest and can
2990 * not be zero.
2991 * The length value is in rb. For a subset of these instructions,
2992 * the length is stored in bits 0:7, versus 56:63 of r15.
2994 int i;
2995 unsigned long l;
2996 int buffer_pattern;
2998 VERBOSE_FUNCTION_CALLOUT
3000 for (i = 0; i < nb_vargs; i += 2) {
3001 for (l = 0; l <= 16; l += 4) {
3003 for (buffer_pattern = 0; buffer_pattern < MAX_BUFFER_PATTERNS;
3004 buffer_pattern++) {
3006 /* set patterns on both ends */
3007 vec_xt = (vector unsigned long){vsxargs[i], vsxargs[i+1]};
3009 initialize_buffer(buffer_pattern);
3011 printf("%s ", instruction_name);
3012 printf("%016lx %016lx ", (unsigned long)vec_xt[1],
3013 (unsigned long)vec_xt[0] );
3014 if (uses_bits_0to7(instruction_name)) {
3015 printf(" 0x%2lx ", (long unsigned)r15>>56 );
3017 } else {
3018 printf(" 0x%2lx ", (long unsigned)r15 );
3021 dump_small_buffer();
3023 if (uses_bits_0to7(instruction_name)) {
3024 /* length is stored in bits 0:7 of gpr[r15]. */
3025 r15 = (unsigned long)((0xff & l) << 56);
3027 } else {
3028 /* length is stored in gpr[r15]. */
3029 r15 = l;
3031 r14 = (unsigned long) & buffer;
3033 (*test_function)();
3035 if (load_4_bytes(instruction_name)) {
3036 /* Double word element 1 (BE numbering) is undefined, clear for
3037 consistency. Only loaded bits [0:31], mask out rest of
3038 element 0.
3040 vec_xt[0] = 0;
3041 vec_xt[1] &= 0xFFFFFFFF00000000;
3044 printf("=> %016lx %016lx & %16lx", (unsigned long)vec_xt[1],
3045 (unsigned long)vec_xt[0], (long unsigned)r15 );
3046 dump_small_buffer();
3048 printf("\n");
3054 static void testfunction_vector_count_bytes (const char* instruction_name,
3055 test_func_t test_function,
3056 unsigned int ignore_flags)
3058 int i;
3060 VERBOSE_FUNCTION_CALLOUT
3062 for (i = 0; i < nb_vargs; i += 2) {
3063 vec_xb = (vector unsigned long){vsxargs[i], vsxargs[i+1]};
3064 r14 = 0;
3066 printf("%s ", instruction_name);
3067 printf("%016lx %016lx %2d ", (unsigned long)vec_xb[1],
3068 (unsigned long)vec_xb[0], (unsigned)r14);
3070 (*test_function)();
3072 printf("=> %2d\n", (unsigned)r14 );
3076 static void testfunction_vector_extract (const char* instruction_name,
3077 test_func_t test_function,
3078 unsigned int ignore_flags)
3080 int i;
3082 VERBOSE_FUNCTION_CALLOUT
3084 for (i = 0; i < nb_vargs; i += 2) {
3085 vec_xb = (vector unsigned long){vsxargs[i], vsxargs[i+1]};
3086 for (r15 = 0; r15 < 16; r15++) {
3087 r14 = 0;
3089 printf("%s ", instruction_name);
3090 printf("%016lx %016lx %2d ", (unsigned long)vec_xb[1],
3091 (unsigned long)vec_xb[0], (unsigned)r15);
3093 (*test_function)();
3095 printf("=> %16lx\n", (long unsigned)r14 );
3100 static void testfunction_vector_extend_sign (const char* instruction_name,
3101 test_func_t test_function,
3102 unsigned int ignore_flags)
3104 int i;
3106 VERBOSE_FUNCTION_CALLOUT
3108 for (i = 0; i < nb_vargs; i += 2) {
3109 vec_xb = (vector unsigned long){vsxargs[i], vsxargs[i+1]};
3110 vec_xt = (vector unsigned long){0, 0};
3112 printf("%s ", instruction_name);
3113 printf("%016lx %016lx ",(unsigned long) vec_xb[1],
3114 (unsigned long)vec_xb[0]);
3116 (*test_function)();
3118 printf("=> %016lx %016lx\n", (unsigned long)vec_xt[1],
3119 (unsigned long)vec_xt[0]);
3123 /* packed binary decimal misc */
3125 #define convert_from_zoned(instruction_name) (strncmp(instruction_name, "bcdcfz", 6) ==0 )
3127 #define convert_from_national(instruction_name) (strncmp(instruction_name, "bcdcfn", 6) == 0)
3129 #define convert_to_zoned(instruction_name) (strncmp(instruction_name, "bcdctz", 6) == 0)
3131 #define convert_to_national(instruction_name) (strncmp(instruction_name, "bcdctn", 6) == 0)
3133 #define shift_or_truncate(instruction_name) \
3134 (strncmp(instruction_name, "bcds", 4) == 0 || \
3135 strncmp(instruction_name, "bcdus", 5) == 0 || \
3136 strncmp(instruction_name, "bcdsr", 5) == 0 || \
3137 strncmp(instruction_name, "bcdtrunc", 8) == 0 || \
3138 strncmp(instruction_name, "bcdutrunc", 9) == 0)
3141 /* Helper function - returns 1 or 0 per whether the p1 or p0 string
3142 * exists in the instruction name passed in. The PS indicates preferred
3143 * sign, and has meaning for some of the BCD instructions.
3145 static inline int p_value(const char * instruction_name) {
3146 char * found_p0;
3147 char * found_p1;
3149 found_p1 = strstr(instruction_name, "p1");
3150 found_p0 = strstr(instruction_name, "p0");
3152 if (found_p1) return 1;
3154 if (found_p0) return 0;
3156 if (verbose) printf("p* substring not found in (%s)\n", instruction_name);
3158 return 0;
3161 /* bcd test has been split out a bit.. a few bcd specific global vars here
3162 * to help keep that clean.
3164 long shift_or_truncate_instruction;
3165 int xa_sign, xb_sign, xt_sign;
3166 int short_circuit;
3168 /* testfunction_bcd_setup_inputs
3169 * This is a helper function that sets up the vec_xa, vec_xb values for
3170 * use in the bcd tests.
3172 static inline void testfunction_bcd_setup_inputs(const char * instruction_name,
3173 int i, int j) {
3174 short_circuit=0;
3176 if (shift_or_truncate_instruction) {
3177 if (i >= nb_decimal_shift_entries - 2) {
3178 short_circuit = 1;
3179 return;
3181 vec_xa = (vector unsigned long) {decimal_shift_table[i+1],
3182 decimal_shift_table[i]};
3184 } else {
3185 if (i >= nb_decimal_shift_entries - 2) {
3186 short_circuit = 1;
3187 return;
3190 vec_xa = (vector unsigned long) {packed_decimal_table[i+1],
3191 packed_decimal_table[i]};
3192 xa_sign = extract_packed_decimal_sign(vec_xa[0], vec_xa[1]);
3195 if (convert_from_zoned(instruction_name)) { /* convert from zoned */
3196 if (j >= nb_zoned_decimal_entries - 2) {
3197 short_circuit = 1;
3198 return;
3201 vec_xb = (vector unsigned long) {zoned_decimal_table[j+1],
3202 zoned_decimal_table[j]};
3203 xb_sign = extract_zoned_decimal_sign(vec_xb[0], vec_xb[1]);
3205 } else if (convert_from_national(instruction_name)) {
3206 /* convert from national */
3207 if (j >= nb_national_decimal_entries - 2) {
3208 short_circuit = 1;
3209 return;
3211 vec_xb = (vector unsigned long) {national_decimal_table[j+1],
3212 national_decimal_table[j]};
3213 xb_sign = extract_national_decimal_sign(vec_xb[0], vec_xb[1]);
3215 } else {
3216 /* packed decimal entries */
3217 if (j >= nb_packed_decimal_entries - 2) {
3218 short_circuit = 1;
3219 return;
3221 vec_xb = (vector unsigned long) {packed_decimal_table[j+1],
3222 packed_decimal_table[j]};
3223 xb_sign = extract_packed_decimal_sign(vec_xb[0], vec_xb[1]);
3227 static inline void testfunction_bcd_display_outputs(const char * instruction_name) {
3229 printf(" xt:%016lx %016lx", (unsigned long)vec_xt[1],
3230 (unsigned long)vec_xt[0] );
3232 if (convert_to_zoned(instruction_name)) {
3233 /* convert to zoned */
3234 xt_sign = extract_zoned_decimal_sign(vec_xt[0], vec_xt[1]);
3235 dissect_zoned_decimal_sign(xt_sign, p_value(instruction_name));
3237 } else if (convert_to_national(instruction_name)) {
3238 /* convert to national */
3239 xt_sign = extract_national_decimal_sign(vec_xt[0], vec_xt[1]);
3240 dissect_national_decimal_sign(xt_sign);
3242 } else {
3243 /* packed decimal entries, or shift/truncate */
3244 if (!shift_or_truncate_instruction) {
3245 xt_sign = extract_packed_decimal_sign(vec_xt[0], vec_xt[1]);
3246 dissect_packed_decimal_sign(xt_sign);
3249 printf("\n");
3252 #define uses_half_precision_input(instruction_name) ( \
3253 (strncmp(instruction_name, "xscvhpdp", 8) == 0) || \
3254 (strncmp(instruction_name, "xvcvhpsp", 8) == 0) )
3256 #define uses_single_precision_input(instruction_name) ( \
3257 (strncmp(instruction_name, "xvcvsphp", 8) == 0) )
3259 #define uses_double_precision_input(instruction_name) ( \
3260 (strncmp(instruction_name, "xscvdphp", 8) == 0) )
3262 #define uses_half_precision_output(instruction_name) ( \
3263 (strncmp(instruction_name, "xscvdphp", 8) == 0) || \
3264 (strncmp(instruction_name, "xvcvsphp", 8) == 0) )
3266 #define is_half_precision_instruction(instruction_name) ( \
3267 uses_half_precision_input(instruction_name) || \
3268 uses_half_precision_output(instruction_name) )
3270 /* Helper for those instructions with an unused second dword, indicating
3271 * the outer loop can be short-circuited after one pass.
3273 #define unused_second_dword(instruction_name) ( \
3274 (strncmp(instruction_name, "xscvhpdp", 8) == 0) || \
3275 (strncmp(instruction_name, "xscvdphp", 8) == 0) )
3277 static void testfunction_vector_scalar_two_quad (const char* instruction_name,
3278 test_func_t test_function,
3279 unsigned int ignore_flags)
3281 int i;
3283 VERBOSE_FUNCTION_CALLOUT
3285 for (i = 0; i < nb_vargs; i += 2) {
3286 if (uses_half_precision_input(instruction_name)) {
3287 vec_xb = (vector unsigned long){binary16_float_vsxargs[i],
3288 binary16_float_vsxargs[i+1]};
3289 } else {
3290 vec_xb = (vector unsigned long){vsxargs[i], vsxargs[i+1]};
3293 vec_xt = (vector unsigned long){0, 0};
3295 printf("%s ", instruction_name);
3296 printf("%016lx %016lx ", (unsigned long)vec_xb[1],
3297 (unsigned long)vec_xb[0]);
3299 SET_FPSCR_ZERO
3301 (*test_function)();
3303 GET_FPSCR(local_fpscr);
3305 printf("=> %016lx %016lx", (unsigned long)vec_xt[1],
3306 (unsigned long)vec_xt[0]);
3307 dissect_fpscr(local_fpscr);
3308 printf("\n");
3312 /* helper macro. Use below to limit output to only dword[0] for the inputs
3313 * to the instructions listed here. */
3314 #define instruction_only_uses_dword0_inputs(instruction_name) \
3315 ((strncmp(instruction_name, "xscmpeqdp",9) == 0) || \
3316 (strncmp(instruction_name, "xscmpgtdp",9) == 0) || \
3317 (strncmp(instruction_name, "xscmpgedp",9) == 0) || \
3318 (strncmp(instruction_name, "xsmincdp",8) == 0) || \
3319 (strncmp(instruction_name, "xsmaxcdp",8) == 0) )
3321 static void
3322 testfunction_vector_scalar_compare_double (const char* instruction_name,
3323 test_func_t test_function,
3324 unsigned int ignore_test_flags){
3325 int i,j;
3326 /* Uses global variable x_index */
3328 VERBOSE_FUNCTION_CALLOUT
3330 for (i = 0; i < nb_float_vsxargs - 1; i++) {
3331 for (j = 0; j < nb_float_vsxargs - 1; j++) {
3332 for (x_index = 2; x_index < 3; x_index++) {
3334 /* TODO FIXME- there was a casting issue below. This incantation
3335 * works, but I suspect can be simplified...
3337 vec_xa = (vector unsigned long){(unsigned long)binary64_float_vsxargs[i+1], (unsigned long)binary64_float_vsxargs[i]};
3339 vec_xb = (vector unsigned long){(unsigned long)binary64_float_vsxargs[j], (unsigned long)binary64_float_vsxargs[j+1]};
3341 /* run each test against cleared CR and FPSCR */
3342 /* Note that the SET_*_ZERO calls are not actually sufficient here,
3343 * due to infrastructure between here and there that also set some
3344 * of the CR bits. The condition regs are cleared here, but are
3345 * also both cleared and read within the to-be-tested asm chunk to
3346 * get accurate results.
3348 SET_CR_ZERO
3349 SET_FPSCR_ZERO
3350 if (instruction_only_uses_dword0_inputs(instruction_name)) {
3351 printf("%s %016lx %016lx",
3352 instruction_name, (unsigned long)vec_xa[1],
3353 (unsigned long)vec_xb[1]);
3354 } else {
3355 printf("%s %016lx %016lx %016lx %016lx",
3356 instruction_name,
3357 (unsigned long)vec_xa[1], (unsigned long)vec_xa[0],
3358 (unsigned long)vec_xb[1], (unsigned long)vec_xb[0]);
3361 if (verbose) printf(" cr#%d ", x_index);
3363 printf(" => ");
3365 (*test_function)();
3367 if (instruction_only_uses_dword0_inputs(instruction_name)) {
3368 printf("%016lx %016lx", (unsigned long)vec_xt[1],
3369 (unsigned long)vec_xt[0]);
3372 dissect_fpscr(local_fpscr);
3373 dissect_fpscr_result_value_class(local_fpscr);
3374 dissect_cr_rn(local_cr, x_index);
3375 printf("\n");
3381 /* These instructions set the floating point condition codes. */
3382 /* verify logic reversal */
3383 #define does_not_set_floating_point_cc(instruction_name) \
3384 (strncmp(instruction_name, "xvtstdcdp", 9) == 0) | \
3385 (strncmp(instruction_name, "xvtstdcsp", 9) == 0)
3387 static void
3388 testfunction_vector_scalar_data_class (const char* instruction_name,
3389 test_func_t test_function,
3390 unsigned int ignore_test_flags) {
3391 int j;
3392 /* x_index is used as a key into the DCMX value.
3394 * BF, XB, DCMX
3395 * For instruction tests called through this function, note that we are only
3396 * utilizing bf (condition register) #3; where 3 was mostly randomly
3397 * chosen, and has no special meaning.
3400 VERBOSE_FUNCTION_CALLOUT
3402 for (j = 0; j < nb_float_vsxargs - 1; j++) {
3403 /* for dcmx field, start with x_index=1 to skip the 'all' dcmx entry. */
3404 for (x_index = 1; x_index < 8; x_index++) {
3405 vec_xb[0] = float_vsxargs[j];
3406 vec_xb[1] = float_vsxargs[j+1];
3407 vec_xt[0] = 0x0a0a0a0a0a0a0a0a;
3408 vec_xt[1] = 0x0505050505050505;
3409 SET_CR_ZERO
3410 SET_FPSCR_ZERO
3412 dcmx_match = 0;
3414 (*test_function)();
3416 /* the local_fpscr value is gathered within the test_function call. */
3417 dcmx_match = (local_fpscr & FPCC_FE_BIT);
3419 if (dcmx_match || (verbose>2)) {
3420 printf("%s %016lx, %016lx ",
3421 instruction_name, (unsigned long)vec_xb[1],
3422 (unsigned long)vec_xb[0]);
3424 print_dcmx_field(x_index);
3426 if (dcmx_match)
3427 printf(" => Match. ");
3429 printf(" %016lx, %016lx ", (unsigned long)vec_xt[1],
3430 (unsigned long)vec_xt[0]);
3432 dissect_cr_rn(local_cr,3);
3433 dissect_fpscr_dcmx_indicator(local_fpscr);
3434 printf("\n");
3437 printf("%s %016lx, %016lx => ",
3438 instruction_name, (unsigned long)vec_xb[1],
3439 (unsigned long)vec_xb[0]);
3441 printf(" %016lx, %016lx\n", (unsigned long)vec_xt[1],
3442 (unsigned long)vec_xt[0]);
3447 static void testfunction_vector_scalar_compare_quads (const char* instruction_name,
3448 test_func_t test_function,
3449 unsigned int ignore_test_flags) {
3450 /* Uses global variable x_index */
3451 int i,j;
3453 VERBOSE_FUNCTION_CALLOUT
3455 for (i = 0; i < nb_float_vsxargs - 1; i++) {
3456 for (j = 0; j < nb_float_vsxargs - 1; j++) {
3457 for (x_index = 0; x_index < 3 ; x_index++) {
3458 vec_xa[0] = float_vsxargs[i];
3459 vec_xa[1] = float_vsxargs[i+1];
3460 vec_xb[0] = float_vsxargs[j];
3461 vec_xb[1] = float_vsxargs[j+1];
3463 /* run each test against cleared CR and FPSCR */
3464 /* Note that the SET_*_ZERO calls are not actually sufficient here,
3465 * due to infrastructure between here and there that also set some
3466 * of the CR bits. The condition regs are cleared here, but are
3467 * also both cleared and read within the to-be-tested asm chunk
3468 * to get accurate results.
3470 printf("%s %016lx%016lx %016lx%016lx (cr#%d) => ",
3471 instruction_name,
3472 (unsigned long)vec_xa[1], (unsigned long)vec_xa[0],
3473 (unsigned long)vec_xb[1], (unsigned long)vec_xb[0],
3474 x_index);
3476 SET_CR_ZERO
3477 SET_FPSCR_ZERO
3479 (*test_function)();
3481 GET_CR(local_cr);
3482 GET_FPSCR(local_fpscr);
3484 dissect_fpscr(local_fpscr);
3485 dissect_cr_rn(local_cr, x_index);
3486 printf("\n");
3492 static void testfunction_vector_scalar_rounding_quads (const char* instruction_name,
3493 test_func_t test_function,
3494 unsigned int ignore_test_flags) {
3495 /* Uses global variable x_index */
3496 /* For this function, x_index is used as a key into R and RMC values.
3497 * Also note, the fpscr.rn value may be used to affect the rounding mode.
3498 * that variation is not evaluated here. */
3499 int j;
3501 VERBOSE_FUNCTION_CALLOUT
3503 for (j = 0; j < nb_float_vsxargs - 1; j++) {
3504 for (x_index = 0; x_index < 8; x_index++) {
3505 vec_xb[0] = float_vsxargs[j];
3506 vec_xb[1] = float_vsxargs[j+1];
3508 printf("%s %016lx%016lx (R=%x) (RMC=%x) => ",
3509 instruction_name,
3510 (unsigned long)vec_xb[1], (unsigned long)vec_xb[0],
3511 (x_index & 0x4) >> 2, x_index & 0x3);
3513 SET_CR_ZERO
3514 SET_FPSCR_ZERO
3516 (*test_function)();
3518 GET_FPSCR(local_fpscr);
3520 printf("%016lx%016lx", (unsigned long)vec_xt[1],
3521 (unsigned long)vec_xt[0]);
3522 dissect_fpscr(local_fpscr);
3523 printf("\n");
3528 static void testfunction_vector_three_special (const char* instruction_name,
3529 test_func_t test_function,
3530 unsigned int ignore_test_flags){
3531 /* Notes:
3532 * vector instructions with two inputs, one output.
3533 * vrt, vra, vrb
3535 int i, j;
3536 int t;
3538 VERBOSE_FUNCTION_CALLOUT
3540 for (i = 0; i < nb_float_vsxargs - 1; i++) {
3541 for (j = 0; j < nb_float_vsxargs - 1; j++) {
3542 vec_xa[0] = float_vsxargs[i];
3543 vec_xa[1] = float_vsxargs[i+1];
3544 vec_xb[0] = float_vsxargs[j];
3545 vec_xb[1] = float_vsxargs[j+1];
3547 for (t = 0; t < 2; t++) {
3548 vec_xt[0] = (t == 0) ? 0 : 0xffffffffffffffff;
3549 vec_xt[1] = (t == 0) ? 0 : 0xffffffffffffffff;
3551 SET_FPSCR_ZERO;
3552 printf("%s %016lx%016lx %016lx%016lx %016lx%016lx => ",
3553 instruction_name,
3554 (unsigned long)vec_xa[1], (unsigned long)vec_xa[0],
3555 (unsigned long)vec_xb[1], (unsigned long)vec_xb[0],
3556 (unsigned long)vec_xt[1], (unsigned long)vec_xt[0]);
3558 (*test_function)();
3560 GET_FPSCR(local_fpscr);
3562 printf(" %016lx%016lx", (unsigned long)vec_xt[1],
3563 (unsigned long)vec_xt[0]);
3564 dissect_fpscr(local_fpscr);
3565 printf("\n");
3571 #define vector_instruction_is_xvcvhpsp(instruction_name) \
3572 (strncmp(instruction_name, "xvcvhpsp", 8) == 0)
3574 static void testfunction_vector_scalar_two_double(const char* instruction_name,
3575 test_func_t test_function,
3576 unsigned int ignore_test_flags) {
3577 /* Notes:
3578 * iterate across double values stored in xa, xb.
3579 * Or, on half-word values in vec_xb.
3580 * Results are in vec_xt.
3582 int i, j;
3584 VERBOSE_FUNCTION_CALLOUT
3586 for (i = 0; i < nb_float_vsxargs - 1; i += 2) {
3587 for (j = 0; j < nb_float_vsxargs - 1; j += 2) {
3588 /* vec_xb is only used by the convert instructions, the other callers
3589 * use the r14, r15 fields.
3590 * The 16-bit converts reference every other half-word in the vector.
3591 * For this reason, populate the input field with a cross-section of
3592 * values.
3594 printf("%s ",instruction_name);
3596 if (uses_half_precision_input(instruction_name)) {
3597 vec_xb = (vector unsigned long) {
3598 binary16_float_vsxargs[i] |
3599 binary16_float_vsxargs[j] << 16 |
3600 binary16_float_vsxargs[i+1] << 32 |
3601 binary16_float_vsxargs[j+1] << 48,
3602 binary16_float_vsxargs[(nb_float_vsxargs - 1) - j - 1 ] |
3603 binary16_float_vsxargs[(nb_float_vsxargs - 1) - i - 1] << 16 |
3605 binary16_float_vsxargs[(nb_float_vsxargs - 1) - j ] << 32 |
3606 binary16_float_vsxargs[(nb_float_vsxargs - 1) - i ] << 48
3608 printf(" vec_xb[1] = 0x%lx, vec_xb[0] = 0x%lx ",
3609 (unsigned long)vec_xb[1], (unsigned long)vec_xb[0]);
3611 } else if (uses_single_precision_input(instruction_name)) {
3612 vec_xb = (vector unsigned long) {
3613 binary32_float_vsxargs[i] |
3614 binary32_float_vsxargs[i+1] << 32,
3615 binary32_float_vsxargs[nb_float_vsxargs - 1 - j ] |
3616 binary32_float_vsxargs[nb_float_vsxargs - 1 - j ] << 32
3618 printf(" vec_xb[1] = 0x%lx, vec_xb[0] = 0x%lx ",
3619 (unsigned long)vec_xb[1], (unsigned long)vec_xb[0]);
3621 } else { /* uses double */
3622 r14 = binary64_float_vsxargs[i];
3623 r15 = binary64_float_vsxargs[j];
3624 printf(" r14 = 0x%lx, r15 = 0x%lx ", r14, r15);
3627 vec_xt = (vector unsigned long){0, 0};
3629 printf("%016lx %016lx ", (unsigned long)vec_xb[1],
3630 (unsigned long)vec_xb[0] );
3632 if ((verbose > 2) && uses_double_precision_input(instruction_name)) {
3633 dissect_binary64_float(vec_xb[1]);
3634 dissect_binary64_float(vec_xb[0]);
3637 printf(" => ");
3638 SET_FPSCR_ZERO
3640 (*test_function)();
3642 GET_FPSCR(local_fpscr);
3643 printf(" %016lx %016lx", (unsigned long)vec_xt[1],
3644 (unsigned long)vec_xt[0]);
3646 if ((verbose > 2) && uses_half_precision_output(instruction_name)) {
3647 dissect_double_as_16s(vec_xt[1]);
3648 dissect_double_as_16s(vec_xt[0]);
3651 /* The xvcvhpsp instruction does not set the C and FPCC fields */
3652 if (!vector_instruction_is_xvcvhpsp(instruction_name))
3653 dissect_fpscr(local_fpscr);
3655 printf("\n");
3656 } // j
3658 /* If we are doing half precision conversions, the i-loop can be
3659 * short-circuited to avoid duplicate input values. */
3660 if (unused_second_dword(instruction_name))
3661 i = nb_float_vsxargs+1;
3662 } // i
3665 static void testfunction_set_boolean (const char* instruction_name,
3666 test_func_t test_function,
3667 unsigned int ignore_test_flags)
3669 int cr_base_value;
3670 /* Notes:
3671 * Set RT to values 0, -1, 1 depending on what bits are set in the specified
3672 * CR field. x_index references here reflect the cr_field number.
3675 VERBOSE_FUNCTION_CALLOUT
3677 for (x_index = 0; x_index <= 7; x_index++) {
3678 for (cr_base_value = 0; cr_base_value < 8; cr_base_value++) {
3679 cr_value = (0x11111111 * cr_base_value)
3680 & (0xf << (4 * (7 - x_index))) ;
3682 r14 = 0xa5a5a5a5c7c7c7c7;
3684 printf("%s cr_field:%1x cr_value::%08x",
3685 instruction_name, x_index,cr_value);
3686 printf(" => ");
3688 (*test_function)();
3690 printf(" %016lx\n", r14);
3696 static void testfunction_char_compare (const char* instruction_name,
3697 test_func_t test_function,
3698 unsigned int ignore_test_flags)
3700 /* Notes:
3701 * iterate through char values stored in RA, RB.
3702 * Results stored in cr field BF.
3704 int i, j;
3705 int local_crf;
3707 VERBOSE_FUNCTION_CALLOUT
3709 for (x_index = 0; x_index <= 7; x_index++) {
3710 for (i = 0; i < nb_char_ranges; i += 4) {
3711 for (j = 0; j < nb_char_args; j++) {
3712 r14 = char_args[j];
3714 /* For cmprb*, only needs the lower characters. */
3715 r15 = char_ranges[i] | (char_ranges[i+1] << 8) |
3716 char_ranges[i+2] << 16 | (char_ranges[i+3] << 24);
3718 /* For cmpeqb, also load the rest of the range field, shift allk
3719 * chars up by one.
3721 r15 |= (r15 + 0x01010101) << 32;
3722 printf("%s 0x%02lx (%c) (cmpeq:0x%016lx) (cmprb:src22(%c-%c) src21(%c-%c))",
3723 instruction_name,
3724 r14, (int)r14,
3725 r15, (int)(r15 & 0xff), (int)((r15 >> 8) & 0xff),
3726 (int)((r15 >> 16) & 0xff), (int)((r15 >> 24) & 0xff)
3729 printf(" =>");
3731 /* Clear condition code reg (CR) immediately before test
3732 * instruction, read CR and clear immediately after test
3733 * instruction. Otherwise, the CR gets corrupted and depending
3734 * on optimization level, strange loop control flow issues
3735 * occur because CR has been messed with.
3737 (*test_function)();
3739 // GET_CR(local_cr); done in test case
3740 local_crf = extract_cr_rn(local_cr, x_index);
3742 if (verbose)
3743 printf(" %s found or in range (%x)",
3744 (cr_positive_set(local_crf))?" " : " not", local_crf);
3745 else
3746 if (cr_positive_set(local_crf)) printf(" in range/found");
3748 printf("\n");
3754 #define instruction_uses_quads(instruction_name) (strncmp(instruction_name, "dtstsfiq", 8) == 0)
3756 static void testfunction_dfp_significance (const char* instruction_name,
3757 test_func_t test_function,
3758 unsigned int ignore_test_flags)
3760 int local_crf;
3761 int i;
3762 int num_dfp_vals;
3764 VERBOSE_FUNCTION_CALLOUT
3766 if (instruction_uses_quads(instruction_name)) {
3767 num_dfp_vals = nb_dfp128_vals/2; //Next loop uses two at a time
3768 } else {
3769 num_dfp_vals = nb_dfp64_vals;
3772 for (i = 0; i < num_dfp_vals; i++) {
3773 if (instruction_uses_quads(instruction_name)) {
3774 dfp_value.u128.vall = dfp128_vals[i * 2];
3775 dfp_value.u128.valu = dfp128_vals[(i * 2) + 1];
3777 } else {
3778 // could rework this to use u64.val, but...
3779 dfp_value.u128.vall = dfp128_vals[i ];
3780 dfp_value.u128.valu = dfp128_vals[i ];
3783 /* Keeping test simpler, always using cr3 within test_dtstsfi* */
3784 for (dfp_significance = 0; dfp_significance <= 63;) {
3785 /* Todo: tweak output here, or input values so the generated content
3786 * looks better.
3788 printf("%s significance(0x%02x) ",
3789 instruction_name, dfp_significance);
3791 if (instruction_uses_quads(instruction_name)) {
3792 dissect_dfp128_float(dfp_value.u128.vall, dfp_value.u128.valu);
3794 if (verbose > 6)
3795 printf("(RAW) value = %16lx,%016lx ",
3796 dfp_value.u128.vall, dfp_value.u128.valu /*f14, f15 */);
3798 } else {
3799 dissect_dfp64_float(dfp_value.u128.vall);
3801 if (verbose > 6)
3802 printf("(RAW) value = %16lx ", dfp_value.u128.vall /*f14 */);
3805 (*test_function)();
3807 // GET_CR(local_cr); done in test_function
3809 local_crf = extract_cr_rn(local_cr, /* hardcoded cr3 */ 3);
3810 dissect_cr_rn(local_cr, /* hardcoded cr3 */ 3);
3812 printf(" (%x)", local_crf);
3813 printf("\n");
3815 /* Special case for incrementation of the significance checking
3816 * value.
3818 if (dfp_significance < 8)
3819 dfp_significance += 4; /* 0, 4, 8 */
3821 else if (dfp_significance < 32)
3822 dfp_significance += 8; /* 16, 24, 32 */
3824 else if (dfp_significance < 48)
3825 dfp_significance += 16; /* 48 */
3827 else
3828 dfp_significance += 15; /* 63 */
3833 /* packed binary decimal misc */
3835 #define convert_tofrom_instruction(instruction_name) \
3836 ( (strncmp(instruction_name, "bcdcf", 5) == 0) || \
3837 (strncmp(instruction_name, "bcdct", 5) == 0) )
3839 static void testfunction_bcd_misc (const char* instruction_name,
3840 test_func_t test_function,
3841 unsigned int ignore_test_flags)
3843 int i, j;
3844 int local_crf;
3845 long max_xa_entries = 0;
3846 long max_xb_entries = 0;
3848 VERBOSE_FUNCTION_CALLOUT
3850 shift_or_truncate_instruction = shift_or_truncate(instruction_name);
3852 max_xa_entries = MAX(max_xa_entries, nb_decimal_shift_entries);
3853 max_xa_entries = MAX(max_xa_entries, nb_packed_decimal_entries);
3855 max_xb_entries = MAX(max_xb_entries, nb_zoned_decimal_entries);
3856 max_xb_entries = MAX(max_xb_entries, nb_national_decimal_entries);
3857 max_xb_entries = MAX(max_xb_entries, nb_packed_decimal_entries);
3859 for (i = 0; i < (max_xa_entries - 1); i += 2) {
3860 for (j = 0; j < (max_xb_entries - 1); j += 2) {
3861 testfunction_bcd_setup_inputs(instruction_name, i, j);
3863 if (short_circuit) continue;
3865 printf("%s ", instruction_name);
3866 printf("xa:%016lx %016lx ", (unsigned long)vec_xa[1],
3867 (unsigned long)vec_xa[0]);
3869 if (!shift_or_truncate_instruction)
3870 dissect_packed_decimal_sign(xa_sign);
3872 printf(" xb:%016lx %016lx ", (unsigned long)vec_xb[1],
3873 (unsigned long)vec_xb[0]);
3875 if (convert_from_zoned(instruction_name)) {
3876 /* convert from zoned */
3877 dissect_zoned_decimal_sign(xb_sign, p_value(instruction_name));
3879 } else if (convert_from_national(instruction_name)) {
3880 /* convert from national */
3881 dissect_national_decimal_sign(xb_sign);
3883 } else {
3884 /* packed decimal entries */
3885 if (!shift_or_truncate_instruction)
3886 dissect_packed_decimal_sign(xb_sign);
3889 printf(" => ");
3890 SET_CR_ZERO
3892 (*test_function)();
3894 GET_CR(local_cr);
3896 /* note: the bcd instructions are hard wired to use cr6. */
3897 local_crf = extract_cr_rn(local_cr, 6);
3898 dissect_cr_rn(local_cr, 6);
3899 printf(" (%x)", local_crf);
3901 if (cr_overflow_set(local_crf)) {
3902 /* If overflow (S0) is set the results are undefined. Force the
3903 * output to print as zeros so we have consistent results for
3904 * comparison.
3906 printf(" xt:%016lx %016lx", 0UL, 0UL);
3908 } else {
3909 testfunction_bcd_display_outputs(instruction_name);
3912 printf("\n");
3913 } // j = xb loop.
3915 /* Since the bcdct* convert_tofrom instructions do not use the xa
3916 * field, we will short-circuit the xa (i=*) loop here.
3918 if (convert_tofrom_instruction(instruction_name))
3919 i = nb_packed_decimal_entries;
3920 } //i = xa loop.
3924 static void testfunction_noop_misc (const char* instruction_name,
3925 test_func_t test_function,
3926 unsigned int ignore_test_flags)
3928 VERBOSE_FUNCTION_CALLOUT
3930 printf("%s ", instruction_name);
3931 printf(" =>");
3933 (*test_function)();
3935 printf("\n");
3938 static void testfunction_pc_immediate_misc (const char* instruction_name,
3939 test_func_t test_function,
3940 unsigned int ignore_test_flags)
3942 VERBOSE_FUNCTION_CALLOUT
3944 for (x_index = 0; x_index < 16; x_index++) {
3945 printf("%s ", instruction_name);
3946 printf(" %016x ", x_index);
3947 printf(" => ");
3948 (*test_function)();
3949 /* printf(" %016lx\n", r14); */
3950 printf(" %016x\n", 0); /* test is not portable just print zero */
3954 /* Identify those mffs* variants that take additional arguments.
3955 * This includes the immediate mffs*i variants. */
3956 #define is_not_simple_mffs_instruction(instruction_name) \
3957 ( (strncmp(instruction_name,"mffscdrn",8)==0) || \
3958 (strncmp(instruction_name,"mffscrn",7)==0) )
3960 /* Because some of the mffs* variants here are updating the fpscr as part
3961 * of the read, be sure to dissect both the retrieved (f14) and the updated
3962 * (local_fpscr) fpscr values. */
3963 static void testfunction_mffs(const char* instruction_name,
3964 test_func_t test_function,
3965 unsigned int ignore_test_flags)
3967 union reg_t {
3968 unsigned long int uli;
3969 double dble;
3970 } f14_reg, f15_reg;
3972 /*This function uses global variable x_shift */
3973 VERBOSE_FUNCTION_CALLOUT
3975 if (is_not_simple_mffs_instruction(instruction_name)) {
3976 /* iterate x_shift across values used for RN,RM */
3977 for (x_shift = 0; x_shift < 3; x_shift++) {
3978 printf("%s ", instruction_name);
3979 /* make sure bits in f14 get cleared so we can
3980 see correct resulg*/
3981 f14_reg.uli = 0x3FFFFFFFFUL;
3983 if (strcmp("mffscdrn", instruction_name) == 0) {
3984 /* instruction uses input reg f15 as input for DRN field */
3985 f15_reg.uli = (unsigned long int)x_shift << 32;
3986 printf(" f15 0X%lx ", f15_reg.uli);
3988 /* Setup input register value */
3989 f15 = f15_reg.dble;
3991 } else if (strcmp("mffscrn", instruction_name) == 0) {
3992 /* instruction uses input reg f15 as input for RN field */
3993 f15_reg.uli = (unsigned long int)x_shift;
3994 printf(" f15 0X%lx ", f15_reg.uli);
3996 /* Setup input register value */
3997 f15 = f15_reg.dble;
3999 } else {
4000 printf(" %x ", x_shift);
4004 (*test_function)();
4005 printf(" => ");
4006 f14_reg.dble = f14;
4007 printf(" 0X%lx\n", f14_reg.uli);
4008 printf(" fpscr: f14 ");
4009 dissect_fpscr(f14);
4010 printf(" local_fpscr: ");
4011 dissect_fpscr(local_fpscr);
4012 printf("\n");
4014 } else {
4015 printf("%s ", instruction_name);
4016 printf(" => ");
4017 (*test_function)();
4018 printf(" %016f\n", f14);
4019 printf(" fpscr: f14 ");
4020 dissect_fpscr(f14);
4021 printf("\n");
4022 printf(" local_fpscr: ");
4023 dissect_fpscr(local_fpscr);
4024 printf("\n");
4028 /* ######## begin grand testing loops. */
4029 typedef struct insn_sel_flags_t_struct {
4030 unsigned int one_arg, two_args, three_args, four_args, cmp_args, ld_args, st_args,
4031 one_imed_args;
4032 unsigned int arith, logical, compare, popcnt, ldst, insert_extract, permute, round;
4033 unsigned int integer, altivec, altivec_quad, altivec_double, dfp, bcd, misc, mffs,
4034 no_op, pc_immediate;
4035 unsigned int cr;
4036 } insn_sel_flags_t;
4038 static void do_tests ( insn_sel_flags_t seln_flags)
4040 test_group_t group_function;
4041 test_list_t *tests;
4042 unsigned int nb_args, type, family;
4043 int i, j, n;
4045 n = 0;
4046 group_function = NULL;
4048 /* self-test of some utility functions. */
4049 if (verbose > 1) {
4050 printf("fpscr zero'd out:");
4051 dissect_fpscr(0);
4052 printf("\n");
4053 printf("fpscr all ones:");
4054 dissect_fpscr(0xffffffffffffffff);
4055 printf("\n");
4056 printf("fpscr RN bits:");
4057 dissect_fpscr_rounding_mode(0x0000000000000003);
4058 dissect_fpscr_rounding_mode(0x0000000000000002);
4059 dissect_fpscr_rounding_mode(0x0000000000000001);
4060 dissect_fpscr_rounding_mode(0x0000000000000000);
4061 printf("\n");
4062 printf("XER bits: (64)");
4063 dissect_xer(0xffffffffffffffff);
4064 printf("\n");
4065 printf("XER bits: (32)");
4066 dissect_xer(0xffffffff);
4067 printf("\n\n");
4070 for (i=0; all_tests[i].name != NULL; i++) {
4071 nb_args = all_tests[i].flags & PPC_NB_ARGS_MASK;
4072 /* Check number of arguments */
4073 if ((nb_args == 1 && !seln_flags.one_arg) ||
4074 (nb_args == 2 && !seln_flags.two_args) ||
4075 (nb_args == 3 && !seln_flags.three_args) ||
4076 (nb_args == 4 && !seln_flags.four_args) ||
4077 (nb_args == 5 && !seln_flags.cmp_args) ||
4078 (nb_args == 6 && !seln_flags.ld_args) ||
4079 (nb_args == 7 && !seln_flags.st_args) ||
4080 (nb_args == 8 && !seln_flags.one_imed_args))
4081 continue;
4083 /* Check instruction type */
4084 type = all_tests[i].flags & PPC_TYPE_MASK;
4085 if ((type == PPC_ARITH && !seln_flags.arith) ||
4086 (type == PPC_LDST && !seln_flags.ldst) ||
4087 (type == PPC_LOGICAL && !seln_flags.logical) ||
4088 (type == PPC_COMPARE && !seln_flags.compare) ||
4089 (type == PPC_POPCNT && !seln_flags.compare) ||
4090 (type == PPC_INSERTEXTRACT && !seln_flags.insert_extract))
4091 continue;
4093 /* Check instruction family */
4094 family = all_tests[i].flags & PPC_FAMILY_MASK;
4096 /* do each check each case individually to reduce computation */
4097 if (family == PPC_INTEGER && seln_flags.integer == 0) continue;
4098 if (family == PPC_ALTIVEC && seln_flags.altivec == 0) continue;
4099 if (family == PPC_DFP && seln_flags.dfp == 0) continue;
4100 if (family == PPC_BCD && seln_flags.bcd == 0) continue;
4101 if (family == PPC_NO_OP && seln_flags.no_op == 0) continue;
4102 if (family == PPC_MISC && seln_flags.misc == 0) continue;
4103 if (family == PPC_MFFS && seln_flags.mffs == 0) continue;
4104 if (family == PPC_ALTIVEC_DOUBLE && seln_flags.altivec_double == 0)
4105 continue;
4107 if (family == PPC_ALTIVEC_QUAD && seln_flags.altivec_quad == 0)
4108 continue;
4110 if (family == PPC_PC_IMMEDIATE && seln_flags.pc_immediate == 0)
4111 continue;
4113 /* Check flags update */
4114 if (((all_tests[i].flags & PPC_CR) && seln_flags.cr == 0) ||
4115 (!(all_tests[i].flags & PPC_CR) && seln_flags.cr == 1))
4116 continue;
4118 /* All criteria validation passed, do the tests */
4119 tests = all_tests[i].tests;
4121 /* Select the test group */
4122 switch (family) {
4123 case PPC_MFFS:
4124 group_function = &testfunction_mffs;
4125 break;
4127 case PPC_INTEGER:
4128 switch(type) {
4129 case PPC_ARITH:
4130 switch(nb_args) {
4131 case PPC_TWO_ARGS:
4132 group_function = &testfunction_int_two_args;
4133 break;
4135 case PPC_THREE_ARGS:
4136 group_function = &testfunction_three_args;
4137 break;
4139 default:
4140 printf("ERROR: PPC_INTEGER, unhandled number of arguments. 0x%08x\n",
4141 nb_args);
4143 break;
4145 case PPC_LOGICAL:
4146 switch(nb_args) {
4147 case PPC_ONE_IMM:
4148 group_function = &testfunction_set_boolean;
4149 break;
4151 case PPC_ONE_ARG:
4152 group_function = &testfunction_logical_one;
4153 break;
4155 default:
4156 printf("ERROR: PPC_LOGICAL, unhandled number of arguments. 0x%08x\n",
4157 nb_args);
4159 break;
4161 case PPC_COMPARE:
4162 group_function = &testfunction_char_compare;
4163 break;
4165 default:
4166 printf("ERROR: PPC_INTEGER, unhandled type 0x%08x\n", type);
4167 continue;
4168 } /* switch (type) */
4169 break;
4171 case PPC_ALTIVEC:
4172 switch(type) {
4173 case PPC_ARITH:
4174 switch(nb_args) {
4175 case PPC_TWO_ARGS:
4176 group_function = &testfunction_vector_absolute;
4178 break;
4179 default:
4180 printf("ERROR: PPC_ALTIVEC, PPC_ARITH, unhandled number of arguments. 0x%08x\n", nb_args);
4181 continue;
4182 } /* switch (PPC_ARITH, nb_args) */
4183 break;
4185 case PPC_LOGICAL:
4186 switch(nb_args) {
4187 case PPC_ONE_IMM:
4188 group_function = &testfunction_vector_immediate;
4189 break;
4191 case PPC_ONE_ARG:
4192 group_function = &testfunction_vector_logical_one;
4193 break;
4195 case PPC_TWO_ARGS:
4196 group_function = &testfunction_vector_extend_sign;
4197 break;
4199 case PPC_THREE_ARGS:
4200 group_function = &testfunction_vector_three_special;
4201 break;
4203 case PPC_FOUR_ARGS:
4204 group_function = &testfunction_vector_logical_four;
4205 break;
4207 case PPC_ONE_GPR_ONE_VEC:
4208 group_function = &testfunction_gpr_vector_logical_one;
4209 break;
4211 default:
4212 printf("ERROR: PPC_ALTIVEC, PPC_LOGICAL, unhandled number of arguments. 0x%08x\n", nb_args);
4213 continue;
4214 } /* switch(PPC_INSERTEXTRACT, nb_args) */
4215 break;
4217 case PPC_INSERTEXTRACT:
4218 switch(nb_args) {
4219 case PPC_ONE_IMM:
4220 group_function = &testfunction_vector_insert_or_extract_immediate;
4221 break;
4223 case PPC_TWO_ARGS:
4224 group_function = testfunction_vector_extract;
4225 break;
4227 default:
4228 printf("ERROR: PPC_ALTIVEC, PPC_INSERTEXTRACT, unhandled number of arguments. 0x%08x\n", nb_args);
4229 continue;
4230 } /* switch(PPC_INSERTEXTRACT, nb_args) */
4231 break;
4233 case PPC_PERMUTE:
4234 group_function = &testfunction_vector_xxpermute;
4235 break;
4237 case PPC_LDST:
4238 switch(nb_args) {
4239 case PPC_ONE_IMM:
4240 /* Register holds immediate length value */
4241 group_function = &testfunction_vector_scalar_loadstore_length;
4242 break;
4244 case PPC_TWO_ARGS:
4245 /* Register holds address of buffer */
4246 group_function = &testfunction_vector_loadstore;
4247 break;
4249 default:
4250 printf("ERROR: PPC_ALTIVEC, PPC_LDST, unhandled number of arguments. 0x%08x\n", nb_args);
4251 continue;
4252 } /* switch(PPC_LDST, nb_args) */
4253 break;
4255 case PPC_POPCNT:
4256 group_function = &testfunction_vector_count_bytes;
4257 break;
4259 default:
4260 printf("ERROR: PPC_ALTIVEC, unhandled type. %d\n", type);
4261 continue;
4262 } /* switch (PPC_ALTIVEC, type) */
4263 break;
4265 case PPC_MISC:
4266 switch(nb_args) {
4267 case PPC_TWO_ARGS:
4268 group_function = &testfunction_vectorscalar_move_tofrom;
4269 break;
4270 case PPC_THREE_ARGS:
4271 group_function = &testfunction_one_arg_with_shift;
4272 break;
4273 default:
4274 printf("ERROR: PPC_MISC, unhandled number of arguments. 0x%08x\n", nb_args);
4275 continue;
4276 } /* switch(PPC_MISC, nb_args) */
4277 break;
4279 case PPC_ALTIVEC_QUAD:
4280 switch(type) {
4281 case PPC_LOGICAL:
4282 switch(nb_args) {
4283 case PPC_TWO_ARGS:
4284 group_function = &testfunction_vector_scalar_two_quad;
4285 break;
4287 default:
4288 printf("ERROR: PPC_ALTIVEC_QUAD, PPC_LOGICAL, unhandled number of arguments. 0x%08x\n", nb_args);
4289 continue;
4290 } /* switch(PPC_LOGICAL, nb_args) */
4291 break;
4293 case PPC_COMPARE:
4294 group_function = &testfunction_vector_scalar_compare_quads;
4295 break;
4297 case PPC_ROUND:
4298 group_function = &testfunction_vector_scalar_rounding_quads;
4299 break;
4301 default:
4302 printf("ERROR: PPC_ALTIVEC_QUAD, unhandled type. %d\n", type);
4303 continue;
4304 } /* switch(type) */
4305 break;
4307 case PPC_ALTIVEC_DOUBLE:
4308 switch(type) {
4309 case PPC_COMPARE:
4310 switch(nb_args) {
4311 case PPC_ONE_ARG:
4312 group_function = &testfunction_vector_scalar_data_class;
4313 break;
4315 case PPC_TWO_ARGS:
4316 group_function = &testfunction_vector_scalar_two_double;
4317 break;
4319 case PPC_COMPARE_ARGS:
4320 group_function = &testfunction_vector_scalar_compare_double;
4321 break;
4323 default:
4324 printf("ERROR: PPC_ALTIVEC_DOUBLE, PPC_COMPARE, unhandled number of arguments. 0x%08x\n", nb_args);
4325 continue;
4326 } /* switch(PPC_COMPARE, nb_args) */
4327 break;
4329 default:
4330 printf("ERROR: PPC_ALTIVEC_DOUBLE, unhandled type. %d\n", type);
4331 continue;
4333 } /* switch(type) */
4334 break;
4336 case PPC_DFP:
4337 group_function = &testfunction_dfp_significance;
4338 break;
4340 case PPC_BCD:
4341 group_function = &testfunction_bcd_misc;
4342 break;
4344 case PPC_NO_OP:
4345 group_function = &testfunction_noop_misc;
4346 break;
4348 case PPC_PC_IMMEDIATE:
4349 group_function = &testfunction_pc_immediate_misc;
4350 break;
4352 default:
4353 printf("ERROR: unknown instruction family %08x\n", family);
4354 continue;
4355 } /* switch(family) */
4357 printf("%s:\n", all_tests[i].name);
4359 printf("Test instruction group [%s]\n", all_tests[i].name);
4360 /* Now, spin through all entries in the group_function to
4361 * run the individual instruction tests.
4363 for (j = 0; tests[j].name != NULL; j++) {
4364 if (verbose > 1)
4365 printf("Test instruction %s\n", tests[j].name);
4366 (*group_function)(tests[j].name, tests[j].func, all_tests[i].flags);
4367 printf("\n");
4368 n++;
4371 if (verbose) printf("\n");
4373 printf("All done. Tested %d different instructions\n", n);
4374 } /* for (i = 0; all_tests[i].name...) */
4377 static void usage (void)
4379 fprintf(stderr,
4380 "Usage: test_isa_3_0 [OPTIONS]\n"
4381 "\t-i: test integer instructions (default)\n"
4382 "\t-a: test altivec instructions\n"
4383 "\t-d: test altivec double instructions\n"
4384 "\t-q: test altivec quad instructions\n"
4385 "\t-D: test DFP instructions\n"
4386 "\t-B: test BCD instructions\n"
4387 "\t-N: test No Op instructions\n"
4388 "\t-P: test PC Immediate Shifted instructions\n"
4389 "\t-m: test miscellaneous instructions\n"
4390 "\t-M: test MFFS instructions\n"
4391 "\t-v: be verbose\n"
4392 "\t-h: display this help and exit\n"
4396 #endif // HAS_ISA_3_00
4397 int main (int argc, char **argv)
4400 #ifndef HAS_ISA_3_00
4401 printf("NO ISA 3.00 SUPPORT\n");
4402 return 0;
4404 #else
4405 insn_sel_flags_t flags;
4406 int c;
4409 // Args
4410 flags.one_arg = 1;
4411 flags.two_args = 1;
4412 flags.three_args = 1;
4413 flags.four_args = 1;
4414 flags.cmp_args = 1;
4415 flags.ld_args = 1;
4416 flags.st_args = 1;
4417 flags.one_imed_args = 1;
4419 // Type
4420 flags.arith = 1;
4421 flags.logical = 1;
4422 flags.compare = 1;
4423 flags.ldst = 1;
4424 flags.popcnt = 1;
4425 flags.insert_extract = 1;
4426 flags.permute = 1;
4427 flags.round = 1;
4429 // Family
4430 flags.integer = 0;
4431 flags.altivec = 0;
4432 flags.altivec_double = 0;
4433 flags.altivec_quad = 0;
4434 flags.dfp = 0;
4435 flags.bcd = 0;
4436 flags.misc = 0;
4437 flags.mffs = 0;
4438 flags.no_op = 0;
4439 flags.pc_immediate = 0;
4441 // Flags
4442 flags.cr = 2;
4444 while ((c = getopt(argc, argv, "ifmadqhvADBMNP")) != -1) {
4445 switch (c) {
4446 case 'i':
4447 flags.integer = 1;
4448 break;
4450 case 'a':
4451 flags.altivec = 1;
4452 break;
4454 case 'd':
4455 flags.altivec_double = 1;
4456 break;
4458 case 'q':
4459 flags.altivec_quad = 1;
4460 break;
4462 case 'D':
4463 flags.dfp = 1;
4464 break;
4466 case 'B':
4467 flags.bcd = 1;
4468 break;
4470 case 'm':
4471 flags.misc = 1;
4472 break;
4474 case 'M':
4475 flags.mffs = 1;
4476 break;
4478 case 'N':
4479 flags.no_op = 1;
4480 break;
4482 case 'P':
4483 flags.pc_immediate = 1;
4484 break;
4486 case 'h':
4487 usage();
4488 return 0;
4490 case 'v':
4491 verbose++;
4492 break;
4494 default:
4495 usage();
4496 fprintf(stderr, "Unknown argument: '%c'\n", c);
4497 return 1;
4501 build_iargs_table();
4502 build_vsx_table();
4503 build_float_vsx_tables();
4504 build_vector_permute_table();
4505 build_char_table();
4506 build_char_range_table();
4507 build_packed_decimal_table();
4508 build_national_decimal_table();
4509 build_zoned_decimal_table();
4510 build_decimal_shift_table();
4512 if (verbose>2) {
4513 dump_char_table();
4514 dump_char_range_table();
4515 dump_float_vsx_table();
4516 dump_packed_decimal_table();
4517 dump_national_decimal_table();
4518 dump_zoned_decimal_table();
4519 dump_decimal_shift_table();
4520 dump_dfp64_table();
4521 dump_dfp128_table();
4524 if (verbose > 1) {
4525 printf("\nInstruction Selection:\n");
4526 printf(" n_args: \n");
4527 printf(" one_arg = %d\n", flags.one_arg);
4528 printf(" two_args = %d\n", flags.two_args);
4529 printf(" three_args = %d\n", flags.three_args);
4530 printf(" four_args = %d\n", flags.four_args);
4531 printf(" cmp_args = %d\n", flags.cmp_args);
4532 printf(" load_args = %d\n", flags.ld_args);
4533 printf(" store_args = %d\n", flags.st_args);
4534 printf(" one_im_args = %d\n", flags.one_imed_args);
4535 printf(" type: \n");
4536 printf(" arith = %d\n", flags.arith);
4537 printf(" logical = %d\n", flags.logical);
4538 printf(" popcnt = %d\n", flags.popcnt);
4539 printf(" compare = %d\n", flags.compare);
4540 printf(" inset/extract = %d\n", flags.insert_extract);
4541 printf(" family: \n");
4542 printf(" integer = %d\n", flags.integer);
4543 printf(" altivec = %d\n", flags.altivec);
4544 printf(" altivec double = %d\n", flags.altivec_double);
4545 printf(" altivec quad = %d\n", flags.altivec_quad);
4546 printf(" DFP = %d\n", flags.dfp);
4547 printf(" BCD = %d\n", flags.bcd);
4548 printf(" PC immediate shifted = %d\n", flags.pc_immediate);
4549 printf(" misc = %d\n", flags.misc);
4550 printf(" cr update: \n");
4551 printf(" cr = %d\n", flags.cr);
4552 printf("\n");
4553 printf(" num args: \n");
4554 printf(" iargs - %d\n", nb_iargs);
4555 printf("\n");
4558 do_tests( flags );
4559 #endif
4561 return 0;