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