1 /* HOW TO COMPILE: 2 * 64bit build: 3 * gcc -Winline -Wall -g -O -mregnames -maltivec -m64 4 */ 5 6 /* 7 * test_isa_3_0.c: 8 * Copyright (C) 2016-2017 Carl Love <cel (at) us.ibm.com> 9 * Copyright (C) 2016-2017 Will Schmidt <will_schmidt (at) vnet.ibm.com> 10 * 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 107 static 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! */ 132 register HWord_t r14 __asm__ ("r14"); 133 register HWord_t r15 __asm__ ("r15"); 134 register HWord_t r16 __asm__ ("r16"); 135 register HWord_t r17 __asm__ ("r17"); 136 register double f14 __asm__ ("fr14"); 137 register double f15 __asm__ ("fr15"); 138 139 /* globals used for vector tests */ 140 static 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 */ 148 unsigned long local_cr; 149 unsigned long local_fpscr; 150 unsigned long local_xer; 151 volatile unsigned int cr_value; 152 153 /* global for holding the DFP values */ 154 dfp_val_t dfp_value; 155 156 /* individual instruction tests */ 157 typedef void (*test_func_t) (void); 158 struct test_list_t { 159 test_func_t func; 160 const char *name; 161 }; 162 typedef struct test_list_t test_list_t; 163 164 /* global variable, used to pass shift info down to the test functions.*/ 165 volatile int x_shift; 166 167 /* Indicator for DCMX (Data Class Mask) matches. */ 168 volatile int dcmx_match; 169 170 /* Error indicator to determine of the UIN (Unsigned Immediate) field 171 * from insert/extract was out of range */ 172 volatile int insert_extract_error; 173 174 /* vector splat value */ 175 volatile int x_splat; 176 volatile int dfp_significance; 177 178 /* global variable, ... vector insert functions. */ 179 volatile int x_index; 180 181 /* global variable, used to pass shift info down to the test functions.*/ 182 /* Also used to control DRM,RM values for mffs* functions. */ 183 volatile int x_shift; 184 185 /* groups of instruction tests, calling individual tests */ 186 typedef void (*test_group_t) (const char *name, test_func_t func, 187 unsigned int test_flags); 188 189 enum 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, 222 PPC_MFFS = 0x000B0000, 223 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 230 static void test_cnttzw (void) 231 { 232 __asm__ __volatile__ ("cnttzw 17, 14"); 233 } 234 235 static void test_cnttzd (void) 236 { 237 __asm__ __volatile__ ("cnttzd 17, 14"); 238 } 239 240 static void test_dotted_cnttzw (void) 241 { 242 __asm__ __volatile__ ("cnttzw. 17, 14"); 243 } 244 245 static void test_dotted_cnttzd (void) 246 { 247 __asm__ __volatile__ ("cnttzd. 17, 14"); 248 } 249 250 static test_list_t testgroup_logical_one[] = { 251 { &test_cnttzw , "cnttzw" }, 252 { &test_cnttzd , "cnttzd" }, 253 { &test_dotted_cnttzw, "cnttzw." }, 254 { &test_dotted_cnttzd, "cnttzd." }, 255 { NULL , NULL }, 256 }; 257 258 static void test_modsw (void) 259 { 260 __asm__ __volatile__ ("modsw 17, 14, 15"); 261 } 262 263 static void test_moduw (void) 264 { 265 __asm__ __volatile__ ("moduw 17, 14, 15"); 266 } 267 268 static void test_modsd (void) 269 { 270 __asm__ __volatile__ ("modsd 17, 14, 15"); 271 } 272 273 static void test_modud (void) 274 { 275 __asm__ __volatile__ ("modud 17, 14, 15"); 276 } 277 278 static void test_addex(void) { 279 /* addex RT,RA,RB,CY # at the time of this writing, only CY=0 is valid. CY values of 1,2,3 are reserved. */ 280 __asm__ __volatile__ ("addex %0, %1, %2, 0" : "=r" (r17) : "r" (r14), "r" (r15) ); 281 } 282 283 static test_list_t testgroup_ia_ops_two[] = { 284 { &test_modsw, "modsw" }, 285 { &test_moduw, "moduw" }, 286 { &test_modsd, "modsd" }, 287 { &test_modud, "modud" }, 288 //{ &test_addex, "addex" }, 289 { NULL , NULL }, 290 }; 291 292 static 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 316 static 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 340 static test_list_t testgroup_shifted_one[] = { 341 { &test_extswsli , "extswsli " }, 342 { &test_dotted_extswsli, "extswsli." }, 343 { NULL , NULL }, 344 }; 345 346 static void test_maddhd (void) 347 { 348 __asm__ __volatile__ ("maddhd 17, 14, 15, 16"); 349 } 350 static void test_maddhdu (void) 351 { 352 __asm__ __volatile__ ("maddhdu 17, 14, 15, 16"); 353 } 354 static void test_maddld (void) 355 { 356 __asm__ __volatile__ ("maddld 17, 14, 15, 16"); 357 } 358 359 static 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. */ 367 static 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. */ 373 static void test_xxpermr (void) 374 { 375 __asm__ __volatile__ ("xxpermr %x0, %x1, %x2" : "+wa" (vec_xt): "wa" (vec_xa), "wa" (vec_xb)); 376 } 377 378 static test_list_t testgroup_vsx_xxpermute[] = { 379 { &test_xxperm , "xxperm" }, 380 { &test_xxpermr, "xxpermr" }, 381 { NULL , NULL }, 382 }; 383 384 static void test_vabsdub(void) { 385 __asm__ __volatile__ ("vabsdub %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb)); 386 } 387 388 static void test_vabsduh(void) { 389 __asm__ __volatile__ ("vabsduh %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb)); 390 } 391 392 static void test_vabsduw(void) { 393 __asm__ __volatile__ ("vabsduw %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb)); 394 } 395 396 static void test_vcmpneb(void) { 397 __asm__ __volatile__ ("vcmpneb %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb)); 398 } 399 400 static void test_dotted_vcmpneb(void) { 401 __asm__ __volatile__ ("vcmpneb. %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb)); 402 } 403 404 static void test_vcmpnezb(void) { 405 __asm__ __volatile__ ("vcmpnezb %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb)); 406 } 407 408 static void test_dotted_vcmpnezb(void) { 409 __asm__ __volatile__ ("vcmpnezb. %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb)); 410 } 411 412 static void test_vcmpneh(void) { 413 __asm__ __volatile__ ("vcmpneh %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb)); 414 } 415 416 static void test_dotted_vcmpneh(void) { 417 __asm__ __volatile__ ("vcmpneh. %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb)); 418 } 419 420 static void test_vcmpnezh(void) { 421 __asm__ __volatile__ ("vcmpnezh %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb)); 422 } 423 424 static void test_dotted_vcmpnezh(void) { 425 __asm__ __volatile__ ("vcmpnezh. %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb)); 426 } 427 428 static void test_vcmpnew(void) { 429 __asm__ __volatile__ ("vcmpnew %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb)); 430 } 431 432 static void test_dotted_vcmpnew(void) { 433 __asm__ __volatile__ ("vcmpnew. %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb)); 434 } 435 436 static void test_vcmpnezw(void) { 437 __asm__ __volatile__ ("vcmpnezw %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb)); 438 } 439 440 static void test_dotted_vcmpnezw(void) { 441 __asm__ __volatile__ ("vcmpnezw. %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb)); 442 } 443 444 static void test_vrlwmi(void) { 445 __asm__ __volatile__ ("vrlwmi %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb)); 446 } 447 448 static void test_vrldmi(void) { 449 __asm__ __volatile__ ("vrldmi %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb)); 450 } 451 452 static void test_vbpermd(void) { 453 /* vector bit permute doubleword */ 454 __asm__ __volatile__ ("vbpermd %0, %1, %2 " : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb)); 455 } 456 457 static void test_vrlwnm(void) { 458 __asm__ __volatile__ ("vrlwnm %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb)); 459 } 460 461 static void test_vrldnm(void) { 462 __asm__ __volatile__ ("vrldnm %0, %1, %2" : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb)); 463 } 464 465 static void test_xviexpdp(void) { 466 __asm__ __volatile__ ("xviexpdp %0, %1, %2 " : "+wa" (vec_xt): "wa" (vec_xa), "wa" (vec_xb)); 467 } 468 469 static void test_xviexpsp(void) { 470 __asm__ __volatile__ ("xviexpsp %0, %1, %2 " : "+wa" (vec_xt): "wa" (vec_xa), "wa" (vec_xb)); 471 } 472 473 static test_list_t testgroup_vsx_absolute[] = { 474 { &test_vabsdub , "vabsdub" }, 475 { &test_vabsduh , "vabsduh" }, 476 { &test_vabsduw , "vabsduw" }, 477 { &test_vcmpneb , "vcmpneb" }, 478 { &test_dotted_vcmpneb , "vcmpneb." }, 479 { &test_vcmpnezb , "vcmpnezb" }, 480 { &test_dotted_vcmpnezb, "vcmpnezb." }, 481 { &test_vcmpneh , "vcmpneh" }, 482 { &test_dotted_vcmpneh , "vcmpneh." }, 483 { &test_vcmpnezh , "vcmpnezh" }, 484 { &test_dotted_vcmpnezh, "vcmpnezh." }, 485 { &test_vcmpnew , "vcmpnew" }, 486 { &test_dotted_vcmpnew , "vcmpnew." }, 487 { &test_vcmpnezw , "vcmpnezw" }, 488 { &test_dotted_vcmpnezw, "vcmpnezw." }, 489 { &test_vrlwnm , "vrlwnm" }, 490 { &test_vrlwmi , "vrlwmi" }, 491 { &test_vrldnm , "vrldnm" }, 492 { &test_vrldmi , "vrldmi" }, 493 { &test_vbpermd , "vbpermd" }, 494 { &test_xviexpdp , "xviexpdp" }, 495 { &test_xviexpsp , "xviexpsp" }, 496 { NULL , NULL }, 497 }; 498 499 static void test_vpermr(void) 500 { /* vector permute right-indexed */ 501 __asm__ __volatile__ ("vpermr %0, %1, %2, %3 " : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb), "v" (vec_xc)); 502 } 503 504 static void test_vmsumudm(void) 505 { /* vector multiply-sum unsigned byte modulo. */ 506 __asm__ __volatile__ ("vmsumudm %0, %1, %2, %3 " : "+v" (vec_xt): "v" (vec_xa), "v" (vec_xb), "v" (vec_xc)); 507 } 508 509 /* vector, 3->1 unique; four arguments. xt, xa, xb, xc (xc = permute) */ 510 static test_list_t testgroup_vector_four[] = { 511 { &test_vpermr, "vpermr" }, 512 // { &test_vmsumudm, "vmsumudm" }, 513 { NULL , NULL }, 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 537 static 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 562 static 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 586 static 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 608 static 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 */ 627 static 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 652 static 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 676 static 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 697 static 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 715 static 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 737 static 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 759 static test_list_t testgroup_vector_inserts[] = { 760 { &test_vinsertb , "vinsertb " }, 761 { &test_vinserth , "vinserth " }, 762 { &test_vinsertw , "vinsertw " }, 763 { &test_vinsertd , "vinsertd " }, 764 { &test_vextractub , "vextractub " }, 765 { &test_vextractuh , "vextractuh " }, 766 { &test_vextractuw , "vextractuw " }, 767 { &test_vextractd , "vextractd " }, 768 { &test_xxinsertw , "xxinsertw " }, 769 { &test_xxextractuw, "xxextractuw" }, 770 { NULL , NULL }, 771 }; 772 773 static void test_xxspltib(void) 774 { /* vector splat byte */ 775 switch(x_splat) { 776 case SPLAT0: __asm__ __volatile__ ("xxspltib %x0, %1 " : "=wa"(vec_xt) : "i"(SPLAT0)); break; 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 791 static test_list_t testgroup_vector_immediate[] = { 792 { &test_xxspltib, "xxspltib" }, 793 { NULL , NULL }, 794 }; 795 796 /* vector reverse bytes ... */ 797 static void test_xxbrh(void) 798 { /* vector reverse byte halfword*/ 799 __asm__ __volatile__ ("xxbrh %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa)); 800 } 801 802 static void test_xxbrw(void) 803 { /* vector reverse byte word*/ 804 __asm__ __volatile__ ("xxbrw %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa)); 805 } 806 807 static void test_xxbrd(void) 808 { /* vector reverse byte double*/ 809 __asm__ __volatile__ ("xxbrd %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa)); 810 } 811 812 static void test_xxbrq(void) 813 { /* vector reverse byte */ 814 __asm__ __volatile__ ("xxbrq %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa)); 815 } 816 817 static void test_xvxexpdp(void) { 818 __asm__ __volatile__ ("xvxexpdp %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa)); 819 } 820 821 static void test_xvxexpsp(void) { 822 __asm__ __volatile__ ("xvxexpsp %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa)); 823 } 824 825 static void test_xvxsigdp(void) { 826 __asm__ __volatile__ ("xvxsigdp %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa)); 827 } 828 829 static void test_xvxsigsp(void) { 830 __asm__ __volatile__ ("xvxsigsp %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa)); 831 } 832 833 static void test_xsxexpdp(void) { 834 __asm__ __volatile__ ("xsxexpdp %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa)); 835 } 836 837 static void test_xsxsigdp(void) { 838 __asm__ __volatile__ ("xsxsigdp %x0, %x1 " : "=wa" (vec_xt) : "wa" (vec_xa)); 839 } 840 841 static 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 855 static void test_lxvx(void) { 856 __asm__ __volatile__ ("lxvx %x0, 14, 15" : "=wa" (vec_xt)); 857 } 858 859 static void test_lxvwsx(void) { 860 __asm__ __volatile__ ("lxvwsx %x0, 14, 15" : "=wa" (vec_xt)); 861 } 862 863 static void test_lxvh8x(void) { 864 __asm__ __volatile__ ("lxvh8x %x0, 14, 15" : "=wa" (vec_xt)); 865 } 866 867 static void test_lxvb16x(void) { 868 __asm__ __volatile__ ("lxvb16x %x0, 14, 15" : "=wa" (vec_xt)); 869 } 870 871 static void test_stxvx(void) { 872 __asm__ __volatile__ ("stxvx %x0, 14, 15" : "=wa" (vec_xt)); 873 } 874 875 static void test_stxvh8x(void) { 876 __asm__ __volatile__ ("stxvh8x %x0, 14, 15" : "=wa" (vec_xt)); 877 } 878 879 static void test_stxvb16x(void) { 880 __asm__ __volatile__ ("stxvb16x %x0, 14, 15" : "=wa" (vec_xt)); 881 } 882 883 static 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 894 static void test_lxvl(void) { 895 __asm__ __volatile__ ("lxvl %0, 14, 15" : "=wa" (vec_xt)); 896 } 897 898 static void test_stxvl(void) { 899 __asm__ __volatile__ ("stxvl %0, 14, 15" : "=wa" (vec_xt)); 900 } 901 902 static void test_lxvll(void) { 903 __asm__ __volatile__ ("lxvll %0, 14, 15" : "=wa" (vec_xt)); 904 } 905 906 static void test_stxvll(void) { 907 __asm__ __volatile__ ("stxvll %0, 14, 15" : "=wa" (vec_xt)); 908 } 909 910 static void test_lxsibzx(void) { 911 __asm__ __volatile__ ("lxsibzx %x0, 14, 15" : "=wa" (vec_xt)); 912 } 913 914 static void test_lxsihzx(void) { 915 __asm__ __volatile__ ("lxsihzx %x0, 14, 15" : "=wa" (vec_xt)); 916 } 917 918 static void test_stxsibx(void) { 919 __asm__ __volatile__ ("stxsibx %x0, 14, 15" : "=wa" (vec_xt)); 920 } 921 922 static void test_stxsihx(void) { 923 __asm__ __volatile__ ("stxsihx %x0, 14, 15" : "=wa" (vec_xt)); 924 } 925 926 /* d-form vsx load/store */ 927 static void test_lxsd_0(void) { 928 __asm__ __volatile__ ("lxsd %0, 0(%1) " : "=v"(vec_xt) : "r"(r14)); 929 } 930 931 static void test_stxsd_0(void) { 932 __asm__ __volatile__ ("stxsd %0, 0(%1)" : "=v"(vec_xt) : "r"(r14)); 933 } 934 935 static void test_lxsd_16(void) { 936 __asm__ __volatile__ ("lxsd %0, 16(%1)" : "=v"(vec_xt) : "r"(r14)); 937 } 938 939 static void test_stxsd_16(void) { 940 __asm__ __volatile__ ("stxsd %0, 16(%1)" : "=v"(vec_xt) : "r"(r14)); 941 } 942 943 static void test_lxssp_0(void) { 944 __asm__ __volatile__ ("lxssp %0, 0(%1)" : "=wa"(vec_xt) : "r"(r14)); 945 } 946 947 static void test_stxssp_0(void) { 948 __asm__ __volatile__ ("stxssp %0, 0(%1)" : "=wa"(vec_xt) : "r"(r14)); 949 } 950 951 static void test_lxssp_16(void) { 952 __asm__ __volatile__ ("lxssp %0, 16(%1)" : "=wa"(vec_xt) : "r"(r14)); 953 } 954 955 static void test_stxssp_16(void) { 956 __asm__ __volatile__ ("stxssp %0, 16(%1)" : "=wa"(vec_xt) : "r"(r14)); 957 } 958 959 static void test_lxv_0(void) { 960 __asm__ __volatile__ ("lxv %0, 0(%1)" : "=wa"(vec_xt) : "r"(r14)); 961 } 962 963 static void test_stxv_0(void) { 964 __asm__ __volatile__ ("stxv %0, 0(%1)" : "=wa"(vec_xt) : "r"(r14)); 965 } 966 967 static void test_lxv_16(void) { 968 __asm__ __volatile__ ("lxv %0, 16(%1)" : "=wa"(vec_xt) : "r"(r14)); 969 } 970 971 static void test_stxv_16(void) { 972 __asm__ __volatile__ ("stxv %0, 16(%1)" : "=wa"(vec_xt) : "r"(r14)); 973 } 974 975 static 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 */ 1000 static void test_mfvsrld (void) 1001 { 1002 __asm__ __volatile__ ("mfvsrld %0, %x1" : "=r" (r14) : "wa" (vec_xt)); 1003 }; 1004 1005 static void test_mtvsrdd (void) 1006 { 1007 __asm__ __volatile__ ("mtvsrdd %x0, 14, 15" : "=wa" (vec_xt)); 1008 }; 1009 1010 static 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 1017 static 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. */ 1026 static void test_vclzlsbb(void) { 1027 __asm__ __volatile__ ("vclzlsbb %0, %1" : "=r"(r14) : "v"(vec_xb)); 1028 } 1029 1030 static void test_vctzlsbb(void) { 1031 __asm__ __volatile__ ("vctzlsbb %0, %1" : "=r"(r14) : "v"(vec_xb)); 1032 } 1033 1034 static test_list_t testgroup_vector_count_bytes[] = { 1035 { &test_vclzlsbb, "vclzlsbb" }, 1036 { &test_vctzlsbb, "vctzlsbb" }, 1037 { NULL , NULL }, 1038 }; 1039 1040 static void test_vextsb2w(void) { 1041 __asm__ __volatile__ ("vextsb2w %0, %1" : "=v"(vec_xt) : "v"(vec_xb)); 1042 } 1043 1044 static void test_vextsb2d(void) { 1045 __asm__ __volatile__ ("vextsb2d %0, %1" : "=v"(vec_xt) : "v"(vec_xb)); 1046 } 1047 1048 static void test_vextsh2w(void) { 1049 __asm__ __volatile__ ("vextsh2w %0, %1" : "=v"(vec_xt) : "v"(vec_xb)); 1050 } 1051 1052 static void test_vextsh2d(void) { 1053 __asm__ __volatile__ ("vextsh2d %0, %1" : "=v"(vec_xt) : "v"(vec_xb)); 1054 } 1055 1056 static void test_vextsw2d(void) { 1057 __asm__ __volatile__ ("vextsw2d %0, %1" : "=v"(vec_xt) : "v"(vec_xb)); 1058 } 1059 1060 static void test_vnegw(void) { 1061 __asm__ __volatile__ ("vnegw %0, %1" : "=v"(vec_xt) : "v"(vec_xb)); 1062 } 1063 1064 static void test_vnegd(void) { 1065 __asm__ __volatile__ ("vnegd %0, %1" : "=v"(vec_xt) : "v"(vec_xb)); 1066 } 1067 1068 static void test_vprtybw(void) { 1069 __asm__ __volatile__ ("vprtybw %0, %1" : "=v"(vec_xt) : "v"(vec_xb)); 1070 } 1071 1072 static void test_vprtybd(void) { 1073 __asm__ __volatile__ ("vprtybd %0, %1" : "=v"(vec_xt) : "v"(vec_xb)); 1074 } 1075 1076 static void test_vprtybq(void) { 1077 __asm__ __volatile__ ("vprtybq %0, %1" : "=v"(vec_xt) : "v"(vec_xb)); 1078 } 1079 1080 static void test_vctzb(void) { 1081 __asm__ __volatile__ ("vctzb %0, %1" : "=v"(vec_xt) : "v"(vec_xb)); 1082 } 1083 1084 static void test_vctzh(void) { 1085 __asm__ __volatile__ ("vctzh %0, %1" : "=v"(vec_xt) : "v"(vec_xb)); 1086 } 1087 1088 static void test_vctzw(void) { 1089 __asm__ __volatile__ ("vctzw %0, %1" : "=v"(vec_xt) : "v"(vec_xb)); 1090 } 1091 1092 static void test_vctzd(void) { 1093 __asm__ __volatile__ ("vctzd %0, %1" : "=v"(vec_xt) : "v"(vec_xb)); 1094 } 1095 1096 static 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 1114 static void test_vextublx(void) { 1115 __asm__ __volatile__ ("vextublx %0, %1, %2" : "=r"(r14) : "r" (r15), "v" (vec_xb)); 1116 } 1117 1118 static void test_vextubrx(void) { 1119 __asm__ __volatile__ ("vextubrx %0, %1, %2" : "=r"(r14) : "r"(r15), "v"(vec_xb)); 1120 } 1121 1122 static 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 1127 static 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 1132 static 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 1137 static 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 1142 static 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__ \ 1156 ("xscmpexpdp %0, %1, %2"::"i"(x), "wa"(vec_xa), "wa"(vec_xb));\ 1157 GET_CR(local_cr); \ 1158 GET_FPSCR(local_fpscr); 1159 1160 static 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 1175 static 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 1220 static 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 1233 static 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 1246 static 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 1259 static 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 */ 1276 static 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 1289 static 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 1298 static 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 1335 static 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 */ 1348 static 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 1376 static 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 1404 static 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 1432 static 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 1439 static void test_bcdtrunc_p0(void) { 1440 __asm__ __volatile__ ("bcdtrunc. %0, %1, %2, 0": "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb)); 1441 } 1442 1443 static void test_bcdtrunc_p1(void) { 1444 __asm__ __volatile__ ("bcdtrunc. %0, %1, %2, 1": "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb)); 1445 } 1446 1447 static void test_bcdutrunc(void) { 1448 __asm__ __volatile__ ("bcdutrunc. %0, %1, %2 ": "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb)); 1449 } 1450 1451 static void test_bcdadd_p0(void) { 1452 __asm__ __volatile__ ("bcdadd. %0, %1, %2, 0" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb)); 1453 } 1454 1455 static void test_bcdadd_p1(void) { 1456 __asm__ __volatile__ ("bcdadd. %0, %1, %2, 1" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb)); 1457 } 1458 1459 static void test_bcdsub_p0(void) { 1460 __asm__ __volatile__ ("bcdsub. %0, %1, %2, 0" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb)); 1461 } 1462 1463 static void test_bcdsub_p1(void) { 1464 __asm__ __volatile__ ("bcdsub. %0, %1, %2, 1" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb)); 1465 } 1466 1467 static void test_bcdcpsgn(void) { 1468 __asm__ __volatile__ ("bcdcpsgn. %0, %1, %2 ": "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb)); 1469 } 1470 1471 static void test_bcdctz_p0(void) { 1472 __asm__ __volatile__ ("bcdctz. %0, %1, 0 " : "=v"(vec_xt) : "v"(vec_xb)); 1473 } 1474 1475 static void test_bcdctz_p1(void) { 1476 __asm__ __volatile__ ("bcdctz. %0, %1, 1 " : "=v"(vec_xt) : "v"(vec_xb)); 1477 } 1478 1479 static void test_bcdsetsgn_p0(void) { 1480 __asm__ __volatile__ ("bcdsetsgn. %0, %1, 0 " : "=v"(vec_xt) : "v"(vec_xb)); 1481 } 1482 1483 static void test_bcdsetsgn_p1(void) { 1484 __asm__ __volatile__ ("bcdsetsgn. %0, %1, 1 " : "=v"(vec_xt) : "v"(vec_xb)); 1485 } 1486 1487 static void test_bcds_p0(void) { 1488 __asm__ __volatile__ ("bcds. %0, %1, %2, 0" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb)); 1489 } 1490 1491 static void test_bcds_p1(void) { 1492 __asm__ __volatile__ ("bcds. %0, %1, %2, 1" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb)); 1493 } 1494 1495 static void test_bcdus(void) { 1496 __asm__ __volatile__ ("bcdus. %0, %1, %2 " : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb)); 1497 } 1498 1499 static void test_bcdsr_p0(void) { 1500 __asm__ __volatile__ ("bcdsr. %0, %1, %2, 0" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb)); 1501 } 1502 1503 static void test_bcdsr_p1(void) { 1504 __asm__ __volatile__ ("bcdsr. %0, %1, %2, 1" : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb)); 1505 } 1506 1507 static void test_bcdcfn_p0(void) { 1508 __asm__ __volatile__ ("bcdcfn. %0, %1, 0 " : "=v"(vec_xt) : "v"(vec_xb)); 1509 } 1510 1511 static void test_bcdcfn_p1(void) { 1512 __asm__ __volatile__ ("bcdcfn. %0, %1, 1 " : "=v"(vec_xt) : "v"(vec_xb)); 1513 } 1514 1515 static void test_bcdcfz_p0(void) { 1516 __asm__ __volatile__ ("bcdcfz. %0, %1, 0 " : "=v"(vec_xt) : "v"(vec_xb)); 1517 } 1518 1519 static void test_bcdcfz_p1(void) { 1520 __asm__ __volatile__ ("bcdcfz. %0, %1, 1 " : "=v"(vec_xt) : "v"(vec_xb)); 1521 } 1522 1523 static void test_bcdctn(void) { 1524 __asm__ __volatile__ ("bcdctn. %0, %1 " : "=v"(vec_xt) : "v"(vec_xb)); 1525 } 1526 1527 static void test_vmul10uq(void) { 1528 __asm__ __volatile__ ("vmul10uq %0, %1 " : "=v"(vec_xt) : "v"(vec_xa)); 1529 } 1530 1531 static void test_vmul10cuq(void) { 1532 __asm__ __volatile__ ("vmul10cuq %0, %1 " : "=v"(vec_xt) : "v"(vec_xa)); 1533 } 1534 1535 static void test_vmul10euq(void) { 1536 __asm__ __volatile__ ("vmul10euq %0, %1, %2 " : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb)); 1537 } 1538 1539 static void test_vmul10ecuq(void) { 1540 __asm__ __volatile__ ("vmul10ecuq %0, %1, %2 " : "=v"(vec_xt) : "v"(vec_xa), "v"(vec_xb)); 1541 } 1542 1543 static void test_bcdctsq(void) { 1544 __asm__ __volatile__ ("bcdctsq. %0, %1 " : "=v"(vec_xt) : "v"(vec_xb)); 1545 } 1546 1547 static void test_bcdcfsq_p0(void) { 1548 __asm__ __volatile__ ("bcdcfsq. %0, %1, 0 " : "=v"(vec_xt) : "v"(vec_xb)); 1549 } 1550 1551 static void test_bcdcfsq_p1(void) { 1552 __asm__ __volatile__ ("bcdcfsq. %0, %1, 1 " : "=v"(vec_xt) : "v"(vec_xb)); 1553 } 1554 1555 static 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 1588 static void test_wait(void) { 1589 __asm__ __volatile__ ("wait 0" : :); 1590 } 1591 1592 static 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 */ 1600 static 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 1638 static 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 1676 static test_list_t testgroup_dfp_significance[] = { 1677 { &test_dtstsfi , "dtstsfi" }, 1678 { &test_dtstsfiq, "dtstsfiq" }, 1679 { NULL , NULL }, 1680 }; 1681 1682 static 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 1703 static 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 1724 static test_list_t testgroup_pc_immediate_misc[] = { 1725 { &test_addpcis, "addpcis " }, 1726 { &test_subpcis, "subpcis " }, 1727 { NULL , NULL }, 1728 }; 1729 1730 static void test_xsiexpdp(void) { 1731 __asm__ __volatile__ ("xsiexpdp %0, %1, %2 " : "+wa" (vec_xt): "r" (r14), "r" (r15)); 1732 } 1733 1734 static void test_xscvhpdp(void) { 1735 __asm__ __volatile__ ("xscvhpdp %x0, %x1 " : "+wa" (vec_xt) : "wa" (vec_xb)); 1736 } 1737 1738 static void test_xscvdphp(void) { 1739 __asm__ __volatile__ ("xscvdphp %x0, %x1 " : "+wi" (vec_xt) : "wi" (vec_xb)); 1740 } 1741 1742 static void test_xvcvhpsp(void) { 1743 __asm__ __volatile__ ("xvcvhpsp %x0, %x1 " : "+ww" (vec_xt) : "ww" (vec_xb)); 1744 } 1745 1746 static void test_xvcvsphp(void) { 1747 __asm__ __volatile__ ("xvcvsphp %x0, %x1 " : "+ww" (vec_xt) : "ww" (vec_xb)); 1748 } 1749 1750 static 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 1760 static void test_xsabsqp(void) { 1761 __asm__ __volatile__ ("xsabsqp %0, %1" : "+v"(vec_xt) : "v"(vec_xb)); 1762 } 1763 1764 static void test_xscvdpqp(void) { 1765 __asm__ __volatile__ ("xscvdpqp %0, %1" : "+v"(vec_xt) : "v"(vec_xb)); 1766 } 1767 1768 static void test_xscvqpdp(void) { 1769 __asm__ __volatile__ ("xscvqpdp %0, %1" : "+v"(vec_xt) : "v"(vec_xb)); 1770 } 1771 1772 static void test_xscvqpdpo(void) { 1773 __asm__ __volatile__ ("xscvqpdpo %0, %1" : "+v"(vec_xt) : "v"(vec_xb)); 1774 } 1775 1776 static void test_xscvqpsdz(void) { 1777 __asm__ __volatile__ ("xscvqpsdz %0, %1" : "+v"(vec_xt) : "v"(vec_xb)); 1778 } 1779 1780 static void test_xscvqpswz(void) { 1781 __asm__ __volatile__ ("xscvqpswz %0, %1" : "+v"(vec_xt) : "v"(vec_xb)); 1782 } 1783 1784 static void test_xscvqpudz(void) { 1785 __asm__ __volatile__ ("xscvqpudz %0, %1" : "+v"(vec_xt) : "v"(vec_xb)); 1786 } 1787 1788 static void test_xscvqpuwz(void) { 1789 __asm__ __volatile__ ("xscvqpuwz %0, %1" : "+v"(vec_xt) : "v"(vec_xb)); 1790 } 1791 1792 static void test_xscvsdqp(void) { 1793 __asm__ __volatile__ ("xscvsdqp %0, %1" : "+v"(vec_xt) : "v"(vec_xb)); 1794 } 1795 1796 static void test_xscvudqp(void) { 1797 __asm__ __volatile__ ("xscvudqp %0, %1" : "+v"(vec_xt) : "v"(vec_xb)); 1798 } 1799 1800 static void test_xsxexpqp(void) { 1801 __asm__ __volatile__ ("xsxexpqp %0, %1" : "+v"(vec_xt) : "v"(vec_xb)); 1802 } 1803 1804 static void test_xsxsigqp(void) { 1805 __asm__ __volatile__ ("xsxsigqp %0, %1" : "+v"(vec_xt) : "v"(vec_xb)); 1806 } 1807 1808 static void test_xsnegqp(void) { 1809 __asm__ __volatile__ ("xsnegqp %0, %1" : "+v"(vec_xt) : "v"(vec_xb)); 1810 } 1811 1812 static void test_xsnabsqp(void) { 1813 __asm__ __volatile__ ("xsnabsqp %0, %1" : "+v"(vec_xt) : "v"(vec_xb)); 1814 } 1815 1816 static void test_xssqrtqp(void) { 1817 __asm__ __volatile__ ("xssqrtqp %0, %1" : "+v"(vec_xt) : "v"(vec_xb)); 1818 } 1819 1820 static void test_xssqrtqpo(void) { 1821 __asm__ __volatile__ ("xssqrtqpo %0, %1" : "+v"(vec_xt) : "v"(vec_xb)); 1822 } 1823 1824 static 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 1844 static void test_xsaddqp(void) { 1845 __asm__ __volatile__ ("xsaddqp %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb)); 1846 } 1847 1848 static void test_xsaddqpo(void) { 1849 __asm__ __volatile__ ("xsaddqpo %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb)); 1850 } 1851 1852 static void test_xscpsgnqp(void) { 1853 __asm__ __volatile__ ("xscpsgnqp %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb)); 1854 } 1855 1856 static void test_xsdivqp(void) { 1857 __asm__ __volatile__ ("xsdivqp %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb)); 1858 } 1859 1860 static void test_xsdivqpo(void) { 1861 __asm__ __volatile__ ("xsdivqpo %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb)); 1862 } 1863 1864 static void test_xsiexpqp(void) { 1865 __asm__ __volatile__ ("xsiexpqp %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb)); 1866 } 1867 1868 static void test_xsmaddqp(void) { 1869 __asm__ __volatile__ ("xsmaddqp %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb)); 1870 } 1871 1872 static void test_xsmaddqpo(void) { 1873 __asm__ __volatile__ ("xsmaddqpo %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb)); 1874 } 1875 1876 static void test_xsmsubqp(void) { 1877 __asm__ __volatile__ ("xsmsubqp %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb)); 1878 } 1879 1880 static void test_xsmsubqpo(void) { 1881 __asm__ __volatile__ ("xsmsubqpo %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb)); 1882 } 1883 1884 static void test_xsmulqp(void) { 1885 __asm__ __volatile__ ("xsmulqp %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb)); 1886 } 1887 1888 static void test_xsmulqpo(void) { 1889 __asm__ __volatile__ ("xsmulqpo %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb)); 1890 } 1891 1892 static void test_xsnmaddqp(void) { 1893 __asm__ __volatile__ ("xsnmaddqp %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb)); 1894 } 1895 1896 static void test_xsnmaddqpo(void) { 1897 __asm__ __volatile__ ("xsnmaddqpo %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb)); 1898 } 1899 1900 static void test_xsnmsubqp(void) { 1901 __asm__ __volatile__ ("xsnmsubqp %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb)); 1902 } 1903 1904 static void test_xsnmsubqpo(void) { 1905 __asm__ __volatile__ ("xsnmsubqpo %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb)); 1906 } 1907 1908 static void test_xssubqp(void) { 1909 __asm__ __volatile__ ("xssubqp %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb)); 1910 } 1911 1912 static void test_xssubqpo(void) { 1913 __asm__ __volatile__ ("xssubqpo %0, %1, %2" : "+v"(vec_xt) : "v"(vec_xa), "v"(vec_xb)); 1914 } 1915 1916 static 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 1962 static 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 1977 static 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 1992 static 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 2007 static 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 */ 2042 static 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 } 2054 static 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 2067 static 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 2080 static 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 2087 /* 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*/ 2096 static 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 */ 2102 static 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 */ 2108 static 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*/ 2114 static 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*/ 2133 static 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*/ 2139 static 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 */ 2157 static 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. */ 2164 static 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. */ 2172 static 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 2180 2181 /* ###### begin all_tests table. */ 2182 2183 /* table containing all of the instruction groups */ 2184 struct test_group_table_t { 2185 test_list_t *tests; 2186 const char *name; 2187 unsigned int flags; 2188 }; 2189 2190 typedef struct test_group_table_t test_group_table_t; 2191 2192 static 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 }, 2338 { 2339 testgroup_mffs_misc, 2340 "ppc mffpscr", 2341 PPC_MFFS, 2342 }, 2343 { 2344 testgroup_mffs_misc_one, 2345 "ppc mffpscr", 2346 PPC_MFFS, 2347 }, 2348 { NULL, NULL, 0x00000000, }, 2349 }; 2350 2351 #define instruction_touches_xer(instruction_name) \ 2352 (strncmp(instruction_name, "addex", 5) == 0) 2353 2354 static 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); 2373 GET_XER(local_xer); 2374 res = r17; 2375 2376 printf("%s %016lx, %016lx => %016lx (%08x)", 2377 instruction_name, (long unsigned)iargs[i], 2378 (long unsigned)iargs[j], (long unsigned)res, 2379 cr); 2380 if (instruction_touches_xer(instruction_name)) { 2381 dissect_xer(local_xer); 2382 } 2383 printf("\n"); 2384 } 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 2393 static 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 2430 void 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 2461 static 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 2495 static 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 2535 static 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 2582 static 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 2616 static 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 2659 static 2660 void 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 2710 static 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 2735 static 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 2775 static 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 2818 static 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 2877 static 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 2898 static 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 2921 static 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 */ 2964 static 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 */ 2983 long shift_or_truncate_instruction; 2984 int xa_sign, xb_sign, xt_sign; 2985 int 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 */ 2991 static 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 3046 static 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 3095 static 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 3128 static void 3129 testfunction_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 3184 static void 3185 testfunction_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 3240 static 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 3285 static 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 3320 static 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 3365 static 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 3454 static 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 3485 static 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 3539 static 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 3622 static 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 3705 static 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 3719 static 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)(); 3730 /* 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. */ 3744 static 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"); 3806 } 3807 } 3808 3809 /* ######## begin grand testing loops. */ 3810 typedef 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; 3814 unsigned int integer, altivec, altivec_quad, altivec_double, dfp, bcd, misc, mffs, 3815 no_op, pc_immediate; 3816 unsigned int cr; 3817 } insn_sel_flags_t; 3818 3819 static 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"); 3843 printf("XER bits: (64)"); 3844 dissect_xer(0xffffffffffffffff); 3845 printf("\n"); 3846 printf("XER bits: (32)"); 3847 dissect_xer(0xffffffff); 3848 printf("\n\n"); 3849 } 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; 3884 if (family == PPC_MFFS && seln_flags.mffs == 0) continue; 3885 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) { 3904 case PPC_MFFS: 3905 group_function = &testfunction_mffs; 3906 break; 3907 3908 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 4154 static 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" 4167 "\t-M: test MFFS instructions\n" 4168 "\t-v: be verbose\n" 4169 "\t-h: display this help and exit\n" 4170 ); 4171 } 4172 4173 #endif // HAS_ISA_3_00 4174 int 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; 4214 flags.mffs = 0; 4215 flags.no_op = 0; 4216 flags.pc_immediate = 0; 4217 4218 // Flags 4219 flags.cr = 2; 4220 4221 while ((c = getopt(argc, argv, "ifmadqhvADBMNP")) != -1) { 4222 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 4251 case 'M': 4252 flags.mffs = 1; 4253 break; 4254 4255 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 } 4340