blob: 6e4e7dc39fcabfb64e2fb6489c88d0c3d804ed8a [file] [log] [blame]
Elliott Hughesa0664b92017-04-18 17:46:52 -07001/* HOW TO COMPILE:
2 * 64bit build:
3 * gcc -Winline -Wall -g -O -mregnames -maltivec -m64
4 */
5
6/*
7 * test_isa_3_0.c:
Elliott Hughesed398002017-06-21 14:41:24 -07008 * Copyright (C) 2016-2017 Carl Love <cel@us.ibm.com>
9 * Copyright (C) 2016-2017 Will Schmidt <will_schmidt@vnet.ibm.com>
Elliott Hughesa0664b92017-04-18 17:46:52 -070010 *
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.
15 */
16
17/*
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
21 *
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.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 */
31
32/*
33 * Theory of operations:
34 * a few registers are reserved for the test program:
35 * r14...r18
36 * f14...f18
37 * - pre-load test values in r14 through r17
38 * - patch the test opcode if any immediate operands are
39 * required
40 * - execute the tested opcode.
41 * CR and FPSCR are cleared before every test.
42 * results in {r,f}17
43 * check FPSCR for floating point operations.
44 */
45
46/*
47 * Operation details
48 * -----------------
49 * The 'test' functions (via all_tests[]) are wrappers of
50 * single __asm__ instructions
51 *
52 * The 'loops' (e.g. int_loops) do the actual work:
53 * - loops over as many arguments as the instruction needs (regs | imms)
54 * - sets up the environment (reset cr, assign src regs...)
55 * - maybe modifies the asm instruction to test different immediate args
56 * - call the test function
57 * - retrieve relevant register data (rD,cr,...)
58 * - prints argument and result data.
59 *
60 * all_tests[i] holds instruction tests
61 * - of which each holds: {instn_test_arr[], description, flags}
62 *
63 * flags hold 3 instruction classifiers: {family, type, arg_type}
64 *
65 * // The main test loop:
66 * do_tests( user_ctl_flags ) {
67 * foreach(curr_test = all_test[i]) {
68 *
69 * // flags are used to control what tests are run:
70 * if (curr_test->flags && !user_ctl_flags)
71 * continue;
72 *
73 * // a 'loop_family_arr' is chosen based on the 'family' flag...
74 * switch(curr_test->flags->family) {
75 * case x: loop_family_arr = int_loops;
76 * ...
77 * }
78 *
79 * // ...and the actual test_loop to run is found by indexing into
80 * // the loop_family_arr with the 'arg_type' flag:
81 * test_loop = loop_family[curr_test->flags->arg_type]
82 *
83 * // finally, loop over all instn tests for this test:
84 * foreach (instn_test = curr_test->instn_test_arr[i]) {
85 *
86 * // and call the test_loop with the current instn_test function,name
87 * test_loop( instn_test->func, instn_test->name )
88 * }
89 * }
90 * }
91 */
92
93#include <stdio.h>
94#include <stdint.h>
95
96/* This test is only valid on machines that support IBM POWER ISA 3.0. */
97#ifdef HAS_ISA_3_00
98
99#include <assert.h>
100#include <ctype.h> // isspace
101#include <stdlib.h>
102#include <string.h>
103#include <unistd.h> // getopt
104#include <altivec.h> // vector
105
106#undef DEBUG_VECTOR_PERMUTE
107static int verbose = 0;
108
109#include "../ppc64/ppc64_helpers.h" // SET_CR() and friends.
110
111#define VERBOSE_FUNCTION_CALLOUT \
112 if (verbose) \
113 printf("Test Harness Function: %s\n", __FUNCTION__);
114
115/* generic out-of-range reporting.
116 * Note: results are typically 'undefined' in these cases, so rather than
117 * pushing through and getting potentially random results, avoid the check.
118 * The caller should suppress output when insert_extract_error is set. */
119#define vinsertextract_err \
120 insert_extract_error = 1; \
121 if (verbose > 1) \
122 printf("Expected error - index out of range in %s (%d)\n", \
123 __FUNCTION__, x_index);
124
125#define MAX(x, y) (x > y ? x : y)
126
127/* Used in do_tests, indexed by flags->nb_args
128 Elements correspond to enum test_flags::num args
129*/
130
131/* XXXX these must all be callee-save regs! */
132register HWord_t r14 __asm__ ("r14");
133register HWord_t r15 __asm__ ("r15");
134register HWord_t r16 __asm__ ("r16");
135register HWord_t r17 __asm__ ("r17");
136register double f14 __asm__ ("fr14");
137register double f15 __asm__ ("fr15");
138
139/* globals used for vector tests */
140static vector unsigned long vec_xa, vec_xb, vec_xc, vec_xt;
141
142/* globals for the condition register fields. These are used to
143 * capture the condition register values immediately after the
144 * instruction under test is tested.
145 * This is to help prevent other test overhead, switch statements,
146 * compares, what-not from interfering.
147 */
148unsigned long local_cr;
149unsigned long local_fpscr;
Elliott Hughesed398002017-06-21 14:41:24 -0700150unsigned long local_xer;
Elliott Hughesa0664b92017-04-18 17:46:52 -0700151volatile unsigned int cr_value;
152
153/* global for holding the DFP values */
154dfp_val_t dfp_value;
155
156/* individual instruction tests */
157typedef void (*test_func_t) (void);
158struct test_list_t {
159 test_func_t func;
160 const char *name;
161};
162typedef struct test_list_t test_list_t;
163
164/* global variable, used to pass shift info down to the test functions.*/
165volatile int x_shift;
166
167/* Indicator for DCMX (Data Class Mask) matches. */
168volatile int dcmx_match;
169
170/* Error indicator to determine of the UIN (Unsigned Immediate) field
171 * from insert/extract was out of range */
172volatile int insert_extract_error;
173
174/* vector splat value */
175volatile int x_splat;
176volatile int dfp_significance;
177
178/* global variable, ... vector insert functions. */
179volatile int x_index;
180
181/* global variable, used to pass shift info down to the test functions.*/
Elliott Hughesed398002017-06-21 14:41:24 -0700182/* Also used to control DRM,RM values for mffs* functions. */
Elliott Hughesa0664b92017-04-18 17:46:52 -0700183volatile int x_shift;
184
185/* groups of instruction tests, calling individual tests */
186typedef void (*test_group_t) (const char *name, test_func_t func,
187 unsigned int test_flags);
188
189enum test_flags {
190 /* Nb arguments */
191 PPC_ONE_ARG = 0x00000001,
192 PPC_TWO_ARGS = 0x00000002,
193 PPC_THREE_ARGS = 0x00000003,
194 PPC_FOUR_ARGS = 0x00000004,
195 PPC_COMPARE_ARGS = 0x00000005,
196 PPC_LD_ARGS = 0x00000006,
197 PPC_ST_ARGS = 0x00000007,
198 PPC_ONE_IMM = 0x00000008,
199 PPC_NB_ARGS_MASK = 0x0000000F,
200
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,
211
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,
Elliott Hughesed398002017-06-21 14:41:24 -0700222 PPC_MFFS = 0x000B0000,
Elliott Hughesa0664b92017-04-18 17:46:52 -0700223 PPC_FAMILY_MASK = 0x000F0000,
224
225 /* Flags: these may be combined, so use separate bit-fields. */
226 PPC_CR = 0x01000000,
227 PPC_XER_CA = 0x02000000,
228};
229
230static void test_cnttzw (void)
231{
232 __asm__ __volatile__ ("cnttzw 17, 14");
233}
234
235static void test_cnttzd (void)
236{
237 __asm__ __volatile__ ("cnttzd 17, 14");
238}
239
240static void test_dotted_cnttzw (void)
241{
242 __asm__ __volatile__ ("cnttzw. 17, 14");
243}
244
245static void test_dotted_cnttzd (void)
246{
247 __asm__ __volatile__ ("cnttzd. 17, 14");
248}
249
250static 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 },
256};
257
258static void test_modsw (void)
259{
260 __asm__ __volatile__ ("modsw 17, 14, 15");
261}
262
263static void test_moduw (void)
264{
265 __asm__ __volatile__ ("moduw 17, 14, 15");
266}
267
268static void test_modsd (void)
269{
270 __asm__ __volatile__ ("modsd 17, 14, 15");
271}
272
273static void test_modud (void)
274{
275 __asm__ __volatile__ ("modud 17, 14, 15");
276}
277
Elliott Hughesed398002017-06-21 14:41:24 -0700278static 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) );
281}
282
Elliott Hughesa0664b92017-04-18 17:46:52 -0700283static test_list_t testgroup_ia_ops_two[] = {
Elliott Hughesed398002017-06-21 14:41:24 -0700284 { &test_modsw, "modsw" },
285 { &test_moduw, "moduw" },
286 { &test_modsd, "modsd" },
287 { &test_modud, "modud" },
288 //{ &test_addex, "addex" },
289 { NULL , NULL },
Elliott Hughesa0664b92017-04-18 17:46:52 -0700290};
291
292static void test_dotted_extswsli (void)
293{
294 switch(x_shift) {
295 case SH_0:
296 __asm__ __volatile__ ("extswsli. %0, %1, %2" : "=r" (r17) : "r" (r14), "i" (SH_0) );
297 break;
298
299 case SH_1:
300 __asm__ __volatile__ ("extswsli. %0, %1, %2" : "=r" (r17) : "r" (r14), "i" (SH_1) );
301 break;
302
303 case SH_2:
304 __asm__ __volatile__ ("extswsli. %0, %1, %2" : "=r" (r17) : "r" (r14), "i" (SH_2) );
305 break;
306
307 case SH_3:
308 __asm__ __volatile__ ("extswsli. %0, %1, %2" : "=r" (r17) : "r" (r14), "i" (SH_3) );
309 break;
310
311 default:
312 printf("Unhandled shift value for extswsli. %d\n", x_shift);
313 }
314}
315
316static void test_extswsli (void)
317{
318 switch(x_shift) {
319 case SH_0:
320 __asm__ __volatile__ ("extswsli %0, %1, %2" : "=r" (r17) : "r" (r14), "i"(SH_0));
321 break;
322
323 case SH_1:
324 __asm__ __volatile__ ("extswsli %0, %1, %2" : "=r" (r17) : "r" (r14), "i"(SH_1));
325 break;
326
327 case SH_2:
328 __asm__ __volatile__ ("extswsli %0, %1, %2" : "=r" (r17) : "r" (r14), "i"(SH_2));
329 break;
330
331 case SH_3:
332 __asm__ __volatile__ ("extswsli %0, %1, %2" : "=r" (r17) : "r" (r14), "i"(SH_3));
333 break;
334
335 default:
336 printf("Unhandled shift value for extswsli %d\n", x_shift);
337 }
338}
339
340static test_list_t testgroup_shifted_one[] = {
341 { &test_extswsli , "extswsli " },
342 { &test_dotted_extswsli, "extswsli." },
343 { NULL , NULL },
344};
345
346static void test_maddhd (void)
347{
348 __asm__ __volatile__ ("maddhd 17, 14, 15, 16");
349}
350static void test_maddhdu (void)
351{
352 __asm__ __volatile__ ("maddhdu 17, 14, 15, 16");
353}
354static void test_maddld (void)
355{
356 __asm__ __volatile__ ("maddld 17, 14, 15, 16");
357}
358
359static test_list_t testgroup_three_args[] = {
360 { &test_maddhd , "maddhd " },
361 { &test_maddhdu, "maddhdu" },
362 { &test_maddld , "maddld " },
363 { NULL , NULL },
364};
365
366/* VSX vector permutes. */
367static void test_xxperm (void)
368{
369 __asm__ __volatile__ ("xxperm %x0, %x1, %x2" : "+wa" (vec_xt): "wa" (vec_xa), "wa" (vec_xb));
370}
371
372/* VSX vector permute, right indexed. */
373static void test_xxpermr (void)
374{
375 __asm__ __volatile__ ("xxpermr %x0, %x1, %x2" : "+wa" (vec_xt): "wa" (vec_xa), "wa" (vec_xb));
376}
377
378static test_list_t testgroup_vsx_xxpermute[] = {
379 { &test_xxperm , "xxperm" },
380 { &test_xxpermr, "xxpermr" },
381 { NULL , NULL },
382};
383
384static void test_vabsdub(void) {
385 __asm__ __volatile__ ("vabsdub %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
386}
387
388static void test_vabsduh(void) {
389 __asm__ __volatile__ ("vabsduh %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
390}
391
392static void test_vabsduw(void) {
393 __asm__ __volatile__ ("vabsduw %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
394}
395
396static void test_vcmpneb(void) {
397 __asm__ __volatile__ ("vcmpneb %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
398}
399
400static void test_dotted_vcmpneb(void) {
401 __asm__ __volatile__ ("vcmpneb. %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
402}
403
404static void test_vcmpnezb(void) {
405 __asm__ __volatile__ ("vcmpnezb %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
406}
407
408static void test_dotted_vcmpnezb(void) {
409 __asm__ __volatile__ ("vcmpnezb. %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
410}
411
412static void test_vcmpneh(void) {
413 __asm__ __volatile__ ("vcmpneh %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
414}
415
416static void test_dotted_vcmpneh(void) {
417 __asm__ __volatile__ ("vcmpneh. %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
418}
419
420static void test_vcmpnezh(void) {
421 __asm__ __volatile__ ("vcmpnezh %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
422}
423
424static void test_dotted_vcmpnezh(void) {
425 __asm__ __volatile__ ("vcmpnezh. %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
426}
427
428static void test_vcmpnew(void) {
429 __asm__ __volatile__ ("vcmpnew %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
430}
431
432static void test_dotted_vcmpnew(void) {
433 __asm__ __volatile__ ("vcmpnew. %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
434}
435
436static void test_vcmpnezw(void) {
437 __asm__ __volatile__ ("vcmpnezw %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
438}
439
440static void test_dotted_vcmpnezw(void) {
441 __asm__ __volatile__ ("vcmpnezw. %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
442}
443
444static void test_vrlwmi(void) {
445 __asm__ __volatile__ ("vrlwmi %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
446}
447
448static void test_vrldmi(void) {
449 __asm__ __volatile__ ("vrldmi %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
450}
451
452static 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));
455}
456
457static void test_vrlwnm(void) {
458 __asm__ __volatile__ ("vrlwnm %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
459}
460
461static void test_vrldnm(void) {
462 __asm__ __volatile__ ("vrldnm %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb));
463}
464
465static void test_xviexpdp(void) {
466 __asm__ __volatile__ ("xviexpdp %0, %1, %2 " : "+wa" (vec_xt): "wa" (vec_xa), "wa" (vec_xb));
467}
468
469static void test_xviexpsp(void) {
470 __asm__ __volatile__ ("xviexpsp %0, %1, %2 " : "+wa" (vec_xt): "wa" (vec_xa), "wa" (vec_xb));
471}
472
473static 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 },
497};
498
499static 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));
502}
503
Elliott Hughesed398002017-06-21 14:41:24 -0700504static 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));
507}
508
Elliott Hughesa0664b92017-04-18 17:46:52 -0700509/* vector, 3->1 unique; four arguments. xt, xa, xb, xc (xc = permute) */
510static test_list_t testgroup_vector_four[] = {
Elliott Hughesed398002017-06-21 14:41:24 -0700511 { &test_vpermr, "vpermr" },
512 // { &test_vmsumudm, "vmsumudm" },
Elliott Hughesa0664b92017-04-18 17:46:52 -0700513 { NULL , NULL },
514};
515
516/* vector insert instructions */
517#define VINSERTB(X) __asm__ __volatile__ ("vinsertb %0, %1, %2" : "+v" (vec_xt) : "v" (vec_xb), "i"(X));
518
519#define VINSERTH(X) __asm__ __volatile__ ("vinserth %0, %1, %2" : "+v" (vec_xt) : "v" (vec_xb), "i"(X));
520
521#define VINSERTW(X) __asm__ __volatile__ ("vinsertw %0, %1, %2" : "+v" (vec_xt) : "v" (vec_xb), "i"(X));
522
523#define VINSERTD(X) __asm__ __volatile__ ("vinsertd %0, %1, %2" : "+v" (vec_xt) : "v" (vec_xb), "i"(X));
524
525#define VEXTRACTUB(X) __asm__ __volatile__ ("vextractub %0, %1, %2" : "+v" (vec_xt) : "v" (vec_xb), "i"(X));
526
527#define VEXTRACTUH(X) __asm__ __volatile__ ("vextractuh %0, %1, %2" : "+v" (vec_xt) : "v" (vec_xb), "i"(X));
528
529#define VEXTRACTUW(X) __asm__ __volatile__ ("vextractuw %0, %1, %2" : "+v" (vec_xt) : "v" (vec_xb), "i"(X));
530
531#define VEXTRACTD(X) __asm__ __volatile__ ("vextractd %0, %1, %2" : "+v" (vec_xt) : "v" (vec_xb), "i"(X));
532
533#define XXINSERTW(X) __asm__ __volatile__ ("xxinsertw %0, %1, %2" : "+wa" (vec_xt) : "wa" (vec_xb), "i"(X));
534
535#define XXEXTRACTUW(X) __asm__ __volatile__ ("xxextractuw %0, %1, %2" : "+wa" (vec_xt) : "wa" (vec_xb), "i"(X));
536
537static void test_vinsertb (void)
538{
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;
559 }
560}
561
562static void test_vinserth (void)
563{
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;
583 }
584}
585
586static void test_vinsertw (void)
587{
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;
605 }
606}
607
608static void test_vinsertd (void)
609{
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;
623 }
624}
625
626/* extracts */
627static void test_vextractub (void)
628{
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;
649 }
650}
651
652static void test_vextractuh (void)
653{
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;
673 }
674}
675
676static void test_vextractuw (void)
677{
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;
694 }
695}
696
697static void test_vextractd (void)
698{
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;
712 }
713}
714
715static void test_xxinsertw (void)
716{
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;
734 }
735}
736
737static void test_xxextractuw (void)
738{
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;
756 }
757}
758
759static 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 },
771};
772
773static 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;
777
778 case SPLAT1: __asm__ __volatile__ ("xxspltib %x0, %1 " : "=wa"(vec_xt) : "i"(SPLAT1)); break;
779
780 case SPLAT2: __asm__ __volatile__ ("xxspltib %x0, %1 " : "=wa"(vec_xt) : "i"(SPLAT2)); break;
781
782 case SPLAT3: __asm__ __volatile__ ("xxspltib %x0, %1 " : "=wa"(vec_xt) : "i"(SPLAT3)); break;
783
784 case SPLAT4: __asm__ __volatile__ ("xxspltib %x0, %1 " : "=wa"(vec_xt) : "i"(SPLAT4)); break;
785
786 default:
787 printf("Unhandled splat value for %s %d\n", __FUNCTION__, x_splat);
788 }
789};
790
791static test_list_t testgroup_vector_immediate[] = {
792 { &test_xxspltib, "xxspltib" },
793 { NULL , NULL },
794};
795
796/* vector reverse bytes ... */
797static void test_xxbrh(void)
798{ /* vector reverse byte halfword*/
799 __asm__ __volatile__ ("xxbrh %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa));
800}
801
802static void test_xxbrw(void)
803{ /* vector reverse byte word*/
804 __asm__ __volatile__ ("xxbrw %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa));
805}
806
807static void test_xxbrd(void)
808{ /* vector reverse byte double*/
809 __asm__ __volatile__ ("xxbrd %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa));
810}
811
812static void test_xxbrq(void)
813{ /* vector reverse byte */
814 __asm__ __volatile__ ("xxbrq %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa));
815}
816
817static void test_xvxexpdp(void) {
818 __asm__ __volatile__ ("xvxexpdp %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa));
819}
820
821static void test_xvxexpsp(void) {
822 __asm__ __volatile__ ("xvxexpsp %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa));
823}
824
825static void test_xvxsigdp(void) {
826 __asm__ __volatile__ ("xvxsigdp %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa));
827}
828
829static void test_xvxsigsp(void) {
830 __asm__ __volatile__ ("xvxsigsp %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa));
831}
832
833static void test_xsxexpdp(void) {
834 __asm__ __volatile__ ("xsxexpdp %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa));
835}
836
837static void test_xsxsigdp(void) {
838 __asm__ __volatile__ ("xsxsigdp %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa));
839}
840
841static test_list_t testgroup_vector_logical_one[] = {
842 { &test_xxbrh , "xxbrh" },
843 { &test_xxbrw , "xxbrw" },
844 { &test_xxbrd , "xxbrd" },
845 { &test_xxbrq , "xxbrq" },
846 { &test_xvxexpdp, "xvxexpdp" },
847 { &test_xvxexpsp, "xvxexpsp" },
848 { &test_xvxsigdp, "xvxsigdp" },
849 { &test_xvxsigsp, "xvxsigsp" },
850 { &test_xsxexpdp, "xsxexpdp" },
851 { &test_xsxsigdp, "xsxsigdp" },
852 { NULL , NULL },
853};
854
855static void test_lxvx(void) {
856 __asm__ __volatile__ ("lxvx %x0, 14, 15" : "=wa" (vec_xt));
857}
858
859static void test_lxvwsx(void) {
860 __asm__ __volatile__ ("lxvwsx %x0, 14, 15" : "=wa" (vec_xt));
861}
862
863static void test_lxvh8x(void) {
864 __asm__ __volatile__ ("lxvh8x %x0, 14, 15" : "=wa" (vec_xt));
865}
866
867static void test_lxvb16x(void) {
868 __asm__ __volatile__ ("lxvb16x %x0, 14, 15" : "=wa" (vec_xt));
869}
870
871static void test_stxvx(void) {
872 __asm__ __volatile__ ("stxvx %x0, 14, 15" : "=wa" (vec_xt));
873}
874
875static void test_stxvh8x(void) {
876 __asm__ __volatile__ ("stxvh8x %x0, 14, 15" : "=wa" (vec_xt));
877}
878
879static void test_stxvb16x(void) {
880 __asm__ __volatile__ ("stxvb16x %x0, 14, 15" : "=wa" (vec_xt));
881}
882
883static test_list_t testgroup_vector_loadstore[] = {
884 { &test_lxvx , "lxvx" },
885 { &test_lxvwsx , "lxvwsx" },
886 { &test_lxvh8x , "lxvh8x" },
887 { &test_lxvb16x , "lxvb16x" },
888 { &test_stxvx , "stxvx" },
889 { &test_stxvh8x , "stxvh8x" },
890 { &test_stxvb16x, "stxvb16x" },
891 { NULL , NULL },
892};
893
894static void test_lxvl(void) {
895 __asm__ __volatile__ ("lxvl %0, 14, 15" : "=wa" (vec_xt));
896}
897
898static void test_stxvl(void) {
899 __asm__ __volatile__ ("stxvl %0, 14, 15" : "=wa" (vec_xt));
900}
901
902static void test_lxvll(void) {
903 __asm__ __volatile__ ("lxvll %0, 14, 15" : "=wa" (vec_xt));
904}
905
906static void test_stxvll(void) {
907 __asm__ __volatile__ ("stxvll %0, 14, 15" : "=wa" (vec_xt));
908}
909
910static void test_lxsibzx(void) {
911 __asm__ __volatile__ ("lxsibzx %x0, 14, 15" : "=wa" (vec_xt));
912}
913
914static void test_lxsihzx(void) {
915 __asm__ __volatile__ ("lxsihzx %x0, 14, 15" : "=wa" (vec_xt));
916}
917
918static void test_stxsibx(void) {
919 __asm__ __volatile__ ("stxsibx %x0, 14, 15" : "=wa" (vec_xt));
920}
921
922static void test_stxsihx(void) {
923 __asm__ __volatile__ ("stxsihx %x0, 14, 15" : "=wa" (vec_xt));
924}
925
926/* d-form vsx load/store */
927static void test_lxsd_0(void) {
928 __asm__ __volatile__ ("lxsd %0, 0(%1) " : "=v"(vec_xt) : "r"(r14));
929}
930
931static void test_stxsd_0(void) {
932 __asm__ __volatile__ ("stxsd %0, 0(%1)" : "=v"(vec_xt) : "r"(r14));
933}
934
935static void test_lxsd_16(void) {
936 __asm__ __volatile__ ("lxsd %0, 16(%1)" : "=v"(vec_xt) : "r"(r14));
937}
938
939static void test_stxsd_16(void) {
940 __asm__ __volatile__ ("stxsd %0, 16(%1)" : "=v"(vec_xt) : "r"(r14));
941}
942
943static void test_lxssp_0(void) {
944 __asm__ __volatile__ ("lxssp %0, 0(%1)" : "=wa"(vec_xt) : "r"(r14));
945}
946
947static void test_stxssp_0(void) {
948 __asm__ __volatile__ ("stxssp %0, 0(%1)" : "=wa"(vec_xt) : "r"(r14));
949}
950
951static void test_lxssp_16(void) {
952 __asm__ __volatile__ ("lxssp %0, 16(%1)" : "=wa"(vec_xt) : "r"(r14));
953}
954
955static void test_stxssp_16(void) {
956 __asm__ __volatile__ ("stxssp %0, 16(%1)" : "=wa"(vec_xt) : "r"(r14));
957}
958
959static void test_lxv_0(void) {
960 __asm__ __volatile__ ("lxv %0, 0(%1)" : "=wa"(vec_xt) : "r"(r14));
961}
962
963static void test_stxv_0(void) {
964 __asm__ __volatile__ ("stxv %0, 0(%1)" : "=wa"(vec_xt) : "r"(r14));
965}
966
967static void test_lxv_16(void) {
968 __asm__ __volatile__ ("lxv %0, 16(%1)" : "=wa"(vec_xt) : "r"(r14));
969}
970
971static void test_stxv_16(void) {
972 __asm__ __volatile__ ("stxv %0, 16(%1)" : "=wa"(vec_xt) : "r"(r14));
973}
974
975static test_list_t testgroup_vector_scalar_loadstore_length[] = {
976 { &test_lxvl , "lxvl " },
977 { &test_lxvll , "lxvll " },
978 { &test_lxsibzx , "lxsibzx " },
979 { &test_lxsihzx , "lxsihzx " },
980 { &test_stxvl , "stxvl " },
981 { &test_stxvll , "stxvll " },
982 { &test_stxsibx , "stxsibx " },
983 { &test_stxsihx , "stxsihx " },
984 { &test_lxsd_0 , "lxsd 0 " },
985 { &test_stxsd_0 , "stxsd 0 " },
986 { &test_lxsd_16 , "lxsd 16 " },
987 { &test_stxsd_16 , "stxsd 16 " },
988 { &test_lxssp_0 , "lxssp 0 " },
989 { &test_stxssp_0 , "stxssp 0 " },
990 { &test_lxssp_16 , "lxssp 16 " },
991 { &test_stxssp_16, "stxssp 16" },
992 { &test_lxv_0 , "lxv 0 " },
993 { &test_stxv_0 , "stxv 0 " },
994 { &test_lxv_16 , "lxv 16 " },
995 { &test_stxv_16 , "stxv 16 " },
996 { NULL , NULL },
997};
998
999/* move from/to VSR */
1000static void test_mfvsrld (void)
1001{
1002 __asm__ __volatile__ ("mfvsrld %0, %x1" : "=r" (r14) : "wa" (vec_xt));
1003};
1004
1005static void test_mtvsrdd (void)
1006{
1007 __asm__ __volatile__ ("mtvsrdd %x0, 14, 15" : "=wa" (vec_xt));
1008};
1009
1010static void test_mtvsrws (void)
1011{ /* To fit in better with the caller for the mfvsrdd test, use r15
1012 * instead of r14 as input here.
1013 */
1014 __asm__ __volatile__ ("mtvsrws %0, 15" : "=wa" (vec_xt));
1015};
1016
1017static test_list_t testgroup_vectorscalar_move_tofrom[] = {
1018 { &test_mfvsrld, "mfvsrld" }, /* RA, XS */
1019 { &test_mtvsrdd, "mtvsrdd" }, /* XT, RA, RB */
1020 { &test_mtvsrws, "mtvsrws" }, /* XT, RA */
1021 { NULL , NULL },
1022};
1023
1024/* vector count {leading, trailing} zero least-significant bits byte.
1025 * roughly... how many leading/trailing bytes are even. */
1026static void test_vclzlsbb(void) {
1027 __asm__ __volatile__ ("vclzlsbb %0, %1" : "=r"(r14) : "v"(vec_xb));
1028}
1029
1030static void test_vctzlsbb(void) {
1031 __asm__ __volatile__ ("vctzlsbb %0, %1" : "=r"(r14) : "v"(vec_xb));
1032}
1033
1034static test_list_t testgroup_vector_count_bytes[] = {
1035 { &test_vclzlsbb, "vclzlsbb" },
1036 { &test_vctzlsbb, "vctzlsbb" },
1037 { NULL , NULL },
1038};
1039
1040static void test_vextsb2w(void) {
1041 __asm__ __volatile__ ("vextsb2w %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1042}
1043
1044static void test_vextsb2d(void) {
1045 __asm__ __volatile__ ("vextsb2d %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1046}
1047
1048static void test_vextsh2w(void) {
1049 __asm__ __volatile__ ("vextsh2w %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1050}
1051
1052static void test_vextsh2d(void) {
1053 __asm__ __volatile__ ("vextsh2d %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1054}
1055
1056static void test_vextsw2d(void) {
1057 __asm__ __volatile__ ("vextsw2d %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1058}
1059
1060static void test_vnegw(void) {
1061 __asm__ __volatile__ ("vnegw %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1062}
1063
1064static void test_vnegd(void) {
1065 __asm__ __volatile__ ("vnegd %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1066}
1067
1068static void test_vprtybw(void) {
1069 __asm__ __volatile__ ("vprtybw %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1070}
1071
1072static void test_vprtybd(void) {
1073 __asm__ __volatile__ ("vprtybd %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1074}
1075
1076static void test_vprtybq(void) {
1077 __asm__ __volatile__ ("vprtybq %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1078}
1079
1080static void test_vctzb(void) {
1081 __asm__ __volatile__ ("vctzb %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1082}
1083
1084static void test_vctzh(void) {
1085 __asm__ __volatile__ ("vctzh %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1086}
1087
1088static void test_vctzw(void) {
1089 __asm__ __volatile__ ("vctzw %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1090}
1091
1092static void test_vctzd(void) {
1093 __asm__ __volatile__ ("vctzd %0, %1" : "=v"(vec_xt) : "v"(vec_xb));
1094}
1095
1096static test_list_t testgroup_vector_extend_sign[] = {
1097 { &test_vextsb2w, "vextsb2w" },
1098 { &test_vextsb2d, "vextsb2d" },
1099 { &test_vextsh2w, "vextsh2w" },
1100 { &test_vextsh2d, "vextsh2d" },
1101 { &test_vextsw2d, "vextsw2d" },
1102 { &test_vnegw , "vnegw " },
1103 { &test_vnegd , "vnegd " },
1104 { &test_vprtybw , "vprtybw " },
1105 { &test_vprtybd , "vprtybd " },
1106 { &test_vprtybq , "vprtybq " },
1107 { &test_vctzb , "vctzb " },
1108 { &test_vctzh , "vctzh " },
1109 { &test_vctzw , "vctzw " },
1110 { &test_vctzd , "vctzd " },
1111 { NULL , NULL },
1112};
1113
1114static void test_vextublx(void) {
1115 __asm__ __volatile__ ("vextublx %0, %1, %2" : "=r"(r14) : "r" (r15), "v" (vec_xb));
1116}
1117
1118static void test_vextubrx(void) {
1119 __asm__ __volatile__ ("vextubrx %0, %1, %2" : "=r"(r14) : "r"(r15), "v"(vec_xb));
1120}
1121
1122static void test_vextuhlx(void) {
1123 if (r15 > 14) return; // limit to 14 halfwords
1124 __asm__ __volatile__ ("vextuhlx %0, %1, %2" : "=r"(r14) : "r"(r15), "v"(vec_xb));
1125}
1126
1127static void test_vextuhrx(void) {
1128 if (r15 > 14) return; // limit to 14 halfwords
1129 __asm__ __volatile__ ("vextuhrx %0, %1, %2" : "=r"(r14) : "r"(r15), "v"(vec_xb));
1130}
1131
1132static void test_vextuwlx(void) {
1133 if (r15 > 12) return; // limit to 12 words
1134 __asm__ __volatile__ ("vextuwlx %0, %1, %2" : "=r"(r14) : "r"(r15), "v"(vec_xb));
1135}
1136
1137static void test_vextuwrx(void) {
1138 if (r15 > 12) return; // limit to 12 words
1139 __asm__ __volatile__ ("vextuwrx %0, %1, %2" : "=r"(r14) : "r"(r15), "v"(vec_xb));
1140}
1141
1142static test_list_t testgroup_vector_extract[] = {
1143 { &test_vextublx, "vextublx" },
1144 { &test_vextubrx, "vextubrx" },
1145 { &test_vextuhlx, "vextuhlx" },
1146 { &test_vextuhrx, "vextuhrx" },
1147 { &test_vextuwlx, "vextuwlx" },
1148 { &test_vextuwrx, "vextuwrx" },
1149 { NULL , NULL },
1150};
1151
1152#define XSCMPEXPDP(x) \
1153 SET_FPSCR_ZERO \
1154 SET_CR_ZERO \
1155 __asm__ __volatile__ \
Elliott Hughesed398002017-06-21 14:41:24 -07001156 ("xscmpexpdp %0, %1, %2"::"i"(x), "wa"(vec_xa), "wa"(vec_xb));\
Elliott Hughesa0664b92017-04-18 17:46:52 -07001157 GET_CR(local_cr); \
1158 GET_FPSCR(local_fpscr);
1159
1160static void test_xscmpexpdp(void) {
1161 switch(x_index) {
1162 case 0: XSCMPEXPDP(0); break;
1163 case 1: XSCMPEXPDP(1); break;
1164 case 2: XSCMPEXPDP(2); break;
1165 case 3: XSCMPEXPDP(3); break;
1166 case 4: XSCMPEXPDP(4); break;
1167 case 5: XSCMPEXPDP(5); break;
1168 case 6: XSCMPEXPDP(6); break;
1169 case 7: XSCMPEXPDP(7); break;
1170 default:
1171 printf("Unhandled shift value for %s %x\n", __FUNCTION__, x_index);
1172 };
1173}
1174
1175static test_list_t testgroup_vector_scalar_compare_exp_double[] = {
1176 { &test_xscmpexpdp , "xscmpexpdp " },
1177 { NULL , NULL },
1178};
1179
1180#define XSTSTDCQP(R,DCMX) \
1181 SET_FPSCR_ZERO \
1182 SET_CR_ZERO \
1183 __asm__ __volatile__ \
1184 ("xststdcqp %0, %1, %2":: "i"(R), "wa"(vec_xb), "i"(DCMX)); \
1185 GET_CR(local_cr); \
1186 GET_FPSCR(local_fpscr);
1187
1188#define XSTSTDCDP(R,DCMX) \
1189 SET_FPSCR_ZERO \
1190 SET_CR_ZERO \
1191 __asm__ __volatile__ \
1192 ("xststdcdp %0, %1, %2":: "i"(R), "wa"(vec_xb), "i"(DCMX)); \
1193 GET_CR(local_cr); \
1194 GET_FPSCR(local_fpscr);
1195
1196#define XSTSTDCSP(R,DCMX) \
1197 SET_FPSCR_ZERO \
1198 SET_CR_ZERO \
1199 __asm__ __volatile__ \
1200 ("xststdcsp %0, %1, %2":: "i"(R), "wa"(vec_xb), "i"(DCMX)); \
1201 GET_CR(local_cr); \
1202 GET_FPSCR(local_fpscr);
1203
1204#define XVTSTDCDP(R,DCMX) \
1205 SET_FPSCR_ZERO \
1206 SET_CR_ZERO \
1207 __asm__ __volatile__ \
1208 ("xvtstdcdp %0, %1, %2": "=wa"(vec_xt) : "wa"(vec_xb), "i"(DCMX)); \
1209 GET_CR(local_cr); \
1210 GET_FPSCR(local_fpscr);
1211
1212#define XVTSTDCSP(R,DCMX) \
1213 SET_FPSCR_ZERO \
1214 SET_CR_ZERO \
1215 __asm__ __volatile__ \
1216 ("xvtstdcsp %0, %1, %2": "=wa"(vec_xt) : "wa"(vec_xb), "i"(DCMX)); \
1217 GET_CR(local_cr); \
1218 GET_FPSCR(local_fpscr);
1219
1220static void test_xststdcqp(void) {
1221 switch(x_index) {
1222 case 1: XSTSTDCQP(3, 0x01); break; /* NaN */
1223 case 2: XSTSTDCQP(3, 0x02); break; /* +inf */
1224 case 3: XSTSTDCQP(3, 0x04); break; /* -inf */
1225 case 4: XSTSTDCQP(3, 0x08); break; /* +zero */
1226 case 5: XSTSTDCQP(3, 0x10); break; /* -zero */
1227 case 6: XSTSTDCQP(3, 0x20); break; /* +denormal */
1228 case 7: XSTSTDCQP(3, 0x40); break; /* -denormal */
1229 case 0: XSTSTDCQP(3, 0x7f); break; /* all of the above */
1230 }
1231}
1232
1233static void test_xststdcdp(void) {
1234 switch(x_index) {
1235 case 1: XSTSTDCDP(3, 0x01); break; /* NaN */
1236 case 2: XSTSTDCDP(3, 0x02); break; /* +inf */
1237 case 3: XSTSTDCDP(3, 0x04); break; /* -inf */
1238 case 4: XSTSTDCDP(3, 0x08); break; /* +zero */
1239 case 5: XSTSTDCDP(3, 0x10); break; /* -zero */
1240 case 6: XSTSTDCDP(3, 0x20); break; /* +denormal */
1241 case 7: XSTSTDCDP(3, 0x40); break; /* -denormal */
1242 case 0: XSTSTDCDP(3, 0x7f); break; /* all of the above */
1243 }
1244}
1245
1246static void test_xststdcsp(void) {
1247 switch(x_index) {
1248 case 1: XSTSTDCSP(3, 0x01); break; /* NaN */
1249 case 2: XSTSTDCSP(3, 0x02); break; /* +inf */
1250 case 3: XSTSTDCSP(3, 0x04); break; /* -inf */
1251 case 4: XSTSTDCSP(3, 0x08); break; /* +zero */
1252 case 5: XSTSTDCSP(3, 0x10); break; /* -zero */
1253 case 6: XSTSTDCSP(3, 0x20); break; /* +denormal */
1254 case 7: XSTSTDCSP(3, 0x40); break; /* -denormal */
1255 case 0: XSTSTDCSP(3, 0x7f); break; /* all of the above */
1256 }
1257}
1258
1259static void test_xvtstdcdp(void) {
1260 switch(x_index) {
1261 case 1: XVTSTDCDP(3, 0x01); break; /* NaN */
1262 case 2: XVTSTDCDP(3, 0x02); break; /* +inf */
1263 case 3: XVTSTDCDP(3, 0x04); break; /* -inf */
1264 case 4: XVTSTDCDP(3, 0x08); break; /* +zero */
1265 case 5: XVTSTDCDP(3, 0x10); break; /* -zero */
1266 case 6: XVTSTDCDP(3, 0x20); break; /* +denormal */
1267 case 7: XVTSTDCDP(3, 0x40); break; /* -denormal */
1268 case 0: XVTSTDCDP(3, 0x7f); break; /* all of the above */
1269 }
1270}
1271
1272/* Note: Due to the test groupings, the input for the xvtstdcsp test is
1273 * actually 'double'. It is good enough for this test, but may wish to break
1274 * this one out eventually.
1275 */
1276static void test_xvtstdcsp(void) {
1277 switch(x_index) {
1278 case 1: XVTSTDCSP(3, 0x01); break; /* NaN */
1279 case 2: XVTSTDCSP(3, 0x02); break; /* +inf */
1280 case 3: XVTSTDCSP(3, 0x04); break; /* -inf */
1281 case 4: XVTSTDCSP(3, 0x08); break; /* +zero */
1282 case 5: XVTSTDCSP(3, 0x10); break; /* -zero */
1283 case 6: XVTSTDCSP(3, 0x20); break; /* +denormal */
1284 case 7: XVTSTDCSP(3, 0x40); break; /* -denormal */
1285 case 0: XVTSTDCSP(3, 0x7f); break; /* all of the above */
1286 }
1287}
1288
1289static test_list_t testgroup_vector_scalar_data_class[] = {
1290 { &test_xststdcqp, "xststdcqp " },
1291 { &test_xststdcdp, "xststdcdp " },
1292 { &test_xststdcsp, "xststdcsp " },
1293 { &test_xvtstdcsp, "xvtstdcsp " },
1294 { &test_xvtstdcdp, "xvtstdcdp " },
1295 { NULL , NULL },
1296};
1297
1298static void test_setb (void) {
1299 /* setb RT,BFA
1300 * BFA is a 3-bit field. */
1301
1302 switch(x_index) {
1303 case 0:SET_CR0_FIELD(cr_value);
1304 __asm__ __volatile__ ("setb %0, 0" : "=r" (r14)); break;
1305
1306 case 1:SET_CR1_FIELD(cr_value);
1307 __asm__ __volatile__ ("setb %0, 1" : "=r" (r14)); break;
1308
1309 case 2:SET_CR2_FIELD(cr_value);
1310 __asm__ __volatile__ ("setb %0, 2" : "=r" (r14)); break;
1311
1312 case 3:SET_CR3_FIELD(cr_value);
1313 __asm__ __volatile__ ("setb %0, 3" : "=r" (r14)); break;
1314
1315 case 4:SET_CR4_FIELD(cr_value);
1316 __asm__ __volatile__ ("setb %0, 4" : "=r" (r14)); break;
1317
1318 case 5:SET_CR5_FIELD(cr_value);
1319 __asm__ __volatile__ ("setb %0, 5" : "=r" (r14)); break;
1320
1321 case 6:SET_CR6_FIELD(cr_value);
1322 __asm__ __volatile__ ("setb %0, 6" : "=r" (r14)); break;
1323
1324 case 7:SET_CR7_FIELD(cr_value);
1325 __asm__ __volatile__ ("setb %0, 7" : "=r" (r14)); break;
1326 }
1327
1328 GET_CR(local_cr);
1329
1330 if (verbose) {
1331 dissect_cr(local_cr);
1332 }
1333}
1334
1335static test_list_t testgroup_set_boolean[] = {
1336 { &test_setb, "setb"},
1337 { NULL , NULL },
1338};
1339
1340/* cmprb l = 0:
1341 * compares r14 = src with range specified by values in r15
1342 * bits (48:55 - 56:63)].
1343 *
1344 * cmprb l=1:
1345 * compares r14 = src with ranges between two pairs of values, as above and
1346 * also in r15 bits (32:39 - 40:47 .
1347 */
1348static void test_cmprb_l0() {
1349 switch(x_index) {
1350 case 0: __asm__ __volatile__ ("cmprb 0, 0, %0, %1" : : "r"(r14), "r"(r15));
1351 GET_CR(local_cr); break;
1352
1353 case 1: __asm__ __volatile__ ("cmprb 1, 0, %0, %1" : : "r"(r14), "r"(r15));
1354 GET_CR(local_cr); break;
1355
1356 case 2: __asm__ __volatile__ ("cmprb 2, 0, %0, %1" : : "r"(r14), "r"(r15));
1357 GET_CR(local_cr); break;
1358
1359 case 3: __asm__ __volatile__ ("cmprb 3, 0, %0, %1" : : "r"(r14), "r"(r15));
1360 GET_CR(local_cr); break;
1361
1362 case 4: __asm__ __volatile__ ("cmprb 4, 0, %0, %1" : : "r"(r14), "r"(r15));
1363 GET_CR(local_cr); break;
1364
1365 case 5: __asm__ __volatile__ ("cmprb 5, 0, %0, %1" : : "r"(r14), "r"(r15));
1366 GET_CR(local_cr); break;
1367
1368 case 6: __asm__ __volatile__ ("cmprb 6, 0, %0, %1" : : "r"(r14), "r"(r15));
1369 GET_CR(local_cr); break;
1370
1371 case 7: __asm__ __volatile__ ("cmprb 7, 0, %0, %1" : : "r"(r14), "r"(r15));
1372 GET_CR(local_cr); break;
1373 }
1374}
1375
1376static void test_cmprb_l1() {
1377 switch(x_index) {
1378 case 0: __asm__ __volatile__ ("cmprb 0, 1 ,%0, %1" : : "r"(r14), "r"(r15));
1379 GET_CR(local_cr); break;
1380
1381 case 1: __asm__ __volatile__ ("cmprb 1, 1, %0, %1" : : "r"(r14), "r"(r15));
1382 GET_CR(local_cr); break;
1383
1384 case 2: __asm__ __volatile__ ("cmprb 2, 1, %0, %1" : : "r"(r14), "r"(r15));
1385 GET_CR(local_cr); break;
1386
1387 case 3: __asm__ __volatile__ ("cmprb 3, 1, %0, %1" : : "r"(r14), "r"(r15));
1388 GET_CR(local_cr); break;
1389
1390 case 4: __asm__ __volatile__ ("cmprb 4, 1, %0, %1" : : "r"(r14), "r"(r15));
1391 GET_CR(local_cr); break;
1392
1393 case 5: __asm__ __volatile__ ("cmprb 5, 1, %0, %1" : : "r"(r14), "r"(r15));
1394 GET_CR(local_cr); break;
1395
1396 case 6: __asm__ __volatile__ ("cmprb 6, 1, %0, %1" : : "r"(r14), "r"(r15));
1397 GET_CR(local_cr); break;
1398
1399 case 7: __asm__ __volatile__ ("cmprb 7, 1, %0, %1" : : "r"(r14), "r"(r15));
1400 GET_CR(local_cr); break;
1401 }
1402}
1403
1404static void test_cmpeqb() {
1405 switch(x_index) {
1406 case 0: __asm__ __volatile__ ("cmpeqb 0,%0, %1" : : "r"(r14), "r"(r15));
1407 GET_CR(local_cr); break;
1408
1409 case 1: __asm__ __volatile__ ("cmpeqb 1,%0, %1" : : "r"(r14), "r"(r15));
1410 GET_CR(local_cr); break;
1411
1412 case 2: __asm__ __volatile__ ("cmpeqb 2,%0, %1" : : "r"(r14), "r"(r15));
1413 GET_CR(local_cr); break;
1414
1415 case 3: __asm__ __volatile__ ("cmpeqb 3,%0, %1" : : "r"(r14), "r"(r15));
1416 GET_CR(local_cr); break;
1417
1418 case 4: __asm__ __volatile__ ("cmpeqb 4,%0, %1" : : "r"(r14), "r"(r15));
1419 GET_CR(local_cr); break;
1420
1421 case 5: __asm__ __volatile__ ("cmpeqb 5,%0, %1" : : "r"(r14), "r"(r15));
1422 GET_CR(local_cr); break;
1423
1424 case 6: __asm__ __volatile__ ("cmpeqb 6,%0, %1" : : "r"(r14), "r"(r15));
1425 GET_CR(local_cr); break;
1426
1427 case 7: __asm__ __volatile__ ("cmpeqb 7,%0, %1" : : "r"(r14), "r"(r15));
1428 GET_CR(local_cr); break;
1429 }
1430}
1431
1432static test_list_t testgroup_char_compare[] = {
1433 { &test_cmprb_l0, "cmprb l=0" },
1434 { &test_cmprb_l1, "cmprb l=1" },
1435 { &test_cmpeqb , "cmpeqb" },
1436 { NULL , NULL },
1437};
1438
1439static void test_bcdtrunc_p0(void) {
1440 __asm__ __volatile__ ("bcdtrunc. %0, %1, %2, 0": "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1441}
1442
1443static void test_bcdtrunc_p1(void) {
1444 __asm__ __volatile__ ("bcdtrunc. %0, %1, %2, 1": "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1445}
1446
1447static void test_bcdutrunc(void) {
1448 __asm__ __volatile__ ("bcdutrunc. %0, %1, %2 ": "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1449}
1450
1451static void test_bcdadd_p0(void) {
1452 __asm__ __volatile__ ("bcdadd. %0, %1, %2, 0" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1453}
1454
1455static void test_bcdadd_p1(void) {
1456 __asm__ __volatile__ ("bcdadd. %0, %1, %2, 1" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1457}
1458
1459static void test_bcdsub_p0(void) {
1460 __asm__ __volatile__ ("bcdsub. %0, %1, %2, 0" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1461}
1462
1463static void test_bcdsub_p1(void) {
1464 __asm__ __volatile__ ("bcdsub. %0, %1, %2, 1" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1465}
1466
1467static void test_bcdcpsgn(void) {
1468 __asm__ __volatile__ ("bcdcpsgn. %0, %1, %2 ": "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1469}
1470
1471static void test_bcdctz_p0(void) {
1472 __asm__ __volatile__ ("bcdctz. %0, %1, 0 " : "=v"(vec_xt) : "v"(vec_xb));
1473}
1474
1475static void test_bcdctz_p1(void) {
1476 __asm__ __volatile__ ("bcdctz. %0, %1, 1 " : "=v"(vec_xt) : "v"(vec_xb));
1477}
1478
1479static void test_bcdsetsgn_p0(void) {
1480 __asm__ __volatile__ ("bcdsetsgn. %0, %1, 0 " : "=v"(vec_xt) : "v"(vec_xb));
1481}
1482
1483static void test_bcdsetsgn_p1(void) {
1484 __asm__ __volatile__ ("bcdsetsgn. %0, %1, 1 " : "=v"(vec_xt) : "v"(vec_xb));
1485}
1486
1487static void test_bcds_p0(void) {
1488 __asm__ __volatile__ ("bcds. %0, %1, %2, 0" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1489}
1490
1491static void test_bcds_p1(void) {
1492 __asm__ __volatile__ ("bcds. %0, %1, %2, 1" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1493}
1494
1495static void test_bcdus(void) {
1496 __asm__ __volatile__ ("bcdus. %0, %1, %2 " : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1497}
1498
1499static void test_bcdsr_p0(void) {
1500 __asm__ __volatile__ ("bcdsr. %0, %1, %2, 0" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1501}
1502
1503static void test_bcdsr_p1(void) {
1504 __asm__ __volatile__ ("bcdsr. %0, %1, %2, 1" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1505}
1506
1507static void test_bcdcfn_p0(void) {
1508 __asm__ __volatile__ ("bcdcfn. %0, %1, 0 " : "=v"(vec_xt) : "v"(vec_xb));
1509}
1510
1511static void test_bcdcfn_p1(void) {
1512 __asm__ __volatile__ ("bcdcfn. %0, %1, 1 " : "=v"(vec_xt) : "v"(vec_xb));
1513}
1514
1515static void test_bcdcfz_p0(void) {
1516 __asm__ __volatile__ ("bcdcfz. %0, %1, 0 " : "=v"(vec_xt) : "v"(vec_xb));
1517}
1518
1519static void test_bcdcfz_p1(void) {
1520 __asm__ __volatile__ ("bcdcfz. %0, %1, 1 " : "=v"(vec_xt) : "v"(vec_xb));
1521}
1522
1523static void test_bcdctn(void) {
1524 __asm__ __volatile__ ("bcdctn. %0, %1 " : "=v"(vec_xt) : "v"(vec_xb));
1525}
1526
1527static void test_vmul10uq(void) {
1528 __asm__ __volatile__ ("vmul10uq %0, %1 " : "=v"(vec_xt) : "v"(vec_xa));
1529}
1530
1531static void test_vmul10cuq(void) {
1532 __asm__ __volatile__ ("vmul10cuq %0, %1 " : "=v"(vec_xt) : "v"(vec_xa));
1533}
1534
1535static void test_vmul10euq(void) {
1536 __asm__ __volatile__ ("vmul10euq %0, %1, %2 " : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1537}
1538
1539static void test_vmul10ecuq(void) {
1540 __asm__ __volatile__ ("vmul10ecuq %0, %1, %2 " : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1541}
1542
1543static void test_bcdctsq(void) {
1544 __asm__ __volatile__ ("bcdctsq. %0, %1 " : "=v"(vec_xt) : "v"(vec_xb));
1545}
1546
1547static void test_bcdcfsq_p0(void) {
1548 __asm__ __volatile__ ("bcdcfsq. %0, %1, 0 " : "=v"(vec_xt) : "v"(vec_xb));
1549}
1550
1551static void test_bcdcfsq_p1(void) {
1552 __asm__ __volatile__ ("bcdcfsq. %0, %1, 1 " : "=v"(vec_xt) : "v"(vec_xb));
1553}
1554
1555static test_list_t testgroup_bcd_misc[] = {
1556 { &test_bcdadd_p0 , "bcdadd. p0" },
1557 { &test_bcdadd_p1 , "bcdadd. p1" },
1558 { &test_bcdsub_p0 , "bcdsub. p0" },
1559 { &test_bcdsub_p1 , "bcdsub. p1" },
1560 { &test_bcdcfn_p0 , "bcdcfn. p0" },
1561 { &test_bcdcfn_p1 , "bcdcfn. p1" },
1562 { &test_bcdcfz_p0 , "bcdcfz. p0" }, /* The p0, p1 substrings are used later */
1563 { &test_bcdcfz_p1 , "bcdcfz. p1" }, /* " " */
1564 { &test_bcdctn , "bcdctn. " },
1565 { &test_bcdctz_p0 , "bcdctz. p0" }, /* note: p0, p1 substrings are used later */
1566 { &test_bcdctz_p1 , "bcdctz. p1" }, /* " " */
1567 { &test_bcdcpsgn , "bcdcpsgn." },
1568 { &test_bcdsetsgn_p0, "bcdsetsgn. p0" },
1569 { &test_bcdsetsgn_p1, "bcdsetsgn. p1" },
1570 { &test_bcds_p0 , "bcds. p0" },
1571 { &test_bcds_p1 , "bcds. p1" },
1572 { &test_bcdus , "bcdus. " },
1573 { &test_bcdsr_p0 , "bcdsr. p0" },
1574 { &test_bcdsr_p1 , "bcdsr. p1" },
1575 { &test_bcdtrunc_p0 , "bcdtrunc. p0" },
1576 { &test_bcdtrunc_p1 , "bcdtrunc. p1" },
1577 { &test_bcdutrunc , "bcdutrunc. " },
1578 { &test_vmul10uq , "vmul10uq " },
1579 { &test_vmul10cuq , "vmul10cuq " },
1580 { &test_vmul10euq , "vmul10euq " },
1581 { &test_vmul10ecuq , "vmul10ecuq " },
1582 { &test_bcdctsq , "bcdctsq." },
1583 { &test_bcdcfsq_p0 , "bcdcfsq. p0" },
1584 { &test_bcdcfsq_p1 , "bcdcfsq. p1" },
1585 { NULL , NULL },
1586};
1587
1588static void test_wait(void) {
1589 __asm__ __volatile__ ("wait 0" : :);
1590}
1591
1592static test_list_t testgroup_noop_misc[] = {
1593 { &test_wait, "wait ",},
1594 { NULL , NULL, },
1595};
1596
1597/* The significance field can be any values within bits 10-15 of the
1598 * instruction. For this test, limiting the values to one per bit location.
1599 */
1600static void test_dtstsfi() {
1601 _Decimal128 df14 = dfp_value.dec_val128;
1602 switch(dfp_significance) {
1603 case 0x00: __asm__ __volatile__ ("dtstsfi 3, 0x00, %0" : : "f" (df14));
1604 GET_CR(local_cr); break;
1605
1606 case 0x01: __asm__ __volatile__ ("dtstsfi 3, 0x01, %0" : : "f" (df14));
1607 GET_CR(local_cr); break;
1608
1609 case 0x02: __asm__ __volatile__ ("dtstsfi 3, 0x02, %0" : : "f" (df14));
1610 GET_CR(local_cr); break;
1611
1612 case 0x03: __asm__ __volatile__ ("dtstsfi 3, 0x03, %0" : : "f" (df14));
1613 GET_CR(local_cr); break;
1614
1615 case 0x04: __asm__ __volatile__ ("dtstsfi 3, 0x04, %0" : : "f" (df14));
1616 GET_CR(local_cr); break;
1617
1618 case 0x06: __asm__ __volatile__ ("dtstsfi 3, 0x06, %0" : : "f" (df14));
1619 GET_CR(local_cr); break;
1620
1621 case 0x08: __asm__ __volatile__ ("dtstsfi 3, 0x08, %0" : : "f" (df14));
1622 GET_CR(local_cr); break;
1623
1624 case 0x0c: __asm__ __volatile__ ("dtstsfi 3, 0x0c, %0" : : "f" (df14));
1625 GET_CR(local_cr); break;
1626
1627 case 0x10: __asm__ __volatile__ ("dtstsfi 3, 0x10, %0" : : "f" (df14));
1628 GET_CR(local_cr); break;
1629
1630 case 0x18: __asm__ __volatile__ ("dtstsfi 3, 0x18, %0" : : "f" (df14));
1631 GET_CR(local_cr); break;
1632
1633 case 0x20: __asm__ __volatile__ ("dtstsfi 3, 0x20, %0" : : "f" (df14));
1634 GET_CR(local_cr); break;
1635 }
1636}
1637
1638static void test_dtstsfiq() {
1639 _Decimal128 df14 = dfp_value.dec_val128;
1640 switch(dfp_significance) {
1641 case 0x00: __asm__ __volatile__ ("dtstsfiq 3, 0x00, %0" : : "f" (df14));
1642 GET_CR(local_cr); break;
1643
1644 case 0x01: __asm__ __volatile__ ("dtstsfiq 3, 0x01, %0" : : "f" (df14));
1645 GET_CR(local_cr); break;
1646
1647 case 0x02: __asm__ __volatile__ ("dtstsfiq 3, 0x02, %0" : : "f" (df14));
1648 GET_CR(local_cr); break;
1649
1650 case 0x03: __asm__ __volatile__ ("dtstsfiq 3, 0x03, %0" : : "f" (df14));
1651 GET_CR(local_cr); break;
1652
1653 case 0x04: __asm__ __volatile__ ("dtstsfiq 3, 0x04, %0" : : "f" (df14));
1654 GET_CR(local_cr); break;
1655
1656 case 0x06: __asm__ __volatile__ ("dtstsfiq 3, 0x06, %0" : : "f" (df14));
1657 GET_CR(local_cr); break;
1658
1659 case 0x08: __asm__ __volatile__ ("dtstsfiq 3, 0x08, %0" : : "f" (df14));
1660 GET_CR(local_cr); break;
1661
1662 case 0x0c: __asm__ __volatile__ ("dtstsfiq 3, 0x0c, %0" : : "f" (df14));
1663 GET_CR(local_cr); break;
1664
1665 case 0x10: __asm__ __volatile__ ("dtstsfiq 3, 0x10, %0" : : "f" (df14));
1666 GET_CR(local_cr); break;
1667
1668 case 0x18: __asm__ __volatile__ ("dtstsfiq 3, 0x18, %0" : : "f" (df14));
1669 GET_CR(local_cr); break;
1670
1671 case 0x20: __asm__ __volatile__ ("dtstsfiq 3, 0x20, %0" : : "f" (df14));
1672 GET_CR(local_cr); break;
1673 }
1674}
1675
1676static test_list_t testgroup_dfp_significance[] = {
1677 { &test_dtstsfi , "dtstsfi" },
1678 { &test_dtstsfiq, "dtstsfiq" },
1679 { NULL , NULL },
1680};
1681
1682static void test_addpcis(void) {
1683 switch (x_index) {
1684 case 0x0: __asm__ __volatile__ ("addpcis 14, %0" : : "i"(0x0) ); break;
1685 case 0x1: __asm__ __volatile__ ("addpcis 14, %0" : : "i"(0x1) ); break;
1686 case 0x2: __asm__ __volatile__ ("addpcis 14, %0" : : "i"(0x2) ); break;
1687 case 0x3: __asm__ __volatile__ ("addpcis 14, %0" : : "i"(0x40) ); break;
1688 case 0x4: __asm__ __volatile__ ("addpcis 14, %0" : : "i"(0x800) ); break;
1689 case 0x5: __asm__ __volatile__ ("addpcis 14, %0" : : "i"(0x2000) ); break;
1690 case 0x6: __asm__ __volatile__ ("addpcis 14, %0" : : "i"(0x7fff) ); break;
1691 case 0x7: __asm__ __volatile__ ("addpcis 14, %0" : : "i"(0x8000) ); break;
1692 case 0x8: __asm__ __volatile__ ("addpcis 14, -%0" : : "i"(0x0) ); break;
1693 case 0x9: __asm__ __volatile__ ("addpcis 14, -%0" : : "i"(0x1) ); break;
1694 case 0xa: __asm__ __volatile__ ("addpcis 14, -%0" : : "i"(0x2) ); break;
1695 case 0xb: __asm__ __volatile__ ("addpcis 14, -%0" : : "i"(0x40) ); break;
1696 case 0xc: __asm__ __volatile__ ("addpcis 14, -%0" : : "i"(0x800) ); break;
1697 case 0xd: __asm__ __volatile__ ("addpcis 14, -%0" : : "i"(0x2000) ); break;
1698 case 0xe: __asm__ __volatile__ ("addpcis 14, -%0" : : "i"(0x7fff) ); break;
1699 case 0xf: __asm__ __volatile__ ("addpcis 14, -%0" : : "i"(0x8000) ); break;
1700 }
1701}
1702
1703static void test_subpcis(void) {
1704 switch (x_index) {
1705 case 0x0: __asm__ __volatile__ ("subpcis 14, %0" : : "i"(0x0) ); break;
1706 case 0x1: __asm__ __volatile__ ("subpcis 14, %0" : : "i"(0x1) ); break;
1707 case 0x2: __asm__ __volatile__ ("subpcis 14, %0" : : "i"(0x2) ); break;
1708 case 0x3: __asm__ __volatile__ ("subpcis 14, %0" : : "i"(0x40) ); break;
1709 case 0x4: __asm__ __volatile__ ("subpcis 14, %0" : : "i"(0x800) ); break;
1710 case 0x5: __asm__ __volatile__ ("subpcis 14, %0" : : "i"(0x2000) ); break;
1711 case 0x6: __asm__ __volatile__ ("subpcis 14, %0" : : "i"(0x7fff) ); break;
1712 case 0x7: __asm__ __volatile__ ("subpcis 14, %0" : : "i"(0x8000) ); break;
1713 case 0x8: __asm__ __volatile__ ("subpcis 14, -%0" : : "i"(0x0) ); break;
1714 case 0x9: __asm__ __volatile__ ("subpcis 14, -%0" : : "i"(0x1) ); break;
1715 case 0xa: __asm__ __volatile__ ("subpcis 14, -%0" : : "i"(0x2) ); break;
1716 case 0xb: __asm__ __volatile__ ("subpcis 14, -%0" : : "i"(0x40) ); break;
1717 case 0xc: __asm__ __volatile__ ("subpcis 14, -%0" : : "i"(0x80) ); break;
1718 case 0xd: __asm__ __volatile__ ("subpcis 14, -%0" : : "i"(0x200) ); break;
1719 case 0xe: __asm__ __volatile__ ("subpcis 14, -%0" : : "i"(0x7fff) ); break;
1720 case 0xf: __asm__ __volatile__ ("subpcis 14, -%0" : : "i"(0x8000) ); break;
1721 }
1722}
1723
1724static test_list_t testgroup_pc_immediate_misc[] = {
1725 { &test_addpcis, "addpcis " },
1726 { &test_subpcis, "subpcis " },
1727 { NULL , NULL },
1728};
1729
1730static void test_xsiexpdp(void) {
1731 __asm__ __volatile__ ("xsiexpdp %0, %1, %2 " : "+wa" (vec_xt): "r" (r14), "r" (r15));
1732}
1733
1734static void test_xscvhpdp(void) {
1735 __asm__ __volatile__ ("xscvhpdp %x0, %x1 " : "+wa" (vec_xt) : "wa" (vec_xb));
1736}
1737
1738static void test_xscvdphp(void) {
1739 __asm__ __volatile__ ("xscvdphp %x0, %x1 " : "+wi" (vec_xt) : "wi" (vec_xb));
1740}
1741
1742static void test_xvcvhpsp(void) {
1743 __asm__ __volatile__ ("xvcvhpsp %x0, %x1 " : "+ww" (vec_xt) : "ww" (vec_xb));
1744}
1745
1746static void test_xvcvsphp(void) {
1747 __asm__ __volatile__ ("xvcvsphp %x0, %x1 " : "+ww" (vec_xt) : "ww" (vec_xb));
1748}
1749
1750static test_list_t testgroup_vector_scalar_two_double[] = {
1751 { &test_xsiexpdp, "xsiexpdp" },
1752 { &test_xscvhpdp, "xscvhpdp" },
1753 { &test_xscvdphp, "xscvdphp" },
1754 { &test_xvcvhpsp, "xvcvhpsp" },
1755 { &test_xvcvsphp, "xvcvsphp" },
1756 { NULL , NULL },
1757};
1758
1759
1760static void test_xsabsqp(void) {
1761 __asm__ __volatile__ ("xsabsqp %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1762}
1763
1764static void test_xscvdpqp(void) {
1765 __asm__ __volatile__ ("xscvdpqp %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1766}
1767
1768static void test_xscvqpdp(void) {
1769 __asm__ __volatile__ ("xscvqpdp %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1770}
1771
1772static void test_xscvqpdpo(void) {
1773 __asm__ __volatile__ ("xscvqpdpo %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1774}
1775
1776static void test_xscvqpsdz(void) {
1777 __asm__ __volatile__ ("xscvqpsdz %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1778}
1779
1780static void test_xscvqpswz(void) {
1781 __asm__ __volatile__ ("xscvqpswz %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1782}
1783
1784static void test_xscvqpudz(void) {
1785 __asm__ __volatile__ ("xscvqpudz %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1786}
1787
1788static void test_xscvqpuwz(void) {
1789 __asm__ __volatile__ ("xscvqpuwz %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1790}
1791
1792static void test_xscvsdqp(void) {
1793 __asm__ __volatile__ ("xscvsdqp %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1794}
1795
1796static void test_xscvudqp(void) {
1797 __asm__ __volatile__ ("xscvudqp %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1798}
1799
1800static void test_xsxexpqp(void) {
1801 __asm__ __volatile__ ("xsxexpqp %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1802}
1803
1804static void test_xsxsigqp(void) {
1805 __asm__ __volatile__ ("xsxsigqp %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1806}
1807
1808static void test_xsnegqp(void) {
1809 __asm__ __volatile__ ("xsnegqp %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1810}
1811
1812static void test_xsnabsqp(void) {
1813 __asm__ __volatile__ ("xsnabsqp %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1814}
1815
1816static void test_xssqrtqp(void) {
1817 __asm__ __volatile__ ("xssqrtqp %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1818}
1819
1820static void test_xssqrtqpo(void) {
1821 __asm__ __volatile__ ("xssqrtqpo %0, %1" : "+v"(vec_xt) : "v"(vec_xb));
1822}
1823
1824static test_list_t testgroup_vector_scalar_two_quad[] = {
1825 { &test_xsabsqp , "xsabsqp " },
1826 { &test_xscvdpqp , "xscvdpqp " },
1827 { &test_xscvqpdp , "xscvqpdp " },
1828 { &test_xscvqpdpo, "xscvqpdpo " },
1829 { &test_xscvqpsdz, "xscvqpsdz " },
1830 { &test_xscvqpswz, "xscvqpswz " },
1831 { &test_xscvqpudz, "xscvqpudz " },
1832 { &test_xscvqpuwz, "xscvqpuwz " },
1833 { &test_xscvsdqp , "xscvsdqp " },
1834 { &test_xscvudqp , "xscvudqp " },
1835 { &test_xsxexpqp , "xsxexpqp " },
1836 { &test_xsxsigqp , "xsxsigqp " },
1837 { &test_xsnegqp , "xsnegqp " },
1838 { &test_xsnabsqp , "xsnabsqp " },
1839 { &test_xssqrtqp , "xssqrtqp " },
1840 { &test_xssqrtqpo, "xssqrtqpo " },
1841 { NULL , NULL },
1842};
1843
1844static void test_xsaddqp(void) {
1845 __asm__ __volatile__ ("xsaddqp %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1846}
1847
1848static void test_xsaddqpo(void) {
1849 __asm__ __volatile__ ("xsaddqpo %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1850}
1851
1852static void test_xscpsgnqp(void) {
1853 __asm__ __volatile__ ("xscpsgnqp %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1854}
1855
1856static void test_xsdivqp(void) {
1857 __asm__ __volatile__ ("xsdivqp %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1858}
1859
1860static void test_xsdivqpo(void) {
1861 __asm__ __volatile__ ("xsdivqpo %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1862}
1863
1864static void test_xsiexpqp(void) {
1865 __asm__ __volatile__ ("xsiexpqp %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1866}
1867
1868static void test_xsmaddqp(void) {
1869 __asm__ __volatile__ ("xsmaddqp %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1870}
1871
1872static void test_xsmaddqpo(void) {
1873 __asm__ __volatile__ ("xsmaddqpo %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1874}
1875
1876static void test_xsmsubqp(void) {
1877 __asm__ __volatile__ ("xsmsubqp %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1878}
1879
1880static void test_xsmsubqpo(void) {
1881 __asm__ __volatile__ ("xsmsubqpo %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1882}
1883
1884static void test_xsmulqp(void) {
1885 __asm__ __volatile__ ("xsmulqp %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1886}
1887
1888static void test_xsmulqpo(void) {
1889 __asm__ __volatile__ ("xsmulqpo %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1890}
1891
1892static void test_xsnmaddqp(void) {
1893 __asm__ __volatile__ ("xsnmaddqp %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1894}
1895
1896static void test_xsnmaddqpo(void) {
1897 __asm__ __volatile__ ("xsnmaddqpo %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1898}
1899
1900static void test_xsnmsubqp(void) {
1901 __asm__ __volatile__ ("xsnmsubqp %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1902}
1903
1904static void test_xsnmsubqpo(void) {
1905 __asm__ __volatile__ ("xsnmsubqpo %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1906}
1907
1908static void test_xssubqp(void) {
1909 __asm__ __volatile__ ("xssubqp %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1910}
1911
1912static void test_xssubqpo(void) {
1913 __asm__ __volatile__ ("xssubqpo %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb));
1914}
1915
1916static test_list_t testgroup_vector_three_quad[] = {
1917 { &test_xsaddqp , "xsaddqp " },
1918 { &test_xsaddqpo , "xsaddqpo " },
1919 { &test_xscpsgnqp , "xscpsgnqp " },
1920 { &test_xsdivqp , "xsdivqp " },
1921 { &test_xsdivqpo , "xsdivqpo " },
1922 { &test_xsiexpqp , "xsiexpqp " },
1923 { &test_xsmaddqp , "xsmaddqp " },
1924 { &test_xsmaddqpo , "xsmaddqpo " },
1925 { &test_xsmsubqp , "xsmsubqp " },
1926 { &test_xsmsubqpo , "xsmsubqpo " },
1927 { &test_xsmulqp , "xsmulqp " },
1928 { &test_xsmulqpo , "xsmulqpo " },
1929 { &test_xsnmaddqp , "xsnmaddqp " },
1930 { &test_xsnmaddqpo, "xsnmaddqpo " },
1931 { &test_xsnmsubqp , "xsnmsubqp " },
1932 { &test_xsnmsubqpo, "xsnmsubqpo " },
1933 { &test_xssubqp , "xssubqp " },
1934 { &test_xssubqpo , "xssubqpo " },
1935 { NULL , NULL },
1936};
1937
1938#define XSCMPEXPQP(x) \
1939 SET_FPSCR_ZERO \
1940 SET_CR_ZERO \
1941 __asm__ __volatile__ \
1942 ("xscmpexpqp %0, %1, %2" :: "i"(x), "v"(vec_xa), "v"(vec_xb)); \
1943 GET_CR(local_cr); \
1944 GET_FPSCR(local_fpscr);
1945
1946#define XSCMPOQP(x) \
1947 SET_FPSCR_ZERO \
1948 SET_CR_ZERO \
1949 __asm__ __volatile__ \
1950 ("xscmpoqp %0, %1, %2" :: "i"(x), "v"(vec_xa), "v"(vec_xb)); \
1951 GET_CR(local_cr); \
1952 GET_FPSCR(local_fpscr);
1953
1954#define XSCMPUQP(x) \
1955 SET_FPSCR_ZERO \
1956 SET_CR_ZERO \
1957 __asm__ __volatile__ \
1958 ("xscmpuqp %0, %1, %2"::"i"(x), "v"(vec_xa), "v"(vec_xb)); \
1959 GET_CR(local_cr); \
1960 GET_FPSCR(local_fpscr);
1961
1962static void test_xscmpexpqp(void) {
1963 switch(x_index) {
1964 case 0: XSCMPEXPQP(0); break;
1965 case 1: XSCMPEXPQP(1); break;
1966 case 2: XSCMPEXPQP(2); break;
1967 case 3: XSCMPEXPQP(3); break;
1968 case 4: XSCMPEXPQP(4); break;
1969 case 5: XSCMPEXPQP(5); break;
1970 case 6: XSCMPEXPQP(6); break;
1971 case 7: XSCMPEXPQP(7); break;
1972 default:
1973 printf("Unhandled shift value for %s %x\n", __FUNCTION__, x_index);
1974 };
1975}
1976
1977static void test_xscmpoqp(void) {
1978 switch(x_index) {
1979 case 0: XSCMPOQP(0); break;
1980 case 1: XSCMPOQP(1); break;
1981 case 2: XSCMPOQP(2); break;
1982 case 3: XSCMPOQP(3); break;
1983 case 4: XSCMPOQP(4); break;
1984 case 5: XSCMPOQP(5); break;
1985 case 6: XSCMPOQP(6); break;
1986 case 7: XSCMPOQP(7); break;
1987 default:
1988 printf("Unhandled shift value for %s %x\n", __FUNCTION__, x_index);
1989 };
1990}
1991
1992static void test_xscmpuqp(void) {
1993 switch(x_index) {
1994 case 0: XSCMPUQP(0); break;
1995 case 1: XSCMPUQP(1); break;
1996 case 2: XSCMPUQP(2); break;
1997 case 3: XSCMPUQP(3); break;
1998 case 4: XSCMPUQP(4); break;
1999 case 5: XSCMPUQP(5); break;
2000 case 6: XSCMPUQP(6); break;
2001 case 7: XSCMPUQP(7); break;
2002 default:
2003 printf("Unhandled shift value for %s %x\n", __FUNCTION__, x_index);
2004 };
2005}
2006
2007static test_list_t testgroup_vector_scalar_compare_quads[] = {
2008 { &test_xscmpexpqp, "xscmpexpqp" },
2009 { &test_xscmpoqp , "xscmpoqp " },
2010 { &test_xscmpuqp , "xscmpuqp " },
2011 { NULL , NULL },
2012};
2013
2014#define XSRQPI(R,RMC) \
2015 SET_FPSCR_ZERO \
2016 SET_CR_ZERO \
2017 __asm__ __volatile__ \
2018 ("xsrqpi %1, %0, %2, %3" : "=v"(vec_xt) : "i"(R), "v"(vec_xb), "i"(RMC)); \
2019 GET_CR(local_cr); \
2020 GET_FPSCR(local_fpscr);
2021
2022#define XSRQPIX(R,RMC) \
2023 SET_FPSCR_ZERO \
2024 SET_CR_ZERO \
2025 __asm__ __volatile__ \
2026 ("xsrqpix %1, %0, %2, %3" : "=v"(vec_xt) : "i"(R), "v"(vec_xb), "i"(RMC));\
2027 GET_CR(local_cr); \
2028 GET_FPSCR(local_fpscr);
2029
2030#define XSRQPXP(R,RMC) \
2031 SET_FPSCR_ZERO \
2032 SET_CR_ZERO \
2033 __asm__ __volatile__ \
2034 ("xsrqpxp %1, %0, %2, %3" : "=v"(vec_xt) : "i"(R), "v"(vec_xb), "i"(RMC));\
2035 GET_CR(local_cr); \
2036 GET_FPSCR(local_fpscr);
2037
2038/* For the scalar round to quad instructions, x_index is used to key into
2039 * two fields; x_index bit [2] becomes the one-bit 'R' and x_index bits [0, 1]
2040 * becomes the two-bit 'RMC'.
2041 */
2042static void test_xsrqpi(void) {
2043 switch(x_index) {
2044 case 0: XSRQPI(0, 0); break;
2045 case 1: XSRQPI(0, 1); break;
2046 case 2: XSRQPI(0, 2); break;
2047 case 3: XSRQPI(0, 3); break;
2048 case 4: XSRQPI(1, 0); break;
2049 case 5: XSRQPI(1, 1); break;
2050 case 6: XSRQPI(1, 2); break;
2051 case 7: XSRQPI(1, 3); break;
2052 }
2053}
2054static void test_xsrqpix(void) {
2055 switch(x_index) {
2056 case 0: XSRQPIX(0, 0); break;
2057 case 1: XSRQPIX(0, 1); break;
2058 case 2: XSRQPIX(0, 2); break;
2059 case 3: XSRQPIX(0, 3); break;
2060 case 4: XSRQPIX(1, 0); break;
2061 case 5: XSRQPIX(1, 1); break;
2062 case 6: XSRQPIX(1, 2); break;
2063 case 7: XSRQPIX(1, 3); break;
2064 }
2065}
2066
2067static void test_xsrqpxp(void) {
2068 switch(x_index) {
2069 case 0: XSRQPXP(0, 0); break;
2070 case 1: XSRQPXP(0, 1); break;
2071 case 2: XSRQPXP(0, 2); break;
2072 case 3: XSRQPXP(0, 3); break;
2073 case 4: XSRQPXP(1, 0); break;
2074 case 5: XSRQPXP(1, 1); break;
2075 case 6: XSRQPXP(1, 2); break;
2076 case 7: XSRQPXP(1, 3); break;
2077 }
2078}
2079
2080static test_list_t testgroup_vector_scalar_rounding_quads[] = {
2081 { &test_xsrqpi , "xsrqpi " },
2082 { &test_xsrqpix, "xsrqpix" },
2083 { &test_xsrqpxp, "xsrqpxp" },
2084 { NULL , NULL },
2085};
2086
Elliott Hughesed398002017-06-21 14:41:24 -07002087/* Move From FPSCR variants:
2088 * Move From FpScr [ &
2089 * Clear Enables |
2090 * Lightweight |
2091 * Control [&
2092 * set DRN [ Immediate] |
2093 * set RN [ Immediate ] ]]
2094 */
2095/* mffs FRT # Move From FPSCR*/
2096static void test_mffs (void) {
2097 __asm__ __volatile__ ("mffs %0" : "=f"(f14) );
2098 GET_FPSCR(local_fpscr);
2099}
2100
2101/* mffsce FRT # Move From FPSCR and Clear Enables */
2102static void test_mffsce (void) {
2103 __asm__ __volatile__ ("mffsce %0" : "=f"(f14) );
2104 GET_FPSCR(local_fpscr);
2105}
2106
2107/* mffscdrn FRT,FRB # Move From FpScr and Control &set DRN */
2108static void test_mffscdrn (void) {
2109 __asm__ __volatile__ ("mffscdrn %0,%1" : "=f"(f14): "f"(f15) );
2110 GET_FPSCR(local_fpscr);
2111}
2112
2113/* mffscdrni FRT,DRM # Move From FpScr & Control &set DRN Immediate*/
2114static void test_mffscdrni (void) {
2115 switch(x_shift) {
2116 default:
2117 case 0:
2118 __asm__ __volatile__ ("mffscdrni %0,0" : "=f"(f14) );
2119 GET_FPSCR(local_fpscr);
2120 break;
2121 case 1:
2122 __asm__ __volatile__ ("mffscdrni %0,1" : "=f"(f14) );
2123 GET_FPSCR(local_fpscr);
2124 break;
2125 case 2:
2126 __asm__ __volatile__ ("mffscdrni %0,2" : "=f"(f14) );
2127 GET_FPSCR(local_fpscr);
2128 break;
2129 }
2130}
2131
2132/* mffscrn FRT,FRB # Move From FpScr and Control &set RN*/
2133static void test_mffscrn (void) {
2134 __asm__ __volatile__ ("mffscrn %0,%1" : "=f"(f14):"f"(f15));
2135 GET_FPSCR(local_fpscr);
2136}
2137
2138/* mffscrni FRT,RM # Move from FpScr and Control &set RN Immediate*/
2139static void test_mffscrni (void) {
2140 switch(x_shift) {
2141 case 0:
2142 __asm__ __volatile__ ("mffscrni %0,0" : "=f"(f14) );
2143 GET_FPSCR(local_fpscr);
2144 break;
2145 case 1:
2146 __asm__ __volatile__ ("mffscrni %0,1" : "=f"(f14) );
2147 GET_FPSCR(local_fpscr);
2148 break;
2149 case 2:
2150 __asm__ __volatile__ ("mffscrni %0,2" : "=f"(f14) );
2151 GET_FPSCR(local_fpscr);
2152 break;
2153 }
2154}
2155
2156/* mffsl FRT # Move From FpScr Lightweight */
2157static void test_mffsl (void) {
2158 __asm__ __volatile__ ("mffsl %0" : "=f"(f14) );
2159 GET_FPSCR(local_fpscr);
2160}
2161
2162/* mffs* instructions using FRT only. */
2163/* Note to self - Watch DRM,RM fields. */
2164static test_list_t testgroup_mffs_misc[] = {
2165 // { &test_mffsce, "mffsce" },
2166 // { &test_mffsl, "mffsl" },
2167 { &test_mffs, "mffs" },
2168 { NULL , NULL },
2169};
2170
2171/* mffs* instructions using FRT,FRB. */
2172static test_list_t testgroup_mffs_misc_one[] = {
2173 // { &test_mffscdrni, "mffscdrni" },
2174 // { &test_mffscdrn, "mffscdrn" },
2175 // { &test_mffscrni, "mffscrni" },
2176 // { &test_mffscrn, "mffscrn" },
2177 { NULL , NULL },
2178};
2179
Elliott Hughesa0664b92017-04-18 17:46:52 -07002180
2181/* ###### begin all_tests table. */
2182
2183/* table containing all of the instruction groups */
2184struct test_group_table_t {
2185 test_list_t *tests;
2186 const char *name;
2187 unsigned int flags;
2188};
2189
2190typedef struct test_group_table_t test_group_table_t;
2191
2192static test_group_table_t all_tests[] = {
2193 {
2194 testgroup_ia_ops_two,
2195 "PPC integer arith instructions with two args",
2196 PPC_INTEGER | PPC_ARITH | PPC_TWO_ARGS,
2197 },
2198 {
2199 testgroup_shifted_one,
2200 "ppc one argument plus shift",
2201 PPC_MISC | PPC_CR | PPC_TWO_ARGS,
2202 },
2203 {
2204 testgroup_three_args,
2205 "ppc three parameter ops",
2206 PPC_INTEGER | PPC_ARITH | PPC_THREE_ARGS,
2207 },
2208 {
2209 testgroup_logical_one,
2210 "ppc count zeros",
2211 PPC_INTEGER | PPC_LOGICAL | PPC_ONE_ARG,
2212 },
2213 {
2214 testgroup_set_boolean,
2215 "ppc set boolean",
2216 PPC_INTEGER | PPC_LOGICAL | PPC_ONE_IMM,
2217 },
2218 {
2219 testgroup_char_compare,
2220 "ppc char compare",
2221 PPC_INTEGER | PPC_COMPARE,
2222 },
2223 {
2224 testgroup_vsx_absolute,
2225 "ppc vector absolutes",
2226 PPC_ALTIVEC | PPC_ARITH | PPC_TWO_ARGS,
2227 },
2228 {
2229 testgroup_vector_immediate,
2230 "ppc vector logical immediate",
2231 PPC_ALTIVEC | PPC_LOGICAL | PPC_ONE_IMM,
2232 },
2233 {
2234 testgroup_vector_logical_one,
2235 "ppc vector logical one",
2236 PPC_ALTIVEC | PPC_LOGICAL | PPC_ONE_ARG,
2237 },
2238 {
2239 testgroup_vector_extend_sign,
2240 "ppc vector extend sign",
2241 PPC_ALTIVEC | PPC_LOGICAL | PPC_TWO_ARGS,
2242 },
2243 {
2244 testgroup_vector_three_quad,
2245 "ppc vector three quad",
2246 PPC_ALTIVEC | PPC_LOGICAL | PPC_THREE_ARGS,
2247 },
2248 {
2249 testgroup_vector_scalar_two_quad,
2250 "ppc vector scalar quad",
2251 PPC_ALTIVEC_QUAD | PPC_LOGICAL | PPC_TWO_ARGS,
2252 },
2253 {
2254 testgroup_vector_scalar_compare_quads,
2255 "ppc vector scalar compare exponents quads",
2256 PPC_ALTIVEC_QUAD | PPC_COMPARE | PPC_COMPARE_ARGS,
2257 },
2258 {
2259 testgroup_vector_scalar_rounding_quads,
2260 "ppc vector scalar rounding quads",
2261 PPC_ALTIVEC_QUAD | PPC_ROUND,
2262 },
2263 {
2264 testgroup_vsx_xxpermute,
2265 "ppc vector permutes",
2266 PPC_ALTIVEC | PPC_PERMUTE,
2267 },
2268 {
2269 testgroup_vector_four,
2270 "ppc vector three args + dest",
2271 PPC_ALTIVEC | PPC_LOGICAL | PPC_FOUR_ARGS,
2272 },
2273 {
2274 testgroup_vector_inserts,
2275 "ppc vector inserts",
2276 PPC_ALTIVEC | PPC_INSERTEXTRACT | PPC_ONE_IMM,
2277 },
2278 {
2279 testgroup_vector_extract,
2280 "ppc vector extract from vector to reg",
2281 PPC_ALTIVEC | PPC_INSERTEXTRACT | PPC_TWO_ARGS,
2282 },
2283 {
2284 testgroup_vector_count_bytes,
2285 "ppc vector count leading/trailing bytes",
2286 PPC_ALTIVEC | PPC_POPCNT,
2287 },
2288 {
2289 testgroup_vector_scalar_loadstore_length,
2290 "ppc vector load/store",
2291 PPC_ALTIVEC | PPC_LDST | PPC_ONE_IMM,
2292 },
2293 {
2294 testgroup_vector_loadstore,
2295 "ppc vector load/store",
2296 PPC_ALTIVEC | PPC_LDST | PPC_TWO_ARGS,
2297 },
2298 {
2299 testgroup_vectorscalar_move_tofrom,
2300 "ppc vector scalar move to/from",
2301 PPC_MISC | PPC_TWO_ARGS,
2302 },
2303 {
2304 testgroup_vector_scalar_compare_exp_double,
2305 "ppc vector scalar compare exponents doubles",
2306 PPC_ALTIVEC_DOUBLE | PPC_COMPARE | PPC_COMPARE_ARGS,
2307 },
2308 {
2309 testgroup_vector_scalar_data_class,
2310 "ppc vector scalar test data class tests",
2311 PPC_ALTIVEC_DOUBLE | PPC_COMPARE | PPC_ONE_ARG,
2312 },
2313 {
2314 testgroup_vector_scalar_two_double,
2315 "ppc vector scalar tests against float double two args ",
2316 PPC_ALTIVEC_DOUBLE | PPC_COMPARE | PPC_TWO_ARGS,
2317 },
2318 {
2319 testgroup_dfp_significance,
2320 "ppc dfp significance",
2321 PPC_DFP,
2322 },
2323 {
2324 testgroup_bcd_misc,
2325 "ppc bcd misc",
2326 PPC_BCD,
2327 },
2328 {
2329 testgroup_noop_misc,
2330 "ppc noop misc",
2331 PPC_NO_OP,
2332 },
2333 {
2334 testgroup_pc_immediate_misc,
2335 "ppc addpc_misc",
2336 PPC_PC_IMMEDIATE,
2337 },
Elliott Hughesed398002017-06-21 14:41:24 -07002338 {
2339 testgroup_mffs_misc,
2340 "ppc mffpscr",
2341 PPC_MFFS,
2342 },
2343 {
2344 testgroup_mffs_misc_one,
2345 "ppc mffpscr",
2346 PPC_MFFS,
2347 },
Elliott Hughesa0664b92017-04-18 17:46:52 -07002348 { NULL, NULL, 0x00000000, },
2349};
2350
Elliott Hughesed398002017-06-21 14:41:24 -07002351#define instruction_touches_xer(instruction_name) \
2352 (strncmp(instruction_name, "addex", 5) == 0)
2353
Elliott Hughesa0664b92017-04-18 17:46:52 -07002354static void testfunction_int_two_args (const char* instruction_name,
2355 test_func_t func,
2356 unsigned int test_flags)
2357{
2358 volatile HWord_t res;
2359 volatile unsigned int cr;
2360 int i, j;
2361
2362 VERBOSE_FUNCTION_CALLOUT
2363
2364 for (i = 0; i < nb_iargs; i++) {
2365 for (j = 0; j < nb_iargs; j++) {
2366
2367 r14 = iargs[i];
2368 r15 = iargs[j];
2369
2370 SET_CR_ZERO;
2371 (*func)();
2372 GET_CR(cr);
Elliott Hughesed398002017-06-21 14:41:24 -07002373 GET_XER(local_xer);
Elliott Hughesa0664b92017-04-18 17:46:52 -07002374 res = r17;
2375
Elliott Hughesed398002017-06-21 14:41:24 -07002376 printf("%s %016lx, %016lx => %016lx (%08x)",
Elliott Hughesa0664b92017-04-18 17:46:52 -07002377 instruction_name, (long unsigned)iargs[i],
2378 (long unsigned)iargs[j], (long unsigned)res,
2379 cr);
Elliott Hughesed398002017-06-21 14:41:24 -07002380 if (instruction_touches_xer(instruction_name)) {
2381 dissect_xer(local_xer);
2382 }
2383 printf("\n");
Elliott Hughesa0664b92017-04-18 17:46:52 -07002384 }
2385 if (verbose) printf("\n");
2386 }
2387}
2388
2389#define instruction_sets_cr0_to_zero(inst_name) \
2390 ( (strncmp(inst_name, "cnttzw.", 7) == 0 ) || \
2391 (strncmp(inst_name, "cnttzd.", 7) == 0 ) )
2392
2393static void testfunction_logical_one (const char* instruction_name,
2394 test_func_t func,
2395 unsigned int test_flags) {
2396 int i;
2397 volatile HWord_t res;
2398 volatile unsigned int cr;
2399
2400 VERBOSE_FUNCTION_CALLOUT
2401
2402 for (i = 0; i < nb_iargs; i++) {
2403
2404 r14 = iargs[i];
2405
2406 /* The logical instructions will set CR fields to zero, so
2407 * lets start with some non zero content in CR0.
2408 */
2409 SET_CR0_FIELD(0xF);
2410
2411 (*func)();
2412
2413 res = r17;
2414 GET_CR(cr);
2415
2416 printf("%s %016lx => %016lx",
2417 instruction_name, (long unsigned)iargs[i], (long unsigned)res);
2418
2419 if (instruction_sets_cr0_to_zero(instruction_name)
2420 && ((cr & 0xF0000000) != 0 )) {
2421 /* The dotted version sets the CR0 to 0, verify */
2422 printf(" Expected cr0 to be zero, it is (%08x)\n", cr & 0xF0000000);
2423 }
2424 printf("\n");
2425
2426 if (verbose) printf("\n");
2427 }
2428}
2429
2430void testfunction_one_arg_with_shift (const char* instruction_name,
2431 test_func_t test_function,
2432 unsigned int ignore_test_flags)
2433{
2434 /*This function uses global variable x_shift */
2435 volatile HWord_t res;
2436 volatile unsigned int cr;
2437 int i, j;
2438
2439 VERBOSE_FUNCTION_CALLOUT
2440
2441 for (i = 0; i < SHIFT_VALUES_SIZE; i++) {
2442 for (j = 0; j < SHIFT_ARRAY_SIZE; j++) {
2443
2444 r14 = values_to_shift[i];
2445 x_shift = shift_amounts[j];
2446
2447 SET_CR_ZERO;
2448
2449 (*test_function)();
2450
2451 GET_CR(cr);
2452 res = r17;
2453
2454 printf("%s %016lx, %016lx => %016lx (%08x)\n",
2455 instruction_name, (long unsigned)values_to_shift[i],
2456 (long unsigned)x_shift, (long unsigned)res, cr);
2457 }
2458 }
2459}
2460
2461static void testfunction_three_args (const char* instruction_name,
2462 test_func_t test_function,
2463 unsigned int ignore_test_flags)
2464{
2465 volatile HWord_t res;
2466 volatile unsigned int cr;
2467 int i, j, l;
2468
2469 VERBOSE_FUNCTION_CALLOUT
2470
2471 for (i = 0; i < nb_iargs; i++) {
2472 for (j = 0; j < nb_iargs; j++) {
2473 for (l = 0; l < nb_iargs; l++) {
2474 r14 = iargs[i];
2475 r15 = iargs[j];
2476 r16 = iargs[l];
2477
2478 SET_CR_ZERO;
2479
2480 (*test_function)();
2481
2482 GET_CR(cr);
2483 res = r17;
2484
2485 printf("%s %016lx, %016lx, %016lx => %016lx (%08x)\n",
2486 instruction_name,
2487 (long unsigned)r14, (long unsigned)r15,
2488 (long unsigned)r16, (long unsigned)res,
2489 cr);
2490 }
2491 }
2492 }
2493}
2494
2495static void testfunction_vector_absolute (const char* instruction_name,
2496 test_func_t test_function,
2497 unsigned int ignore_test_flags)
2498{
2499 /* Notes:
2500 * iterate across xa, xb values.
2501 * Results are in xt.
2502 */
2503 volatile unsigned int cr;
2504 int i, j;
2505
2506 VERBOSE_FUNCTION_CALLOUT
2507
2508 for (i = 0; i < nb_vargs; i += 4) {
2509 /* patterns more interesting when shifted like so.. */
2510 for (j = 0; j < nb_vpcv; j += 2) {
2511
2512 vec_xa = (vector unsigned long){vsxargs[i], vsxargs[i+1]};
2513 vec_xb = (vector unsigned long){vsxargs[j], vsxargs[j]};
2514 vec_xt = (vector unsigned long){0, 0};
2515
2516 printf("%s xa:%016lx %016lx xb:%016lx %016lx ",
2517 instruction_name,
2518 vec_xa[1],vec_xa[0],
2519 vec_xb[0],vec_xb[1]
2520 );
2521 printf(" => ");
2522
2523 SET_CR_ZERO;
2524
2525 (*test_function)();
2526
2527 GET_CR(cr);
2528
2529 printf(" xt:%016lx %016lx (%08x)\n", vec_xt[0], vec_xt[1], cr);
2530 }
2531 if (verbose) printf("\n");
2532 }
2533}
2534
2535static void testfunction_vector_xxpermute (const char* instruction_name,
2536 test_func_t test_function,
2537 unsigned int ignore_test_flags)
2538{
2539 /* Notes:
2540 * VSX permute uses both xt and xa as source registers.
2541 * Permute control vector is in xb.
2542 * Results are in xt.
2543 */
2544 volatile unsigned int cr;
2545 int i, j;
2546
2547 VERBOSE_FUNCTION_CALLOUT
2548
2549 for (i = 0; i < nb_vargs; i += 4) {
2550 for (j = 0; j < nb_vpcv; j += 2) {
2551
2552 vec_xa = (vector unsigned long){vsxargs[i], vsxargs[i+1]};
2553 vec_xt = (vector unsigned long){vsxargs[i+2], vsxargs[i+3]};
2554 vec_xb = (vector unsigned long){vpcv[j], vpcv[j+1]};
2555
2556 printf("%s %016lx %016lx %016lx %016lx, pcv[%016lx %016lx] => ",
2557 instruction_name,
2558 vec_xa[1], vec_xa[0],
2559 vec_xt[1], vec_xt[0],
2560 vec_xb[0], vec_xb[1]);
2561
2562 SET_CR_ZERO;
2563
2564 (*test_function)();
2565
2566 GET_CR(cr);
2567
2568 printf(" %016lx %016lx (%08x)\n", vec_xt[0], vec_xt[1], cr);
2569
2570#if defined (DEBUG_VECTOR_PERMUTE)
2571 printf("DEBUG:%s %016lx %016lx %016lx %016lx, pcv[%016lx %016lx]\n",
2572 ignore_name,
2573 vec_xa[0], vec_xa[1],
2574 vec_xt[0], vec_xt[1],
2575 vec_xb[0], vec_xb[1]);
2576#endif
2577 }
2578 if (verbose) printf("\n");
2579 }
2580}
2581
2582static void testfunction_vector_logical_one (const char* instruction_name,
2583 test_func_t test_function,
2584 unsigned int ignore_test_flags)
2585{
2586 /* Notes:
2587 * vector instructions with one input, one output.
2588 * xt, xa
2589 */
2590 int i;
2591 int t;
2592
2593 VERBOSE_FUNCTION_CALLOUT
2594
2595 for (i = 0; i < nb_vargs; i += 2) {
2596
2597 vec_xa = (vector unsigned long){vsxargs[i], vsxargs[i+1]};
2598 for (t = 0; t < 2; t++) {
2599 vec_xt[0] = (t == 0) ? 0 : 0xffffffffffffffff;
2600 vec_xt[1] = (t == 0) ? 0 : 0xffffffffffffffff;
2601
2602 printf("%s xa:%016lx %016lx xt:%016lx %016lx => ",
2603 instruction_name,
2604 vec_xa[0], vec_xa[1],
2605 vec_xt[0], vec_xt[1]);
2606
2607 (*test_function)();
2608
2609 printf(" xt:%016lx %016lx\n",
2610 vec_xt[0], vec_xt[1]);
2611 }
2612 }
2613 if (verbose) printf("\n");
2614}
2615
2616static void testfunction_vector_logical_four (const char* instruction_name,
2617 test_func_t test_function,
2618 unsigned int ignore_test_flags) {
2619 /* Notes:
2620 * vector instructions with three input arguments, one output.
2621 * xt, xa, xb, xc.
2622 * Permute control vector is in xc.
2623 * Results are in xt.
2624 */
2625 volatile unsigned int cr;
2626 int i, j;
2627 int p;
2628
2629 VERBOSE_FUNCTION_CALLOUT
2630
2631 for (i = 0; i < nb_vargs; i += 4) {
2632 for (j = 0; j < nb_vargs; j += 4) {
2633 for (p = 0; p < nb_vpcv; p += 2) {
2634
2635 vec_xa = (vector unsigned long){vsxargs[i], vsxargs[i+1]};
2636 vec_xb = (vector unsigned long){vsxargs[j], vsxargs[j+1]};
2637 vec_xc = (vector unsigned long){vpcv[p], vpcv[p+1]};
2638
2639 printf("%s %016lx %016lx %016lx %016lx, pcv[%016lx %016lx] => ",
2640 instruction_name,
2641 vec_xa[1], vec_xa[0],
2642 vec_xb[1], vec_xb[0],
2643 vec_xc[0], vec_xc[1]);
2644
2645 SET_CR_ZERO;
2646
2647 (*test_function)();
2648
2649 GET_CR(cr);
2650
2651 printf(" %016lx %016lx (%08x)\n", vec_xt[0], vec_xt[1], cr);
2652 }
2653 }
2654
2655 if (verbose) printf("\n");
2656 }
2657}
2658
2659static
2660void testfunction_vector_insert_or_extract_immediate (const char* instruction_name,
2661 test_func_t test_function,
2662 unsigned int ignore_test_flags) {
2663 /* Uses global variable x_index */
2664 /* uses global variable insert_extract_error */
2665 int i;
2666 int t;
2667
2668 VERBOSE_FUNCTION_CALLOUT
2669
2670 /* for the insert and extract tests, we deliberately use only a
2671 * subset of the vsxargs array as input data.
2672 */
2673 for (i = 2; i < 9 ; i += 4) { /* index into vsxargs[] array */
2674
2675 /* Note:
2676 * Determining the proper offset for {extract, insert} byte, halfword,
2677 * word, double would complicate things. For simplicity, allow the
2678 * sub-functions to ignore input that would be invalid. Catch and
2679 * suppress output for those cases per the global variable.
2680 */
2681 for (x_index = 0; x_index < 16 ; x_index++) {
2682 vec_xb[0] = (unsigned long) vsxargs[i];
2683 vec_xb[1] = (unsigned long) vsxargs[i+1];
2684
2685 /* Run each test against all zeros and then all ones,
2686 * This is intended to help any bitfield changes stand out.
2687 */
2688 for (t = 0; t < 2; t++) {
2689
2690 vec_xt[0] = (t == 0) ? 0 : 0xffffffffffffffff;
2691 vec_xt[1] = (t == 0) ? 0 : 0xffffffffffffffff;
2692
2693 insert_extract_error = 0;
2694
2695 (*test_function)();
2696
2697 if (!insert_extract_error) {
2698 printf("%s %016lx %016lx [%d] (into%s) => ",
2699 instruction_name, vec_xb[1], vec_xb[0], x_index,
2700 (t == 0 ? " zeros" : " ones") );
2701
2702 printf("%016lx %016lx\n", vec_xt[1], vec_xt[0]);
2703 }
2704 }
2705 }
2706 }
2707}
2708
2709
2710static void testfunction_vector_immediate (const char * instruction_name,
2711 test_func_t test_function,
2712 unsigned int ignore_test_flags) {
2713 /* Uses global variable x_splat */
2714 int i;
2715 int t;
2716
2717 VERBOSE_FUNCTION_CALLOUT
2718
2719 for (i = 0; i < SPLAT_ARRAY_SIZE; i++) {
2720 x_splat = splat_values[i];
2721 for (t = 0; t < 2; t++) {
2722 vec_xt[0] = (t == 0) ? 0 : 0xffffffffffffffff;
2723 vec_xt[1] = (t == 0) ? 0 : 0xffffffffffffffff;
2724
2725 printf("%s %016lx %016lx [%2x] => ",
2726 instruction_name, vec_xt[1], vec_xt[0], x_splat);
2727
2728 (*test_function)();
2729
2730 printf("%016lx %016lx\n", vec_xt[1], vec_xt[0]);
2731 }
2732 }
2733}
2734
2735static void testfunction_vector_loadstore (const char* instruction_name,
2736 test_func_t test_function,
2737 unsigned int ignore_flags) {
2738 /* exercises vector loads from memory, and vector stores from memory.
2739 * <load or store instruction> XS, RA, RB
2740 * For these tests, RA will be zero.
2741 * EA is then, simply, RB.
2742 */
2743 int i;
2744 int buffer_pattern;
2745
2746 VERBOSE_FUNCTION_CALLOUT
2747
2748 for (i = 0; i < nb_vargs; i += 2) {
2749
2750 vec_xt = (vector unsigned long){vsxargs[i], vsxargs[i+1]};
2751 r14 = 0;
2752 r15 = (unsigned long) & buffer;
2753
2754 for (buffer_pattern = 0; buffer_pattern < MAX_BUFFER_PATTERNS;
2755 buffer_pattern++) {
2756
2757 /* set patterns on both ends */
2758 initialize_buffer(buffer_pattern);
2759
2760 printf("%s ", instruction_name);
2761 printf("%016lx %016lx ", vec_xt[1], vec_xt[0]);
2762 dump_small_buffer();
2763 printf(" =>\n");
2764
2765 (*test_function)();
2766
2767 printf(" %016lx %016lx ", vec_xt[1], vec_xt[0]);
2768 dump_small_buffer();
2769 printf("\n");
2770 }
2771 }
2772}
2773
2774
2775static void testfunction_vectorscalar_move_tofrom (const char * instruction_name,
2776 test_func_t test_function,
2777 unsigned int ignore_test_flags) {
2778 /* Move to / move from vector scalar. spin through simple variants of
2779 * both the VSR and the register.
2780 * for simplicity, RA from 'mtvsrdd xt, ra, rb' is 0.
2781 */
2782 int i, v;
2783
2784 VERBOSE_FUNCTION_CALLOUT
2785
2786 for (i = 0; i < PATTERN_SIZE; i++) {
2787 for (v = 0; v < PATTERN_SIZE; v++) {
2788 /* if i==v, patterns will match, so just skip these as
2789 * non-interesting..
2790 */
2791 if (i == v) continue;
2792 r14 = 0;
2793 r15 = pattern[i%PATTERN_SIZE];
2794 vec_xt[0] = pattern[v%PATTERN_SIZE];
2795 vec_xt[1] = pattern[v%PATTERN_SIZE];
2796
2797 printf("%s ", instruction_name);
2798 printf("%016lx %016lx %lx %016lx ", vec_xt[1], vec_xt[0],
2799 (long unsigned)r14, (long unsigned)r15 );
2800
2801 (*test_function)();
2802
2803 printf("=> %016lx %016lx %lx %016lx", vec_xt[1], vec_xt[0],
2804 (long unsigned)r14, (long unsigned)r15 );
2805 printf("\n");
2806 }
2807 }
2808}
2809
2810/* Some of the load/store vector instructions use a length value that
2811 * is stored in bits 0:7 of RB. */
2812#define uses_bits_0to7(instruction_name) ( \
2813 (strncmp(instruction_name, "lxvl " ,5) == 0) || \
2814 (strncmp(instruction_name, "lxvll " ,6) == 0) || \
2815 (strncmp(instruction_name, "stxvl " ,6) == 0) || \
2816 (strncmp(instruction_name, "stxvll ",7) == 0) )
2817
2818static void testfunction_vector_scalar_loadstore_length (const char* instruction_name,
2819 test_func_t test_function,
2820 unsigned int ignore_flags) {
2821 /* exercises vector loads from memory, and vector stores from memory.
2822 * with length specification.
2823 * <load or store instruction> XS, RA, RB
2824 * For these tests, RA (i.e. EA) is address of source/dest and can
2825 * not be zero.
2826 * The length value is in rb. For a subset of these instructions,
2827 * the length is stored in bits 0:7, versus 56:63 of r15.
2828 */
2829 int i;
2830 unsigned long l;
2831 int buffer_pattern;
2832
2833 VERBOSE_FUNCTION_CALLOUT
2834
2835 for (i = 0; i < nb_vargs; i += 2) {
2836 for (l = 0; l <= 16; l += 4) {
2837
2838 for (buffer_pattern = 0; buffer_pattern < MAX_BUFFER_PATTERNS;
2839 buffer_pattern++) {
2840
2841 /* set patterns on both ends */
2842 vec_xt = (vector unsigned long){vsxargs[i], vsxargs[i+1]};
2843 r14 = (unsigned long) & buffer;
2844
2845 if (uses_bits_0to7(instruction_name)) {
2846 /* length is stored in bits 0:7 of gpr[r15]. */
2847 r15 = (unsigned long)((0xff & l) << 56);
2848
2849 } else {
2850 /* length is stored in gpr[r15]. */
2851 r15 = l;
2852 }
2853
2854 initialize_buffer(buffer_pattern);
2855
2856 printf("%s ", instruction_name);
2857 printf("%016lx %016lx ", vec_xt[1], vec_xt[0] );
2858 if (uses_bits_0to7(instruction_name)) {
2859 printf(" 0x%2lx ", (long unsigned)r15>>56 );
2860
2861 } else {
2862 printf(" l = 0x%2lx ", (long unsigned)r15 );
2863 }
2864
2865 dump_small_buffer();
2866
2867 (*test_function)();
2868
2869 printf("=> %016lx %016lx & %16lx", vec_xt[1], vec_xt[0],
2870 (long unsigned)r15 );
2871 printf("\n");
2872 }
2873 }
2874 }
2875}
2876
2877static void testfunction_vector_count_bytes (const char* instruction_name,
2878 test_func_t test_function,
2879 unsigned int ignore_flags)
2880{
2881 int i;
2882
2883 VERBOSE_FUNCTION_CALLOUT
2884
2885 for (i = 0; i < nb_vargs; i += 2) {
2886 vec_xb = (vector unsigned long){vsxargs[i], vsxargs[i+1]};
2887 r14 = 0;
2888
2889 printf("%s ", instruction_name);
2890 printf("%016lx %016lx %2d ", vec_xb[1], vec_xb[0], (unsigned)r14);
2891
2892 (*test_function)();
2893
2894 printf("=> %2d\n", (unsigned)r14 );
2895 }
2896}
2897
2898static void testfunction_vector_extract (const char* instruction_name,
2899 test_func_t test_function,
2900 unsigned int ignore_flags)
2901{
2902 int i;
2903
2904 VERBOSE_FUNCTION_CALLOUT
2905
2906 for (i = 0; i < nb_vargs; i += 2) {
2907 vec_xb = (vector unsigned long){vsxargs[i], vsxargs[i+1]};
2908 for (r15 = 0; r15 < 16; r15++) {
2909 r14 = 0;
2910
2911 printf("%s ", instruction_name);
2912 printf("%016lx %016lx %2d ", vec_xb[1], vec_xb[0], (unsigned)r15);
2913
2914 (*test_function)();
2915
2916 printf("=> %16lx\n", (long unsigned)r14 );
2917 }
2918 }
2919}
2920
2921static void testfunction_vector_extend_sign (const char* instruction_name,
2922 test_func_t test_function,
2923 unsigned int ignore_flags)
2924{
2925 int i;
2926
2927 VERBOSE_FUNCTION_CALLOUT
2928
2929 for (i = 0; i < nb_vargs; i += 2) {
2930 vec_xb = (vector unsigned long){vsxargs[i], vsxargs[i+1]};
2931 vec_xt = (vector unsigned long){0, 0};
2932
2933 printf("%s ", instruction_name);
2934 printf("%016lx %016lx ", vec_xb[1], vec_xb[0]);
2935
2936 (*test_function)();
2937
2938 printf("=> %016lx %016lx\n", vec_xt[1], vec_xt[0]);
2939 }
2940}
2941
2942/* packed binary decimal misc */
2943
2944#define convert_from_zoned(instruction_name) (strncmp(instruction_name, "bcdcfz", 6) ==0 )
2945
2946#define convert_from_national(instruction_name) (strncmp(instruction_name, "bcdcfn", 6) == 0)
2947
2948#define convert_to_zoned(instruction_name) (strncmp(instruction_name, "bcdctz", 6) == 0)
2949
2950#define convert_to_national(instruction_name) (strncmp(instruction_name, "bcdctn", 6) == 0)
2951
2952#define shift_or_truncate(instruction_name) \
2953 (strncmp(instruction_name, "bcds", 4) == 0 || \
2954 strncmp(instruction_name, "bcdus", 5) == 0 || \
2955 strncmp(instruction_name, "bcdsr", 5) == 0 || \
2956 strncmp(instruction_name, "bcdtrunc", 8) == 0 || \
2957 strncmp(instruction_name, "bcdutrunc", 9) == 0)
2958
2959
2960/* Helper function - returns 1 or 0 per whether the p1 or p0 string
2961 * exists in the instruction name passed in. The PS indicates preferred
2962 * sign, and has meaning for some of the BCD instructions.
2963 */
2964static inline int p_value(const char * instruction_name) {
2965 char * found_p0;
2966 char * found_p1;
2967
2968 found_p1 = strstr(instruction_name, "p1");
2969 found_p0 = strstr(instruction_name, "p0");
2970
2971 if (found_p1) return 1;
2972
2973 if (found_p0) return 0;
2974
2975 if (verbose) printf("p* substring not found in (%s)\n", instruction_name);
2976
2977 return 0;
2978}
2979
2980/* bcd test has been split out a bit.. a few bcd specific global vars here
2981 * to help keep that clean.
2982 */
2983long shift_or_truncate_instruction;
2984int xa_sign, xb_sign, xt_sign;
2985int short_circuit;
2986
2987/* testfunction_bcd_setup_inputs
2988 * This is a helper function that sets up the vec_xa, vec_xb values for
2989 * use in the bcd tests.
2990 */
2991static inline void testfunction_bcd_setup_inputs(const char * instruction_name,
2992 int i, int j) {
2993 short_circuit=0;
2994
2995 if (shift_or_truncate_instruction) {
2996 if (i >= nb_decimal_shift_entries - 2) {
2997 short_circuit = 1;
2998 return;
2999 }
3000 vec_xa = (vector unsigned long) {decimal_shift_table[i+1],
3001 decimal_shift_table[i]};
3002
3003 } else {
3004 if (i >= nb_decimal_shift_entries - 2) {
3005 short_circuit = 1;
3006 return;
3007 }
3008
3009 vec_xa = (vector unsigned long) {packed_decimal_table[i+1],
3010 packed_decimal_table[i]};
3011 xa_sign = extract_packed_decimal_sign(vec_xa[0], vec_xa[1]);
3012 }
3013
3014 if (convert_from_zoned(instruction_name)) { /* convert from zoned */
3015 if (j >= nb_zoned_decimal_entries - 2) {
3016 short_circuit = 1;
3017 return;
3018 }
3019
3020 vec_xb = (vector unsigned long) {zoned_decimal_table[j+1],
3021 zoned_decimal_table[j]};
3022 xb_sign = extract_zoned_decimal_sign(vec_xb[0], vec_xb[1]);
3023
3024 } else if (convert_from_national(instruction_name)) {
3025 /* convert from national */
3026 if (j >= nb_national_decimal_entries - 2) {
3027 short_circuit = 1;
3028 return;
3029 }
3030 vec_xb = (vector unsigned long) {national_decimal_table[j+1],
3031 national_decimal_table[j]};
3032 xb_sign = extract_national_decimal_sign(vec_xb[0], vec_xb[1]);
3033
3034 } else {
3035 /* packed decimal entries */
3036 if (j >= nb_packed_decimal_entries - 2) {
3037 short_circuit = 1;
3038 return;
3039 }
3040 vec_xb = (vector unsigned long) {packed_decimal_table[j+1],
3041 packed_decimal_table[j]};
3042 xb_sign = extract_packed_decimal_sign(vec_xb[0], vec_xb[1]);
3043 }
3044}
3045
3046static inline void testfunction_bcd_display_outputs(const char * instruction_name) {
3047
3048 printf(" xt:%016lx %016lx", vec_xt[0], vec_xt[1] );
3049
3050 if (convert_to_zoned(instruction_name)) {
3051 /* convert to zoned */
3052 xt_sign = extract_zoned_decimal_sign(vec_xt[0], vec_xt[1]);
3053 dissect_zoned_decimal_sign(xt_sign, p_value(instruction_name));
3054
3055 } else if (convert_to_national(instruction_name)) {
3056 /* convert to national */
3057 xt_sign = extract_national_decimal_sign(vec_xt[0], vec_xt[1]);
3058 dissect_national_decimal_sign(xt_sign);
3059
3060 } else {
3061 /* packed decimal entries, or shift/truncate */
3062 if (!shift_or_truncate_instruction) {
3063 xt_sign = extract_packed_decimal_sign(vec_xt[0], vec_xt[1]);
3064 dissect_packed_decimal_sign(xt_sign);
3065 }
3066 }
3067 printf("\n");
3068}
3069
3070#define uses_half_precision_input(instruction_name) ( \
3071 (strncmp(instruction_name, "xscvhpdp", 8) == 0) || \
3072 (strncmp(instruction_name, "xvcvhpsp", 8) == 0) )
3073
3074#define uses_single_precision_input(instruction_name) ( \
3075 (strncmp(instruction_name, "xvcvsphp", 8) == 0) )
3076
3077#define uses_double_precision_input(instruction_name) ( \
3078 (strncmp(instruction_name, "xscvdphp", 8) == 0) )
3079
3080#define uses_half_precision_output(instruction_name) ( \
3081 (strncmp(instruction_name, "xscvdphp", 8) == 0) || \
3082 (strncmp(instruction_name, "xvcvsphp", 8) == 0) )
3083
3084#define is_half_precision_instruction(instruction_name) ( \
3085 uses_half_precision_input(instruction_name) || \
3086 uses_half_precision_output(instruction_name) )
3087
3088/* Helper for those instructions with an unused second dword, indicating
3089 * the outer loop can be short-circuited after one pass.
3090 */
3091#define unused_second_dword(instruction_name) ( \
3092 (strncmp(instruction_name, "xscvhpdp", 8) == 0) || \
3093 (strncmp(instruction_name, "xscvdphp", 8) == 0) )
3094
3095static void testfunction_vector_scalar_two_quad (const char* instruction_name,
3096 test_func_t test_function,
3097 unsigned int ignore_flags)
3098{
3099 int i;
3100
3101 VERBOSE_FUNCTION_CALLOUT
3102
3103 for (i = 0; i < nb_vargs; i += 2) {
3104 if (uses_half_precision_input(instruction_name)) {
3105 vec_xb = (vector unsigned long){binary16_float_vsxargs[i],
3106 binary16_float_vsxargs[i+1]};
3107 } else {
3108 vec_xb = (vector unsigned long){vsxargs[i], vsxargs[i+1]};
3109 }
3110
3111 vec_xt = (vector unsigned long){0, 0};
3112
3113 printf("%s ", instruction_name);
3114 printf("%016lx %016lx ", vec_xb[1], vec_xb[0]);
3115
3116 SET_FPSCR_ZERO
3117
3118 (*test_function)();
3119
3120 GET_FPSCR(local_fpscr);
3121
3122 printf("=> %016lx %016lx", vec_xt[1], vec_xt[0]);
3123 dissect_fpscr(local_fpscr);
3124 printf("\n");
3125 }
3126}
3127
3128static void
3129testfunction_vector_scalar_compare_exp_double (const char* instruction_name,
3130 test_func_t test_function,
3131 unsigned int ignore_test_flags){
3132 int i,j;
3133 /* Uses global variable x_index */
3134
3135 VERBOSE_FUNCTION_CALLOUT
3136
3137 for (i = 0; i < nb_float_vsxargs - 1; i++) {
3138 for (j = 0; j < nb_float_vsxargs - 1; j++) {
3139 for (x_index = 2; x_index < 3; x_index++) {
3140
3141 /* TODO FIXME- there was a casting issue below. This incantation
3142 * works, but I suspect can be simplified...
3143 */
3144 vec_xa = (vector unsigned long){(unsigned long)binary64_float_vsxargs[i+1], (unsigned long)binary64_float_vsxargs[i]};
3145
3146 vec_xb = (vector unsigned long){(unsigned long)binary64_float_vsxargs[j], (unsigned long)binary64_float_vsxargs[j+1]};
3147
3148 /* run each test against cleared CR and FPSCR */
3149 /* Note that the SET_*_ZERO calls are not actually sufficient here,
3150 * due to infrastructure between here and there that also set some
3151 * of the CR bits. The condition regs are cleared here, but are
3152 * also both cleared and read within the to-be-tested asm chunk to
3153 * get accurate results.
3154 */
3155 SET_CR_ZERO
3156 SET_FPSCR_ZERO
3157
3158 printf("%s %016lx %016lx %016lx %016lx",
3159 instruction_name,
3160 vec_xa[0], vec_xa[1],
3161 vec_xb[0], vec_xb[1]);
3162
3163 if (verbose) printf(" cr#%d ", x_index);
3164
3165 printf(" => ");
3166
3167 (*test_function)();
3168
3169 dissect_fpscr(local_fpscr);
3170 dissect_fpscr_result_value_class(local_fpscr);
3171 dissect_cr_rn(local_cr, x_index);
3172 printf("\n");
3173 }
3174 }
3175 }
3176}
3177
3178/* These instructions set the floating point condition codes. */
3179/* verify logic reversal */
3180#define does_not_set_floating_point_cc(instruction_name) \
3181 (strncmp(instruction_name, "xvtstdcdp", 9) == 0) | \
3182 (strncmp(instruction_name, "xvtstdcsp", 9) == 0)
3183
3184static void
3185testfunction_vector_scalar_data_class (const char* instruction_name,
3186 test_func_t test_function,
3187 unsigned int ignore_test_flags) {
3188 int j;
3189 /* x_index is used as a key into the DCMX value.
3190 *
3191 * BF, XB, DCMX
3192 * For instruction tests called through this function, note that we are only
3193 * utilizing bf (condition register) #3; where 3 was mostly randomly
3194 * chosen, and has no special meaning.
3195 */
3196
3197 VERBOSE_FUNCTION_CALLOUT
3198
3199 for (j = 0; j < nb_float_vsxargs - 1; j++) {
3200 /* for dcmx field, start with x_index=1 to skip the 'all' dcmx entry. */
3201 for (x_index = 1; x_index < 8; x_index++) {
3202 vec_xb[0] = float_vsxargs[j];
3203 vec_xb[1] = float_vsxargs[j+1];
3204 vec_xt[0] = 0x0a0a0a0a0a0a0a0a;
3205 vec_xt[1] = 0x0505050505050505;
3206 SET_CR_ZERO
3207 SET_FPSCR_ZERO
3208
3209 dcmx_match = 0;
3210
3211 (*test_function)();
3212
3213 /* the local_fpscr value is gathered within the test_function call. */
3214 dcmx_match = (local_fpscr & FPCC_FE_BIT);
3215
3216 if (dcmx_match || (verbose>2)) {
3217 printf("%s %016lx, %016lx ",
3218 instruction_name, vec_xb[1], vec_xb[0]);
3219
3220 print_dcmx_field(x_index);
3221
3222 if (dcmx_match)
3223 printf(" => Match. ");
3224
3225 printf(" %016lx, %016lx ", vec_xt[1], vec_xt[0]);
3226
3227 dissect_cr_rn(local_cr,3);
3228 dissect_fpscr_dcmx_indicator(local_fpscr);
3229 printf("\n");
3230 }
3231
3232 printf("%s %016lx, %016lx => ",
3233 instruction_name, vec_xb[1], vec_xb[0]);
3234
3235 printf(" %016lx, %016lx\n", vec_xt[1], vec_xt[0]);
3236 }
3237 }
3238}
3239
3240static void testfunction_vector_scalar_compare_quads (const char* instruction_name,
3241 test_func_t test_function,
3242 unsigned int ignore_test_flags) {
3243 /* Uses global variable x_index */
3244 int i,j;
3245
3246 VERBOSE_FUNCTION_CALLOUT
3247
3248 for (i = 0; i < nb_float_vsxargs - 1; i++) {
3249 for (j = 0; j < nb_float_vsxargs - 1; j++) {
3250 for (x_index = 0; x_index < 3 ; x_index++) {
3251 vec_xa[0] = float_vsxargs[i];
3252 vec_xa[1] = float_vsxargs[i+1];
3253 vec_xb[0] = float_vsxargs[j];
3254 vec_xb[1] = float_vsxargs[j+1];
3255
3256 /* run each test against cleared CR and FPSCR */
3257 /* Note that the SET_*_ZERO calls are not actually sufficient here,
3258 * due to infrastructure between here and there that also set some
3259 * of the CR bits. The condition regs are cleared here, but are
3260 * also both cleared and read within the to-be-tested asm chunk
3261 * to get accurate results.
3262 */
3263 printf("%s %016lx%016lx %016lx%016lx (cr#%d) => ",
3264 instruction_name,
3265 vec_xa[1], vec_xa[0],
3266 vec_xb[1], vec_xb[0],
3267 x_index);
3268
3269 SET_CR_ZERO
3270 SET_FPSCR_ZERO
3271
3272 (*test_function)();
3273
3274 GET_CR(local_cr);
3275 GET_FPSCR(local_fpscr);
3276
3277 dissect_fpscr(local_fpscr);
3278 dissect_cr_rn(local_cr, x_index);
3279 printf("\n");
3280 }
3281 }
3282 }
3283}
3284
3285static void testfunction_vector_scalar_rounding_quads (const char* instruction_name,
3286 test_func_t test_function,
3287 unsigned int ignore_test_flags) {
3288 /* Uses global variable x_index */
3289 /* For this function, x_index is used as a key into R and RMC values.
3290 * Also note, the fpscr.rn value may be used to affect the rounding mode.
3291 * that variation is not evaluated here. */
3292 int j;
3293
3294 VERBOSE_FUNCTION_CALLOUT
3295
3296 for (j = 0; j < nb_float_vsxargs - 1; j++) {
3297 for (x_index = 0; x_index < 8; x_index++) {
3298 vec_xb[0] = float_vsxargs[j];
3299 vec_xb[1] = float_vsxargs[j+1];
3300
3301 printf("%s %016lx%016lx (R=%x) (RMC=%x) => ",
3302 instruction_name,
3303 vec_xb[1], vec_xb[0],
3304 (x_index & 0x4) >> 2, x_index & 0x3);
3305
3306 SET_CR_ZERO
3307 SET_FPSCR_ZERO
3308
3309 (*test_function)();
3310
3311 GET_FPSCR(local_fpscr);
3312
3313 printf("%016lx%016lx", vec_xt[1], vec_xt[0]);
3314 dissect_fpscr(local_fpscr);
3315 printf("\n");
3316 }
3317 }
3318}
3319
3320static void testfunction_vector_three_special (const char* instruction_name,
3321 test_func_t test_function,
3322 unsigned int ignore_test_flags){
3323 /* Notes:
3324 * vector instructions with two inputs, one output.
3325 * vrt, vra, vrb
3326 */
3327 int i, j;
3328 int t;
3329
3330 VERBOSE_FUNCTION_CALLOUT
3331
3332 for (i = 0; i < nb_float_vsxargs - 1; i++) {
3333 for (j = 0; j < nb_float_vsxargs - 1; j++) {
3334 vec_xa[0] = float_vsxargs[i];
3335 vec_xa[1] = float_vsxargs[i+1];
3336 vec_xb[0] = float_vsxargs[j];
3337 vec_xb[1] = float_vsxargs[j+1];
3338
3339 for (t = 0; t < 2; t++) {
3340 vec_xt[0] = (t == 0) ? 0 : 0xffffffffffffffff;
3341 vec_xt[1] = (t == 0) ? 0 : 0xffffffffffffffff;
3342
3343 SET_FPSCR_ZERO;
3344 printf("%s %016lx%016lx %016lx%016lx %016lx%016lx => ",
3345 instruction_name,
3346 vec_xa[1], vec_xa[0],
3347 vec_xb[1], vec_xb[0],
3348 vec_xt[1], vec_xt[0]);
3349
3350 (*test_function)();
3351
3352 GET_FPSCR(local_fpscr);
3353
3354 printf(" %016lx%016lx", vec_xt[1], vec_xt[0]);
3355 dissect_fpscr(local_fpscr);
3356 printf("\n");
3357 }
3358 }
3359 }
3360}
3361
3362#define vector_instruction_is_xvcvhpsp(instruction_name) \
3363 (strncmp(instruction_name, "xvcvhpsp", 8) == 0)
3364
3365static void testfunction_vector_scalar_two_double(const char* instruction_name,
3366 test_func_t test_function,
3367 unsigned int ignore_test_flags) {
3368 /* Notes:
3369 * iterate across double values stored in xa, xb.
3370 * Or, on half-word values in vec_xb.
3371 * Results are in vec_xt.
3372 */
3373 int i, j;
3374
3375 VERBOSE_FUNCTION_CALLOUT
3376
3377 for (i = 0; i < nb_float_vsxargs - 1; i += 2) {
3378 for (j = 0; j < nb_float_vsxargs - 1; j += 2) {
3379 /* vec_xb is only used by the convert instructions, the other callers
3380 * use the r14, r15 fields.
3381 * The 16-bit converts reference every other half-word in the vector.
3382 * For this reason, populate the input field with a cross-section of
3383 * values.
3384 */
3385 printf("%s ",instruction_name);
3386
3387 if (uses_half_precision_input(instruction_name)) {
3388 vec_xb = (vector unsigned long) {
3389 binary16_float_vsxargs[i] |
3390 binary16_float_vsxargs[j] << 16 |
3391 binary16_float_vsxargs[i+1] << 32 |
3392 binary16_float_vsxargs[j+1] << 48,
3393 binary16_float_vsxargs[(nb_float_vsxargs - 1) - j - 1 ] |
3394 binary16_float_vsxargs[(nb_float_vsxargs - 1) - i - 1] << 16 |
3395
3396 binary16_float_vsxargs[(nb_float_vsxargs - 1) - j ] << 32 |
3397 binary16_float_vsxargs[(nb_float_vsxargs - 1) - i ] << 48
3398 };
3399 printf(" vec_xb[1] = 0x%lx, vec_xb[0] = 0x%lx ",
3400 vec_xb[1], vec_xb[0]);
3401
3402 } else if (uses_single_precision_input(instruction_name)) {
3403 vec_xb = (vector unsigned long) {
3404 binary32_float_vsxargs[i] |
3405 binary32_float_vsxargs[i+1] << 32,
3406 binary32_float_vsxargs[nb_float_vsxargs - 1 - j ] |
3407 binary32_float_vsxargs[nb_float_vsxargs - 1 - j ] << 32
3408 };
3409 printf(" vec_xb[1] = 0x%lx, vec_xb[0] = 0x%lx ",
3410 vec_xb[1], vec_xb[0]);
3411
3412 } else { /* uses double */
3413 r14 = binary64_float_vsxargs[i];
3414 r15 = binary64_float_vsxargs[j];
3415 printf(" r14 = 0x%lx, r15 = 0x%lx ", r14, r15);
3416 }
3417
3418 vec_xt = (vector unsigned long){0, 0};
3419
3420 printf("%016lx %016lx ", vec_xb[1], vec_xb[0] );
3421
3422 if ((verbose > 2) && uses_double_precision_input(instruction_name)) {
3423 dissect_binary64_float(vec_xb[1]);
3424 dissect_binary64_float(vec_xb[0]);
3425 }
3426
3427 printf(" => ");
3428 SET_FPSCR_ZERO
3429
3430 (*test_function)();
3431
3432 GET_FPSCR(local_fpscr);
3433 printf(" %016lx %016lx", vec_xt[1], vec_xt[0]);
3434
3435 if ((verbose > 2) && uses_half_precision_output(instruction_name)) {
3436 dissect_double_as_16s(vec_xt[1]);
3437 dissect_double_as_16s(vec_xt[0]);
3438 }
3439
3440 /* The xvcvhpsp instruction does not set the C and FPCC fields */
3441 if (!vector_instruction_is_xvcvhpsp(instruction_name))
3442 dissect_fpscr(local_fpscr);
3443
3444 printf("\n");
3445 } // j
3446
3447 /* If we are doing half precision conversions, the i-loop can be
3448 * short-circuited to avoid duplicate input values. */
3449 if (unused_second_dword(instruction_name))
3450 i = nb_float_vsxargs+1;
3451 } // i
3452}
3453
3454static void testfunction_set_boolean (const char* instruction_name,
3455 test_func_t test_function,
3456 unsigned int ignore_test_flags)
3457{
3458 int cr_base_value;
3459 /* Notes:
3460 * Set RT to values 0, -1, 1 depending on what bits are set in the specified
3461 * CR field. x_index references here reflect the cr_field number.
3462 */
3463
3464 VERBOSE_FUNCTION_CALLOUT
3465
3466 for (x_index = 0; x_index <= 7; x_index++) {
3467 for (cr_base_value = 0; cr_base_value <= 8; cr_base_value++) {
3468 cr_value = (0x11111111 * cr_base_value)
3469 & (0xf << (4 * (7 - x_index))) ;
3470
3471 r14 = 0xa5a5a5a5c7c7c7c7;
3472
3473 printf("%s cr_field:%1x cr_value::%08x",
3474 instruction_name, x_index,cr_value);
3475 printf(" => ");
3476
3477 (*test_function)();
3478
3479 printf(" %016lx\n", r14);
3480 }
3481 }
3482}
3483
3484
3485static void testfunction_char_compare (const char* instruction_name,
3486 test_func_t test_function,
3487 unsigned int ignore_test_flags)
3488{
3489 /* Notes:
3490 * iterate through char values stored in RA, RB.
3491 * Results stored in cr field BF.
3492 */
3493 int i, j;
3494 int local_crf;
3495
3496 VERBOSE_FUNCTION_CALLOUT
3497
3498 for (x_index = 0; x_index <= 7; x_index++) {
3499 for (i = 0; i < nb_char_ranges; i += 4) {
3500 for (j = 0; j < nb_char_args; j++) {
3501 r14 = char_args[j];
3502
3503 /* For cmprb*, only needs the lower characters. */
3504 r15 = char_ranges[i] | (char_ranges[i+1] << 8) |
3505 char_ranges[i+2] << 16 | (char_ranges[i+3] << 24);
3506
3507 /* For cmpeqb, also load the rest of the range field, shift allk
3508 * chars up by one.
3509 */
3510 r15 |= (r15 + 0x01010101) << 32;
3511 printf("%s 0x%02lx (%c) (cmpeq:0x%016lx) (cmprb:src22(%c-%c) src21(%c-%c))",
3512 instruction_name,
3513 r14, (int)r14,
3514 r15, (int)(r15 & 0xff), (int)((r15 >> 8) & 0xff),
3515 (int)((r15 >> 16) & 0xff), (int)((r15 >> 24) & 0xff)
3516 );
3517
3518 printf(" =>");
3519
3520 (*test_function)();
3521
3522 GET_CR(local_cr);
3523 local_crf = extract_cr_rn(local_cr, x_index);
3524
3525 if (verbose)
3526 printf(" %s found or in range (%x)",
3527 (cr_positive_set(local_crf))?" " : " not", local_crf);
3528 else
3529 if (cr_positive_set(local_crf)) printf(" in range/found");
3530
3531 printf("\n");
3532 }
3533 }
3534 }
3535}
3536
3537#define instruction_uses_quads(instruction_name) (strncmp(instruction_name, "dtstsfiq", 8) == 0)
3538
3539static void testfunction_dfp_significance (const char* instruction_name,
3540 test_func_t test_function,
3541 unsigned int ignore_test_flags)
3542{
3543 int local_crf;
3544 int i;
3545 int num_dfp_vals;
3546
3547 VERBOSE_FUNCTION_CALLOUT
3548
3549 if (instruction_uses_quads(instruction_name)) {
3550 num_dfp_vals = nb_dfp128_vals;
3551 } else {
3552 num_dfp_vals = nb_dfp64_vals;
3553 }
3554
3555 for (i = 0; i < num_dfp_vals; i++) {
3556 if (instruction_uses_quads(instruction_name)) {
3557 dfp_value.u128.vall = dfp128_vals[i * 2];
3558 dfp_value.u128.valu = dfp128_vals[(i * 2) + 1];
3559
3560 } else {
3561 // could rework this to use u64.val, but...
3562 dfp_value.u128.vall = dfp128_vals[i ];
3563 dfp_value.u128.valu = dfp128_vals[i ];
3564 }
3565
3566 /* Keeping test simpler, always using cr3 within test_dtstsfi* */
3567 for (dfp_significance = 0; dfp_significance <= 63;) {
3568 /* Todo: tweak output here, or input values so the generated content
3569 * looks better.
3570 */
3571 printf("%s significance(0x%02x) ",
3572 instruction_name, dfp_significance);
3573
3574 if (instruction_uses_quads(instruction_name)) {
3575 dissect_dfp128_float(dfp_value.u128.vall, dfp_value.u128.valu);
3576
3577 if (verbose > 6)
3578 printf("(RAW) value = %16lx,%016lx ",
3579 dfp_value.u128.vall, dfp_value.u128.valu /*f14, f15 */);
3580
3581 } else {
3582 dissect_dfp64_float(dfp_value.u128.vall);
3583
3584 if (verbose > 6)
3585 printf("(RAW) value = %16lx ", dfp_value.u128.vall /*f14 */);
3586 }
3587
3588 (*test_function)();
3589
3590 GET_CR(local_cr);
3591
3592 local_crf = extract_cr_rn(local_cr, /* hardcoded cr3 */ 3);
3593 dissect_cr_rn(local_cr, /* hardcoded cr3 */ 3);
3594
3595 printf(" (%x)", local_crf);
3596 printf("\n");
3597
3598 /* Special case for incrementation of the significance checking
3599 * value.
3600 */
3601 if (dfp_significance < 8)
3602 dfp_significance += 4; /* 0, 4, 8 */
3603
3604 else if (dfp_significance < 32)
3605 dfp_significance += 8; /* 16, 24, 32 */
3606
3607 else if (dfp_significance < 48)
3608 dfp_significance += 16; /* 48 */
3609
3610 else
3611 dfp_significance += 15; /* 63 */
3612 }
3613 }
3614}
3615
3616/* packed binary decimal misc */
3617
3618#define convert_tofrom_instruction(instruction_name) \
3619 ( (strncmp(instruction_name, "bcdcf", 5) == 0) || \
3620 (strncmp(instruction_name, "bcdct", 5) == 0) )
3621
3622static void testfunction_bcd_misc (const char* instruction_name,
3623 test_func_t test_function,
3624 unsigned int ignore_test_flags)
3625{
3626 int i, j;
3627 int local_crf;
3628 long max_xa_entries = 0;
3629 long max_xb_entries = 0;
3630
3631 VERBOSE_FUNCTION_CALLOUT
3632
3633 shift_or_truncate_instruction = shift_or_truncate(instruction_name);
3634
3635 max_xa_entries = MAX(max_xa_entries, nb_decimal_shift_entries);
3636 max_xa_entries = MAX(max_xa_entries, nb_packed_decimal_entries);
3637
3638 max_xb_entries = MAX(max_xb_entries, nb_zoned_decimal_entries);
3639 max_xb_entries = MAX(max_xb_entries, nb_national_decimal_entries);
3640 max_xb_entries = MAX(max_xb_entries, nb_packed_decimal_entries);
3641
3642 for (i = 0; i < (max_xa_entries - 1); i += 2) {
3643 for (j = 0; j < (max_xb_entries - 1); j += 2) {
3644 testfunction_bcd_setup_inputs(instruction_name, i, j);
3645
3646 if (short_circuit) continue;
3647
3648 printf("%s ", instruction_name);
3649 printf("xa:%016lx %016lx ", vec_xa[0], vec_xa[1]);
3650
3651 if (!shift_or_truncate_instruction)
3652 dissect_packed_decimal_sign(xa_sign);
3653
3654 printf(" xb:%016lx %016lx ", vec_xb[0], vec_xb[1]);
3655
3656 if (convert_from_zoned(instruction_name)) {
3657 /* convert from zoned */
3658 dissect_zoned_decimal_sign(xb_sign, p_value(instruction_name));
3659
3660 } else if (convert_from_national(instruction_name)) {
3661 /* convert from national */
3662 dissect_national_decimal_sign(xb_sign);
3663
3664 } else {
3665 /* packed decimal entries */
3666 if (!shift_or_truncate_instruction)
3667 dissect_packed_decimal_sign(xb_sign);
3668 }
3669
3670 printf(" => ");
3671 SET_CR_ZERO
3672
3673 (*test_function)();
3674
3675 GET_CR(local_cr);
3676
3677 /* note: the bcd instructions are hard wired to use cr6. */
3678 local_crf = extract_cr_rn(local_cr, 6);
3679 dissect_cr_rn(local_cr, 6);
3680 printf(" (%x)", local_crf);
3681
3682 if (cr_overflow_set(local_crf)) {
3683 /* If overflow (S0) is set the results are undefined. Force the
3684 * output to print as zeros so we have consistent results for
3685 * comparison.
3686 */
3687 printf(" xt:%016lx %016lx", 0UL, 0UL);
3688
3689 } else {
3690 testfunction_bcd_display_outputs(instruction_name);
3691 }
3692
3693 printf("\n");
3694 } // j = xb loop.
3695
3696 /* Since the bcdct* convert_tofrom instructions do not use the xa
3697 * field, we will short-circuit the xa (i=*) loop here.
3698 */
3699 if (convert_tofrom_instruction(instruction_name))
3700 i = nb_packed_decimal_entries;
3701 } //i = xa loop.
3702}
3703
3704
3705static void testfunction_noop_misc (const char* instruction_name,
3706 test_func_t test_function,
3707 unsigned int ignore_test_flags)
3708{
3709 VERBOSE_FUNCTION_CALLOUT
3710
3711 printf("%s ", instruction_name);
3712 printf(" =>");
3713
3714 (*test_function)();
3715
3716 printf("\n");
3717}
3718
3719static void testfunction_pc_immediate_misc (const char* instruction_name,
3720 test_func_t test_function,
3721 unsigned int ignore_test_flags)
3722{
3723 VERBOSE_FUNCTION_CALLOUT
3724
3725 for (x_index = 0; x_index < 16; x_index++) {
3726 printf("%s ", instruction_name);
3727 printf(" %016x ", x_index);
3728 printf(" => ");
3729 (*test_function)();
Elliott Hughesed398002017-06-21 14:41:24 -07003730 /* printf(" %016lx\n", r14); */
3731 printf(" %016x\n", 0); /* test is not portable just print zero */
3732 }
3733}
3734
3735/* Identify those mffs* variants that take additional arguments.
3736 * This includes the immediate mffs*i variants. */
3737#define is_not_simple_mffs_instruction(instruction_name) \
3738 ( (strncmp(instruction_name,"mffscdrn",8)==0) || \
3739 (strncmp(instruction_name,"mffscrn",7)==0) )
3740
3741/* Because some of the mffs* variants here are updating the fpscr as part
3742 * of the read, be sure to dissect both the retrieved (f14) and the updated
3743 * (local_fpscr) fpscr values. */
3744static void testfunction_mffs(const char* instruction_name,
3745 test_func_t test_function,
3746 unsigned int ignore_test_flags)
3747{
3748 union reg_t {
3749 unsigned long int uli;
3750 double dble;
3751 } f14_reg, f15_reg;
3752
3753 /*This function uses global variable x_shift */
3754 VERBOSE_FUNCTION_CALLOUT
3755
3756 if (is_not_simple_mffs_instruction(instruction_name)) {
3757 /* iterate x_shift across values used for RN,RM */
3758 for (x_shift = 0; x_shift < 3; x_shift++) {
3759 printf("%s ", instruction_name);
3760 /* make sure bits in f14 get cleared so we can
3761 see correct resulg*/
3762 f14_reg.uli = 0x3FFFFFFFFUL;
3763
3764 if (strcmp("mffscdrn", instruction_name) == 0) {
3765 /* instruction uses input reg f15 as input for DRN field */
3766 f15_reg.uli = (unsigned long int)x_shift << 32;
3767 printf(" f15 0X%lx ", f15_reg.uli);
3768
3769 /* Setup input register value */
3770 f15 = f15_reg.dble;
3771
3772 } else if (strcmp("mffscrn", instruction_name) == 0) {
3773 /* instruction uses input reg f15 as input for RN field */
3774 f15_reg.uli = (unsigned long int)x_shift;
3775 printf(" f15 0X%lx ", f15_reg.uli);
3776
3777 /* Setup input register value */
3778 f15 = f15_reg.dble;
3779
3780 } else {
3781 printf(" %x ", x_shift);
3782 }
3783
3784
3785 (*test_function)();
3786 printf(" => ");
3787 f14_reg.dble = f14;
3788 printf(" 0X%lx\n", f14_reg.uli);
3789 printf(" fpscr: f14 ");
3790 dissect_fpscr(f14);
3791 printf(" local_fpscr: ");
3792 dissect_fpscr(local_fpscr);
3793 printf("\n");
3794 }
3795 } else {
3796 printf("%s ", instruction_name);
3797 printf(" => ");
3798 (*test_function)();
3799 printf(" %016f\n", f14);
3800 printf(" fpscr: f14 ");
3801 dissect_fpscr(f14);
3802 printf("\n");
3803 printf(" local_fpscr: ");
3804 dissect_fpscr(local_fpscr);
3805 printf("\n");
Elliott Hughesa0664b92017-04-18 17:46:52 -07003806 }
3807}
3808
3809/* ######## begin grand testing loops. */
3810typedef struct insn_sel_flags_t_struct {
3811 unsigned int one_arg, two_args, three_args, four_args, cmp_args, ld_args, st_args,
3812 one_imed_args;
3813 unsigned int arith, logical, compare, popcnt, ldst, insert_extract, permute, round;
Elliott Hughesed398002017-06-21 14:41:24 -07003814 unsigned int integer, altivec, altivec_quad, altivec_double, dfp, bcd, misc, mffs,
Elliott Hughesa0664b92017-04-18 17:46:52 -07003815 no_op, pc_immediate;
3816 unsigned int cr;
3817} insn_sel_flags_t;
3818
3819static void do_tests ( insn_sel_flags_t seln_flags)
3820{
3821 test_group_t group_function;
3822 test_list_t *tests;
3823 unsigned int nb_args, type, family;
3824 int i, j, n;
3825
3826 n = 0;
3827 group_function = NULL;
3828
3829 /* self-test of some utility functions. */
3830 if (verbose > 1) {
3831 printf("fpscr zero'd out:");
3832 dissect_fpscr(0);
3833 printf("\n");
3834 printf("fpscr all ones:");
3835 dissect_fpscr(0xffffffffffffffff);
3836 printf("\n");
3837 printf("fpscr RN bits:");
3838 dissect_fpscr_rounding_mode(0x0000000000000003);
3839 dissect_fpscr_rounding_mode(0x0000000000000002);
3840 dissect_fpscr_rounding_mode(0x0000000000000001);
3841 dissect_fpscr_rounding_mode(0x0000000000000000);
3842 printf("\n");
Elliott Hughesed398002017-06-21 14:41:24 -07003843 printf("XER bits: (64)");
3844 dissect_xer(0xffffffffffffffff);
3845 printf("\n");
3846 printf("XER bits: (32)");
3847 dissect_xer(0xffffffff);
3848 printf("\n\n");
Elliott Hughesa0664b92017-04-18 17:46:52 -07003849 }
3850
3851 for (i=0; all_tests[i].name != NULL; i++) {
3852 nb_args = all_tests[i].flags & PPC_NB_ARGS_MASK;
3853 /* Check number of arguments */
3854 if ((nb_args == 1 && !seln_flags.one_arg) ||
3855 (nb_args == 2 && !seln_flags.two_args) ||
3856 (nb_args == 3 && !seln_flags.three_args) ||
3857 (nb_args == 4 && !seln_flags.four_args) ||
3858 (nb_args == 5 && !seln_flags.cmp_args) ||
3859 (nb_args == 6 && !seln_flags.ld_args) ||
3860 (nb_args == 7 && !seln_flags.st_args) ||
3861 (nb_args == 8 && !seln_flags.one_imed_args))
3862 continue;
3863
3864 /* Check instruction type */
3865 type = all_tests[i].flags & PPC_TYPE_MASK;
3866 if ((type == PPC_ARITH && !seln_flags.arith) ||
3867 (type == PPC_LDST && !seln_flags.ldst) ||
3868 (type == PPC_LOGICAL && !seln_flags.logical) ||
3869 (type == PPC_COMPARE && !seln_flags.compare) ||
3870 (type == PPC_POPCNT && !seln_flags.compare) ||
3871 (type == PPC_INSERTEXTRACT && !seln_flags.insert_extract))
3872 continue;
3873
3874 /* Check instruction family */
3875 family = all_tests[i].flags & PPC_FAMILY_MASK;
3876
3877 /* do each check each case individually to reduce computation */
3878 if (family == PPC_INTEGER && seln_flags.integer == 0) continue;
3879 if (family == PPC_ALTIVEC && seln_flags.altivec == 0) continue;
3880 if (family == PPC_DFP && seln_flags.dfp == 0) continue;
3881 if (family == PPC_BCD && seln_flags.bcd == 0) continue;
3882 if (family == PPC_NO_OP && seln_flags.no_op == 0) continue;
3883 if (family == PPC_MISC && seln_flags.misc == 0) continue;
Elliott Hughesed398002017-06-21 14:41:24 -07003884 if (family == PPC_MFFS && seln_flags.mffs == 0) continue;
Elliott Hughesa0664b92017-04-18 17:46:52 -07003885 if (family == PPC_ALTIVEC_DOUBLE && seln_flags.altivec_double == 0)
3886 continue;
3887
3888 if (family == PPC_ALTIVEC_QUAD && seln_flags.altivec_quad == 0)
3889 continue;
3890
3891 if (family == PPC_PC_IMMEDIATE && seln_flags.pc_immediate == 0)
3892 continue;
3893
3894 /* Check flags update */
3895 if (((all_tests[i].flags & PPC_CR) && seln_flags.cr == 0) ||
3896 (!(all_tests[i].flags & PPC_CR) && seln_flags.cr == 1))
3897 continue;
3898
3899 /* All criteria validation passed, do the tests */
3900 tests = all_tests[i].tests;
3901
3902 /* Select the test group */
3903 switch (family) {
Elliott Hughesed398002017-06-21 14:41:24 -07003904 case PPC_MFFS:
3905 group_function = &testfunction_mffs;
3906 break;
3907
Elliott Hughesa0664b92017-04-18 17:46:52 -07003908 case PPC_INTEGER:
3909 switch(type) {
3910 case PPC_ARITH:
3911 switch(nb_args) {
3912 case PPC_TWO_ARGS:
3913 group_function = &testfunction_int_two_args;
3914 break;
3915
3916 case PPC_THREE_ARGS:
3917 group_function = &testfunction_three_args;
3918 break;
3919
3920 default:
3921 printf("ERROR: PPC_INTEGER, unhandled number of arguments. 0x%08x\n",
3922 nb_args);
3923 }
3924 break;
3925
3926 case PPC_LOGICAL:
3927 switch(nb_args) {
3928 case PPC_ONE_IMM:
3929 group_function = &testfunction_set_boolean;
3930 break;
3931
3932 case PPC_ONE_ARG:
3933 group_function = &testfunction_logical_one;
3934 break;
3935
3936 default:
3937 printf("ERROR: PPC_LOGICAL, unhandled number of arguments. 0x%08x\n",
3938 nb_args);
3939 }
3940 break;
3941
3942 case PPC_COMPARE:
3943 group_function = &testfunction_char_compare;
3944 break;
3945
3946 default:
3947 printf("ERROR: PPC_INTEGER, unhandled type 0x%08x\n", type);
3948 continue;
3949 } /* switch (type) */
3950 break;
3951
3952 case PPC_ALTIVEC:
3953 switch(type) {
3954 case PPC_ARITH:
3955 switch(nb_args) {
3956 case PPC_TWO_ARGS:
3957 group_function = &testfunction_vector_absolute;
3958
3959 break;
3960 default:
3961 printf("ERROR: PPC_ALTIVEC, PPC_ARITH, unhandled number of arguments. 0x%08x\n", nb_args);
3962 continue;
3963 } /* switch (PPC_ARITH, nb_args) */
3964 break;
3965
3966 case PPC_LOGICAL:
3967 switch(nb_args) {
3968 case PPC_ONE_IMM:
3969 group_function = &testfunction_vector_immediate;
3970 break;
3971
3972 case PPC_ONE_ARG:
3973 group_function = &testfunction_vector_logical_one;
3974 break;
3975
3976 case PPC_TWO_ARGS:
3977 group_function = &testfunction_vector_extend_sign;
3978 break;
3979
3980 case PPC_THREE_ARGS:
3981 group_function = &testfunction_vector_three_special;
3982 break;
3983
3984 case PPC_FOUR_ARGS:
3985 group_function = &testfunction_vector_logical_four;
3986 break;
3987
3988 default:
3989 printf("ERROR: PPC_ALTIVEC, PPC_LOGICAL, unhandled number of arguments. 0x%08x\n", nb_args);
3990 continue;
3991 } /* switch(PPC_INSERTEXTRACT, nb_args) */
3992 break;
3993
3994 case PPC_INSERTEXTRACT:
3995 switch(nb_args) {
3996 case PPC_ONE_IMM:
3997 group_function = &testfunction_vector_insert_or_extract_immediate;
3998 break;
3999
4000 case PPC_TWO_ARGS:
4001 group_function = testfunction_vector_extract;
4002 break;
4003
4004 default:
4005 printf("ERROR: PPC_ALTIVEC, PPC_INSERTEXTRACT, unhandled number of arguments. 0x%08x\n", nb_args);
4006 continue;
4007 } /* switch(PPC_INSERTEXTRACT, nb_args) */
4008 break;
4009
4010 case PPC_PERMUTE:
4011 group_function = &testfunction_vector_xxpermute;
4012 break;
4013
4014 case PPC_LDST:
4015 switch(nb_args) {
4016 case PPC_ONE_IMM:
4017 /* Register holds immediate length value */
4018 group_function = &testfunction_vector_scalar_loadstore_length;
4019 break;
4020
4021 case PPC_TWO_ARGS:
4022 /* Register holds address of buffer */
4023 group_function = &testfunction_vector_loadstore;
4024 break;
4025
4026 default:
4027 printf("ERROR: PPC_ALTIVEC, PPC_LDST, unhandled number of arguments. 0x%08x\n", nb_args);
4028 continue;
4029 } /* switch(PPC_LDST, nb_args) */
4030 break;
4031
4032 case PPC_POPCNT:
4033 group_function = &testfunction_vector_count_bytes;
4034 break;
4035
4036 default:
4037 printf("ERROR: PPC_ALTIVEC, unhandled type. %d\n", type);
4038 continue;
4039 } /* switch (PPC_ALTIVEC, type) */
4040 break;
4041
4042 case PPC_MISC:
4043 switch(nb_args) {
4044 case PPC_TWO_ARGS:
4045 group_function = &testfunction_vectorscalar_move_tofrom;
4046 break;
4047 case PPC_THREE_ARGS:
4048 group_function = &testfunction_one_arg_with_shift;
4049 break;
4050 default:
4051 printf("ERROR: PPC_MISC, unhandled number of arguments. 0x%08x\n", nb_args);
4052 continue;
4053 } /* switch(PPC_MISC, nb_args) */
4054 break;
4055
4056 case PPC_ALTIVEC_QUAD:
4057 switch(type) {
4058 case PPC_LOGICAL:
4059 switch(nb_args) {
4060 case PPC_TWO_ARGS:
4061 group_function = &testfunction_vector_scalar_two_quad;
4062 break;
4063
4064 default:
4065 printf("ERROR: PPC_ALTIVEC_QUAD, PPC_LOGICAL, unhandled number of arguments. 0x%08x\n", nb_args);
4066 continue;
4067 } /* switch(PPC_LOGICAL, nb_args) */
4068 break;
4069
4070 case PPC_COMPARE:
4071 group_function = &testfunction_vector_scalar_compare_quads;
4072 break;
4073
4074 case PPC_ROUND:
4075 group_function = &testfunction_vector_scalar_rounding_quads;
4076 break;
4077
4078 default:
4079 printf("ERROR: PPC_ALTIVEC_QUAD, unhandled type. %d\n", type);
4080 continue;
4081 } /* switch(type) */
4082 break;
4083
4084 case PPC_ALTIVEC_DOUBLE:
4085 switch(type) {
4086 case PPC_COMPARE:
4087 switch(nb_args) {
4088 case PPC_ONE_ARG:
4089 group_function = &testfunction_vector_scalar_data_class;
4090 break;
4091
4092 case PPC_TWO_ARGS:
4093 group_function = &testfunction_vector_scalar_two_double;
4094 break;
4095
4096 case PPC_COMPARE_ARGS:
4097 group_function = &testfunction_vector_scalar_compare_exp_double;
4098 break;
4099
4100 default:
4101 printf("ERROR: PPC_ALTIVEC_DOUBLE, PPC_COMPARE, unhandled number of arguments. 0x%08x\n", nb_args);
4102 continue;
4103 } /* switch(PPC_COMPARE, nb_args) */
4104 break;
4105
4106 default:
4107 printf("ERROR: PPC_ALTIVEC_DOUBLE, unhandled type. %d\n", type);
4108 continue;
4109
4110 } /* switch(type) */
4111 break;
4112
4113 case PPC_DFP:
4114 group_function = &testfunction_dfp_significance;
4115 break;
4116
4117 case PPC_BCD:
4118 group_function = &testfunction_bcd_misc;
4119 break;
4120
4121 case PPC_NO_OP:
4122 group_function = &testfunction_noop_misc;
4123 break;
4124
4125 case PPC_PC_IMMEDIATE:
4126 group_function = &testfunction_pc_immediate_misc;
4127 break;
4128
4129 default:
4130 printf("ERROR: unknown instruction family %08x\n", family);
4131 continue;
4132 } /* switch(family) */
4133
4134 printf("%s:\n", all_tests[i].name);
4135
4136 printf("Test instruction group [%s]\n", all_tests[i].name);
4137 /* Now, spin through all entries in the group_function to
4138 * run the individual instruction tests.
4139 */
4140 for (j = 0; tests[j].name != NULL; j++) {
4141 if (verbose > 1)
4142 printf("Test instruction %s\n", tests[j].name);
4143 (*group_function)(tests[j].name, tests[j].func, all_tests[i].flags);
4144 printf("\n");
4145 n++;
4146 }
4147
4148 if (verbose) printf("\n");
4149
4150 printf("All done. Tested %d different instructions\n", n);
4151 } /* for (i = 0; all_tests[i].name...) */
4152}
4153
4154static void usage (void)
4155{
4156 fprintf(stderr,
4157 "Usage: test_isa_3_0 [OPTIONS]\n"
4158 "\t-i: test integer instructions (default)\n"
4159 "\t-a: test altivec instructions\n"
4160 "\t-d: test altivec double instructions\n"
4161 "\t-q: test altivec quad instructions\n"
4162 "\t-D: test DFP instructions\n"
4163 "\t-B: test BCD instructions\n"
4164 "\t-N: test No Op instructions\n"
4165 "\t-P: test PC Immediate Shifted instructions\n"
4166 "\t-m: test miscellaneous instructions\n"
Elliott Hughesed398002017-06-21 14:41:24 -07004167 "\t-M: test MFFS instructions\n"
Elliott Hughesa0664b92017-04-18 17:46:52 -07004168 "\t-v: be verbose\n"
4169 "\t-h: display this help and exit\n"
4170 );
4171}
4172
4173#endif // HAS_ISA_3_00
4174int main (int argc, char **argv)
4175{
4176
4177#ifndef HAS_ISA_3_00
4178 printf("NO ISA 3.00 SUPPORT\n");
4179 return 0;
4180
4181#else
4182 insn_sel_flags_t flags;
4183 int c;
4184
4185
4186 // Args
4187 flags.one_arg = 1;
4188 flags.two_args = 1;
4189 flags.three_args = 1;
4190 flags.four_args = 1;
4191 flags.cmp_args = 1;
4192 flags.ld_args = 1;
4193 flags.st_args = 1;
4194 flags.one_imed_args = 1;
4195
4196 // Type
4197 flags.arith = 1;
4198 flags.logical = 1;
4199 flags.compare = 1;
4200 flags.ldst = 1;
4201 flags.popcnt = 1;
4202 flags.insert_extract = 1;
4203 flags.permute = 1;
4204 flags.round = 1;
4205
4206 // Family
4207 flags.integer = 0;
4208 flags.altivec = 0;
4209 flags.altivec_double = 0;
4210 flags.altivec_quad = 0;
4211 flags.dfp = 0;
4212 flags.bcd = 0;
4213 flags.misc = 0;
Elliott Hughesed398002017-06-21 14:41:24 -07004214 flags.mffs = 0;
Elliott Hughesa0664b92017-04-18 17:46:52 -07004215 flags.no_op = 0;
4216 flags.pc_immediate = 0;
4217
4218 // Flags
4219 flags.cr = 2;
4220
Elliott Hughesed398002017-06-21 14:41:24 -07004221 while ((c = getopt(argc, argv, "ifmadqhvADBMNP")) != -1) {
Elliott Hughesa0664b92017-04-18 17:46:52 -07004222 switch (c) {
4223 case 'i':
4224 flags.integer = 1;
4225 break;
4226
4227 case 'a':
4228 flags.altivec = 1;
4229 break;
4230
4231 case 'd':
4232 flags.altivec_double = 1;
4233 break;
4234
4235 case 'q':
4236 flags.altivec_quad = 1;
4237 break;
4238
4239 case 'D':
4240 flags.dfp = 1;
4241 break;
4242
4243 case 'B':
4244 flags.bcd = 1;
4245 break;
4246
4247 case 'm':
4248 flags.misc = 1;
4249 break;
4250
Elliott Hughesed398002017-06-21 14:41:24 -07004251 case 'M':
4252 flags.mffs = 1;
4253 break;
4254
Elliott Hughesa0664b92017-04-18 17:46:52 -07004255 case 'N':
4256 flags.no_op = 1;
4257 break;
4258
4259 case 'P':
4260 flags.pc_immediate = 1;
4261 break;
4262
4263 case 'h':
4264 usage();
4265 return 0;
4266
4267 case 'v':
4268 verbose++;
4269 break;
4270
4271 default:
4272 usage();
4273 fprintf(stderr, "Unknown argument: '%c'\n", c);
4274 return 1;
4275 }
4276 }
4277
4278 build_iargs_table();
4279 build_vsx_table();
4280 build_float_vsx_tables();
4281 build_vector_permute_table();
4282 build_char_table();
4283 build_char_range_table();
4284 build_packed_decimal_table();
4285 build_national_decimal_table();
4286 build_zoned_decimal_table();
4287 build_decimal_shift_table();
4288
4289 if (verbose>2) {
4290 dump_char_table();
4291 dump_char_range_table();
4292 dump_float_vsx_table();
4293 dump_packed_decimal_table();
4294 dump_national_decimal_table();
4295 dump_zoned_decimal_table();
4296 dump_decimal_shift_table();
4297 dump_dfp64_table();
4298 dump_dfp128_table();
4299 }
4300
4301 if (verbose > 1) {
4302 printf("\nInstruction Selection:\n");
4303 printf(" n_args: \n");
4304 printf(" one_arg = %d\n", flags.one_arg);
4305 printf(" two_args = %d\n", flags.two_args);
4306 printf(" three_args = %d\n", flags.three_args);
4307 printf(" four_args = %d\n", flags.four_args);
4308 printf(" cmp_args = %d\n", flags.cmp_args);
4309 printf(" load_args = %d\n", flags.ld_args);
4310 printf(" store_args = %d\n", flags.st_args);
4311 printf(" one_im_args = %d\n", flags.one_imed_args);
4312 printf(" type: \n");
4313 printf(" arith = %d\n", flags.arith);
4314 printf(" logical = %d\n", flags.logical);
4315 printf(" popcnt = %d\n", flags.popcnt);
4316 printf(" compare = %d\n", flags.compare);
4317 printf(" inset/extract = %d\n", flags.insert_extract);
4318 printf(" family: \n");
4319 printf(" integer = %d\n", flags.integer);
4320 printf(" altivec = %d\n", flags.altivec);
4321 printf(" altivec double = %d\n", flags.altivec_double);
4322 printf(" altivec quad = %d\n", flags.altivec_quad);
4323 printf(" DFP = %d\n", flags.dfp);
4324 printf(" BCD = %d\n", flags.bcd);
4325 printf(" PC immediate shifted = %d\n", flags.pc_immediate);
4326 printf(" misc = %d\n", flags.misc);
4327 printf(" cr update: \n");
4328 printf(" cr = %d\n", flags.cr);
4329 printf("\n");
4330 printf(" num args: \n");
4331 printf(" iargs - %d\n", nb_iargs);
4332 printf("\n");
4333 }
4334
4335 do_tests( flags );
4336#endif
4337
4338 return 0;
4339}