2 * Valgrind testcase for PowerPC ISA 3.1
4 * Copyright (C) 2019-2020 Will Schmidt <will_schmidt@vnet.ibm.com>
7 * gcc -Winline -Wall -g -O -mregnames -maltivec -m64
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; either version 2 of the
14 * License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
40 /* Condition Register fields.
41 These are used to capture the condition register values immediately after
42 the instruction under test is executed. This is done to help prevent other
43 test overhead (switch statements, result compares, etc) from disturbing
44 the test case results. */
45 unsigned long current_cr
;
46 unsigned long current_fpscr
;
48 struct test_list_t current_test
;
50 #include "isa_3_1_helpers.h"
52 static void test_pstxvp_off0_R1 (void) {
53 __asm__
__volatile__ ("pstxvp 20, -0x1f400+0(0),1");
55 static void test_pstxvp_off16_R1 (void) {
56 __asm__
__volatile__ ("pstxvp 20, -0x1f400+16(0),1");
58 static void test_pstxvp_off32_R1 (void) {
59 __asm__
__volatile__ ("pstxvp 20, -0x1f400+32(0),1");
61 static void test_pstxvp_off48_R1 (void) {
62 __asm__
__volatile__ ("pstxvp 20, -0x1f400+48(0),1");
64 static void test_plfd_64_R1 (void) {
65 __asm__
__volatile__ ("plfd 28, +64(0), 1");
69 static void test_plfd_32_R1 (void) {
70 __asm__
__volatile__ ("plfd 28, +32(0), 1");
73 static void test_plfd_16_R1 (void) {
74 __asm__
__volatile__ ("plfd 28, +16(0), 1");
77 static void test_plfd_8_R1 (void) {
78 __asm__
__volatile__ ("plfd 28, +8(0), 1");
81 static void test_plfd_4_R1 (void) {
82 __asm__
__volatile__ ("plfd 28, +4(0), 1");
85 static void test_plfd_0_R1 (void) {
86 __asm__
__volatile__ ("plfd 28, +0(0), 1");
89 static void test_plfs_64_R1 (void) {
90 __asm__
__volatile__ ("plfs 28, +64(0), 1");
94 static void test_plfs_32_R1 (void) {
95 __asm__
__volatile__ ("plfs 28, +32(0), 1");
98 static void test_plfs_16_R1 (void) {
99 __asm__
__volatile__ ("plfs 28, +16(0), 1");
102 static void test_plfs_8_R1 (void) {
103 __asm__
__volatile__ ("plfs 28, +8(0), 1");
106 static void test_plfs_4_R1 (void) {
107 __asm__
__volatile__ ("plfs 28, +4(0), 1");
110 static void test_plfs_0_R1 (void) {
111 __asm__
__volatile__ ("plfs 28, +0(0), 1");
114 static void test_pstfd_32_R1 (void) {
115 __asm__
__volatile__ ("pstfd 26, -0x1f400+32(0), 1");
117 static void test_pstfd_16_R1 (void) {
118 __asm__
__volatile__ ("pstfd 26, -0x1f400+16(0), 1");
120 static void test_pstfd_8_R1 (void) {
121 __asm__
__volatile__ ("pstfd 26, -0x1f400+8(0), 1");
123 static void test_pstfd_4_R1 (void) {
124 __asm__
__volatile__ ("pstfd 26, -0x1f400+4(0), 1");
126 static void test_pstfd_0_R1 (void) {
127 __asm__
__volatile__ ("pstfd 26, -0x1f400+0(0), 1");
129 static void test_pstfs_32_R1 (void) {
130 __asm__
__volatile__ ("pstfs 26, -0x1f400+32(0), 1");
132 static void test_pstfs_16_R1 (void) {
133 __asm__
__volatile__ ("pstfs 26, -0x1f400+16(0), 1");
135 static void test_pstfs_8_R1 (void) {
136 __asm__
__volatile__ ("pstfs 26, -0x1f400+8(0), 1");
138 static void test_pstfs_4_R1 (void) {
139 __asm__
__volatile__ ("pstfs 26, -0x1f400+4(0), 1");
141 static void test_pstfs_0_R1 (void) {
142 __asm__
__volatile__ ("pstfs 26, -0x1f400+0(0), 1");
144 static void test_plxsd_64_R1 (void) {
145 __asm__
__volatile__ ("plxsd %0, +64(0), 1" : "=v" (vrt
) );
149 static void test_plxsd_32_R1 (void) {
150 __asm__
__volatile__ (".align 2 ; plxsd %0, +32(0), 1" : "=v" (vrt
) );
153 static void test_plxsd_16_R1 (void) {
154 __asm__
__volatile__ ("plxsd %0, +16(0), 1; pnop;pnop;pnop; " : "=v" (vrt
) );
157 static void test_plxsd_8_R1 (void) {
158 __asm__
__volatile__ ("plxsd %0, +8(0), 1; pnop;pnop;pnop; " : "=v" (vrt
) );
161 static void test_plxsd_4_R1 (void) {
162 __asm__
__volatile__ ("plxsd %0, +4(0), 1; pnop;pnop;pnop; " : "=v" (vrt
) );
165 static void test_plxsd_0_R1 (void) {
166 __asm__
__volatile__ ("plxsd %0, +0(0), 1; pnop;pnop;pnop; " : "=v" (vrt
) );
169 static void test_plxssp_64_R1 (void) {
170 __asm__
__volatile__ ("plxssp %0, +64(0), 1; pnop;pnop;pnop; " : "=v" (vrt
) );
174 static void test_plxssp_32_R1 (void) {
175 __asm__
__volatile__ ("plxssp %0, +32(0), 1; pnop; " : "=v" (vrt
) );
178 static void test_plxssp_16_R1 (void) {
179 __asm__
__volatile__ ("plxssp %0, +16(0), 1; pnop;pnop;pnop; " : "=v" (vrt
) );
182 static void test_plxssp_8_R1 (void) {
183 __asm__
__volatile__ ("plxssp %0, +8(0), 1; pnop;pnop;pnop; " : "=v" (vrt
) );
186 static void test_plxssp_4_R1 (void) {
187 __asm__
__volatile__ ("plxssp %0, +4(0), 1; pnop;pnop;pnop; " : "=v" (vrt
) );
190 static void test_plxssp_0_R1 (void) {
191 __asm__
__volatile__ ("plxssp %0, +0(0), 1; pnop;pnop;pnop; " : "=v" (vrt
) );
194 /* Follow the short-range plxv instructions with nop in order to
195 pad out subsequent instructions. When written there are found
196 to be fluctuations in the instructions to store the result back
197 into the target variable. (pla,pstxv...).
199 static void test_plxv_16_R1 (void) {
200 __asm__
__volatile__ ("plxv %x0, +16(0), 1; pnop;pnop;pnop;" : "=wa" (vec_xt
) );
203 static void test_plxv_8_R1 (void) {
204 __asm__
__volatile__ ("plxv %x0, +8(0), 1; pnop;pnop;pnop;" : "=wa" (vec_xt
) );
207 static void test_plxv_4_R1 (void) {
208 __asm__
__volatile__ ("plxv %x0, +4(0), 1; pnop;pnop;pnop;" : "=wa" (vec_xt
) );
211 static void test_plxv_0_R1 (void) {
212 __asm__
__volatile__ ("plxv %x0, +0(0), 1; pnop;pnop;pnop; " : "=wa" (vec_xt
) );
215 static void test_pstxsd_64_R1 (void) {
216 __asm__
__volatile__ (".align 2 ; pstxsd 22, -0x1f400+64(0), 1" );
218 static void test_pstxsd_32_R1 (void) {
219 __asm__
__volatile__ (".align 2 ; pstxsd 22, -0x1f400+32(0), 1" );
221 static void test_pstxsd_16_R1 (void) {
222 __asm__
__volatile__ (".align 2 ; pstxsd 22, -0x1f400+16(0), 1" );
224 static void test_pstxsd_8_R1 (void) {
225 __asm__
__volatile__ (".align 2 ; pstxsd 22, -0x1f400+8(0), 1" );
227 static void test_pstxsd_4_R1 (void) {
228 __asm__
__volatile__ (".align 2 ; pstxsd 22, -0x1f400+4(0), 1" );
230 static void test_pstxsd_0_R1 (void) {
231 __asm__
__volatile__ (".align 2 ; pstxsd 22, -0x1f400+0(0), 1" );
233 static void test_pstxssp_64_R1 (void) {
234 __asm__
__volatile__ ("pstxssp 22, -0x1f400+64(0), 1" );
236 static void test_pstxssp_32_R1 (void) {
237 __asm__
__volatile__ ("pstxssp 22, -0x1f400+32(0), 1");
239 static void test_pstxssp_16_R1 (void) {
240 __asm__
__volatile__ ("pstxssp 22, -0x1f400+16(0), 1");
242 static void test_pstxssp_8_R1 (void) {
243 __asm__
__volatile__ ("pstxssp 22, -0x1f400+8(0), 1");
245 static void test_pstxssp_4_R1 (void) {
246 __asm__
__volatile__ ("pstxssp 22, -0x1f400+4(0), 1");
248 static void test_pstxssp_0_R1 (void) {
249 __asm__
__volatile__ ("pstxssp 22, -0x1f400+0(0), 1");
251 static void test_pstxv_16_R1 (void) {
252 __asm__
__volatile__ ("pstxv %x0, -0x1f400+16(0), 1" :: "wa" (vec_xs
));
254 static void test_pstxv_8_R1 (void) {
255 __asm__
__volatile__ ("pstxv %x0, -0x1f400+8(0), 1" :: "wa" (vec_xs
));
257 static void test_pstxv_4_R1 (void) {
258 __asm__
__volatile__ ("pstxv %x0, -0x1f400+4(0), 1" :: "wa" (vec_xs
));
260 static void test_pstxv_0_R1 (void) {
261 __asm__
__volatile__ ("pstxv %x0, -0x1f400+0(0), 1" :: "wa" (vec_xs
));
264 static test_list_t testgroup_generic
[] = {
265 { &test_plfd_0_R1
, "plfd 0_R1", "FRT,D(RA),R"}, /* bcwp */
266 { &test_plfd_4_R1
, "plfd 4_R1", "FRT,D(RA),R"}, /* bcwp */
267 { &test_plfd_8_R1
, "plfd 8_R1", "FRT,D(RA),R"}, /* bcwp */
268 { &test_plfd_16_R1
, "plfd 16_R1", "FRT,D(RA),R"}, /* bcwp */
269 { &test_plfd_32_R1
, "plfd 32_R1", "FRT,D(RA),R"}, /* bcwp */
270 { &test_plfd_64_R1
, "plfd 64_R1", "FRT,D(RA),R"}, /* bcwp */
271 { &test_plfs_0_R1
, "plfs 0_R1", "FRT,D(RA),R"}, /* bcwp */
272 { &test_plfs_4_R1
, "plfs 4_R1", "FRT,D(RA),R"}, /* bcwp */
273 { &test_plfs_8_R1
, "plfs 8_R1", "FRT,D(RA),R"}, /* bcwp */
274 { &test_plfs_16_R1
, "plfs 16_R1", "FRT,D(RA),R"}, /* bcwp */
275 { &test_plfs_32_R1
, "plfs 32_R1", "FRT,D(RA),R"}, /* bcwp */
276 { &test_plfs_64_R1
, "plfs 64_R1", "FRT,D(RA),R"}, /* bcwp */
277 { &test_plxsd_0_R1
, "plxsd 0_R1", "VRT,D(RA),R", 0b00110000}, /* bcwp */
278 { &test_plxsd_4_R1
, "plxsd 4_R1", "VRT,D(RA),R", 0b00110000}, /* bcwp */
279 { &test_plxsd_8_R1
, "plxsd 8_R1", "VRT,D(RA),R", 0b00110000}, /* bcwp */
280 { &test_plxsd_16_R1
, "plxsd 16_R1", "VRT,D(RA),R", 0b00110000}, /* bcwp */
281 { &test_plxsd_32_R1
, "plxsd 32_R1", "VRT,D(RA),R", 0b00110000}, /* bcwp */
282 { &test_plxsd_64_R1
, "plxsd 64_R1", "VRT,D(RA),R", 0b00110000}, /* bcwp */
283 { &test_plxssp_0_R1
, "plxssp 0_R1", "VRT,D(RA),R", 0b00001111}, /* bcwp */
284 { &test_plxssp_4_R1
, "plxssp 4_R1", "VRT,D(RA),R", 0b00001111}, /* bcwp */
285 { &test_plxssp_8_R1
, "plxssp 8_R1", "VRT,D(RA),R", 0b00001111}, /* bcwp */
286 { &test_plxssp_16_R1
, "plxssp 16_R1", "VRT,D(RA),R", 0b00001111}, /* bcwp */
287 { &test_plxssp_32_R1
, "plxssp 32_R1", "VRT,D(RA),R", 0b00001111}, /* bcwp */
288 { &test_plxssp_64_R1
, "plxssp 64_R1", "VRT,D(RA),R", 0b00001111}, /* bcwp */
289 { &test_plxv_0_R1
, "plxv 0_R1", "XT,D(RA),R"}, /* bcwp */
290 { &test_plxv_4_R1
, "plxv 4_R1", "XT,D(RA),R"}, /* bcwp */
291 { &test_plxv_8_R1
, "plxv 8_R1", "XT,D(RA),R"}, /* bcwp */
292 { &test_plxv_16_R1
, "plxv 16_R1", "XT,D(RA),R"}, /* bcwp */
293 { &test_pstfd_0_R1
, "pstfd 0_R1", "FRS,D(RA),R", 0b00110000}, /* bcwp */
294 { &test_pstfd_4_R1
, "pstfd 4_R1", "FRS,D(RA),R", 0b00110000}, /* bcwp */
295 { &test_pstfd_8_R1
, "pstfd 8_R1", "FRS,D(RA),R", 0b00110000}, /* bcwp */
296 { &test_pstfd_16_R1
, "pstfd 16_R1", "FRS,D(RA),R", 0b00110000}, /* bcwp */
297 { &test_pstfd_32_R1
, "pstfd 32_R1", "FRS,D(RA),R", 0b00110000}, /* bcwp */
298 { &test_pstfs_0_R1
, "pstfs 0_R1", "FRS,D(RA),R", 0b00001111}, /* bcwp */
299 { &test_pstfs_4_R1
, "pstfs 4_R1", "FRS,D(RA),R", 0b00001111}, /* bcwp */
300 { &test_pstfs_8_R1
, "pstfs 8_R1", "FRS,D(RA),R", 0b00001111}, /* bcwp */
301 { &test_pstfs_16_R1
, "pstfs 16_R1", "FRS,D(RA),R", 0b00001111}, /* bcwp */
302 { &test_pstfs_32_R1
, "pstfs 32_R1", "FRS,D(RA),R", 0b00001111}, /* bcwp */
303 { &test_pstxsd_0_R1
, "pstxsd 0_R1", "VRS,D(RA),R"}, /* bcwp */
304 { &test_pstxsd_4_R1
, "pstxsd 4_R1", "VRS,D(RA),R"}, /* bcwp */
305 { &test_pstxsd_8_R1
, "pstxsd 8_R1", "VRS,D(RA),R"}, /* bcwp */
306 { &test_pstxsd_16_R1
, "pstxsd 16_R1", "VRS,D(RA),R"}, /* bcwp */
307 { &test_pstxsd_32_R1
, "pstxsd 32_R1", "VRS,D(RA),R"}, /* bcwp */
308 { &test_pstxsd_64_R1
, "pstxsd 64_R1", "VRS,D(RA),R"}, /* bcwp */
309 { &test_pstxssp_0_R1
, "pstxssp 0_R1", "VRS,D(RA),R"}, /* bcwp */
310 { &test_pstxssp_4_R1
, "pstxssp 4_R1", "VRS,D(RA),R"}, /* bcwp */
311 { &test_pstxssp_8_R1
, "pstxssp 8_R1", "VRS,D(RA),R"}, /* bcwp */
312 { &test_pstxssp_16_R1
, "pstxssp 16_R1", "VRS,D(RA),R"}, /* bcwp */
313 { &test_pstxssp_32_R1
, "pstxssp 32_R1", "VRS,D(RA),R"}, /* bcwp */
314 { &test_pstxssp_64_R1
, "pstxssp 64_R1", "VRS,D(RA),R"}, /* bcwp */
315 { &test_pstxvp_off0_R1
, "pstxvp off0_R1", "XSp,D(RA),R"}, /* bcwp */
316 { &test_pstxvp_off16_R1
, "pstxvp off16_R1", "XSp,D(RA),R"}, /* bcwp */
317 { &test_pstxvp_off32_R1
, "pstxvp off32_R1", "XSp,D(RA),R"}, /* bcwp */
318 { &test_pstxvp_off48_R1
, "pstxvp off48_R1", "XSp,D(RA),R"}, /* bcwp */
319 { &test_pstxv_0_R1
, "pstxv 0_R1", "XS,D(RA),R"}, /* bcwp */
320 { &test_pstxv_4_R1
, "pstxv 4_R1", "XS,D(RA),R"}, /* bcwp */
321 { &test_pstxv_8_R1
, "pstxv 8_R1", "XS,D(RA),R"}, /* bcwp */
322 { &test_pstxv_16_R1
, "pstxv 16_R1", "XS,D(RA),R"}, /* bcwp */
326 /* Allow skipping of tests. */
327 unsigned long test_count
=0xffff;
328 unsigned long skip_count
=0;
329 unsigned long setup_only
=0;
331 /* Set up a setjmp/longjmp to gently handle our SIGILLs and SIGSEGVs. */
332 static jmp_buf mybuf
;
334 /* This (testfunction_generic) is meant to handle all of the instruction
335 variations. The helpers set up the register and iterator values
336 as is appropriate for the instruction being tested. */
337 static void testfunction_generic (const char* instruction_name
,
338 test_func_t test_function
,
339 unsigned int ignore_flags
,
342 identify_form_components (instruction_name
, cur_form
);
343 debug_show_form (instruction_name
, cur_form
);
345 debug_show_iter_ranges ();
346 initialize_buffer (0);
347 init_pcrelative_write_target ();
348 debug_dump_buffer ();
350 for (vrai
= a_start
; vrai
< a_iters
; vrai
+=a_inc
) {
351 for (vrbi
= b_start
; vrbi
< b_iters
; vrbi
+=b_inc
) {
352 for (vrci
= c_start
; vrci
< c_iters
; vrci
+=c_inc
) {
353 for (vrmi
= m_start
; (vrmi
< m_iters
) ; vrmi
+=m_inc
) {
355 debug_show_current_iteration ();
356 // Be sure to initialize the target registers first.
357 initialize_target_registers ();
358 initialize_source_registers ();
361 printf ("%s", instruction_name
);
362 print_register_header ();
363 printf( " =>"); fflush (stdout
);
366 if ( setjmp ( mybuf
) ) {
367 printf("signal tripped. (FIXME)\n");
373 print_register_footer ();
374 print_result_buffer ();
375 print_pcrelative_write_target ();
383 void mykillhandler ( int x
) { longjmp (mybuf
, 1); }
384 void mysegvhandler ( int x
) { longjmp (mybuf
, 1); }
386 static void do_tests ( void )
390 test_group_t group_function
= &testfunction_generic
;
391 test_list_t
*tests
= testgroup_generic
;
393 struct sigaction kill_action
, segv_action
;
394 struct sigaction old_kill_action
, old_segv_action
;
396 kill_action
.sa_handler
= mykillhandler
;
397 segv_action
.sa_handler
= mysegvhandler
;
398 sigemptyset ( &kill_action
.sa_mask
);
399 sigemptyset ( &segv_action
.sa_mask
);
400 kill_action
.sa_flags
= SA_NODEFER
;
401 segv_action
.sa_flags
= SA_NODEFER
;
402 sigaction ( SIGILL
, &kill_action
, &old_kill_action
);
403 sigaction ( SIGSEGV
, &segv_action
, &old_segv_action
);
406 for (groupcount
= 0; tests
[groupcount
].name
!= NULL
; groupcount
++) {
407 cur_form
= strdup(tests
[groupcount
].form
);
408 current_test
= tests
[groupcount
];
409 identify_instruction_by_func_name (current_test
.name
);
410 if (groupcount
< skip_count
) continue;
411 if (verbose
) printf("Test #%d ,", groupcount
);
412 if (verbose
> 1) printf(" instruction %s (v=%d)", current_test
.name
, verbose
);
413 (*group_function
) (current_test
.name
, current_test
.func
, 0, cur_form
);
415 if (groupcount
>= (skip_count
+test_count
)) break;
417 if (debug_show_labels
) printf("\n");
418 printf ("All done. Tested %d different instruction groups\n", groupcount
);
421 static void usage (void)
424 "Usage: test_isa_XXX [OPTIONS]\n"
425 "\t-h: display this help and exit\n"
426 "\t-v: increase verbosity\n"
427 "\t-a <foo> : limit number of a-iterations to <foo>\n"
428 "\t-b <foo> : limit number of b-iterations to <foo>\n"
429 "\t-c <foo> : limit number of c-iterations to <foo>\n"
430 "\t-n <foo> : limit to this number of tests.\n"
431 "\t-r <foo>: run only test # <foo> \n"
433 "\t-j :enable setjmp to recover from illegal insns. \n"
434 "\t-m :(dev only?) lock VRM value to zero.\n"
435 "\t-z :(dev only?) lock MC value to zero.\n"
436 "\t-p :(dev only?) disable prefix instructions\n"
437 "\t-s <foo>: skip <foo> tests \n"
438 "\t-c <foo>: stop after running <foo> # of tests \n"
439 "\t-f : Do the test setup but do not actually execute the test instruction. \n"
443 int main (int argc
, char **argv
)
446 while ((c
= getopt(argc
, argv
, "dhjvmpfzs:a:b:c:n:r:")) != -1) {
456 /* Options related to limiting the test iterations. */
458 a_limit
=atoi (optarg
);
459 printf ("limiting a-iters to %ld.\n", a_limit
);
462 b_limit
=atoi (optarg
);
463 printf ("limiting b-iters to %ld.\n", b_limit
);
466 c_limit
=atoi (optarg
);
467 printf ("limiting c-iters to %ld.\n", c_limit
);
469 case 'n': // run this number of tests.
470 test_count
=atoi (optarg
);
471 printf ("limiting to %ld tests\n", test_count
);
473 case 'r': // run just test #<foo>.
474 skip_count
=atoi (optarg
);
476 if (verbose
) printf("Running test number %ld\n", skip_count
);
478 case 's': // skip this number of tests.
479 skip_count
=atoi (optarg
);
480 printf ("skipping %ld tests\n", skip_count
);
486 printf("DEBUG:dump_tables.\n");
490 printf("DEBUG:setup_only.\n");
494 printf ("DEBUG:setjmp enabled.\n");
498 printf ("DEBUG:vrm override enabled.\n");
502 printf ("DEBUG:prefix override enabled.\n");
506 printf ("DEBUG:MC override enabled.\n");
510 fprintf(stderr
, "Unknown argument: '%c'\n", c
);
517 build_float_vsx_tables ();
520 dump_float_vsx_tables ();
530 int main (int argc
, char **argv
)
532 printf("NO ISA 3.1 SUPPORT\n");